packages feed

pcre2 (empty) → 1.0.0

raw patch · 84 files changed

+121978/−0 lines, 84 filesdep +basedep +containersdep +criterionsetup-changed

Dependencies added: base, containers, criterion, hspec, microlens-platform, mtl, pcre-light, pcre2, regex-pcre-builtin, template-haskell, text

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for pcre2++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,202 @@++                                 Apache License+                           Version 2.0, January 2004+                        http://www.apache.org/licenses/++   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION++   1. Definitions.++      "License" shall mean the terms and conditions for use, reproduction,+      and distribution as defined by Sections 1 through 9 of this document.++      "Licensor" shall mean the copyright owner or entity authorized by+      the copyright owner that is granting the License.++      "Legal Entity" shall mean the union of the acting entity and all+      other entities that control, are controlled by, or are under common+      control with that entity. For the purposes of this definition,+      "control" means (i) the power, direct or indirect, to cause the+      direction or management of such entity, whether by contract or+      otherwise, or (ii) ownership of fifty percent (50%) or more of the+      outstanding shares, or (iii) beneficial ownership of such entity.++      "You" (or "Your") shall mean an individual or Legal Entity+      exercising permissions granted by this License.++      "Source" form shall mean the preferred form for making modifications,+      including but not limited to software source code, documentation+      source, and configuration files.++      "Object" form shall mean any form resulting from mechanical+      transformation or translation of a Source form, including but+      not limited to compiled object code, generated documentation,+      and conversions to other media types.++      "Work" shall mean the work of authorship, whether in Source or+      Object form, made available under the License, as indicated by a+      copyright notice that is included in or attached to the work+      (an example is provided in the Appendix below).++      "Derivative Works" shall mean any work, whether in Source or Object+      form, that is based on (or derived from) the Work and for which the+      editorial revisions, annotations, elaborations, or other modifications+      represent, as a whole, an original work of authorship. For the purposes+      of this License, Derivative Works shall not include works that remain+      separable from, or merely link (or bind by name) to the interfaces of,+      the Work and Derivative Works thereof.++      "Contribution" shall mean any work of authorship, including+      the original version of the Work and any modifications or additions+      to that Work or Derivative Works thereof, that is intentionally+      submitted to Licensor for inclusion in the Work by the copyright owner+      or by an individual or Legal Entity authorized to submit on behalf of+      the copyright owner. For the purposes of this definition, "submitted"+      means any form of electronic, verbal, or written communication sent+      to the Licensor or its representatives, including but not limited to+      communication on electronic mailing lists, source code control systems,+      and issue tracking systems that are managed by, or on behalf of, the+      Licensor for the purpose of discussing and improving the Work, but+      excluding communication that is conspicuously marked or otherwise+      designated in writing by the copyright owner as "Not a Contribution."++      "Contributor" shall mean Licensor and any individual or Legal Entity+      on behalf of whom a Contribution has been received by Licensor and+      subsequently incorporated within the Work.++   2. Grant of Copyright License. Subject to the terms and conditions of+      this License, each Contributor hereby grants to You a perpetual,+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable+      copyright license to reproduce, prepare Derivative Works of,+      publicly display, publicly perform, sublicense, and distribute the+      Work and such Derivative Works in Source or Object form.++   3. Grant of Patent License. Subject to the terms and conditions of+      this License, each Contributor hereby grants to You a perpetual,+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable+      (except as stated in this section) patent license to make, have made,+      use, offer to sell, sell, import, and otherwise transfer the Work,+      where such license applies only to those patent claims licensable+      by such Contributor that are necessarily infringed by their+      Contribution(s) alone or by combination of their Contribution(s)+      with the Work to which such Contribution(s) was submitted. If You+      institute patent litigation against any entity (including a+      cross-claim or counterclaim in a lawsuit) alleging that the Work+      or a Contribution incorporated within the Work constitutes direct+      or contributory patent infringement, then any patent licenses+      granted to You under this License for that Work shall terminate+      as of the date such litigation is filed.++   4. Redistribution. You may reproduce and distribute copies of the+      Work or Derivative Works thereof in any medium, with or without+      modifications, and in Source or Object form, provided that You+      meet the following conditions:++      (a) You must give any other recipients of the Work or+          Derivative Works a copy of this License; and++      (b) You must cause any modified files to carry prominent notices+          stating that You changed the files; and++      (c) You must retain, in the Source form of any Derivative Works+          that You distribute, all copyright, patent, trademark, and+          attribution notices from the Source form of the Work,+          excluding those notices that do not pertain to any part of+          the Derivative Works; and++      (d) If the Work includes a "NOTICE" text file as part of its+          distribution, then any Derivative Works that You distribute must+          include a readable copy of the attribution notices contained+          within such NOTICE file, excluding those notices that do not+          pertain to any part of the Derivative Works, in at least one+          of the following places: within a NOTICE text file distributed+          as part of the Derivative Works; within the Source form or+          documentation, if provided along with the Derivative Works; or,+          within a display generated by the Derivative Works, if and+          wherever such third-party notices normally appear. The contents+          of the NOTICE file are for informational purposes only and+          do not modify the License. You may add Your own attribution+          notices within Derivative Works that You distribute, alongside+          or as an addendum to the NOTICE text from the Work, provided+          that such additional attribution notices cannot be construed+          as modifying the License.++      You may add Your own copyright statement to Your modifications and+      may provide additional or different license terms and conditions+      for use, reproduction, or distribution of Your modifications, or+      for any such Derivative Works as a whole, provided Your use,+      reproduction, and distribution of the Work otherwise complies with+      the conditions stated in this License.++   5. Submission of Contributions. Unless You explicitly state otherwise,+      any Contribution intentionally submitted for inclusion in the Work+      by You to the Licensor shall be under the terms and conditions of+      this License, without any additional terms or conditions.+      Notwithstanding the above, nothing herein shall supersede or modify+      the terms of any separate license agreement you may have executed+      with Licensor regarding such Contributions.++   6. Trademarks. This License does not grant permission to use the trade+      names, trademarks, service marks, or product names of the Licensor,+      except as required for reasonable and customary use in describing the+      origin of the Work and reproducing the content of the NOTICE file.++   7. Disclaimer of Warranty. Unless required by applicable law or+      agreed to in writing, Licensor provides the Work (and each+      Contributor provides its Contributions) on an "AS IS" BASIS,+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or+      implied, including, without limitation, any warranties or conditions+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A+      PARTICULAR PURPOSE. You are solely responsible for determining the+      appropriateness of using or redistributing the Work and assume any+      risks associated with Your exercise of permissions under this License.++   8. Limitation of Liability. In no event and under no legal theory,+      whether in tort (including negligence), contract, or otherwise,+      unless required by applicable law (such as deliberate and grossly+      negligent acts) or agreed to in writing, shall any Contributor be+      liable to You for damages, including any direct, indirect, special,+      incidental, or consequential damages of any character arising as a+      result of this License or out of the use or inability to use the+      Work (including but not limited to damages for loss of goodwill,+      work stoppage, computer failure or malfunction, or any and all+      other commercial damages or losses), even if such Contributor+      has been advised of the possibility of such damages.++   9. Accepting Warranty or Additional Liability. While redistributing+      the Work or Derivative Works thereof, You may choose to offer,+      and charge a fee for, acceptance of support, warranty, indemnity,+      or other liability obligations and/or rights consistent with this+      License. However, in accepting such obligations, You may act only+      on Your own behalf and on Your sole responsibility, not on behalf+      of any other Contributor, and only if You agree to indemnify,+      defend, and hold each Contributor harmless for any liability+      incurred by, or claims asserted against, such Contributor by reason+      of your accepting any such warranty or additional liability.++   END OF TERMS AND CONDITIONS++   APPENDIX: How to apply the Apache License to your work.++      To apply the Apache License to your work, attach the following+      boilerplate notice, with the fields enclosed by brackets "[]"+      replaced with your own identifying information. (Don't include+      the brackets!)  The text should be enclosed in the appropriate+      comment syntax for the file format. We also recommend that a+      file or class name and description of purpose be included on the+      same "printed page" as the copyright notice for easier+      identification within third-party archives.++   Copyright [yyyy] [name of copyright owner]++   Licensed under the Apache License, Version 2.0 (the "License");+   you may not use this file except in compliance with the License.+   You may obtain a copy of the License at++       http://www.apache.org/licenses/LICENSE-2.0++   Unless required by applicable law or agreed to in writing, software+   distributed under the License is distributed on an "AS IS" BASIS,+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+   See the License for the specific language governing permissions and+   limitations under the License.
+ README.md view
@@ -0,0 +1,66 @@+# pcre2++Regular expressions for Haskell.++## Teasers+```haskell+embeddedLicensePlate :: Text -> Maybe Text+embeddedLicensePlate = match "[A-Z]{3}[0-9]{3,4}"+```+```haskell+case "The quick brown fox" of+    [regex|brown\s+(?<animal>\S+)|] -> Text.putStrLn animal+    _                               -> error "nothing brown"+```+```haskell+let kv'd = lined . packed . [_regex|^\s*(.*?)\s*[=:]\s*(.*)|]++forMOf kv'd file $ execStateT $ do+    k <- gets $ capture @1+    v <- gets $ capture @2+    liftIO $ Text.putStrLn $ "found " <> k <> " set to " <> v++    case myMap ^. at k of+        Just v' | v /= v' -> do+            liftIO $ Text.putStrLn $ "setting " <> k <> " to " <> v'+            _capture @2 .= v'+        _ -> liftIO $ Text.putStrLn "no change"+```++## Features+* Low-surface API covering most use cases.+* Quiet functions with simple types&mdash;for the most part it's  +`Text` _(pattern)_ `-> Text` _(subject)_ `-> result`.+* Use partial application to create performant, compile-once-match-many code.+* Low cognitive overhead&mdash;there's just one custom datatype for both compile+  and match options, the `Option` monoid.+* `Text` everywhere for interop with both C and the broader Haskell ecosystem.+* Match failures expressed via `Alternative` or pattern match failures.+* Opt-in Template Haskell facilities for compile-time verification of patterns,+  indexing captures, and memoizing inline regexes.+* Opt-in `lens` support.+* No failure monads to express compile errors, preferring pure functions and+  throwing imprecise exceptions with pretty `Show` instances.  Write simple+  code and debug it.  Or, don't, and use the Template Haskell features instead.+  Both are first-class.+* Vast presentation of PCRE2 functionality.  We can even register Haskell+  callbacks to run during matching!+* No dependencies that aren't distributed with GHC.+* Bundled, statically-linked UTF-16 build of ~~up-to-date~~ PCRE2 (version+  10.35), with a complete, exposed Haskell binding.++## TODO+* Global matching.  (We already have global substitution.)+* Many performance optimizations.  Currently we are 2&ndash;3&times; slower+  than other libraries doing everything (a few &mu;s).+* Make use of DFA and JIT compilation.+* Establish automated builds.+* Improve PCRE2 C compile time.+* PCRE2 10.36 is out already.++## License+[Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.html).  +PCRE2 is distributed under the [3-clause BSD](https://www.pcre.org/licence.txt) license.++## Author+&copy;2020 Shlomo Shuck
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bench/Bench.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}++module Main where++import           Criterion.Main+import           Data.List.NonEmpty          (NonEmpty(..))+import qualified Data.Text                   as Text+import           Lens.Micro.Platform+import           System.IO.Unsafe            (unsafePerformIO)+import qualified Text.Regex.PCRE+import qualified Text.Regex.PCRE.Light.Char8+import qualified Text.Regex.PCRE.String+import qualified Text.Regex.PCRE.Text+import           Text.Regex.Pcre2++main :: IO ()+main = defaultMain [+    bgroup "creating single-use regexes" [+        bench "pcre2" $ flip nf strings $ \(patt, subj) ->+            let Just (_ :| [bar]) = capturesA (Text.pack patt) (Text.pack subj)+            in Text.unpack bar,++        bench "regex-pcre-builtin" $ flip nf strings $ \(patt, subj) ->+            let r = Text.Regex.PCRE.makeRegex patt :: Text.Regex.PCRE.Regex+                results :: (String, String, String)+                results@(_, result, _) = Text.Regex.PCRE.match r subj+            in result,++        bench "pcre-light" $ flip nf strings $ \(patt, subj) ->+            let r = Text.Regex.PCRE.Light.Char8.compile patt []+                Just [_, bar] = Text.Regex.PCRE.Light.Char8.match r subj []+            in bar],+    +    bgroup "strings" [+        let r = capturesA $ Text.pack stringPattern+        in bench "pcre2" $ flip nf stringSubject $ \subj ->+            let Just (_ :| [bar]) = r $ Text.pack subj in Text.unpack bar,++        let r = mkRegexBaseR stringPattern+        in bench "regex-pcre-builtin" $ nfIO $ do+            Right (Just (_, _, _, [bar])) <-+                Text.Regex.PCRE.String.regexec r stringSubject+            return bar,++        let r = Text.Regex.PCRE.Light.Char8.compile stringPattern []+        in bench "pcre-light" $ flip nf stringSubject $ \subj ->+            let Just [_, bar] = Text.Regex.PCRE.Light.Char8.match r subj []+            in bar],++    bgroup "texts" [+        bgroupTexts "short" strings,++        bgroupTexts "long" (+            "foo (ba*r) baz",+            "foo b" ++ replicate 1000 'a' ++ "r baz")],++    bgroup "Template Haskell" [+        bench "pattern with named capture" $ flip nf textSubject $ \subj ->+            let [regex|foo (?<bar>bar) baz|] = subj in bar,++        bench "expression with capture" $ flip nf textSubject $ \subj ->+            let Just cs = [regex|foo (?<bar>bar) baz|] subj+            in capture @"bar" cs],++    bgroup "substitutions" [+        bench "PCRE2-native" $ flip nf textSubject $+            sub (Text.pack "(?<=foo )bar(?= baz)") (Text.pack "quux"),++        let quux = Text.pack "quux"+        in bench "lens-powered" $ flip nf textSubject $+            set ([_regex|foo (bar) baz|] . _capture @1) quux]]++stringPattern = "foo (bar) baz"+stringSubject = "foo bar baz"+strings = (stringPattern, stringSubject)++textPattern = Text.pack "foo (bar) baz"+textSubject = Text.pack "foo bar baz"++mkRegexBaseR :: String -> Text.Regex.PCRE.Regex+mkRegexBaseR patt = unsafePerformIO $ do+    Right r <- Text.Regex.PCRE.String.compile 0 0 patt+    return r++bgroupTexts :: String -> (String, String) -> Benchmark+bgroupTexts label (patt, subj) = bgroup label [+    bench "pcre2" $ flip nf textSubject $ \subj ->+        let Just (_ :| [bar]) = pcre2R subj in bar,++    bench "regex-pcre-builtin" $ nfIO $ do+        Text.Regex.PCRE.Text.regexec regexBaseR textSubject >>= \case+            Right (Just (_, _, _, [bar])) -> return bar+            x                             -> do+                print x+                error "BUG!",++    bench "pcre-light" $ flip nf textSubject $ \subj ->+        let Just [_, bar] = Text.Regex.PCRE.Light.Char8.match+                pcreLightR+                (Text.unpack subj)+                []+        in bar]++    where+    textPattern = Text.pack patt+    textSubject = Text.pack subj+    pcre2R = capturesA textPattern+    regexBaseR = mkRegexBaseR patt+    pcreLightR = Text.Regex.PCRE.Light.Char8.compile patt []
+ pcre2.cabal view
@@ -0,0 +1,186 @@+cabal-version:      1.12+name:               pcre2+version:            1.0.0+license:            Apache-2.0+license-file:       LICENSE+copyright:          2020 Shlomo Shuck+maintainer:         stevenjshuck@gmail.com+author:             Shlomo Shuck+homepage:           https://github.com/sjshuck/hs-pcre2#readme+bug-reports:        https://github.com/sjshuck/hs-pcre2/issues+synopsis:           Regular expressions via the PCRE2 C library (included)+description:+    Please see the README on GitHub at <https://github.com/sjshuck/hs-pcre2>++category:           Text+build-type:         Simple+extra-source-files:+    README.md+    ChangeLog.md+    src/c/config.h+    src/c/getters.h+    src/c/pcre2.h+    src/c/pcre2/src/pcre2_internal.h+    src/c/pcre2/src/pcre2_intmodedep.h+    src/c/pcre2/src/pcre2_jit_neon_inc.h+    src/c/pcre2/src/pcre2_jit_simd_inc.h+    src/c/pcre2/src/pcre2_ucp.h+    src/c/pcre2/src/pcre2posix.h+    src/c/pcre2/src/sljit/sljitConfig.h+    src/c/pcre2/src/sljit/sljitConfigInternal.h+    src/c/pcre2/src/sljit/sljitLir.h+    src/c/pcre2/maint/ucptest.c+    src/c/pcre2/maint/utf8.c+    src/c/pcre2/src/pcre2_auto_possess.c+    src/c/pcre2/src/pcre2_compile.c+    src/c/pcre2/src/pcre2_config.c+    src/c/pcre2/src/pcre2_context.c+    src/c/pcre2/src/pcre2_convert.c+    src/c/pcre2/src/pcre2_dfa_match.c+    src/c/pcre2/src/pcre2_dftables.c+    src/c/pcre2/src/pcre2_error.c+    src/c/pcre2/src/pcre2_extuni.c+    src/c/pcre2/src/pcre2_find_bracket.c+    src/c/pcre2/src/pcre2_fuzzsupport.c+    src/c/pcre2/src/pcre2_jit_compile.c+    src/c/pcre2/src/pcre2_jit_match.c+    src/c/pcre2/src/pcre2_jit_misc.c+    src/c/pcre2/src/pcre2_jit_test.c+    src/c/pcre2/src/pcre2_maketables.c+    src/c/pcre2/src/pcre2_match.c+    src/c/pcre2/src/pcre2_match_data.c+    src/c/pcre2/src/pcre2_newline.c+    src/c/pcre2/src/pcre2_ord2utf.c+    src/c/pcre2/src/pcre2_pattern_info.c+    src/c/pcre2/src/pcre2_printint.c+    src/c/pcre2/src/pcre2_script_run.c+    src/c/pcre2/src/pcre2_serialize.c+    src/c/pcre2/src/pcre2_string_utils.c+    src/c/pcre2/src/pcre2_study.c+    src/c/pcre2/src/pcre2_substitute.c+    src/c/pcre2/src/pcre2_substring.c+    src/c/pcre2/src/pcre2_tables.c+    src/c/pcre2/src/pcre2_ucd.c+    src/c/pcre2/src/pcre2_valid_utf.c+    src/c/pcre2/src/pcre2_xclass.c+    src/c/pcre2/src/pcre2demo.c+    src/c/pcre2/src/pcre2grep.c+    src/c/pcre2/src/pcre2posix.c+    src/c/pcre2/src/pcre2test.c+    src/c/pcre2/src/sljit/sljitExecAllocator.c+    src/c/pcre2/src/sljit/sljitLir.c+    src/c/pcre2/src/sljit/sljitNativeARM_32.c+    src/c/pcre2/src/sljit/sljitNativeARM_64.c+    src/c/pcre2/src/sljit/sljitNativeARM_T2_32.c+    src/c/pcre2/src/sljit/sljitNativeMIPS_32.c+    src/c/pcre2/src/sljit/sljitNativeMIPS_64.c+    src/c/pcre2/src/sljit/sljitNativeMIPS_common.c+    src/c/pcre2/src/sljit/sljitNativePPC_32.c+    src/c/pcre2/src/sljit/sljitNativePPC_64.c+    src/c/pcre2/src/sljit/sljitNativePPC_common.c+    src/c/pcre2/src/sljit/sljitNativeSPARC_32.c+    src/c/pcre2/src/sljit/sljitNativeSPARC_common.c+    src/c/pcre2/src/sljit/sljitNativeTILEGX-encoder.c+    src/c/pcre2/src/sljit/sljitNativeTILEGX_64.c+    src/c/pcre2/src/sljit/sljitNativeX86_32.c+    src/c/pcre2/src/sljit/sljitNativeX86_64.c+    src/c/pcre2/src/sljit/sljitNativeX86_common.c+    src/c/pcre2/src/sljit/sljitProtExecAllocator.c+    src/c/pcre2/src/sljit/sljitUtils.c+    src/c/pcre2/src/sljit/sljitWXExecAllocator.c+    src/c/pcre2_chartables.c++source-repository head+    type:     git+    location: https://github.com/sjshuck/hs-pcre2++library+    exposed-modules:+        Text.Regex.Pcre2+        Text.Regex.Pcre2.Foreign++    cc-options:       -DHAVE_CONFIG_H -DPCRE2_CODE_UNIT_WIDTH=16+    c-sources:+        src/c/pcre2/src/pcre2_auto_possess.c+        src/c/pcre2_chartables.c+        src/c/pcre2/src/pcre2_compile.c+        src/c/pcre2/src/pcre2_config.c+        src/c/pcre2/src/pcre2_context.c+        src/c/pcre2/src/pcre2_convert.c+        src/c/pcre2/src/pcre2_dfa_match.c+        src/c/pcre2/src/pcre2_error.c+        src/c/pcre2/src/pcre2_extuni.c+        src/c/pcre2/src/pcre2_find_bracket.c+        src/c/pcre2/src/pcre2_jit_compile.c+        src/c/pcre2/src/pcre2_maketables.c+        src/c/pcre2/src/pcre2_match.c+        src/c/pcre2/src/pcre2_match_data.c+        src/c/pcre2/src/pcre2_newline.c+        src/c/pcre2/src/pcre2_ord2utf.c+        src/c/pcre2/src/pcre2_pattern_info.c+        src/c/pcre2/src/pcre2_script_run.c+        src/c/pcre2/src/pcre2_serialize.c+        src/c/pcre2/src/pcre2_string_utils.c+        src/c/pcre2/src/pcre2_study.c+        src/c/pcre2/src/pcre2_substitute.c+        src/c/pcre2/src/pcre2_substring.c+        src/c/pcre2/src/pcre2_tables.c+        src/c/pcre2/src/pcre2_ucd.c+        src/c/pcre2/src/pcre2_valid_utf.c+        src/c/pcre2/src/pcre2_xclass.c++    hs-source-dirs:   src/hs+    other-modules:+        Text.Regex.Pcre2.Foreign.TH+        Text.Regex.Pcre2.Internal+        Text.Regex.Pcre2.TH+        Paths_pcre2++    default-language: Haskell2010+    include-dirs:     src/c src/c/pcre2/src+    ghc-options:+        -optc=-DPCRE2_CODE_UNIT_WIDTH=16 -optc=-Wno-discarded-qualifiers+        -optc=-Wno-incompatible-pointer-types++    build-depends:+        base >=4.7 && <5,+        containers >=0.6.2.1 && <0.7,+        mtl >=2.2.2 && <2.3,+        template-haskell >=2.15.0.0 && <2.16,+        text >=1.2.4.0 && <1.3++test-suite pcre2-test+    type:             exitcode-stdio-1.0+    main-is:          Spec.hs+    hs-source-dirs:   test+    other-modules:    Paths_pcre2+    default-language: Haskell2010+    ghc-options:      -threaded -rtsopts -with-rtsopts=-N+    build-depends:+        base >=4.7 && <5,+        containers >=0.6.2.1 && <0.7,+        hspec >=2.7.4 && <2.8,+        microlens-platform >=0.4.2 && <0.5,+        mtl >=2.2.2 && <2.3,+        pcre2 -any,+        template-haskell >=2.15.0.0 && <2.16,+        text >=1.2.4.0 && <1.3++benchmark pcre2-benchmarks+    type:             exitcode-stdio-1.0+    main-is:          Bench.hs+    hs-source-dirs:   bench+    other-modules:    Paths_pcre2+    default-language: Haskell2010+    ghc-options:      -threaded -rtsopts -with-rtsopts=-N+    build-depends:+        base >=4.7 && <5,+        containers >=0.6.2.1 && <0.7,+        criterion >=1.5.7.0 && <1.6,+        microlens-platform >=0.4.2 && <0.5,+        mtl >=2.2.2 && <2.3,+        pcre-light >=0.4.1.0 && <0.5,+        pcre2 -any,+        regex-pcre-builtin >=0.95.1.3.8.43 && <0.96,+        template-haskell >=2.15.0.0 && <2.16,+        text >=1.2.4.0 && <1.3
+ src/c/config.h view
@@ -0,0 +1,380 @@+// Copied and edited per the PCRE2 source's NON-AUTOTOOLS-BUILD instructions.++/* 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.++In environments that support the GNU autotools, config.h.in is converted into+config.h by the "configure" script. In environments that use CMake,+config-cmake.in is converted into config.h. If you are going to build PCRE2 "by+hand" without using "configure" or CMake, you should copy the distributed+config.h.generic to config.h, and edit the macro definitions to be the way you+need them. You must then add -DHAVE_CONFIG_H to all of your compile commands,+so that config.h is included at the start of every source.++Alternatively, you can avoid editing by using -D on the compiler command line+to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,+but if you do, default values will be taken from config.h for non-boolean+macros that are not defined on the command line.++Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be+defined (conventionally to 1) for TRUE, and not defined at all for FALSE. All+such macros are listed as a commented #undef in config.h.generic. Macros such+as MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are+surrounded by #ifndef/#endif lines so that the value can be overridden by -D.++PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if+HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make+sure both macros are undefined; an emulation function will then be used. */++/* By default, the \R escape sequence matches any Unicode line ending+   character or sequence of characters. If BSR_ANYCRLF is defined (to any+   value), this is changed so that backslash-R matches only CR, LF, or CRLF.+   The build-time default can be overridden by the user of PCRE2 at runtime.+   */+/* #undef BSR_ANYCRLF */++/* Define to any value to disable the use of the z and t modifiers in+   formatting settings such as %zu or %td (this is rarely needed). */+/* #undef DISABLE_PERCENT_ZT */++/* If you are compiling for a system that uses EBCDIC instead of ASCII+   character codes, define this macro to any value. When EBCDIC is set, PCRE2+   assumes that all input strings are in EBCDIC. If you do not define this+   macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It+   is not possible to build a version of PCRE2 that supports both EBCDIC and+   UTF-8/16/32. */+/* #undef EBCDIC */++/* In an EBCDIC environment, define this macro to any value to arrange for the+   NL character to be 0x25 instead of the default 0x15. NL plays the role that+   LF does in an ASCII/Unicode environment. */+/* #undef EBCDIC_NL25 */++/* Define this if your compiler supports __attribute__((uninitialized)) */+/* #undef HAVE_ATTRIBUTE_UNINITIALIZED */++/* Define to 1 if you have the `bcopy' function. */+/* #undef HAVE_BCOPY */++/* Define to 1 if you have the <bzlib.h> header file. */+/* #undef HAVE_BZLIB_H */++/* Define to 1 if you have the <dirent.h> header file. */+/* #undef HAVE_DIRENT_H */++/* Define to 1 if you have the <dlfcn.h> header file. */+/* #undef HAVE_DLFCN_H */++/* Define to 1 if you have the <editline/readline.h> header file. */+/* #undef HAVE_EDITLINE_READLINE_H */++/* Define to 1 if you have the <edit/readline/readline.h> header file. */+/* #undef HAVE_EDIT_READLINE_READLINE_H */++/* Define to 1 if you have the <inttypes.h> header file. */+#define HAVE_INTTYPES_H 1++/* Define to 1 if you have the <limits.h> header file. */+#define HAVE_LIMITS_H 1++/* Define to 1 if you have the `memfd_create' function. */+/* #undef HAVE_MEMFD_CREATE */++/* Define to 1 if you have the `memmove' function. */+#define HAVE_MEMMOVE 1++/* 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 */++/* Have PTHREAD_PRIO_INHERIT. */+/* #undef HAVE_PTHREAD_PRIO_INHERIT */++/* Define to 1 if you have the <readline/history.h> header file. */+/* #undef HAVE_READLINE_HISTORY_H */++/* 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++/* Define to 1 if you have the <stdlib.h> header file. */+#define HAVE_STDLIB_H 1++/* Define to 1 if you have the `strerror' function. */+#define HAVE_STRERROR 1++/* Define to 1 if you have the <strings.h> header file. */+/* #undef HAVE_STRINGS_H */++/* Define to 1 if you have the <string.h> header file. */+#define HAVE_STRING_H 1++/* Define to 1 if you have the <sys/stat.h> header file. */+/* #undef HAVE_SYS_STAT_H */++/* Define to 1 if you have the <sys/types.h> header file. */+/* #undef HAVE_SYS_TYPES_H */++/* Define to 1 if you have the <sys/wait.h> header file. */+/* #undef HAVE_SYS_WAIT_H */++/* Define to 1 if you have the <unistd.h> header file. */+/* #undef HAVE_UNISTD_H */++/* Define to 1 if the compiler supports simple visibility declarations. */+/* #undef HAVE_VISIBILITY */++/* Define to 1 if you have the <windows.h> header file. */+/* #undef HAVE_WINDOWS_H */++/* Define to 1 if you have the <zlib.h> header file. */+/* #undef HAVE_ZLIB_H */++/* This limits the amount of memory that may be used while matching a pattern.+   It applies to both pcre2_match() and pcre2_dfa_match(). It does not apply+   to JIT matching. The value is in kibibytes (units of 1024 bytes). */+#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+   compiled patterns up to 65535 code units 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+   pcre2_match() function can record a backtrack position during a single+   matching attempt. The value is also used to limit a loop counter in+   pcre2_dfa_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+#define MATCH_LIMIT 10000000+#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. In the case of pcre2_dfa_match(), this limit controls the depth of+   the internal nested function calls that are used for pattern recursions,+   lookarounds, and atomic groups. */+#ifndef MATCH_LIMIT_DEPTH+#define MATCH_LIMIT_DEPTH MATCH_LIMIT+#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_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), 5+   (ANYCRLF), and 6 (NUL). */+#ifndef NEWLINE_DEFAULT+#define NEWLINE_DEFAULT 2+#endif++/* Name of package */+#define PACKAGE "pcre2"++/* Define to the address where bug reports for this package should be sent. */+#define PACKAGE_BUGREPORT ""++/* Define to the full name of this package. */+#define PACKAGE_NAME "PCRE2"++/* Define to the full name and version of this package. */+#define PACKAGE_STRING "PCRE2 10.35"++/* Define to the one symbol short name of this package. */+#define PACKAGE_TARNAME "pcre2"++/* Define to the home page for this package. */+#define PACKAGE_URL ""++/* Define to the version of this package. */+#define PACKAGE_VERSION "10.35"++/* 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 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 */++/* 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+   contain the relevant magic. If you do not define this macro, a suitable+    __declspec value is used for Windows systems; in other environments+   "extern" is used for a C compiler and "extern C" for a C++ compiler.+   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 to any value if linking statically (TODO: make nice with Libtool) */+#define PCRE2_STATIC 1++/* Define to necessary symbol if this constant uses a non-standard name on+   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. */+#define SUPPORT_JIT 1++/* Define to any value to allow pcre2grep to be linked with libbz2, so that it+   is able to handle .bz2 files. */+/* #undef SUPPORT_LIBBZ2 */++/* Define to any value to allow pcre2test to be linked with libedit. */+/* #undef SUPPORT_LIBEDIT */++/* Define to any value to allow pcre2test to be linked with libreadline. */+/* #undef SUPPORT_LIBREADLINE */++/* Define to any value to allow pcre2grep to be linked with libz, so that it+   is able to handle .gz files. */+/* #undef SUPPORT_LIBZ */++/* Define to any value to enable callout script support in pcre2grep. */+/* #undef SUPPORT_PCRE2GREP_CALLOUT */++/* Define to any value to enable fork support in pcre2grep callout scripts.+   This will have no effect unless SUPPORT_PCRE2GREP_CALLOUT is also defined.+   */+/* #undef SUPPORT_PCRE2GREP_CALLOUT_FORK */++/* 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. */+#define SUPPORT_PCRE2_16 1++/* Define to any value to enable the 32 bit PCRE2 library. */+/* #undef SUPPORT_PCRE2_32 */++/* Define to any value to enable the 8 bit PCRE2 library. */+/* #undef 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. */+#define SUPPORT_UNICODE 1++/* 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.35"++/* 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 */++/* Define to the type of a signed integer type of width exactly 64 bits if+   such a type exists and the standard includes do not define it. */+/* #undef int64_t */++/* Define to `unsigned int' if <sys/types.h> does not define. */+/* #undef size_t */
+ src/c/getters.h view
@@ -0,0 +1,60 @@+// Functions to get PCRE2 struct fields.++#include <pcre2.h>++#ifndef GETTERS_H+#define GETTERS_H++#ifdef GETTER+#error GETTER already defined+#endif+#define GETTER(src, field, ret) \+    ret pcre2_##src##_##field(pcre2_##src *block) \+    { \+        return block->field; \+    }++/*+    For example, the first of these produces the following code:++    uint32_t pcre2_callout_block_version(pcre2_callout_block *block)+    {+        return block->version;+    }+*/+GETTER(callout_block, version,               uint32_t)+GETTER(callout_block, callout_number,        uint32_t)+GETTER(callout_block, capture_top,           uint32_t)+GETTER(callout_block, capture_last,          uint32_t)+GETTER(callout_block, callout_flags,         uint32_t)+GETTER(callout_block, offset_vector,         PCRE2_SIZE *)+GETTER(callout_block, mark,                  PCRE2_SPTR)+GETTER(callout_block, subject,               PCRE2_SPTR)+GETTER(callout_block, subject_length,        PCRE2_SIZE)+GETTER(callout_block, start_match,           PCRE2_SIZE)+GETTER(callout_block, current_position,      PCRE2_SIZE)+GETTER(callout_block, pattern_position,      PCRE2_SIZE)+GETTER(callout_block, next_item_length,      PCRE2_SIZE)+GETTER(callout_block, callout_string_offset, PCRE2_SIZE)+GETTER(callout_block, callout_string_length, PCRE2_SIZE)+GETTER(callout_block, callout_string,        PCRE2_SPTR)++GETTER(callout_enumerate_block, version,               uint32_t)+GETTER(callout_enumerate_block, pattern_position,      PCRE2_SIZE)+GETTER(callout_enumerate_block, next_item_length,      PCRE2_SIZE)+GETTER(callout_enumerate_block, callout_number,        uint32_t)+GETTER(callout_enumerate_block, callout_string_offset, PCRE2_SIZE)+GETTER(callout_enumerate_block, callout_string_length, PCRE2_SIZE)+GETTER(callout_enumerate_block, callout_string,        PCRE2_SPTR)++GETTER(substitute_callout_block, version,        uint32_t)+GETTER(substitute_callout_block, subscount,      uint32_t)+GETTER(substitute_callout_block, input,          PCRE2_SPTR)+GETTER(substitute_callout_block, output,         PCRE2_SPTR)+GETTER(substitute_callout_block, ovector,        PCRE2_SIZE *)+GETTER(substitute_callout_block, oveccount,      uint32_t)+GETTER(substitute_callout_block, output_offsets, PCRE2_SIZE *) // array of 2++#undef GETTER++#endif
+ src/c/pcre2.h view
@@ -0,0 +1,993 @@+// Copied per the PCRE2 source's NON-AUTOTOOLS-BUILD instructions.++/*************************************************+*       Perl-Compatible Regular Expressions      *+*************************************************/++/* This is the public header file for the PCRE library, second API, to be+#included by applications that call PCRE2 functions.++           Copyright (c) 2016-2020 University of Cambridge++-----------------------------------------------------------------------------+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright notice,+      this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above copyright+      notice, this list of conditions and the following disclaimer in the+      documentation and/or other materials provided with the distribution.++    * Neither the name of the University of Cambridge nor the names of its+      contributors may be used to endorse or promote products derived from+      this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.+-----------------------------------------------------------------------------+*/++#ifndef PCRE2_H_IDEMPOTENT_GUARD+#define PCRE2_H_IDEMPOTENT_GUARD++/* The current PCRE version information. */++#define PCRE2_MAJOR           10+#define PCRE2_MINOR           35+#define PCRE2_PRERELEASE      +#define PCRE2_DATE            2020-05-09++/* 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+export setting is defined in pcre2_internal.h, which includes this file. So we+don't change existing definitions of PCRE2_EXP_DECL. */++#if defined(_WIN32) && !defined(PCRE2_STATIC)+#  ifndef PCRE2_EXP_DECL+#    define PCRE2_EXP_DECL  extern __declspec(dllimport)+#  endif+#endif++/* By default, we use the standard "extern" declarations. */++#ifndef PCRE2_EXP_DECL+#  ifdef __cplusplus+#    define PCRE2_EXP_DECL  extern "C"+#  else+#    define PCRE2_EXP_DECL  extern+#  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 inttypes.h to ensure that size_t and+uint8_t, UCHAR_MAX, etc are defined. Some systems that do have inttypes.h do+not have stdint.h, which is why we use inttypes.h, which according to the C+standard is a superset of stdint.h. If none of these headers are available,+the relevant values must be provided by some other means. */++#include <limits.h>+#include <stdlib.h>+#include <inttypes.h>++/* Allow for C++ users compiling this directly. */++#ifdef __cplusplus+extern "C" {+#endif++/* The following option bits can be passed to pcre2_compile(), pcre2_match(),+or pcre2_dfa_match(). PCRE2_NO_UTF_CHECK affects only the function to which it+is passed. Put these bits at the most significant end of the options word so+others can be added next to them */++#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.+The following tags indicate which:++C   alters what is compiled by pcre2_compile()+J   alters what is compiled by pcre2_jit_compile()+M   is inspected during pcre2_match() execution+D   is inspected during pcre2_dfa_match() execution+*/++#define PCRE2_ALLOW_EMPTY_CLASS   0x00000001u  /* C       */+#define PCRE2_ALT_BSUX            0x00000002u  /* C       */+#define PCRE2_AUTO_CALLOUT        0x00000004u  /* C       */+#define PCRE2_CASELESS            0x00000008u  /* C       */+#define PCRE2_DOLLAR_ENDONLY      0x00000010u  /*   J M D */+#define PCRE2_DOTALL              0x00000020u  /* C       */+#define PCRE2_DUPNAMES            0x00000040u  /* C       */+#define PCRE2_EXTENDED            0x00000080u  /* C       */+#define PCRE2_FIRSTLINE           0x00000100u  /*   J M D */+#define PCRE2_MATCH_UNSET_BACKREF 0x00000200u  /* C J M   */+#define PCRE2_MULTILINE           0x00000400u  /* C       */+#define PCRE2_NEVER_UCP           0x00000800u  /* C       */+#define PCRE2_NEVER_UTF           0x00001000u  /* C       */+#define PCRE2_NO_AUTO_CAPTURE     0x00002000u  /* C       */+#define PCRE2_NO_AUTO_POSSESS     0x00004000u  /* C       */+#define PCRE2_NO_DOTSTAR_ANCHOR   0x00008000u  /* C       */+#define PCRE2_NO_START_OPTIMIZE   0x00010000u  /*   J M D */+#define PCRE2_UCP                 0x00020000u  /* C J M D */+#define PCRE2_UNGREEDY            0x00040000u  /* C       */+#define PCRE2_UTF                 0x00080000u  /* C J M D */+#define PCRE2_NEVER_BACKSLASH_C   0x00100000u  /* C       */+#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       */+#define PCRE2_MATCH_INVALID_UTF   0x04000000u  /*   J M D */++/* 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 */+#define PCRE2_EXTRA_ESCAPED_CR_IS_LF         0x00000010u  /* C */+#define PCRE2_EXTRA_ALT_BSUX                 0x00000020u  /* C */++/* These are for pcre2_jit_compile(). */++#define PCRE2_JIT_COMPLETE        0x00000001u  /* For full matching */+#define PCRE2_JIT_PARTIAL_SOFT    0x00000002u+#define PCRE2_JIT_PARTIAL_HARD    0x00000004u+#define PCRE2_JIT_INVALID_UTF     0x00000100u++/* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and+pcre2_substitute(). Some are allowed only for one of the functions, and in+these cases it is noted below. Note that PCRE2_ANCHORED, PCRE2_ENDANCHORED and+PCRE2_NO_UTF_CHECK can also be passed to these functions (though+pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */++#define PCRE2_NOTBOL                      0x00000001u+#define PCRE2_NOTEOL                      0x00000002u+#define PCRE2_NOTEMPTY                    0x00000004u  /* ) These two must be kept */+#define PCRE2_NOTEMPTY_ATSTART            0x00000008u  /* ) adjacent to each other. */+#define PCRE2_PARTIAL_SOFT                0x00000010u+#define PCRE2_PARTIAL_HARD                0x00000020u+#define PCRE2_DFA_RESTART                 0x00000040u  /* pcre2_dfa_match() only */+#define PCRE2_DFA_SHORTEST                0x00000080u  /* pcre2_dfa_match() only */+#define PCRE2_SUBSTITUTE_GLOBAL           0x00000100u  /* pcre2_substitute() only */+#define PCRE2_SUBSTITUTE_EXTENDED         0x00000200u  /* pcre2_substitute() only */+#define PCRE2_SUBSTITUTE_UNSET_EMPTY      0x00000400u  /* pcre2_substitute() only */+#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET    0x00000800u  /* pcre2_substitute() only */+#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  0x00001000u  /* pcre2_substitute() only */+#define PCRE2_NO_JIT                      0x00002000u  /* Not for pcre2_dfa_match() */+#define PCRE2_COPY_MATCHED_SUBJECT        0x00004000u+#define PCRE2_SUBSTITUTE_LITERAL          0x00008000u  /* pcre2_substitute() only */+#define PCRE2_SUBSTITUTE_MATCHED          0x00010000u  /* pcre2_substitute() only */+#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u  /* pcre2_substitute() only */++/* 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. */++#define PCRE2_NEWLINE_CR          1+#define PCRE2_NEWLINE_LF          2+#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 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+/* Error 159 is obsolete and should now never occur */+#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+#define PCRE2_ERROR_SUPPORTED_ONLY_IN_UNICODE      193+#define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS      194+#define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN        195+#define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE       196+#define PCRE2_ERROR_TOO_MANY_CAPTURES              197+#define PCRE2_ERROR_CONDITION_ATOMIC_ASSERTION_EXPECTED  198+++/* "Expected" matching error codes: no match and partial match. */++#define PCRE2_ERROR_NOMATCH          (-1)+#define PCRE2_ERROR_PARTIAL          (-2)++/* Error codes for UTF-8 validity checks */++#define PCRE2_ERROR_UTF8_ERR1        (-3)+#define PCRE2_ERROR_UTF8_ERR2        (-4)+#define PCRE2_ERROR_UTF8_ERR3        (-5)+#define PCRE2_ERROR_UTF8_ERR4        (-6)+#define PCRE2_ERROR_UTF8_ERR5        (-7)+#define PCRE2_ERROR_UTF8_ERR6        (-8)+#define PCRE2_ERROR_UTF8_ERR7        (-9)+#define PCRE2_ERROR_UTF8_ERR8       (-10)+#define PCRE2_ERROR_UTF8_ERR9       (-11)+#define PCRE2_ERROR_UTF8_ERR10      (-12)+#define PCRE2_ERROR_UTF8_ERR11      (-13)+#define PCRE2_ERROR_UTF8_ERR12      (-14)+#define PCRE2_ERROR_UTF8_ERR13      (-15)+#define PCRE2_ERROR_UTF8_ERR14      (-16)+#define PCRE2_ERROR_UTF8_ERR15      (-17)+#define PCRE2_ERROR_UTF8_ERR16      (-18)+#define PCRE2_ERROR_UTF8_ERR17      (-19)+#define PCRE2_ERROR_UTF8_ERR18      (-20)+#define PCRE2_ERROR_UTF8_ERR19      (-21)+#define PCRE2_ERROR_UTF8_ERR20      (-22)+#define PCRE2_ERROR_UTF8_ERR21      (-23)++/* Error codes for UTF-16 validity checks */++#define PCRE2_ERROR_UTF16_ERR1      (-24)+#define PCRE2_ERROR_UTF16_ERR2      (-25)+#define PCRE2_ERROR_UTF16_ERR3      (-26)++/* Error codes for UTF-32 validity checks */++#define PCRE2_ERROR_UTF32_ERR1      (-27)+#define PCRE2_ERROR_UTF32_ERR2      (-28)++/* 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 */+#define PCRE2_ERROR_BADMAGIC          (-31)+#define PCRE2_ERROR_BADMODE           (-32)+#define PCRE2_ERROR_BADOFFSET         (-33)+#define PCRE2_ERROR_BADOPTION         (-34)+#define PCRE2_ERROR_BADREPLACEMENT    (-35)+#define PCRE2_ERROR_BADUTFOFFSET      (-36)+#define PCRE2_ERROR_CALLOUT           (-37)  /* Never used by PCRE2 itself */+#define PCRE2_ERROR_DFA_BADRESTART    (-38)+#define PCRE2_ERROR_DFA_RECURSE       (-39)+#define PCRE2_ERROR_DFA_UCOND         (-40)+#define PCRE2_ERROR_DFA_UFUNC         (-41)+#define PCRE2_ERROR_DFA_UITEM         (-42)+#define PCRE2_ERROR_DFA_WSSIZE        (-43)+#define PCRE2_ERROR_INTERNAL          (-44)+#define PCRE2_ERROR_JIT_BADOPTION     (-45)+#define PCRE2_ERROR_JIT_STACKLIMIT    (-46)+#define PCRE2_ERROR_MATCHLIMIT        (-47)+#define PCRE2_ERROR_NOMEMORY          (-48)+#define PCRE2_ERROR_NOSUBSTRING       (-49)+#define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)+#define PCRE2_ERROR_NULL              (-51)+#define PCRE2_ERROR_RECURSELOOP       (-52)+#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)+#define PCRE2_ERROR_BADREPESCAPE      (-57)+#define PCRE2_ERROR_REPMISSINGBRACE   (-58)+#define PCRE2_ERROR_BADSUBSTITUTION   (-59)+#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)+#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)+#define PCRE2_ERROR_DFA_UINVALID_UTF  (-66)+++/* Request types for pcre2_pattern_info() */++#define PCRE2_INFO_ALLOPTIONS            0+#define PCRE2_INFO_ARGOPTIONS            1+#define PCRE2_INFO_BACKREFMAX            2+#define PCRE2_INFO_BSR                   3+#define PCRE2_INFO_CAPTURECOUNT          4+#define PCRE2_INFO_FIRSTCODEUNIT         5+#define PCRE2_INFO_FIRSTCODETYPE         6+#define PCRE2_INFO_FIRSTBITMAP           7+#define PCRE2_INFO_HASCRORLF             8+#define PCRE2_INFO_JCHANGED              9+#define PCRE2_INFO_JITSIZE              10+#define PCRE2_INFO_LASTCODEUNIT         11+#define PCRE2_INFO_LASTCODETYPE         12+#define PCRE2_INFO_MATCHEMPTY           13+#define PCRE2_INFO_MATCHLIMIT           14+#define PCRE2_INFO_MAXLOOKBEHIND        15+#define PCRE2_INFO_MINLENGTH            16+#define PCRE2_INFO_NAMECOUNT            17+#define PCRE2_INFO_NAMEENTRYSIZE        18+#define PCRE2_INFO_NAMETABLE            19+#define PCRE2_INFO_NEWLINE              20+#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(). */++#define PCRE2_CONFIG_BSR                     0+#define PCRE2_CONFIG_JIT                     1+#define PCRE2_CONFIG_JITTARGET               2+#define PCRE2_CONFIG_LINKSIZE                3+#define PCRE2_CONFIG_MATCHLIMIT              4+#define PCRE2_CONFIG_NEWLINE                 5+#define PCRE2_CONFIG_PARENSLIMIT             6+#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+#define PCRE2_CONFIG_TABLES_LENGTH          15+++/* Types for code units in patterns and subject strings. */++typedef uint8_t  PCRE2_UCHAR8;+typedef uint16_t PCRE2_UCHAR16;+typedef uint32_t PCRE2_UCHAR32;++typedef const PCRE2_UCHAR8  *PCRE2_SPTR8;+typedef const PCRE2_UCHAR16 *PCRE2_SPTR16;+typedef const PCRE2_UCHAR32 *PCRE2_SPTR32;++/* The PCRE2_SIZE type is used for all string lengths and offsets in PCRE2,+including pattern offsets for errors and subject offsets after a match. We+define special values to indicate zero-terminated strings and unset offsets in+the offset vector (ovector). */++#define PCRE2_SIZE            size_t+#define PCRE2_SIZE_MAX        SIZE_MAX+#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)+#define PCRE2_UNSET           (~(PCRE2_SIZE)0)++/* Generic types for opaque structures and JIT callback functions. These+declarations are defined in a macro that is expanded for each width later. */++#define PCRE2_TYPES_LIST \+struct pcre2_real_general_context; \+typedef struct pcre2_real_general_context pcre2_general_context; \+\+struct pcre2_real_compile_context; \+typedef struct pcre2_real_compile_context pcre2_compile_context; \+\+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; \+\+struct pcre2_real_match_data; \+typedef struct pcre2_real_match_data pcre2_match_data; \+\+struct pcre2_real_jit_stack; \+typedef struct pcre2_real_jit_stack pcre2_jit_stack; \+\+typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *);+++/* The structures for passing out data via callout functions. We use structures+so that new fields can be added on the end in future versions, without changing+the API of the function, thereby allowing old clients to work without+modification. Define the generic versions 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 */ \+  /* ------------------------ Version 0 ------------------------------- */ \+  uint32_t      callout_number;    /* Number compiled into pattern */ \+  uint32_t      capture_top;       /* Max current capture */ \+  uint32_t      capture_last;      /* Most recently closed capture */ \+  PCRE2_SIZE   *offset_vector;     /* The offset vector */ \+  PCRE2_SPTR    mark;              /* Pointer to current mark or NULL */ \+  PCRE2_SPTR    subject;           /* The subject being matched */ \+  PCRE2_SIZE    subject_length;    /* The length of the subject */ \+  PCRE2_SIZE    start_match;       /* Offset to start of this match attempt */ \+  PCRE2_SIZE    current_position;  /* Where we currently are in the subject */ \+  PCRE2_SIZE    pattern_position;  /* Offset to next item in the pattern */ \+  PCRE2_SIZE    next_item_length;  /* Length of next item in the pattern */ \+  /* ------------------- Added for Version 1 -------------------------- */ \+  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; \+\+typedef struct pcre2_callout_enumerate_block { \+  uint32_t      version;           /* Identifies version of block */ \+  /* ------------------------ Version 0 ------------------------------- */ \+  PCRE2_SIZE    pattern_position;  /* Offset to next item in the pattern */ \+  PCRE2_SIZE    next_item_length;  /* Length of next item in the pattern */ \+  uint32_t      callout_number;    /* Number compiled into pattern */ \+  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 */ \+  /* ------------------------------------------------------------------ */ \+} pcre2_callout_enumerate_block; \+\+typedef struct pcre2_substitute_callout_block { \+  uint32_t      version;           /* Identifies version of block */ \+  /* ------------------------ Version 0 ------------------------------- */ \+  PCRE2_SPTR    input;             /* Pointer to input subject string */ \+  PCRE2_SPTR    output;            /* Pointer to output buffer */ \+  PCRE2_SIZE    output_offsets[2]; /* Changed portion of the output */ \+  PCRE2_SIZE   *ovector;           /* Pointer to current ovector */ \+  uint32_t      oveccount;         /* Count of pairs set in ovector */ \+  uint32_t      subscount;         /* Substitution number */ \+  /* ------------------------------------------------------------------ */ \+} pcre2_substitute_callout_block;+++/* List the generic forms of all other functions in macros, which will be+expanded for each width below. Start with functions that give general+information. */++#define PCRE2_GENERAL_INFO_FUNCTIONS \+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_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_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 uint8_t *); \+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_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_substitute_callout(pcre2_match_context *, \+    int (*)(pcre2_substitute_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_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_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_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 PCRE2_SIZE PCRE2_CALL_CONVENTION \+  pcre2_get_match_data_size(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_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_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_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_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_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 *); \+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \+  pcre2_maketables_free(pcre2_general_context *, const uint8_t *);++/* Define macros that generate width-specific names from generic versions. The+three-level macro scheme is necessary to get the macros expanded when we want+them to be. First we get the width from PCRE2_LOCAL_WIDTH, which is used for+generating three versions of everything below. After that, PCRE2_SUFFIX will be+re-defined to use PCRE2_CODE_UNIT_WIDTH, for use when macros such as+pcre2_compile are called by application code. */++#define PCRE2_JOIN(a,b) a ## b+#define PCRE2_GLUE(a,b) PCRE2_JOIN(a,b)+#define PCRE2_SUFFIX(a) PCRE2_GLUE(a,PCRE2_LOCAL_WIDTH)+++/* Data types */++#define PCRE2_UCHAR                 PCRE2_SUFFIX(PCRE2_UCHAR)+#define PCRE2_SPTR                  PCRE2_SUFFIX(PCRE2_SPTR)++#define pcre2_code                  PCRE2_SUFFIX(pcre2_code_)+#define pcre2_jit_callback          PCRE2_SUFFIX(pcre2_jit_callback_)+#define pcre2_jit_stack             PCRE2_SUFFIX(pcre2_jit_stack_)++#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_)+++/* Data blocks */++#define pcre2_callout_block            PCRE2_SUFFIX(pcre2_callout_block_)+#define pcre2_callout_enumerate_block  PCRE2_SUFFIX(pcre2_callout_enumerate_block_)+#define pcre2_substitute_callout_block PCRE2_SUFFIX(pcre2_substitute_callout_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_)+++/* Functions: the complete list in alphabetical order */++#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_)+#define pcre2_general_context_free            PCRE2_SUFFIX(pcre2_general_context_free_)+#define pcre2_get_error_message               PCRE2_SUFFIX(pcre2_get_error_message_)+#define pcre2_get_mark                        PCRE2_SUFFIX(pcre2_get_mark_)+#define pcre2_get_match_data_size             PCRE2_SUFFIX(pcre2_get_match_data_size_)+#define pcre2_get_ovector_pointer             PCRE2_SUFFIX(pcre2_get_ovector_pointer_)+#define pcre2_get_ovector_count               PCRE2_SUFFIX(pcre2_get_ovector_count_)+#define pcre2_get_startchar                   PCRE2_SUFFIX(pcre2_get_startchar_)+#define pcre2_jit_compile                     PCRE2_SUFFIX(pcre2_jit_compile_)+#define pcre2_jit_match                       PCRE2_SUFFIX(pcre2_jit_match_)+#define pcre2_jit_free_unused_memory          PCRE2_SUFFIX(pcre2_jit_free_unused_memory_)+#define pcre2_jit_stack_assign                PCRE2_SUFFIX(pcre2_jit_stack_assign_)+#define pcre2_jit_stack_create                PCRE2_SUFFIX(pcre2_jit_stack_create_)+#define pcre2_jit_stack_free                  PCRE2_SUFFIX(pcre2_jit_stack_free_)+#define pcre2_maketables                      PCRE2_SUFFIX(pcre2_maketables_)+#define pcre2_maketables_free                 PCRE2_SUFFIX(pcre2_maketables_free_)+#define pcre2_match                           PCRE2_SUFFIX(pcre2_match_)+#define pcre2_match_context_copy              PCRE2_SUFFIX(pcre2_match_context_copy_)+#define pcre2_match_context_create            PCRE2_SUFFIX(pcre2_match_context_create_)+#define pcre2_match_context_free              PCRE2_SUFFIX(pcre2_match_context_free_)+#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_)+#define pcre2_serialize_free                  PCRE2_SUFFIX(pcre2_serialize_free_)+#define pcre2_serialize_get_number_of_codes   PCRE2_SUFFIX(pcre2_serialize_get_number_of_codes_)+#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_substitute_callout          PCRE2_SUFFIX(pcre2_set_substitute_callout_)+#define pcre2_substitute                      PCRE2_SUFFIX(pcre2_substitute_)+#define pcre2_substring_copy_byname           PCRE2_SUFFIX(pcre2_substring_copy_byname_)+#define pcre2_substring_copy_bynumber         PCRE2_SUFFIX(pcre2_substring_copy_bynumber_)+#define pcre2_substring_free                  PCRE2_SUFFIX(pcre2_substring_free_)+#define pcre2_substring_get_byname            PCRE2_SUFFIX(pcre2_substring_get_byname_)+#define pcre2_substring_get_bynumber          PCRE2_SUFFIX(pcre2_substring_get_bynumber_)+#define pcre2_substring_length_byname         PCRE2_SUFFIX(pcre2_substring_length_byname_)+#define pcre2_substring_length_bynumber       PCRE2_SUFFIX(pcre2_substring_length_bynumber_)+#define pcre2_substring_list_get              PCRE2_SUFFIX(pcre2_substring_list_get_)+#define pcre2_substring_list_free             PCRE2_SUFFIX(pcre2_substring_list_free_)+#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. */++#define PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS \+PCRE2_TYPES_LIST \+PCRE2_STRUCTURE_LIST \+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 \+PCRE2_MATCH_FUNCTIONS \+PCRE2_SUBSTRING_FUNCTIONS \+PCRE2_SERIALIZE_FUNCTIONS \+PCRE2_SUBSTITUTE_FUNCTION \+PCRE2_JIT_FUNCTIONS \+PCRE2_OTHER_FUNCTIONS++#define PCRE2_LOCAL_WIDTH 8+PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS+#undef PCRE2_LOCAL_WIDTH++#define PCRE2_LOCAL_WIDTH 16+PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS+#undef PCRE2_LOCAL_WIDTH++#define PCRE2_LOCAL_WIDTH 32+PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS+#undef PCRE2_LOCAL_WIDTH++/* Undefine the list macros; they are no longer needed. */++#undef PCRE2_TYPES_LIST+#undef PCRE2_STRUCTURE_LIST+#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+#undef PCRE2_MATCH_FUNCTIONS+#undef PCRE2_SUBSTRING_FUNCTIONS+#undef PCRE2_SERIALIZE_FUNCTIONS+#undef PCRE2_SUBSTITUTE_FUNCTION+#undef PCRE2_JIT_FUNCTIONS+#undef PCRE2_OTHER_FUNCTIONS+#undef PCRE2_TYPES_STRUCTURES_AND_FUNCTIONS++/* PCRE2_CODE_UNIT_WIDTH must be defined. If it is 8, 16, or 32, redefine+PCRE2_SUFFIX to use it. If it is 0, undefine the other macros and make+PCRE2_SUFFIX a no-op. Otherwise, generate an error. */++#undef PCRE2_SUFFIX+#ifndef PCRE2_CODE_UNIT_WIDTH+#error PCRE2_CODE_UNIT_WIDTH must be defined before including pcre2.h.+#error Use 8, 16, or 32; or 0 for a multi-width application.+#else  /* PCRE2_CODE_UNIT_WIDTH is defined */+#if PCRE2_CODE_UNIT_WIDTH == 8 || \+    PCRE2_CODE_UNIT_WIDTH == 16 || \+    PCRE2_CODE_UNIT_WIDTH == 32+#define PCRE2_SUFFIX(a) PCRE2_GLUE(a, PCRE2_CODE_UNIT_WIDTH)+#elif PCRE2_CODE_UNIT_WIDTH == 0+#undef PCRE2_JOIN+#undef PCRE2_GLUE+#define PCRE2_SUFFIX(a) a+#else+#error PCRE2_CODE_UNIT_WIDTH must be 0, 8, 16, or 32.+#endif+#endif  /* PCRE2_CODE_UNIT_WIDTH is defined */++#ifdef __cplusplus+}  /* extern "C" */+#endif++#endif  /* PCRE2_H_IDEMPOTENT_GUARD */++/* End of pcre2.h */
+ src/c/pcre2/maint/ucptest.c view
@@ -0,0 +1,828 @@+/***************************************************+* A program for testing the Unicode property table *+***************************************************/++/* Copyright (c) University of Cambridge 2008-2020 */++/* Compile thus:++   gcc -DHAVE_CONFIG_H -DPCRE2_CODE_UNIT_WIDTH=8 -o ucptest \+     ucptest.c ../src/pcre2_ucd.c ../src/pcre2_tables.c++   Add -lreadline or -ledit if PCRE2 was configured with readline or libedit+   support in pcre2test.+*/++/* This is a hacked-up program for testing the Unicode properties tables of+PCRE2. It can also be used for finding characters with certain properties.+I wrote it to help with debugging PCRE, and have added things that I found+useful, in a rather haphazard way. The code has never been seriously tidied or+checked for robustness, but it shouldn't now give compiler warnings.++There is only one option: "-s". If given, it applies only to the "findprop" +command. It causes the UTF-8 sequence of bytes that encode the character to be +output between angle brackets at the end of the line. On a UTF-8 terminal, this +will show the appropriate graphic for the code point.++If the command has arguments, they are concatenated into a buffer, separated by+spaces. If the first argument starts "U+" or consists entirely of hexadecimal+digits, "findprop" is inserted at the start. The buffer is then processed as a+single line file, after which the program exits. If there are no arguments, the+program reads commands line by line on stdin and writes output to stdout. The +return code is always zero.++There are three commands:++"findprop" must be followed by a space-separated list of Unicode code points as+hex numbers, either without any prefix or starting with "U+". The output is one+line per character, giving its Unicode properties followed by its other case or +cases if one or more exist, followed by its Script Extension list if it is not+just the same as the base script. This list is in square brackets. The+properties are:++General type        e.g. Letter+Specific type       e.g. Upper case letter+Script              e.g. Medefaidrin+Grapheme break type e.g. Extend (most common is Other)++"find" must be followed by a list of property names and their values. The +values are case-sensitive. This finds characters that have those properties. If+multiple properties are listed, they must all be matched. Currently supported:++  script <name>    The character must have this script property. Only one+                     such script may be given.+  scriptx <name>   This script must be in the character's Script Extension+                     property list. If this is used many times, all the given+                     scripts must be present.+  type <abbrev>    The character's specific type (e.g. Lu or Nd) must match.+  gbreak <name>    The grapheme break property must match.++If a <name> or <abbrev> is preceded by !, the value must NOT be present. For+Script Extensions, there may be a mixture of positive and negative+requirements. All must be satisfied.++Sequences of two or more characters are shown as ranges, for example+U+0041..U+004A. No more than 100 lines are are output. If there are more+characters, the list ends with ... ++"list" must be followed by a property name (script, type, or gbreak). The+defined values for that property are listed. */+++#ifdef HAVE_CONFIG_H+#include "../src/config.h"+#endif++#ifndef SUPPORT_UNICODE+#define SUPPORT_UNICODE+#endif++#include <ctype.h>+#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#include "../src/pcre2_internal.h"+#include "../src/pcre2_ucp.h"++#ifdef HAVE_UNISTD_H+#include <unistd.h>+#endif++#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+#if defined(SUPPORT_LIBREADLINE)+#include <readline/readline.h>+#include <readline/history.h>+#else+#if defined(HAVE_EDITLINE_READLINE_H)+#include <editline/readline.h>+#else+#include <readline/readline.h>+#endif+#endif+#endif+++/* -------------------------------------------------------------------*/++#define CS   (char *)+#define CCS  (const char *)+#define CSS  (char **)+#define US   (unsigned char *)+#define CUS  (const unsigned char *)+#define USS  (unsigned char **)++/* -------------------------------------------------------------------*/++static BOOL show_character = FALSE;++static const unsigned char *type_names[] = {+  US"Cc", US"Control",+  US"Cf", US"Format",+  US"Cn", US"Unassigned",+  US"Co", US"Private use",+  US"Cs", US"Surrogate",+  US"Ll", US"Lower case letter",+  US"Lm", US"Modifier letter",+  US"Lo", US"Other letter",+  US"Lt", US"Title case letter",+  US"Lu", US"Upper case letter",+  US"Mc", US"Spacing mark",+  US"Me", US"Enclosing mark",+  US"Mn", US"Non-spacing mark",+  US"Nd", US"Decimal number",+  US"Nl", US"Letter number",+  US"No", US"Other number",+  US"Pc", US"Connector punctuation",+  US"Pd", US"Dash punctuation",+  US"Pe", US"Close punctuation",+  US"Pf", US"Final punctuation",+  US"Pi", US"Initial punctuation",+  US"Po", US"Other punctuation",+  US"Ps", US"Open punctuation",+  US"Sc", US"Currency symbol",+  US"Sk", US"Modifier symbol",+  US"Sm", US"Mathematical symbol",+  US"So", US"Other symbol",+  US"Zl", US"Line separator",+  US"Zp", US"Paragraph separator",+  US"Zs", US"Space separator" +};++static const unsigned char *gb_names[] = {+  US"CR",                    US"carriage return",+  US"LF",                    US"linefeed",+  US"Control",               US"",+  US"Extend",                US"",+  US"Prepend",               US"",+  US"SpacingMark",           US"",+  US"L",                     US"Hangul syllable type L",+  US"V",                     US"Hangul syllable type V",+  US"T",                     US"Hangul syllable type T",+  US"LV",                    US"Hangul syllable type LV",+  US"LVT",                   US"Hangul syllable type LVT",+  US"RegionalIndicator",     US"",+  US"Other",                 US"",+  US"ZWJ",                   US"zero width joiner",+  US"Extended_Pictographic", US""+};+++static const unsigned int utf8_table1[] = {+  0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff};++static const int utf8_table2[] = {+  0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};+++/*************************************************+*       Convert character value to UTF-8         *+*************************************************/++/* This function takes an unsigned long integer value in the range 0 -+0x7fffffff and encodes it as a UTF-8 character in 1 to 6 bytes.++Arguments:+  cvalue     the character value+  buffer     pointer to buffer for result - at least 6 bytes long++Returns:     number of bytes placed in the buffer+             0 if input code point is too big+*/++static size_t+ord2utf8(unsigned int cvalue, unsigned char *buffer)+{+size_t i, j;+for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++)+  if (cvalue <= utf8_table1[i]) break;+if (i >= sizeof(utf8_table1)/sizeof(int)) return 0;+buffer += i;+for (j = i; j > 0; j--)+ {+ *buffer-- = 0x80 | (cvalue & 0x3f);+ cvalue >>= 6;+ }+*buffer = utf8_table2[i] | cvalue;+return i + 1;+}++++/*************************************************+*             Test for interaction               *+*************************************************/++static BOOL+is_stdin_tty(void)+{+#if defined WIN32+return _isatty(_fileno(stdin));+#else+return isatty(fileno(stdin));+#endif+}+++/*************************************************+*      Get script name from ucp ident            *+*************************************************/++static const char *+get_scriptname(int script)+{+size_t i;+const ucp_type_table *u;++for (i = 0; i < PRIV(utt_size); i++)+  {+  u = PRIV(utt) + i; +  if (u->type == PT_SC && u->value == script) break;+  }+if (i < PRIV(utt_size))+  return PRIV(utt_names) + u->name_offset;+  +return "??";+}  +++/*************************************************+*      Print Unicode property info for a char    *+*************************************************/++static void+print_prop(unsigned int c, BOOL is_just_one)+{+int type = UCD_CATEGORY(c);+int fulltype = UCD_CHARTYPE(c);+int script = UCD_SCRIPT(c);+int scriptx = UCD_SCRIPTX(c);+int gbprop = UCD_GRAPHBREAK(c);+unsigned int othercase = UCD_OTHERCASE(c);+int caseset = UCD_CASESET(c);++const unsigned char *fulltypename = US"??";+const unsigned char *typename = US"??";+const unsigned char *graphbreak = US"??";+const unsigned char *scriptname = CUS get_scriptname(script);++switch (type)+  {+  case ucp_C: typename = US"Control"; break;+  case ucp_L: typename = US"Letter"; break;+  case ucp_M: typename = US"Mark"; break;+  case ucp_N: typename = US"Number"; break;+  case ucp_P: typename = US"Punctuation"; break;+  case ucp_S: typename = US"Symbol"; break;+  case ucp_Z: typename = US"Separator"; break;+  }++switch (fulltype)+  {+  case ucp_Cc: fulltypename = US"Control"; break;+  case ucp_Cf: fulltypename = US"Format"; break;+  case ucp_Cn: fulltypename = US"Unassigned"; break;+  case ucp_Co: fulltypename = US"Private use"; break;+  case ucp_Cs: fulltypename = US"Surrogate"; break;+  case ucp_Ll: fulltypename = US"Lower case letter"; break;+  case ucp_Lm: fulltypename = US"Modifier letter"; break;+  case ucp_Lo: fulltypename = US"Other letter"; break;+  case ucp_Lt: fulltypename = US"Title case letter"; break;+  case ucp_Lu: fulltypename = US"Upper case letter"; break;+  case ucp_Mc: fulltypename = US"Spacing mark"; break;+  case ucp_Me: fulltypename = US"Enclosing mark"; break;+  case ucp_Mn: fulltypename = US"Non-spacing mark"; break;+  case ucp_Nd: fulltypename = US"Decimal number"; break;+  case ucp_Nl: fulltypename = US"Letter number"; break;+  case ucp_No: fulltypename = US"Other number"; break;+  case ucp_Pc: fulltypename = US"Connector punctuation"; break;+  case ucp_Pd: fulltypename = US"Dash punctuation"; break;+  case ucp_Pe: fulltypename = US"Close punctuation"; break;+  case ucp_Pf: fulltypename = US"Final punctuation"; break;+  case ucp_Pi: fulltypename = US"Initial punctuation"; break;+  case ucp_Po: fulltypename = US"Other punctuation"; break;+  case ucp_Ps: fulltypename = US"Open punctuation"; break;+  case ucp_Sc: fulltypename = US"Currency symbol"; break;+  case ucp_Sk: fulltypename = US"Modifier symbol"; break;+  case ucp_Sm: fulltypename = US"Mathematical symbol"; break;+  case ucp_So: fulltypename = US"Other symbol"; break;+  case ucp_Zl: fulltypename = US"Line separator"; break;+  case ucp_Zp: fulltypename = US"Paragraph separator"; break;+  case ucp_Zs: fulltypename = US"Space separator"; break;+  }++switch(gbprop)+  {+  case ucp_gbCR:           graphbreak = US"CR"; break;+  case ucp_gbLF:           graphbreak = US"LF"; break;+  case ucp_gbControl:      graphbreak = US"Control"; break;+  case ucp_gbExtend:       graphbreak = US"Extend"; break;+  case ucp_gbPrepend:      graphbreak = US"Prepend"; break;+  case ucp_gbSpacingMark:  graphbreak = US"SpacingMark"; break;+  case ucp_gbL:            graphbreak = US"Hangul syllable type L"; break;+  case ucp_gbV:            graphbreak = US"Hangul syllable type V"; break;+  case ucp_gbT:            graphbreak = US"Hangul syllable type T"; break;+  case ucp_gbLV:           graphbreak = US"Hangul syllable type LV"; break;+  case ucp_gbLVT:          graphbreak = US"Hangul syllable type LVT"; break;+  case ucp_gbRegionalIndicator:+                           graphbreak = US"Regional Indicator"; break;+  case ucp_gbOther:        graphbreak = US"Other"; break;+  case ucp_gbZWJ:          graphbreak = US"Zero Width Joiner"; break;+  case ucp_gbExtended_Pictographic:+                           graphbreak = US"Extended Pictographic"; break;+  default:                 graphbreak = US"Unknown"; break;+  }++printf("U+%04X %s: %s, %s, %s", c, typename, fulltypename, scriptname, graphbreak);+if (is_just_one && othercase != c)+  {+  printf(", U+%04X", othercase);+  if (caseset != 0)+    {+    const uint32_t *p = PRIV(ucd_caseless_sets) + caseset - 1;+    while (*(++p) < NOTACHAR)+      {+      unsigned int d = *p;  +      if (d != othercase && d != c) printf(", U+%04X", d);+      } +    }+  }++if (scriptx != script)+  {+  printf(", [");+  if (scriptx >= 0)+    printf("%s", get_scriptname(scriptx));+  else+    {+    const char *sep = "";+    const uint8_t *p = PRIV(ucd_script_sets) - scriptx;+    while (*p != 0)+      {+      printf("%s%s", sep, get_scriptname(*p++));+      sep = ", ";+      }+    }+  printf("]");+  }+  +if (show_character && is_just_one)+  {+  unsigned char buffer[8];+  size_t len = ord2utf8(c, buffer);+  printf(", >%.*s<", (int)len, buffer);  +  }  ++printf("\n");+}++++/*************************************************+*   Find character(s) with given property/ies    *+*************************************************/++static void+find_chars(unsigned char *s)+{+unsigned char name[24];+unsigned char value[24];+unsigned char *t;+unsigned int count= 0;+int scriptx_list[24];+unsigned int scriptx_count = 0;+uint32_t i, c;+int script = -1;+int type = -1;+int gbreak = -1;+BOOL script_not = FALSE;+BOOL type_not = FALSE;+BOOL gbreak_not = FALSE;+BOOL hadrange = FALSE;+const ucd_record *ucd, *next_ucd;+const char *pad = "        ";++while (*s != 0)+  {+  unsigned int offset = 0;+  BOOL scriptx_not = FALSE;++  for (t = name; *s != 0 && !isspace(*s); s++) *t++ = *s;+  *t = 0;+  while (isspace(*s)) s++;++  for (t = value; *s != 0 && !isspace(*s); s++) *t++ = *s;+  *t = 0;+  while (isspace(*s)) s++;++  if (strcmp(CS name, "script") == 0 ||+      strcmp(CS name, "scriptx") == 0)+    {+    if (value[0] == '!')+      {+      if (name[6] == 'x') scriptx_not = TRUE;+        else script_not = TRUE;+      offset = 1;+      }++    for (i = 0; i < PRIV(utt_size); i++)+      {+      const ucp_type_table *u = PRIV(utt) + i; +      if (u->type == PT_SC && strcmp(CS(value + offset), +            PRIV(utt_names) + u->name_offset) == 0)+        {+        c = u->value; +        if (name[6] == 'x')+          {+          scriptx_list[scriptx_count++] = scriptx_not? (-c):c;+          }+        else+          {+          if (script < 0) script = c; else+            {+            printf("** Only 1 script value allowed\n");+            return;+            }+          }+        break;+        }+      }++    if (i >= PRIV(utt_size))+      {+      printf("** Unrecognized script name \"%s\"\n", value);+      return;+      }+    }++  else if (strcmp(CS name, "type") == 0)+    {+    if (type >= 0)+      {+      printf("** Only 1 type value allowed\n");+      return;+      }+    else+      {+      if (value[0] == '!')+        {+        type_not = TRUE;+        offset = 1;+        }++      for (i = 0; i < sizeof(type_names)/sizeof(char *); i += 2)+        {+        if (strcmp(CS (value + offset), CS type_names[i]) == 0)+          {+          type = i/2;+          break;+          }+        }+      if (i >= sizeof(type_names)/sizeof(char *))+        {+        printf("** Unrecognized type name \"%s\"\n", value);+        return;+        }+      }+    }++  else if (strcmp(CS name, "gbreak") == 0)+    {+    if (gbreak >= 0)+      {+      printf("** Only 1 grapheme break value allowed\n");+      return;+      }+    else+      {+      if (value[0] == '!')+        {+        gbreak_not = TRUE;+        offset = 1;+        }++      for (i = 0; i < sizeof(gb_names)/sizeof(char *); i += 2)+        {+        if (strcmp(CS (value + offset), CS gb_names[i]) == 0)+          {+          gbreak = i/2;+          break;+          }+        }+      if (i >= sizeof(gb_names)/sizeof(char *))+        {+        printf("** Unrecognized gbreak name \"%s\"\n", value);+        return;+        }+      }+    }++  else+    {+    printf("** Unrecognized property name \"%s\"\n", name);+    return;+    }+  }++if (script < 0 && scriptx_count == 0 && type < 0 && gbreak < 0)+  {+  printf("** No properties specified\n");+  return;+  }++for (c = 0; c <= 0x10ffff; c++)+  {+  if (script >= 0 && (script == UCD_SCRIPT(c)) == script_not) continue;++  if (scriptx_count > 0)+    {+    const uint8_t *char_scriptx = NULL;+    unsigned int found = 0;+    int scriptx = UCD_SCRIPTX(c);++    if (scriptx < 0) char_scriptx = PRIV(ucd_script_sets) - scriptx;++    for (i = 0; i < scriptx_count; i++)+      {+      /* Positive requirment */+      if (scriptx_list[i] >= 0)+        {+        if (scriptx >= 0)+          {+          if (scriptx == scriptx_list[i]) found++;+          }++        else+          {+          const uint8_t *p;+          for (p = char_scriptx; *p != 0; p++)+            {+            if (scriptx_list[i] == *p)+              {+              found++;+              break;+              }+            }+          }+        }+      /* Negative requirement */+      else+        {+        if (scriptx >= 0)+          {+          if (scriptx != -scriptx_list[i]) found++;+          }+        else+          {+          const uint8_t *p;+          for (p = char_scriptx; *p != 0; p++)+            if (-scriptx_list[i] == *p) break;+          if (*p == 0) found++;+          }+        }+      }++    if (found != scriptx_count) continue;+    }++  if (type >= 0)+    {+    if (type_not)+      {+      if (type == UCD_CHARTYPE(c)) continue;+      }+    else+      {+      if (type != UCD_CHARTYPE(c)) continue;+      }+    }++  if (gbreak >= 0)+    {+    if (gbreak_not)+      {+      if (gbreak == UCD_GRAPHBREAK(c)) continue;+      }+    else+      {+      if (gbreak != UCD_GRAPHBREAK(c)) continue;+      }+    }++  /* All conditions are met. Look for runs. */++  ucd = GET_UCD(c);++  for (i = c + 1; i < 0x10ffff; i++)+    {+    next_ucd = GET_UCD(i);+    if (memcmp(ucd, next_ucd, sizeof(ucd_record)) != 0) break;+    }++  if (--i > c)+    {+    printf("U+%04X..", c);+    c = i;+    hadrange = TRUE;+    }+  else if (hadrange) printf("%s", pad);++  print_prop(c, FALSE);+  if (c >= 0x100000) pad = "        ";+    else if (c >= 0x10000) pad = "       ";+  count++;+  if (count >= 100)+    {+    printf("...\n");+    break;+    }+  }++if (count == 0) printf("No characters found\n");+}+++/*************************************************+*        Process command line                    *+*************************************************/++static void+process_command_line(unsigned char *buffer)+{+unsigned char *s, *t;+unsigned char name[24];++s = buffer;+while (isspace(*s)) s++;+if (*s == 0) return;++for (t = name; *s != 0 && !isspace(*s); s++) *t++ = *s;+*t = 0;+while (isspace(*s)) s++;++if (strcmp(CS name, "findprop") == 0)+  {+  while (*s != 0)+    {+    unsigned int c; +    unsigned char *endptr;+    t = s; +    if (strncmp(CS t, "U+", 2) == 0) t += 2;+    c = strtoul(CS t, CSS(&endptr), 16);+    if (*endptr != 0 && !isspace(*endptr))+      {+      while (*endptr != 0 && !isspace(*endptr)) endptr++;+      printf("** Invalid hex number: ignored \"%.*s\"\n", (int)(endptr-s), s);+      }+    else  +      {+      if (c > 0x10ffff) +        printf("** U+%x is too big for a Unicode code point\n", c);+      else   +        print_prop(c, TRUE);+      } +    s = endptr;+    while (isspace(*s)) s++;+    }+  }++else if (strcmp(CS name, "find") == 0)+  {+  find_chars(s);+  }+  +else if (strcmp(CS name, "list") == 0)+  {+  while (*s != 0)+    {+    size_t i;+    for (t = name; *s != 0 && !isspace(*s); s++) *t++ = *s;+    *t = 0;+    while (isspace(*s)) s++;+    +    if (strcmp(CS name, "script") == 0 || strcmp(CS name, "scripts") == 0)+      {+      for (i = 0; i < PRIV(utt_size); i++) +        if (PRIV(utt)[i].type == PT_SC)+          printf("%s\n", PRIV(utt_names) + PRIV(utt)[i].name_offset);  +      }+      +    else if (strcmp(CS name, "type") == 0 || strcmp(CS name, "types") == 0)+      {+      for (i = 0; i < sizeof(type_names)/sizeof(char *); i += 2)+        printf("%s %s\n", type_names[i], type_names[i+1]); +      }  +      +    else if (strcmp(CS name, "gbreak") == 0 || strcmp(CS name, "gbreaks") == 0)+      {+      for (i = 0; i < sizeof(gb_names)/sizeof(char *); i += 2)+        {+        if (gb_names[i+1][0] != 0)  +          printf("%-3s (%s)\n", gb_names[i], gb_names[i+1]);+        else   +          printf("%s\n", gb_names[i]);+        } +      }    ++    else +      {+      printf("** Unknown property \"%s\"\n", name);  +      break;+      }  +    }  +  }  ++else printf("** Unknown test command \"%s\"\n", name);+}++++/*************************************************+*               Main program                     *+*************************************************/++int+main(int argc, char **argv)+{+BOOL interactive;+int first_arg = 1;+unsigned char buffer[1024];++if (argc > 1 && strcmp(argv[1], "-s") == 0)+  {+  show_character = TRUE;+  first_arg++;+  }   ++if (argc > first_arg)+  {+  int i;+  BOOL hexfirst = TRUE; +  char *arg = argv[first_arg]; +  unsigned char *s = buffer;+  +  if (strncmp(arg, "U+", 2) != 0 && !isdigit(*arg)) +    {+    while (*arg != 0) +      {+      if (!isxdigit(*arg++)) { hexfirst = FALSE; break; }  +      } +    } +     +  if (hexfirst)+    {+    strcpy(CS s, "findprop ");+    s += 9;+    }+    +  for (i = first_arg; i < argc; i++)+    {+    s += sprintf(CS s, "%s ", argv[i]);       +    }++  process_command_line(buffer);+  return 0;+  }++interactive = is_stdin_tty();++#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+if (interactive) using_history();+#endif++for(;;)+  {+#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+  if (interactive)+    {+    size_t len;+    unsigned char *s = US readline("> ");+    if (s == NULL) break;+    len = strlen(CS s);+    if (len > 0) add_history(CS s);+    memcpy(buffer, s, len);+    buffer[len] = '\n';+    buffer[len+1] = 0;+    free(s);+    }+  else+#endif++    {+    if (interactive) printf("> ");+    if (fgets(CS buffer, sizeof(buffer), stdin) == NULL) break;+    if (!interactive) printf("%s", buffer);+    }+    +  process_command_line(buffer);+  }++if (interactive) printf("\n");++#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+if (interactive) clear_history();+#endif++return 0;+}++/* End */
+ src/c/pcre2/maint/utf8.c view
@@ -0,0 +1,347 @@+/****************************************************+* PCRE maintainers' helper program: UTF-8 converter *+****************************************************/++/* This is a test program for converting character code points to UTF-8 and+vice versa. Note that this program conforms to the original definition of+UTF-8, which allows codepoints up to 7fffffff. The more recent definition+limits the validity of Unicode UTF-8 codepoints to a maximum of 10ffffff, and+forbids the "surrogate" code points. This program now gives warnings for these+invalid code points.++The arguments are either single code point values written as U+hh.. or 0xhh..+for conversion to UTF-8, or sequences of hex values, written without 0x and+optionally including spaces (but such arguments must be quoted), for conversion+from UTF-8 to codepoints. For example:++./utf8 0x1234+U+00001234 => e1 88 b4++./utf8 "e1 88 b4"+U+00001234 <= e1 88 b4++In the second case, a number of UTF-8 characters can be present in one+argument. In other words, each such argument is interpreted (after ignoring+spaces) as a string of UTF-8 bytes representing a string of characters:++./utf8 "65 e188b4 77"+0x00000065 <= 65+0x00001234 <= e1 88 b4+0x00000077 <= 77++If the option -s is given, the sequence of UTF-bytes is written out between+angle brackets at the end of the line. On a UTF-8 terminal, this will show the+appropriate graphic for the code point.++Errors provoke error messages, but the program carries on with the next+argument. The return code is always zero.++Philip Hazel+Original creation data: unknown+Code extended and tidied to avoid compiler warnings: 26 March 2020+*/+++#include <stdio.h>+#include <stdlib.h>+#include <ctype.h>+#include <string.h>++/* The valid ranges for UTF-8 characters are:++0000 0000  to  0000 007f   1 byte (ascii)+0000 0080  to  0000 07ff   2 bytes+0000 0800  to  0000 ffff   3 bytes+0001 0000  to  001f ffff   4 bytes+0020 0000  to  03ff ffff   5 bytes+0400 0000  to  7fff ffff   6 bytes+*/+++static const unsigned int utf8_table1[] = {+  0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff};++static const int utf8_table2[] = {+  0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};++static const int utf8_table3[] = {+  0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};+++/*************************************************+*       Convert character value to UTF-8         *+*************************************************/++/* This function takes an unsigned long integer value in the range 0 -+0x7fffffff and encodes it as a UTF-8 character in 1 to 6 bytes.++Arguments:+  cvalue     the character value+  buffer     pointer to buffer for result - at least 6 bytes long++Returns:     number of bytes placed in the buffer+             0 if input code point is too big+*/++static size_t+ord2utf8(unsigned long int cvalue, unsigned char *buffer)+{+size_t i, j;+for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++)+  if (cvalue <= utf8_table1[i]) break;+if (i >= sizeof(utf8_table1)/sizeof(int)) return 0;+buffer += i;+for (j = i; j > 0; j--)+ {+ *buffer-- = 0x80 | (cvalue & 0x3f);+ cvalue >>= 6;+ }+*buffer = utf8_table2[i] | cvalue;+return i + 1;+}++++/*************************************************+*            Convert UTF-8 string to value       *+*************************************************/++/* This function takes one or more bytes that represent a UTF-8 character from+the start of a string of bytes. It returns the value of the character, or the+offset of a malformation. For an overlong encoding that works but is not the+correct (shortest) one, the error offset is just after the last byte.++Argument:+  buffer   a pointer to the byte vector+  buffend  a pointer to the end of the buffer+  vptr     a pointer to a variable to receive the value+  lenptr   a pointer to a variable to receive the offset when error detected++Returns:   > 0 => the number of bytes consumed+             0 => invalid UTF-8: first byte missing 0x40 bit+            -1 => invalid UTF-8: first byte has too many high-order 1-bits+            -2 => incomplete sequence at end of string+            -3 => incomplete sequence within string+            -4 => overlong code sequence+*/++static int+utf82ord(unsigned char *buffer, unsigned char *buffend,+  long unsigned int *vptr, int *lenptr)+{+unsigned int c = *buffer++;+unsigned int d = c;+int i, j, s;++/* Check for an ASCII character, or find the number of additional bytes in a+multibyte character. */++for (i = -1; i < 6; i++)+  {+  if ((d & 0x80) == 0) break;+  d <<= 1;+  }++switch (i)+  {+  case -1:      /* ASCII character; first byte does not have 0x80 bit */+  *vptr = c;+  return 1;++  case 0:       /* First byte has 0x80 but is missing 0x40 bit */+  *lenptr = 0;+  return 0;++  case 6:+  *lenptr = 0;  /* Too many high bits */+  return -1;++  default:+  break;+  }++/* i now has a value in the range 1-5 */++s = 6*i;+d = (c & utf8_table3[i]) << s;++for (j = 0; j < i; j++)+  {+  if (buffer >= buffend)+    {+    *lenptr = j + 1;+    return -2;+    }+  c = *buffer++;+  if ((c & 0xc0) != 0x80)+    {+    *lenptr = j + 1;+    return -3;+    }+  s -= 6;+  d |= (c & 0x3f) << s;+  }++/* Valid UTF-8 syntax */++*vptr = d;++/* Check that encoding was the correct one, not overlong */++for (j = 0; j < (int)(sizeof(utf8_table1)/sizeof(int)); j++)+  if (d <= utf8_table1[j]) break;+if (j != i)+  {+  *lenptr = i + 1;+  return -4;+  }++/* Valid value */++return i + 1;+}++++/*************************************************+*                 Main Program                   *+*************************************************/++int+main(int argc, char **argv)+{+int i = 1;+int show = 0;+unsigned char buffer[64];++if (argc > 1 && strcmp(argv[1], "-s") == 0)+  {+  show = 1;+  i = 2;+  }++for (; i < argc; i++)+  {+  char *x = argv[i];+  char *endptr;+  if (strncmp(x, "0x", 2) == 0 || strncmp(x, "U+", 2) == 0)+    {+    size_t rc, j;+    unsigned long int d = strtoul(x+2, &endptr, 16);+    if (*endptr != 0)+      {+      printf("** Invalid hex number %s\n", x);+      continue;   /* With next argument */+      }+    rc = ord2utf8(d, buffer);+    printf("U+%08lx => ", d);+    if (rc == 0)+      printf("** Code point greater than 0x7fffffff cannot be encoded");+    else+      {+      for (j = 0; j < rc; j++) printf("%02x ", buffer[j]);+      if (show)+        {+        printf(">");+        for (j = 0; j < rc; j++) printf("%c", buffer[j]);+        printf("< ");+        }+      if (d >= 0xd800 && d <= 0xdfff)+        printf("** Invalid Unicode (surrogate)");+      else if (d > 0x10ffff)+        printf("** Invalid Unicode (greater than U+10ffff)");+      }+    printf("\n");+    }+  else+    {+    unsigned char *bptr;+    unsigned char *buffend;+    int len = 0;+    int y = 0;+    int z = 0;++    for (;;)+      {+      while (*x == ' ') x++;+      if (*x == 0 && !z) break;+      if (!isxdigit(*x))+        {+        printf("** Malformed hex string: %s\n", argv[i]);+        len = -1;+        break;+        }+      y = y * 16 + tolower(*x) - ((isdigit(*x))? '0' : 'W');+      x++;+      if (z)+        {+        buffer[len++] = y;+        y = 0;+        }+      z ^= 1;+      }++    if (len < 0) continue;  /* With next argument after malformation */++    bptr = buffer;+    buffend = buffer + len;++    while (bptr < buffend)+      {+      unsigned long int d;+      int j;+      int offset;+      int rc = utf82ord(bptr, buffend, &d, &offset);++      if (rc > 0)+        {+        printf("U+%08lx <= ", d);+        for (j = 0; j < rc; j++) printf("%02x ", bptr[j]);+        if (show)+          {+          printf(">");+          for (j = 0; j < rc; j++) printf("%c", bptr[j]);+          printf("<");+          }+        printf("\n");+        bptr += rc;+        }+      else if (rc == -4)+        {+        printf("U+%08lx <= ", d);+        for (j = 0; j < offset; j++) printf("%02x ", bptr[j]);+        printf("** Overlong UTF-8 sequence\n");+        bptr += offset;+        }+      else+        {+        switch (rc)+          {+          case 0:  printf("** First byte missing 0x40 bit");+          break;++          case -1: printf("** First byte has too many high-order bits");+          break;++          case -2: printf("** Incomplete UTF-8 sequence at end of string");+          break;++          case -3: printf("** Incomplete UTF-8 sequence");+          break;++          default: printf("** Unexpected return %d from utf82ord()", rc);+          break;+          }+        printf(" at offset %d in string ", offset);+        while (bptr < buffend) printf("%02x ", *bptr++);+        printf("\n");+        break;+        }+      }+    }+  }++return 0;+}++/* End */
+ src/c/pcre2/src/pcre2_auto_possess.c view
@@ -0,0 +1,1343 @@+/*************************************************+*      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-2020 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 functions that scan a compiled pattern and change+repeats into possessive repeats where possible. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif+++#include "pcre2_internal.h"+++/*************************************************+*        Tables for auto-possessification        *+*************************************************/++/* This table is used to check whether auto-possessification is possible+between adjacent character-type opcodes. The left-hand (repeated) opcode is+used to select the row, and the right-hand opcode is use to select the column.+A value of 1 means that auto-possessification is OK. For example, the second+value in the first row means that \D+\d can be turned into \D++\d.++The Unicode property types (\P and \p) have to be present to fill out the table+because of what their opcode values are, but the table values should always be+zero because property types are handled separately in the code. The last four+columns apply to items that cannot be repeated, so there is no need to have+rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is+*not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */++#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1)+#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1)++static const uint8_t autoposstab[APTROWS][APTCOLS] = {+/* \D \d \S \s \W \w  . .+ \C \P \p \R \H \h \V \v \X \Z \z  $ $M */+  { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \D */+  { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 },  /* \d */+  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 },  /* \S */+  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \s */+  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \W */+  { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 },  /* \w */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* .  */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* .+ */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },  /* \C */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* \P */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* \p */+  { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },  /* \R */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },  /* \H */+  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 },  /* \h */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 },  /* \V */+  { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 },  /* \v */+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }   /* \X */+};++#ifdef SUPPORT_UNICODE+/* This table is used to check whether auto-possessification is possible+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The+left-hand (repeated) opcode is used to select the row, and the right-hand+opcode is used to select the column. The values are as follows:++  0   Always return FALSE (never auto-possessify)+  1   Character groups are distinct (possessify if both are OP_PROP)+  2   Check character categories in the same group (general or particular)+  3   TRUE if the two opcodes are not the same (PROP vs NOTPROP)++  4   Check left general category vs right particular category+  5   Check right general category vs left particular category++  6   Left alphanum vs right general category+  7   Left space vs right general category+  8   Left word vs right general category++  9   Right alphanum vs left general category+ 10   Right space vs left general category+ 11   Right word vs left general category++ 12   Left alphanum vs right particular category+ 13   Left space vs right particular category+ 14   Left word vs right particular category++ 15   Right alphanum vs left particular category+ 16   Right space vs left particular category+ 17   Right word vs left particular category+*/++static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = {+/* ANY LAMP GC  PC  SC ALNUM SPACE PXSPACE WORD CLIST UCNC */+  { 0,  0,  0,  0,  0,    0,    0,      0,   0,    0,   0 },  /* PT_ANY */+  { 0,  3,  0,  0,  0,    3,    1,      1,   0,    0,   0 },  /* PT_LAMP */+  { 0,  0,  2,  4,  0,    9,   10,     10,  11,    0,   0 },  /* PT_GC */+  { 0,  0,  5,  2,  0,   15,   16,     16,  17,    0,   0 },  /* PT_PC */+  { 0,  0,  0,  0,  2,    0,    0,      0,   0,    0,   0 },  /* PT_SC */+  { 0,  3,  6, 12,  0,    3,    1,      1,   0,    0,   0 },  /* PT_ALNUM */+  { 0,  1,  7, 13,  0,    1,    3,      3,   1,    0,   0 },  /* PT_SPACE */+  { 0,  1,  7, 13,  0,    1,    3,      3,   1,    0,   0 },  /* PT_PXSPACE */+  { 0,  0,  8, 14,  0,    0,    1,      1,   3,    0,   0 },  /* PT_WORD */+  { 0,  0,  0,  0,  0,    0,    0,      0,   0,    0,   0 },  /* PT_CLIST */+  { 0,  0,  0,  0,  0,    0,    0,      0,   0,    0,   3 }   /* PT_UCNC */+};++/* This table is used to check whether auto-possessification is possible+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one+specifies a general category and the other specifies a particular category. The+row is selected by the general category and the column by the particular+category. The value is 1 if the particular category is not part of the general+category. */++static const uint8_t catposstab[7][30] = {+/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */+  { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },  /* C */+  { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },  /* L */+  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },  /* M */+  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },  /* N */+  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },  /* P */+  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 },  /* S */+  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }   /* Z */+};++/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against+a general or particular category. The properties in each row are those+that apply to the character set in question. Duplication means that a little+unnecessary work is done when checking, but this keeps things much simpler+because they can all use the same code. For more details see the comment where+this table is used.++Note: SPACE and PXSPACE used to be different because Perl excluded VT from+"space", but from Perl 5.18 it's included, so both categories are treated the+same here. */++static const uint8_t posspropstab[3][4] = {+  { ucp_L, ucp_N, ucp_N, ucp_Nl },  /* ALNUM, 3rd and 4th values redundant */+  { ucp_Z, ucp_Z, ucp_C, ucp_Cc },  /* SPACE and PXSPACE, 2nd value redundant */+  { ucp_L, ucp_N, ucp_P, ucp_Po }   /* WORD */+};+#endif  /* SUPPORT_UNICODE */++++#ifdef SUPPORT_UNICODE+/*************************************************+*        Check a character and a property        *+*************************************************/++/* This function is called by compare_opcodes() when a property item is+adjacent to a fixed character.++Arguments:+  c            the character+  ptype        the property type+  pdata        the data for the type+  negated      TRUE if it's a negated property (\P or \p{^)++Returns:       TRUE if auto-possessifying is OK+*/++static BOOL+check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata,+  BOOL negated)+{+const uint32_t *p;+const ucd_record *prop = GET_UCD(c);++switch(ptype)+  {+  case PT_LAMP:+  return (prop->chartype == ucp_Lu ||+          prop->chartype == ucp_Ll ||+          prop->chartype == ucp_Lt) == negated;++  case PT_GC:+  return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;++  case PT_PC:+  return (pdata == prop->chartype) == negated;++  case PT_SC:+  return (pdata == prop->script) == negated;++  /* These are specials */++  case PT_ALNUM:+  return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+          PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;++  /* Perl space used to exclude VT, but from Perl 5.18 it is included, which+  means that Perl space and POSIX space are now identical. PCRE was changed+  at release 8.34. */++  case PT_SPACE:    /* Perl space */+  case PT_PXSPACE:  /* POSIX space */+  switch(c)+    {+    HSPACE_CASES:+    VSPACE_CASES:+    return negated;++    default:+    return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated;+    }+  break;  /* Control never reaches here */++  case PT_WORD:+  return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+          PRIV(ucp_gentype)[prop->chartype] == ucp_N ||+          c == CHAR_UNDERSCORE) == negated;++  case PT_CLIST:+  p = PRIV(ucd_caseless_sets) + prop->caseset;+  for (;;)+    {+    if (c < *p) return !negated;+    if (c == *p++) return negated;+    }+  break;  /* Control never reaches here */+  }++return FALSE;+}+#endif  /* SUPPORT_UNICODE */++++/*************************************************+*        Base opcode of repeated opcodes         *+*************************************************/++/* Returns the base opcode for repeated single character type opcodes. If the+opcode is not a repeated character type, it returns with the original value.++Arguments:  c opcode+Returns:    base opcode for the type+*/++static PCRE2_UCHAR+get_repeat_base(PCRE2_UCHAR c)+{+return (c > OP_TYPEPOSUPTO)? c :+       (c >= OP_TYPESTAR)?   OP_TYPESTAR :+       (c >= OP_NOTSTARI)?   OP_NOTSTARI :+       (c >= OP_NOTSTAR)?    OP_NOTSTAR :+       (c >= OP_STARI)?      OP_STARI :+                             OP_STAR;+}+++/*************************************************+*        Fill the character property list        *+*************************************************/++/* Checks whether the code points to an opcode that can take part in auto-+possessification, and if so, fills a list with its properties.++Arguments:+  code        points to start of expression+  utf         TRUE if in UTF mode+  ucp         TRUE if in UCP mode+  fcc         points to the case-flipping table+  list        points to output list+              list[0] will be filled with the opcode+              list[1] will be non-zero if this opcode+                can match an empty character string+              list[2..7] depends on the opcode++Returns:      points to the start of the next opcode if *code is accepted+              NULL if *code is not accepted+*/++static PCRE2_SPTR+get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc,+  uint32_t *list)+{+PCRE2_UCHAR c = *code;+PCRE2_UCHAR base;+PCRE2_SPTR end;+uint32_t chr;++#ifdef SUPPORT_UNICODE+uint32_t *clist_dest;+const uint32_t *clist_src;+#else+(void)utf;    /* Suppress "unused parameter" compiler warnings */+(void)ucp;+#endif++list[0] = c;+list[1] = FALSE;+code++;++if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)+  {+  base = get_repeat_base(c);+  c -= (base - OP_STAR);++  if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO)+    code += IMM2_SIZE;++  list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT &&+             c != OP_POSPLUS);++  switch(base)+    {+    case OP_STAR:+    list[0] = OP_CHAR;+    break;++    case OP_STARI:+    list[0] = OP_CHARI;+    break;++    case OP_NOTSTAR:+    list[0] = OP_NOT;+    break;++    case OP_NOTSTARI:+    list[0] = OP_NOTI;+    break;++    case OP_TYPESTAR:+    list[0] = *code;+    code++;+    break;+    }+  c = list[0];+  }++switch(c)+  {+  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:+  case OP_ANYNL:+  case OP_NOT_HSPACE:+  case OP_HSPACE:+  case OP_NOT_VSPACE:+  case OP_VSPACE:+  case OP_EXTUNI:+  case OP_EODN:+  case OP_EOD:+  case OP_DOLL:+  case OP_DOLLM:+  return code;++  case OP_CHAR:+  case OP_NOT:+  GETCHARINCTEST(chr, code);+  list[2] = chr;+  list[3] = NOTACHAR;+  return code;++  case OP_CHARI:+  case OP_NOTI:+  list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT;+  GETCHARINCTEST(chr, code);+  list[2] = chr;++#ifdef SUPPORT_UNICODE+  if (chr < 128 || (chr < 256 && !utf && !ucp))+    list[3] = fcc[chr];+  else+    list[3] = UCD_OTHERCASE(chr);+#elif defined SUPPORT_WIDE_CHARS+  list[3] = (chr < 256) ? fcc[chr] : chr;+#else+  list[3] = fcc[chr];+#endif++  /* The othercase might be the same value. */++  if (chr == list[3])+    list[3] = NOTACHAR;+  else+    list[4] = NOTACHAR;+  return code;++#ifdef SUPPORT_UNICODE+  case OP_PROP:+  case OP_NOTPROP:+  if (code[0] != PT_CLIST)+    {+    list[2] = code[0];+    list[3] = code[1];+    return code + 2;+    }++  /* Convert only if we have enough space. */++  clist_src = PRIV(ucd_caseless_sets) + code[1];+  clist_dest = list + 2;+  code += 2;++  do {+     if (clist_dest >= list + 8)+       {+       /* Early return if there is not enough space. This should never+       happen, since all clists are shorter than 5 character now. */+       list[2] = code[0];+       list[3] = code[1];+       return code;+       }+     *clist_dest++ = *clist_src;+     }+  while(*clist_src++ != NOTACHAR);++  /* All characters are stored. The terminating NOTACHAR is copied from the+  clist itself. */++  list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT;+  return code;+#endif++  case OP_NCLASS:+  case OP_CLASS:+#ifdef SUPPORT_WIDE_CHARS+  case OP_XCLASS:+  if (c == OP_XCLASS)+    end = code + GET(code, 0) - 1;+  else+#endif+    end = code + 32 / sizeof(PCRE2_UCHAR);++  switch(*end)+    {+    case OP_CRSTAR:+    case OP_CRMINSTAR:+    case OP_CRQUERY:+    case OP_CRMINQUERY:+    case OP_CRPOSSTAR:+    case OP_CRPOSQUERY:+    list[1] = TRUE;+    end++;+    break;++    case OP_CRPLUS:+    case OP_CRMINPLUS:+    case OP_CRPOSPLUS:+    end++;+    break;++    case OP_CRRANGE:+    case OP_CRMINRANGE:+    case OP_CRPOSRANGE:+    list[1] = (GET2(end, 1) == 0);+    end += 1 + 2 * IMM2_SIZE;+    break;+    }+  list[2] = (uint32_t)(end - code);+  return end;+  }+return NULL;    /* Opcode not accepted */+}++++/*************************************************+*    Scan further character sets for match       *+*************************************************/++/* Checks whether the base and the current opcode have a common character, in+which case the base cannot be possessified.++Arguments:+  code        points to the byte code+  utf         TRUE in UTF mode+  ucp         TRUE in UCP mode+  cb          compile data block+  base_list   the data list of the base opcode+  base_end    the end of the base opcode+  rec_limit   points to recursion depth counter++Returns:      TRUE if the auto-possessification is possible+*/++static BOOL+compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb,+  const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)+{+PCRE2_UCHAR c;+uint32_t list[8];+const uint32_t *chr_ptr;+const uint32_t *ochr_ptr;+const uint32_t *list_ptr;+PCRE2_SPTR next_code;+#ifdef SUPPORT_WIDE_CHARS+PCRE2_SPTR xclass_flags;+#endif+const uint8_t *class_bitset;+const uint8_t *set1, *set2, *set_end;+uint32_t chr;+BOOL accepted, invert_bits;+BOOL entered_a_group = FALSE;++if (--(*rec_limit) <= 0) return FALSE;  /* Recursion has gone too deep */++/* Note: the base_list[1] contains whether the current opcode has a greedy+(represented by a non-zero value) quantifier. This is a different from+other character type lists, which store here that the character iterator+matches to an empty string (also represented by a non-zero value). */++for(;;)+  {+  /* All operations move the code pointer forward.+  Therefore infinite recursions are not possible. */++  c = *code;++  /* Skip over callouts */++  if (c == OP_CALLOUT)+    {+    code += PRIV(OP_lengths)[c];+    continue;+    }++  if (c == OP_CALLOUT_STR)+    {+    code += GET(code, 1 + 2*LINK_SIZE);+    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)+    {+    /* 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:+    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;++      /* A script run might have to backtrack if the iterated item can match+      characters from more than one script. So give up unless repeating an+      explicit character. */++      case OP_SCRIPT_RUN:+      if (base_list[0] != OP_CHAR && base_list[0] != OP_CHARI)+        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:+      return !entered_a_group;++      /* Non-atomic assertions - don't possessify last iterator. This needs+      more thought. */++      case OP_ASSERT_NA:+      case OP_ASSERTBACK_NA:+      return FALSE;+      }++    /* 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_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, ucp, cb, base_list, base_end, rec_limit))+        return FALSE;+      code = next_code + 1 + LINK_SIZE;+      next_code += GET(next_code, 1);+      }++    entered_a_group = TRUE;+    continue;++    case OP_BRAZERO:+    case OP_BRAMINZERO:++    next_code = code + 1;+    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);++    /* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */++    next_code += 1 + LINK_SIZE;+    if (!compare_opcodes(next_code, utf, ucp, cb, base_list, base_end,+         rec_limit))+      return FALSE;++    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;+    }++  /* 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, ucp, cb->fcc, list);+  if (code == NULL) return FALSE;    /* Unsupported */++  /* If either opcode is a small character list, set pointers for comparing+  characters from that list with another list, or with a property. */++  if (base_list[0] == OP_CHAR)+    {+    chr_ptr = base_list + 2;+    list_ptr = list;+    }+  else if (list[0] == OP_CHAR)+    {+    chr_ptr = list + 2;+    list_ptr = base_list;+    }++  /* Character bitsets can also be compared to certain opcodes. */++  else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS+#if PCRE2_CODE_UNIT_WIDTH == 8+      /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */+      || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS))+#endif+      )+    {+#if PCRE2_CODE_UNIT_WIDTH == 8+    if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS))+#else+    if (base_list[0] == OP_CLASS)+#endif+      {+      set1 = (uint8_t *)(base_end - base_list[2]);+      list_ptr = list;+      }+    else+      {+      set1 = (uint8_t *)(code - list[2]);+      list_ptr = base_list;+      }++    invert_bits = FALSE;+    switch(list_ptr[0])+      {+      case OP_CLASS:+      case OP_NCLASS:+      set2 = (uint8_t *)+        ((list_ptr == list ? code : base_end) - list_ptr[2]);+      break;++#ifdef SUPPORT_WIDE_CHARS+      case OP_XCLASS:+      xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE;+      if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE;+      if ((*xclass_flags & XCL_MAP) == 0)+        {+        /* No bits are set for characters < 256. */+        if (list[1] == 0) return (*xclass_flags & XCL_NOT) == 0;+        /* Might be an empty repeat. */+        continue;+        }+      set2 = (uint8_t *)(xclass_flags + 1);+      break;+#endif++      case OP_NOT_DIGIT:+      invert_bits = TRUE;+      /* Fall through */+      case OP_DIGIT:+      set2 = (uint8_t *)(cb->cbits + cbit_digit);+      break;++      case OP_NOT_WHITESPACE:+      invert_bits = TRUE;+      /* Fall through */+      case OP_WHITESPACE:+      set2 = (uint8_t *)(cb->cbits + cbit_space);+      break;++      case OP_NOT_WORDCHAR:+      invert_bits = TRUE;+      /* Fall through */+      case OP_WORDCHAR:+      set2 = (uint8_t *)(cb->cbits + cbit_word);+      break;++      default:+      return FALSE;+      }++    /* Because the bit sets are unaligned bytes, we need to perform byte+    comparison here. */++    set_end = set1 + 32;+    if (invert_bits)+      {+      do+        {+        if ((*set1++ & ~(*set2++)) != 0) return FALSE;+        }+      while (set1 < set_end);+      }+    else+      {+      do+        {+        if ((*set1++ & *set2++) != 0) return FALSE;+        }+      while (set1 < set_end);+      }++    if (list[1] == 0) return TRUE;+    /* Might be an empty repeat. */+    continue;+    }++  /* Some property combinations also acceptable. Unicode property opcodes are+  processed specially; the rest can be handled with a lookup table. */++  else+    {+    uint32_t leftop, rightop;++    leftop = base_list[0];+    rightop = list[0];++#ifdef SUPPORT_UNICODE+    accepted = FALSE; /* Always set in non-unicode case. */+    if (leftop == OP_PROP || leftop == OP_NOTPROP)+      {+      if (rightop == OP_EOD)+        accepted = TRUE;+      else if (rightop == OP_PROP || rightop == OP_NOTPROP)+        {+        int n;+        const uint8_t *p;+        BOOL same = leftop == rightop;+        BOOL lisprop = leftop == OP_PROP;+        BOOL risprop = rightop == OP_PROP;+        BOOL bothprop = lisprop && risprop;++        /* There's a table that specifies how each combination is to be+        processed:+          0   Always return FALSE (never auto-possessify)+          1   Character groups are distinct (possessify if both are OP_PROP)+          2   Check character categories in the same group (general or particular)+          3   Return TRUE if the two opcodes are not the same+          ... see comments below+        */++        n = propposstab[base_list[2]][list[2]];+        switch(n)+          {+          case 0: break;+          case 1: accepted = bothprop; break;+          case 2: accepted = (base_list[3] == list[3]) != same; break;+          case 3: accepted = !same; break;++          case 4:  /* Left general category, right particular category */+          accepted = risprop && catposstab[base_list[3]][list[3]] == same;+          break;++          case 5:  /* Right general category, left particular category */+          accepted = lisprop && catposstab[list[3]][base_list[3]] == same;+          break;++          /* This code is logically tricky. Think hard before fiddling with it.+          The posspropstab table has four entries per row. Each row relates to+          one of PCRE's special properties such as ALNUM or SPACE or WORD.+          Only WORD actually needs all four entries, but using repeats for the+          others means they can all use the same code below.++          The first two entries in each row are Unicode general categories, and+          apply always, because all the characters they include are part of the+          PCRE character set. The third and fourth entries are a general and a+          particular category, respectively, that include one or more relevant+          characters. One or the other is used, depending on whether the check+          is for a general or a particular category. However, in both cases the+          category contains more characters than the specials that are defined+          for the property being tested against. Therefore, it cannot be used+          in a NOTPROP case.++          Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po.+          Underscore is covered by ucp_P or ucp_Po. */++          case 6:  /* Left alphanum vs right general category */+          case 7:  /* Left space vs right general category */+          case 8:  /* Left word vs right general category */+          p = posspropstab[n-6];+          accepted = risprop && lisprop ==+            (list[3] != p[0] &&+             list[3] != p[1] &&+            (list[3] != p[2] || !lisprop));+          break;++          case 9:   /* Right alphanum vs left general category */+          case 10:  /* Right space vs left general category */+          case 11:  /* Right word vs left general category */+          p = posspropstab[n-9];+          accepted = lisprop && risprop ==+            (base_list[3] != p[0] &&+             base_list[3] != p[1] &&+            (base_list[3] != p[2] || !risprop));+          break;++          case 12:  /* Left alphanum vs right particular category */+          case 13:  /* Left space vs right particular category */+          case 14:  /* Left word vs right particular category */+          p = posspropstab[n-12];+          accepted = risprop && lisprop ==+            (catposstab[p[0]][list[3]] &&+             catposstab[p[1]][list[3]] &&+            (list[3] != p[3] || !lisprop));+          break;++          case 15:  /* Right alphanum vs left particular category */+          case 16:  /* Right space vs left particular category */+          case 17:  /* Right word vs left particular category */+          p = posspropstab[n-15];+          accepted = lisprop && risprop ==+            (catposstab[p[0]][base_list[3]] &&+             catposstab[p[1]][base_list[3]] &&+            (base_list[3] != p[3] || !risprop));+          break;+          }+        }+      }++    else+#endif  /* SUPPORT_UNICODE */++    accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP &&+           rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&+           autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];++    if (!accepted) return FALSE;++    if (list[1] == 0) return TRUE;+    /* Might be an empty repeat. */+    continue;+    }++  /* Control reaches here only if one of the items is a small character list.+  All characters are checked against the other side. */++  do+    {+    chr = *chr_ptr;++    switch(list_ptr[0])+      {+      case OP_CHAR:+      ochr_ptr = list_ptr + 2;+      do+        {+        if (chr == *ochr_ptr) return FALSE;+        ochr_ptr++;+        }+      while(*ochr_ptr != NOTACHAR);+      break;++      case OP_NOT:+      ochr_ptr = list_ptr + 2;+      do+        {+        if (chr == *ochr_ptr)+          break;+        ochr_ptr++;+        }+      while(*ochr_ptr != NOTACHAR);+      if (*ochr_ptr == NOTACHAR) return FALSE;   /* Not found */+      break;++      /* Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not*+      set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */++      case OP_DIGIT:+      if (chr < 256 && (cb->ctypes[chr] & ctype_digit) != 0) return FALSE;+      break;++      case OP_NOT_DIGIT:+      if (chr > 255 || (cb->ctypes[chr] & ctype_digit) == 0) return FALSE;+      break;++      case OP_WHITESPACE:+      if (chr < 256 && (cb->ctypes[chr] & ctype_space) != 0) return FALSE;+      break;++      case OP_NOT_WHITESPACE:+      if (chr > 255 || (cb->ctypes[chr] & ctype_space) == 0) return FALSE;+      break;++      case OP_WORDCHAR:+      if (chr < 255 && (cb->ctypes[chr] & ctype_word) != 0) return FALSE;+      break;++      case OP_NOT_WORDCHAR:+      if (chr > 255 || (cb->ctypes[chr] & ctype_word) == 0) return FALSE;+      break;++      case OP_HSPACE:+      switch(chr)+        {+        HSPACE_CASES: return FALSE;+        default: break;+        }+      break;++      case OP_NOT_HSPACE:+      switch(chr)+        {+        HSPACE_CASES: break;+        default: return FALSE;+        }+      break;++      case OP_ANYNL:+      case OP_VSPACE:+      switch(chr)+        {+        VSPACE_CASES: return FALSE;+        default: break;+        }+      break;++      case OP_NOT_VSPACE:+      switch(chr)+        {+        VSPACE_CASES: break;+        default: return FALSE;+        }+      break;++      case OP_DOLL:+      case OP_EODN:+      switch (chr)+        {+        case CHAR_CR:+        case CHAR_LF:+        case CHAR_VT:+        case CHAR_FF:+        case CHAR_NEL:+#ifndef EBCDIC+        case 0x2028:+        case 0x2029:+#endif  /* Not EBCDIC */+        return FALSE;+        }+      break;++      case OP_EOD:    /* Can always possessify before \z */+      break;++#ifdef SUPPORT_UNICODE+      case OP_PROP:+      case OP_NOTPROP:+      if (!check_char_prop(chr, list_ptr[2], list_ptr[3],+            list_ptr[0] == OP_NOTPROP))+        return FALSE;+      break;+#endif++      case OP_NCLASS:+      if (chr > 255) return FALSE;+      /* Fall through */++      case OP_CLASS:+      if (chr > 255) break;+      class_bitset = (uint8_t *)+        ((list_ptr == list ? code : base_end) - list_ptr[2]);+      if ((class_bitset[chr >> 3] & (1u << (chr & 7))) != 0) return FALSE;+      break;++#ifdef SUPPORT_WIDE_CHARS+      case OP_XCLASS:+      if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) -+          list_ptr[2] + LINK_SIZE, utf)) return FALSE;+      break;+#endif++      default:+      return FALSE;+      }++    chr_ptr++;+    }+  while(*chr_ptr != NOTACHAR);++  /* At least one character must be matched from this opcode. */++  if (list[1] == 0) return TRUE;+  }++/* Control never reaches here. There used to be a fail-save return FALSE; here,+but some compilers complain about an unreachable statement. */+}++++/*************************************************+*    Scan compiled regex for auto-possession     *+*************************************************/++/* Replaces single character iterations with their possessive alternatives+if appropriate. This function modifies the compiled opcode! Hitting a+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+  cb          compile data block++Returns:      0 for success+              -1 if a non-existant opcode is encountered+*/++int+PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb)+{+PCRE2_UCHAR c;+PCRE2_SPTR end;+PCRE2_UCHAR *repeat_opcode;+uint32_t list[8];+int rec_limit = 1000;  /* Was 10,000 but clang+ASAN uses a lot of stack. */+BOOL utf = (cb->external_options & PCRE2_UTF) != 0;+BOOL ucp = (cb->external_options & PCRE2_UCP) != 0;++for (;;)+  {+  c = *code;++  if (c >= OP_TABLE_LENGTH) return -1;   /* Something gone wrong */++  if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)+    {+    c -= get_repeat_base(c) - OP_STAR;+    end = (c <= OP_MINUPTO) ?+      get_chr_property_list(code, utf, ucp, cb->fcc, list) : NULL;+    list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;++    if (end != NULL && compare_opcodes(end, utf, ucp, cb, list, end,+        &rec_limit))+      {+      switch(c)+        {+        case OP_STAR:+        *code += OP_POSSTAR - OP_STAR;+        break;++        case OP_MINSTAR:+        *code += OP_POSSTAR - OP_MINSTAR;+        break;++        case OP_PLUS:+        *code += OP_POSPLUS - OP_PLUS;+        break;++        case OP_MINPLUS:+        *code += OP_POSPLUS - OP_MINPLUS;+        break;++        case OP_QUERY:+        *code += OP_POSQUERY - OP_QUERY;+        break;++        case OP_MINQUERY:+        *code += OP_POSQUERY - OP_MINQUERY;+        break;++        case OP_UPTO:+        *code += OP_POSUPTO - OP_UPTO;+        break;++        case OP_MINUPTO:+        *code += OP_POSUPTO - OP_MINUPTO;+        break;+        }+      }+    c = *code;+    }+  else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS)+    {+#ifdef SUPPORT_WIDE_CHARS+    if (c == OP_XCLASS)+      repeat_opcode = code + GET(code, 1);+    else+#endif+      repeat_opcode = code + 1 + (32 / sizeof(PCRE2_UCHAR));++    c = *repeat_opcode;+    if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)+      {+      /* end must not be NULL. */+      end = get_chr_property_list(code, utf, ucp, cb->fcc, list);++      list[1] = (c & 1) == 0;++      if (compare_opcodes(end, utf, ucp, cb, list, end, &rec_limit))+        {+        switch (c)+          {+          case OP_CRSTAR:+          case OP_CRMINSTAR:+          *repeat_opcode = OP_CRPOSSTAR;+          break;++          case OP_CRPLUS:+          case OP_CRMINPLUS:+          *repeat_opcode = OP_CRPOSPLUS;+          break;++          case OP_CRQUERY:+          case OP_CRMINQUERY:+          *repeat_opcode = OP_CRPOSQUERY;+          break;++          case OP_CRRANGE:+          case OP_CRMINRANGE:+          *repeat_opcode = OP_CRPOSRANGE;+          break;+          }+        }+      }+    c = *code;+    }++  switch(c)+    {+    case OP_END:+    return 0;++    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPOSPLUS:+    case OP_TYPEPOSQUERY:+    if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;+    break;++    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    case OP_TYPEEXACT:+    case OP_TYPEPOSUPTO:+    if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)+      code += 2;+    break;++    case OP_CALLOUT_STR:+    code += GET(code, 1 + 2*LINK_SIZE);+    break;++#ifdef SUPPORT_WIDE_CHARS+    case OP_XCLASS:+    code += GET(code, 1);+    break;+#endif++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_SKIP_ARG:+    case OP_THEN_ARG:+    code += code[1];+    break;+    }++  /* Add in the fixed length from the table */++  code += PRIV(OP_lengths)[c];++  /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be+  followed by a multi-byte character. The length in the table is a minimum, so+  we have to arrange to skip the extra code units. */++#ifdef MAYBE_UTF_MULTI+  if (utf) switch(c)+    {+    case OP_CHAR:+    case OP_CHARI:+    case OP_NOT:+    case OP_NOTI:+    case OP_STAR:+    case OP_MINSTAR:+    case OP_PLUS:+    case OP_MINPLUS:+    case OP_QUERY:+    case OP_MINQUERY:+    case OP_UPTO:+    case OP_MINUPTO:+    case OP_EXACT:+    case OP_POSSTAR:+    case OP_POSPLUS:+    case OP_POSQUERY:+    case OP_POSUPTO:+    case OP_STARI:+    case OP_MINSTARI:+    case OP_PLUSI:+    case OP_MINPLUSI:+    case OP_QUERYI:+    case OP_MINQUERYI:+    case OP_UPTOI:+    case OP_MINUPTOI:+    case OP_EXACTI:+    case OP_POSSTARI:+    case OP_POSPLUSI:+    case OP_POSQUERYI:+    case OP_POSUPTOI:+    case OP_NOTSTAR:+    case OP_NOTMINSTAR:+    case OP_NOTPLUS:+    case OP_NOTMINPLUS:+    case OP_NOTQUERY:+    case OP_NOTMINQUERY:+    case OP_NOTUPTO:+    case OP_NOTMINUPTO:+    case OP_NOTEXACT:+    case OP_NOTPOSSTAR:+    case OP_NOTPOSPLUS:+    case OP_NOTPOSQUERY:+    case OP_NOTPOSUPTO:+    case OP_NOTSTARI:+    case OP_NOTMINSTARI:+    case OP_NOTPLUSI:+    case OP_NOTMINPLUSI:+    case OP_NOTQUERYI:+    case OP_NOTMINQUERYI:+    case OP_NOTUPTOI:+    case OP_NOTMINUPTOI:+    case OP_NOTEXACTI:+    case OP_NOTPOSSTARI:+    case OP_NOTPOSPLUSI:+    case OP_NOTPOSQUERYI:+    case OP_NOTPOSUPTOI:+    if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);+    break;+    }+#else+  (void)(utf);  /* Keep compiler happy by referencing function argument */+#endif  /* SUPPORT_WIDE_CHARS */+  }+}++/* End of pcre2_auto_possess.c */
+ src/c/pcre2/src/pcre2_compile.c view
@@ -0,0 +1,10499 @@+/*************************************************+*      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-2020 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++#define NLBLOCK cb             /* Block containing newline information */+#define PSSTART start_pattern  /* Field containing processed string start */+#define PSEND   end_pattern    /* Field containing processed string end */++#include "pcre2_internal.h"++/* In rare error cases debugging might require calling pcre2_printint(). */++#if 0+#ifdef EBCDIC+#define PRINTABLE(c) ((c) >= 64 && (c) < 255)+#else+#define PRINTABLE(c) ((c) >= 32 && (c) < 127)+#endif+#include "pcre2_printint.c"+#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. */++#if PCRE2_CODE_UNIT_WIDTH == 8+#define STRING_UTFn_RIGHTPAR     STRING_UTF8_RIGHTPAR, 5+#define XDIGIT(c)                xdigitab[c]++#else  /* Either 16-bit or 32-bit */+#define XDIGIT(c)                (MAX_255(c)? xdigitab[c] : 0xff)++#if PCRE2_CODE_UNIT_WIDTH == 16+#define STRING_UTFn_RIGHTPAR     STRING_UTF16_RIGHTPAR, 6++#else  /* 32-bit */+#define STRING_UTFn_RIGHTPAR     STRING_UTF32_RIGHTPAR, 6+#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_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+  set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *,+    compile_block *);++static int+  check_lookbehinds(uint32_t *, uint32_t **, parsed_recurse_check *,+    compile_block *);+++/*************************************************+*      Code parameters and static tables         *+*************************************************/++#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+discarded as soon as they can be, so that hopefully there will never be an+overrun. The code does, however, check for an overrun, which can occur for+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, this workspace is not currently used. */++#define COMPILE_WORK_SIZE (3000*LINK_SIZE)   /* Size in code units */++#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. */++#define WORK_SIZE_SAFETY_MARGIN (100)++/* This value determines the size of the initial vector that is used for+remembering named groups during the pre-compile. It is allocated on the stack,+but if it is too small, it is expanded, in a similar way to the workspace. The+value is the number of slots in the list. */++#define NAMED_GROUP_LIST_SIZE  20++/* 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 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 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) */+#define META_SCRIPT_RUN       0x80220000u  /* (*script_run:...) */++/* These must be kept together to make it easy to check that an assertion+is present where expected in a conditional group. */++#define META_LOOKAHEAD        0x80230000u  /* (?= */+#define META_LOOKAHEADNOT     0x80240000u  /* (?! */+#define META_LOOKBEHIND       0x80250000u  /* (?<= */+#define META_LOOKBEHINDNOT    0x80260000u  /* (?<! */++/* These cannot be conditions */++#define META_LOOKAHEAD_NA     0x80270000u  /* (*napla: */+#define META_LOOKBEHIND_NA    0x80280000u  /* (*naplb: */++/* These must be kept in this order, with consecutive values, and the _ARG+versions of COMMIT, PRUNE, SKIP, and THEN immediately after their non-argument+versions. */++#define META_MARK             0x80290000u  /* (*MARK) */+#define META_ACCEPT           0x802a0000u  /* (*ACCEPT) */+#define META_FAIL             0x802b0000u  /* (*FAIL) */+#define META_COMMIT           0x802c0000u  /* These               */+#define META_COMMIT_ARG       0x802d0000u  /*   pairs             */+#define META_PRUNE            0x802e0000u  /*     must            */+#define META_PRUNE_ARG        0x802f0000u  /*       be            */+#define META_SKIP             0x80300000u  /*         kept        */+#define META_SKIP_ARG         0x80310000u  /*           in        */+#define META_THEN             0x80320000u  /*             this    */+#define META_THEN_ARG         0x80330000u  /*               order */++/* These must be kept in groups of adjacent 3 values, and all together. */++#define META_ASTERISK         0x80340000u  /* *  */+#define META_ASTERISK_PLUS    0x80350000u  /* *+ */+#define META_ASTERISK_QUERY   0x80360000u  /* *? */+#define META_PLUS             0x80370000u  /* +  */+#define META_PLUS_PLUS        0x80380000u  /* ++ */+#define META_PLUS_QUERY       0x80390000u  /* +? */+#define META_QUERY            0x803a0000u  /* ?  */+#define META_QUERY_PLUS       0x803b0000u  /* ?+ */+#define META_QUERY_QUERY      0x803c0000u  /* ?? */+#define META_MINMAX           0x803d0000u  /* {n,m}  repeat */+#define META_MINMAX_PLUS      0x803e0000u  /* {n,m}+ repeat */+#define META_MINMAX_QUERY     0x803f0000u  /* {n,m}? repeat */++#define META_FIRST_QUANTIFIER META_ASTERISK+#define META_LAST_QUANTIFIER  META_MINMAX_QUERY++/* This is a special "meta code" that is used only to distinguish (*asr: from+(*sr: in the table of aphabetic assertions. It is never stored in the parsed+pattern because (*asr: is turned into (*sr:(*atomic: at that stage. There is+therefore no need for it to have a length entry, so use a high value. */++#define META_ATOMIC_SCRIPT_RUN 0x8fff0000u++/* 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_SCRIPT_RUN */+  0,             /* META_LOOKAHEAD */+  0,             /* META_LOOKAHEADNOT */+  SIZEOFFSET,    /* META_LOOKBEHIND */+  SIZEOFFSET,    /* META_LOOKBEHINDNOT */+  0,             /* META_LOOKAHEAD_NA */+  SIZEOFFSET,    /* META_LOOKBEHIND_NA */+  1,             /* META_MARK - plus the string length */+  0,             /* META_ACCEPT */+  0,             /* META_FAIL */+  0,             /* META_COMMIT */+  1,             /* META_COMMIT_ARG - plus the string length */+  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:++  #define SETBIT(a,b) a[(b)/8] |= (uint8_t)(1u << ((b)&7))++Let's hope the apparently less efficient version isn't actually so bad if the+compiler is clever with identical subexpressions. */++#define SETBIT(a,b) a[(b)/8] = (uint8_t)(a[(b)/8] | (1u << ((b)&7)))++/* Private flags added to firstcu and reqcu. */++#define REQ_CASELESS    (1u << 0)       /* Indicates caselessness */+#define REQ_VARY        (1u << 1)       /* reqcu followed non-literal item */+/* Negative values for the firstcu and reqcu flags */+#define REQ_UNSET       (-2)            /* Not yet found anything */+#define REQ_NONE        (-1)            /* Found not fixed char */++/* These flags are used in the groupinfo vector. */++#define GI_SET_FIXED_LENGTH    0x80000000u+#define GI_NOT_FIXED_LENGTH    0x40000000u+#define GI_FIXED_LENGTH_MASK   0x0000ffffu++/* 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). */++#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)++/* Table to identify hex digits. The tables in chartables are dependent on the+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 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+UTF-8 mode. */++#ifndef EBCDIC+static const uint8_t xdigitab[] =+  {+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   0-  7 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   8- 15 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  16- 23 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  24- 31 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*    - '  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  ( - /  */+  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /*  0 - 7  */+  0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff, /*  8 - ?  */+  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /*  @ - G  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  H - O  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  P - W  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  X - _  */+  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /*  ` - g  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  h - o  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  p - w  */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  x -127 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 128-135 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 136-143 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144-151 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 152-159 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160-167 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 168-175 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 176-183 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 192-199 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 2ff-207 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 208-215 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 216-223 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 224-231 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 232-239 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 240-247 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* 248-255 */++#else++/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */++static const uint8_t xdigitab[] =+  {+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   0-  7  0 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*   8- 15    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  16- 23 10 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  24- 31    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  32- 39 20 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  40- 47    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  48- 55 30 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  56- 63    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*    - 71 40 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  72- |     */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  & - 87 50 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  88- 95    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  - -103 60 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 104- ?     */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 112-119 70 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 120- "     */+  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /* 128- g  80 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  h -143    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 144- p  90 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  q -159    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 160- x  A0 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  y -175    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  ^ -183 B0 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 184-191    */+  0xff,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xff, /*  { - G  C0 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  H -207    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  } - P  D0 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  Q -223    */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  \ - X  E0 */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*  Y -239    */+  0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /*  0 - 7  F0 */+  0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff};/*  8 -255    */+#endif  /* EBCDIC */+++/* Table for handling alphanumeric escaped characters. Positive returns are+simple data values; negative values are for special things like \d and so on.+Zero means further processing is needed (for things like \x), or the escape is+invalid. */++/* This is the "normal" table for ASCII systems or for EBCDIC systems running+in UTF-8 mode. It runs from '0' to 'z'. */++#ifndef EBCDIC+#define ESCAPES_FIRST       CHAR_0+#define ESCAPES_LAST        CHAR_z+#define UPPER_CASE(c)       (c-32)++static const short int escapes[] = {+     0,                       0,+     0,                       0,+     0,                       0,+     0,                       0,+     0,                       0,+     CHAR_COLON,              CHAR_SEMICOLON,+     CHAR_LESS_THAN_SIGN,     CHAR_EQUALS_SIGN,+     CHAR_GREATER_THAN_SIGN,  CHAR_QUESTION_MARK,+     CHAR_COMMERCIAL_AT,      -ESC_A,+     -ESC_B,                  -ESC_C,+     -ESC_D,                  -ESC_E,+     0,                       -ESC_G,+     -ESC_H,                  0,+     0,                       -ESC_K,+     0,                       0,+     -ESC_N,                  0,+     -ESC_P,                  -ESC_Q,+     -ESC_R,                  -ESC_S,+     0,                       0,+     -ESC_V,                  -ESC_W,+     -ESC_X,                  0,+     -ESC_Z,                  CHAR_LEFT_SQUARE_BRACKET,+     CHAR_BACKSLASH,          CHAR_RIGHT_SQUARE_BRACKET,+     CHAR_CIRCUMFLEX_ACCENT,  CHAR_UNDERSCORE,+     CHAR_GRAVE_ACCENT,       CHAR_BEL,+     -ESC_b,                  0,+     -ESC_d,                  CHAR_ESC,+     CHAR_FF,                 0,+     -ESC_h,                  0,+     0,                       -ESC_k,+     0,                       0,+     CHAR_LF,                 0,+     -ESC_p,                  0,+     CHAR_CR,                 -ESC_s,+     CHAR_HT,                 0,+     -ESC_v,                  -ESC_w,+     0,                       0,+     -ESC_z+};++#else++/* This is the "abnormal" table for EBCDIC systems without UTF-8 support.+It runs from 'a' to '9'. For some minimal testing of EBCDIC features, the code+is sometimes compiled on an ASCII system. In this case, we must not use CHAR_a+because it is defined as 'a', which of course picks up the ASCII value. */++#if 'a' == 0x81                    /* Check for a real EBCDIC environment */+#define ESCAPES_FIRST       CHAR_a+#define ESCAPES_LAST        CHAR_9+#define UPPER_CASE(c)       (c+64)+#else                              /* Testing in an ASCII environment */+#define ESCAPES_FIRST  ((unsigned char)'\x81')   /* EBCDIC 'a' */+#define ESCAPES_LAST   ((unsigned char)'\xf9')   /* EBCDIC '9' */+#define UPPER_CASE(c)  (c-32)+#endif++static const short int escapes[] = {+/*  80 */         CHAR_BEL, -ESC_b,       0, -ESC_d, CHAR_ESC, CHAR_FF,      0,+/*  88 */ -ESC_h,        0,      0,     '{',      0,        0,       0,      0,+/*  90 */      0,        0, -ESC_k,       0,      0,  CHAR_LF,       0, -ESC_p,+/*  98 */      0,  CHAR_CR,      0,     '}',      0,        0,       0,      0,+/*  A0 */      0,      '~', -ESC_s, CHAR_HT,      0,   -ESC_v,  -ESC_w,      0,+/*  A8 */      0,   -ESC_z,      0,       0,      0,      '[',       0,      0,+/*  B0 */      0,        0,      0,       0,      0,        0,       0,      0,+/*  B8 */      0,        0,      0,       0,      0,      ']',     '=',    '-',+/*  C0 */    '{',   -ESC_A, -ESC_B,  -ESC_C, -ESC_D,   -ESC_E,       0, -ESC_G,+/*  C8 */ -ESC_H,        0,      0,       0,      0,        0,       0,      0,+/*  D0 */    '}',        0, -ESC_K,       0,      0,   -ESC_N,       0, -ESC_P,+/*  D8 */ -ESC_Q,   -ESC_R,      0,       0,      0,        0,       0,      0,+/*  E0 */   '\\',        0, -ESC_S,       0,      0,   -ESC_V,  -ESC_W, -ESC_X,+/*  E8 */      0,   -ESC_Z,      0,       0,      0,        0,       0,      0,+/*  F0 */      0,        0,      0,       0,      0,        0,       0,      0,+/*  F8 */      0,        0+};++/* We also need a table of characters that may follow \c in an EBCDIC+environment for characters 0-31. */++static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";++#endif   /* EBCDIC */+++/* Table of special "verbs" like (*PRUNE). This is a short table, so it is+searched linearly. Put all the names into a single string, in order to reduce+the number of relocations when a shared library is dynamically linked. The+string is built from string macros so that it works in UTF-8 mode on EBCDIC+platforms. */++typedef struct verbitem {+  unsigned int len;          /* Length of verb name */+  uint32_t meta;             /* Base META_ code */+  int has_arg;               /* Argument requirement */+} verbitem;++static const char verbnames[] =+  "\0"                       /* Empty name is a shorthand for MARK */+  STRING_MARK0+  STRING_ACCEPT0+  STRING_F0+  STRING_FAIL0+  STRING_COMMIT0+  STRING_PRUNE0+  STRING_SKIP0+  STRING_THEN;++static const verbitem verbs[] = {+  { 0, META_MARK,   +1 },  /* > 0 => must have an argument */+  { 4, META_MARK,   +1 },+  { 6, META_ACCEPT, -1 },  /* < 0 => Optional argument, convert to pre-MARK */+  { 1, META_FAIL,   -1 },+  { 4, META_FAIL,   -1 },+  { 6, META_COMMIT,  0 },+  { 5, META_PRUNE,   0 },  /* Optional argument; 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. */++static const uint32_t verbops[] = {+  OP_MARK, OP_ACCEPT, OP_FAIL, OP_COMMIT, OP_COMMIT_ARG, OP_PRUNE,+  OP_PRUNE_ARG, OP_SKIP, OP_SKIP_ARG, OP_THEN, OP_THEN_ARG };++/* Table of "alpha assertions" like (*pla:...), similar to the (*VERB) table. */++typedef struct alasitem {+  unsigned int len;          /* Length of name */+  uint32_t meta;             /* Base META_ code */+} alasitem;++static const char alasnames[] =+  STRING_pla0+  STRING_plb0+  STRING_napla0+  STRING_naplb0+  STRING_nla0+  STRING_nlb0+  STRING_positive_lookahead0+  STRING_positive_lookbehind0+  STRING_non_atomic_positive_lookahead0+  STRING_non_atomic_positive_lookbehind0+  STRING_negative_lookahead0+  STRING_negative_lookbehind0+  STRING_atomic0+  STRING_sr0+  STRING_asr0+  STRING_script_run0+  STRING_atomic_script_run;++static const alasitem alasmeta[] = {+  {  3, META_LOOKAHEAD         },+  {  3, META_LOOKBEHIND        },+  {  5, META_LOOKAHEAD_NA      },+  {  5, META_LOOKBEHIND_NA     },+  {  3, META_LOOKAHEADNOT      },+  {  3, META_LOOKBEHINDNOT     },+  { 18, META_LOOKAHEAD         },+  { 19, META_LOOKBEHIND        },+  { 29, META_LOOKAHEAD_NA      },+  { 30, META_LOOKBEHIND_NA     },+  { 18, META_LOOKAHEADNOT      },+  { 19, META_LOOKBEHINDNOT     },+  {  6, META_ATOMIC            },+  {  2, META_SCRIPT_RUN        }, /* sr = script run */+  {  3, META_ATOMIC_SCRIPT_RUN }, /* asr = atomic script run */+  { 10, META_SCRIPT_RUN        }, /* script run */+  { 17, META_ATOMIC_SCRIPT_RUN }  /* atomic script run */+};++static const int alascount = sizeof(alasmeta)/sizeof(alasitem);++/* Offsets from OP_STAR for case-independent and negative repeat opcodes. */++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+library is dynamically loaded. The list of lengths is terminated by a zero+length entry. The first three must be alpha, lower, upper, as this is assumed+for handling case independence. The indices for graph, print, and punct are+needed, so identify them. */++static const char posix_names[] =+  STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0+  STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0+  STRING_graph0 STRING_print0 STRING_punct0 STRING_space0+  STRING_word0  STRING_xdigit;++static const uint8_t posix_name_lengths[] = {+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };++#define PC_GRAPH  8+#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+characters are removed, and for [:alpha:] and [:alnum:] the underscore+character is removed. The triples in the table consist of the base map offset,+second map offset or -1 if no second map, and a non-negative value for map+addition or a negative value for map subtraction (if there are two maps). The+absolute value of the third field has these meanings: 0 => no tweaking, 1 =>+remove vertical space characters, 2 => remove underscore. */++static const int posix_class_maps[] = {+  cbit_word,  cbit_digit, -2,             /* alpha */+  cbit_lower, -1,          0,             /* lower */+  cbit_upper, -1,          0,             /* upper */+  cbit_word,  -1,          2,             /* alnum - word without underscore */+  cbit_print, cbit_cntrl,  0,             /* ascii */+  cbit_space, -1,          1,             /* blank - a GNU extension */+  cbit_cntrl, -1,          0,             /* cntrl */+  cbit_digit, -1,          0,             /* digit */+  cbit_graph, -1,          0,             /* graph */+  cbit_print, -1,          0,             /* print */+  cbit_punct, -1,          0,             /* punct */+  cbit_space, -1,          0,             /* space */+  cbit_word,  -1,          0,             /* word - a Perl extension */+  cbit_xdigit,-1,          0              /* xdigit */+};++#ifdef SUPPORT_UNICODE++/* 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 */+};+#define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t)))+#endif  /* SUPPORT_UNICODE */++/* Masks for checking option settings. When PCRE2_LITERAL is set, only a subset+are allowed. */++#define PUBLIC_LITERAL_COMPILE_OPTIONS \+  (PCRE2_ANCHORED|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_ENDANCHORED| \+   PCRE2_FIRSTLINE|PCRE2_LITERAL|PCRE2_MATCH_INVALID_UTF| \+   PCRE2_NO_START_OPTIMIZE|PCRE2_NO_UTF_CHECK|PCRE2_USE_OFFSET_LIMIT|PCRE2_UTF)++#define PUBLIC_COMPILE_OPTIONS \+  (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| \+    PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX)++/* Compile time error code numbers. They are given names so that they can more+easily be tracked. When a new number is added, the tables called eint1 and+eint2 in pcre2posix.c may need to be updated, and a new error text must be+added to compile_error_texts in pcre2_error.c. */++enum { ERR0 = COMPILE_ERROR_BASE,+       ERR1,  ERR2,  ERR3,  ERR4,  ERR5,  ERR6,  ERR7,  ERR8,  ERR9,  ERR10,+       ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,+       ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30,+       ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40,+       ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50,+       ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60,+       ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70,+       ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80,+       ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90,+       ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98 };++/* 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+compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is+generic and always supported. */++enum { PSO_OPT,     /* Value is an option bit */+       PSO_FLG,     /* Value is a flag bit */+       PSO_NL,      /* Value is a newline type */+       PSO_BSR,     /* Value is a \R type */+       PSO_LIMH,    /* Read integer value for heap limit */+       PSO_LIMM,    /* Read integer value for match limit */+       PSO_LIMD };  /* Read integer value for depth limit */++typedef struct pso {+  const uint8_t *name;+  uint16_t length;+  uint16_t type;+  uint32_t value;+} pso;++/* NB: STRING_UTFn_RIGHTPAR contains the length as well */++static pso pso_list[] = {+  { (uint8_t *)STRING_UTFn_RIGHTPAR,                  PSO_OPT, PCRE2_UTF },+  { (uint8_t *)STRING_UTF_RIGHTPAR,                4, PSO_OPT, PCRE2_UTF },+  { (uint8_t *)STRING_UCP_RIGHTPAR,                4, PSO_OPT, PCRE2_UCP },+  { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR,           9, PSO_FLG, PCRE2_NOTEMPTY_SET },+  { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR,  17, PSO_FLG, PCRE2_NE_ATST_SET },+  { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR,   16, PSO_OPT, PCRE2_NO_AUTO_POSSESS },+  { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR },+  { (uint8_t *)STRING_NO_JIT_RIGHTPAR,             7, PSO_FLG, PCRE2_NOJIT },+  { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR,      13, PSO_OPT, PCRE2_NO_START_OPTIMIZE },+  { (uint8_t *)STRING_LIMIT_HEAP_EQ,              11, PSO_LIMH, 0 },+  { (uint8_t *)STRING_LIMIT_MATCH_EQ,             12, PSO_LIMM, 0 },+  { (uint8_t *)STRING_LIMIT_DEPTH_EQ,             12, PSO_LIMD, 0 },+  { (uint8_t *)STRING_LIMIT_RECURSION_EQ,         16, PSO_LIMD, 0 },+  { (uint8_t *)STRING_CR_RIGHTPAR,                 3, PSO_NL,  PCRE2_NEWLINE_CR },+  { (uint8_t *)STRING_LF_RIGHTPAR,                 3, PSO_NL,  PCRE2_NEWLINE_LF },+  { (uint8_t *)STRING_CRLF_RIGHTPAR,               5, PSO_NL,  PCRE2_NEWLINE_CRLF },+  { (uint8_t *)STRING_ANY_RIGHTPAR,                4, PSO_NL,  PCRE2_NEWLINE_ANY },+  { (uint8_t *)STRING_NUL_RIGHTPAR,                4, PSO_NL,  PCRE2_NEWLINE_NUL },+  { (uint8_t *)STRING_ANYCRLF_RIGHTPAR,            8, PSO_NL,  PCRE2_NEWLINE_ANYCRLF },+  { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR,       12, PSO_BSR, PCRE2_BSR_ANYCRLF },+  { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR,       12, PSO_BSR, PCRE2_BSR_UNICODE }+};++/* This table is used when converting repeating opcodes into possessified+versions as a result of an explicit possessive quantifier such as ++. A zero+value means there is no possessified version - in those cases the item in+question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT+because all relevant opcodes are less than that. */++static const uint8_t opcode_possessify[] = {+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 0 - 15  */+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* 16 - 31 */++  0,                       /* NOTI */+  OP_POSSTAR, 0,           /* STAR, MINSTAR */+  OP_POSPLUS, 0,           /* PLUS, MINPLUS */+  OP_POSQUERY, 0,          /* QUERY, MINQUERY */+  OP_POSUPTO, 0,           /* UPTO, MINUPTO */+  0,                       /* EXACT */+  0, 0, 0, 0,              /* POS{STAR,PLUS,QUERY,UPTO} */++  OP_POSSTARI, 0,          /* STARI, MINSTARI */+  OP_POSPLUSI, 0,          /* PLUSI, MINPLUSI */+  OP_POSQUERYI, 0,         /* QUERYI, MINQUERYI */+  OP_POSUPTOI, 0,          /* UPTOI, MINUPTOI */+  0,                       /* EXACTI */+  0, 0, 0, 0,              /* POS{STARI,PLUSI,QUERYI,UPTOI} */++  OP_NOTPOSSTAR, 0,        /* NOTSTAR, NOTMINSTAR */+  OP_NOTPOSPLUS, 0,        /* NOTPLUS, NOTMINPLUS */+  OP_NOTPOSQUERY, 0,       /* NOTQUERY, NOTMINQUERY */+  OP_NOTPOSUPTO, 0,        /* NOTUPTO, NOTMINUPTO */+  0,                       /* NOTEXACT */+  0, 0, 0, 0,              /* NOTPOS{STAR,PLUS,QUERY,UPTO} */++  OP_NOTPOSSTARI, 0,       /* NOTSTARI, NOTMINSTARI */+  OP_NOTPOSPLUSI, 0,       /* NOTPLUSI, NOTMINPLUSI */+  OP_NOTPOSQUERYI, 0,      /* NOTQUERYI, NOTMINQUERYI */+  OP_NOTPOSUPTOI, 0,       /* NOTUPTOI, NOTMINUPTOI */+  0,                       /* NOTEXACTI */+  0, 0, 0, 0,              /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */++  OP_TYPEPOSSTAR, 0,       /* TYPESTAR, TYPEMINSTAR */+  OP_TYPEPOSPLUS, 0,       /* TYPEPLUS, TYPEMINPLUS */+  OP_TYPEPOSQUERY, 0,      /* TYPEQUERY, TYPEMINQUERY */+  OP_TYPEPOSUPTO, 0,       /* TYPEUPTO, TYPEMINUPTO */+  0,                       /* TYPEEXACT */+  0, 0, 0, 0,              /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */++  OP_CRPOSSTAR, 0,         /* CRSTAR, CRMINSTAR */+  OP_CRPOSPLUS, 0,         /* CRPLUS, CRMINPLUS */+  OP_CRPOSQUERY, 0,        /* CRQUERY, CRMINQUERY */+  OP_CRPOSRANGE, 0,        /* CRRANGE, CRMINRANGE */+  0, 0, 0, 0,              /* CRPOS{STAR,PLUS,QUERY,RANGE} */++  0, 0, 0,                 /* CLASS, NCLASS, XCLASS */+  0, 0,                    /* REF, REFI */+  0, 0,                    /* DNREF, DNREFI */+  0, 0                     /* RECURSE, CALLOUT */+};+++#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_LOOKAHEAD_NA: fprintf(stderr, "META (*napla:"); break;+    case META_SCRIPT_RUN: fprintf(stderr, "META (*sr:"); 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_FAIL: fprintf(stderr, "META (*FAIL)"); break;+    case META_COMMIT: fprintf(stderr, "META (*COMMIT)"); 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_LOOKBEHIND_NA:+    fprintf(stderr, "META (*naplb: %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_COMMIT_ARG:+    fprintf(stderr, "META (*COMMIT:");+    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               *+*************************************************/++/* Compiled JIT code cannot be copied, so the new compiled block has no+associated JIT data. */++PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION+pcre2_code_copy(const pcre2_code *code)+{+PCRE2_SIZE* ref_count;+pcre2_code *newcode;++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;++/* If the code is one that has been deserialized, increment the reference count+in the decoded tables. */++if ((code->flags & PCRE2_DEREF_TABLES) != 0)+  {+  ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);+  (*ref_count)++;+  }++return newcode;+}++++/*************************************************+*     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               *+*************************************************/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_code_free(pcre2_code *code)+{+PCRE2_SIZE* ref_count;++if (code != NULL)+  {+  if (code->executable_jit != NULL)+    PRIV(jit_free)(code->executable_jit, &code->memctl);++  if ((code->flags & PCRE2_DEREF_TABLES) != 0)+    {+    /* Decoded tables belong to the codes after deserialization, and they must+    be freed when there are no more references to them. The *ref_count should+    always be > 0. */++    ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);+    if (*ref_count > 0)+      {+      (*ref_count)--;+      if (*ref_count == 0)+        code->memctl.free((void *)code->tables, code->memctl.memory_data);+      }+    }++  code->memctl.free(code, code->memctl.memory_data);+  }+}++++/*************************************************+*         Read a number, possibly signed         *+*************************************************/++/* 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:+  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:      TRUE  - a number was read+              FALSE - errorcode == 0 => no number was found+                      errorcode != 0 => an error occurred+*/++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)+{+int sign = 0;+uint32_t n = 0;+PCRE2_SPTR ptr = *ptrptr;+BOOL yield = FALSE;++*errorcodeptr = 0;++if (allow_sign >= 0 && ptr < ptrend)+  {+  if (*ptr == CHAR_PLUS)+    {+    sign = +1;+    max_value -= allow_sign;+    ptr++;+    }+  else if (*ptr == CHAR_MINUS)+    {+    sign = -1;+    ptr++;+    }+  }++if (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE;+while (ptr < ptrend && IS_DIGIT(*ptr))+  {+  n = n * 10 + *ptr++ - CHAR_0;+  if (n > max_value)+    {+    *errorcodeptr = max_error;+    goto EXIT;+    }+  }++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 or NULL when called from pcre2_substitute()++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, uint32_t extra_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. */++if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {}  /* Definitely literal */++/* Otherwise, do a table lookup. Non-zero values need little processing here. A+positive value is a literal value for something like \n. A negative value is+the negation of one of the ESC_ macros that is passed back for handling by the+calling function. Some extra checking is needed for \N because only \N{U+dddd}+is supported. If the value is zero, further processing is handled below. */++else if ((i = escapes[c - ESCAPES_FIRST]) != 0)+  {+  if (i > 0)+    {+    c = (uint32_t)i;+    if (c == CHAR_CR && (extra_options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0)+      c = CHAR_LF;+    }+  else  /* Negative table entry */+    {+    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 */++    /* Perl supports \N{name} for character names and \N{U+dddd} for numerical+    Unicode code points, as well as plain \N for "not newline". PCRE does not+    support \N{name}. However, it does support quantification such as \N{2,3},+    so if \N{ is not followed by U+dddd we check for a quantifier. */++    if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)+      {+      PCRE2_SPTR p = ptr + 1;++      /* \N{U+ can be handled by the \x{ code. However, this construction is+      not valid in EBCDIC environments because it specifies a Unicode+      character, not a codepoint in the local code. For example \N{U+0041}+      must be "A" in all environments. Also, in Perl, \N{U+ forces Unicode+      casing semantics for the entire pattern, so allow it only in UTF (i.e.+      Unicode) mode. */++      if (ptrend - p > 1 && *p == CHAR_U && p[1] == CHAR_PLUS)+        {+#ifdef EBCDIC+        *errorcodeptr = ERR93;+#else+        if (utf)+          {+          ptr = p + 1;+          escape = 0;   /* Not a fancy escape after all */+          goto COME_FROM_NU;+          }+        else *errorcodeptr = ERR93;+#endif+        }++      /* Give an error if what follows is not a quantifier, but don't override+      an error set by the quantifier reader (e.g. number overflow). */++      else+        {+        if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) &&+             *errorcodeptr == 0)+          *errorcodeptr = ERR37;+        }+      }+    }+  }++/* Escapes that need further processing, including those that are unknown, have+a zero entry in the lookup table. When called from pcre2_substitute(), only \c,+\o, and \x are recognized (\u and \U can never appear as they are used for case+forcing). */++else+  {+  int s;+  PCRE2_SPTR oldptr;+  BOOL overflow;+  BOOL alt_bsux =+    ((options & PCRE2_ALT_BSUX) | (extra_options & PCRE2_EXTRA_ALT_BSUX)) != 0;++  /* Filter calls from pcre2_substitute(). */++  if (cb == NULL)+    {+    if (c != CHAR_c && c != CHAR_o && c != CHAR_x)+      {+      *errorcodeptr = ERR3;+      return 0;+      }+    alt_bsux = FALSE;   /* Do not modify \x handling */+    }++  switch (c)+    {+    /* A number of Perl escapes are not handled by PCRE. We give an explicit+    error. */++    case CHAR_F:+    case CHAR_l:+    case CHAR_L:+    *errorcodeptr = ERR37;+    break;++    /* \u is unrecognized when neither PCRE2_ALT_BSUX nor PCRE2_EXTRA_ALT_BSUX+    is set. Otherwise, \u must be followed by exactly four hex digits or, if+    PCRE2_EXTRA_ALT_BSUX is set, by any number of hex digits in braces.+    Otherwise it is a lowercase u letter. This gives some compatibility with+    ECMAScript (aka JavaScript). */++    case CHAR_u:+    if (!alt_bsux) *errorcodeptr = ERR37; else+      {+      uint32_t xc;++      if (ptr >= ptrend) break;+      if (*ptr == CHAR_LEFT_CURLY_BRACKET &&+          (extra_options & PCRE2_EXTRA_ALT_BSUX) != 0)+        {+        PCRE2_SPTR hptr = ptr + 1;+        cc = 0;++        while (hptr < ptrend && (xc = XDIGIT(*hptr)) != 0xff)+          {+          if ((cc & 0xf0000000) != 0)  /* Test for 32-bit overflow */+            {+            *errorcodeptr = ERR77;+            ptr = hptr;   /* Show where */+            break;        /* *hptr != } will cause another break below */+            }+          cc = (cc << 4) | xc;+          hptr++;+          }++        if (hptr == ptr + 1 ||   /* No hex digits */+            hptr >= ptrend ||    /* Hit end of input */+            *hptr != CHAR_RIGHT_CURLY_BRACKET)  /* No } terminator */+          break;         /* Hex escape not recognized */++        c = cc;          /* Accept the code point */+        ptr = hptr + 1;+        }++      else  /* Must be exactly 4 hex digits */+        {+        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)+        {+        if (c > 0x10ffffU) *errorcodeptr = ERR77;+        else+          if (c >= 0xd800 && c <= 0xdfff &&+              (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)+                *errorcodeptr = ERR73;+        }+      else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77;+      }+    break;++    /* \U is unrecognized unless PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set,+    in which case it is an upper case letter. */++    case CHAR_U:+    if (!alt_bsux) *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)+      {+      *errorcodeptr = ERR57;+      break;+      }++    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;++    /* 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;+      ptr--;   /* Back to the digit */+      if (!read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, ERR61, &s,+          errorcodeptr))+        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[-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 */+      }++    /* 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. */++    if (c >= CHAR_8) break;++    /* Fall through */++    /* \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;++    /* \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 >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET)+      {+      ptr--;+      *errorcodeptr = ERR55;+      }+    else if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)+      *errorcodeptr = ERR78;+    else+      {+      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 &&+            (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)+          {+          ptr--;+          *errorcodeptr = ERR73;+          }+        }+      else+        {+        ptr--;+        *errorcodeptr = ERR64;+        }+      }+    break;++    /* When PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, \x must be followed+    by two hexadecimal digits. Otherwise it is a lowercase x letter. */++    case CHAR_x:+    if (alt_bsux)+      {+      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;+      }++    /* Handle \x in Perl's style. \x{ddd} is a character code 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)+        {+#ifndef EBCDIC+        COME_FROM_NU:+#endif+        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 &&+              (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+    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 characters suggest we are using the+    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;+    }+  }++/* 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++++/*************************************************+*           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) or an (*alpha_assertion). The initial+pointer must be to the character before the name. If that character is '*' we+are reading a verb or alpha assertion name. The pointer is updated to point+after the name, for a VERB or alpha assertion name, 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+  utf         true if the input is UTF-encoded+  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, BOOL utf, uint32_t terminator,+  PCRE2_SIZE *offsetptr, PCRE2_SPTR *nameptr, uint32_t *namelenptr,+  int *errorcodeptr, compile_block *cb)+{+PCRE2_SPTR ptr = *ptrptr;+BOOL is_group = (*ptr != CHAR_ASTERISK);++if (++ptr >= ptrend)               /* No characters in name */+  {+  *errorcodeptr = is_group? ERR62: /* Subpattern name expected */+                            ERR60; /* Verb not recognized or malformed */+  goto FAILED;+  }++*nameptr = ptr;+*offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern);++/* In UTF mode, a group name may contain letters and decimal digits as defined+by Unicode properties, and underscores, but must not start with a digit. */++#ifdef SUPPORT_UNICODE+if (utf && is_group)+  {+  uint32_t c, type;++  GETCHAR(c, ptr);+  type = UCD_CHARTYPE(c);++  if (type == ucp_Nd)+    {+    *errorcodeptr = ERR44;+    goto FAILED;+    }++  for(;;)+    {+    if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L &&+        c != CHAR_UNDERSCORE) break;+    ptr++;+    FORWARDCHARTEST(ptr, ptrend);+    if (ptr >= ptrend) break;+    GETCHAR(c, ptr);+    type = UCD_CHARTYPE(c);+    }+  }+else+#else+(void)utf;  /* Avoid compiler warning */+#endif      /* SUPPORT_UNICODE */++/* Handle non-group names and group names in non-UTF modes. A group name must+not start with a digit. If either of the others start with a digit it just+won't be recognized. */++  {+  if (is_group && IS_DIGIT(*ptr))+    {+    *errorcodeptr = ERR44;+    goto FAILED;+    }++  while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0)+    {+    ptr++;+    }+  }++/* Check name length */++if (ptr > *nameptr + MAX_NAME_SIZE)+  {+  *errorcodeptr = ERR48;+  goto FAILED;+  }+*namelenptr = (uint32_t)(ptr - *nameptr);++/* Subpattern names must not be empty, and their terminator is checked here.+(What follows a verb or alpha assertion name is checked separately.) */++if (is_group)+  {+  if (ptr == *nameptr)+    {+    *errorcodeptr = ERR62;   /* Subpattern name expected */+    goto FAILED;+    }+  if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)+    {+    *errorcodeptr = ERR42;+    goto FAILED;+    }+  ptr++;+  }++*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+#define NSF_ATOMICSR       0x0004u++/* Options that are changeable within the pattern must be tracked during+parsing. Some (e.g. PCRE2_EXTENDED) are implemented entirely during parsing,+but all must be tracked so that META_OPTIONS items set the correct values for+the main compiling phase. */++#define PARSE_TRACKED_OPTIONS (PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_DUPNAMES| \+  PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \+  PCRE2_UNGREEDY)++/* 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 macro encapsulates+the storing of literal values in the main parsed pattern, where they can always+be quantified. */++#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 *verbstartptr = NULL;+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;+uint32_t add_after_mark = 0;+uint32_t extra_options = cb->cx->extra_options;+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 ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0)+  {+  *parsed_pattern++ = META_CIRCUMFLEX;+  *parsed_pattern++ = META_NOCAPTURE;+  }+else if ((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)+        {                          /* Don't use PARSED_LITERAL() because it */+#if PCRE2_CODE_UNIT_WIDTH == 32    /* sets okquantifier. */+        if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;+#endif+        *parsed_pattern++ = c;+        }+      else+        {+        if (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)) ||+#ifdef SUPPORT_UNICODE+        /* OR: character > 255 AND not Unicode Pattern White Space */+        (c > 255 && (c|1) != 0x200f && (c|1) != 0x2029) ||+#endif+        /* OR: not a # comment or isspace() white space */+        (c < 256 && c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0+#ifdef SUPPORT_UNICODE+        /* and not CHAR_NEL when Unicode is supported */+          && c != CHAR_NEL+#endif+       )))+    {+    PCRE2_SIZE verbnamelength;++    switch(c)+      {+      default:                     /* Don't use PARSED_LITERAL() because it */+#if PCRE2_CODE_UNIT_WIDTH == 32    /* sets okquantifier. */+      if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;+#endif+      *parsed_pattern++ = c;+      break;++      case CHAR_RIGHT_PARENTHESIS:+      inverbname = FALSE;+      /* 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;++      /* If this name was on a verb such as (*ACCEPT) which does not continue,+      a (*MARK) was generated for the name. We now add the original verb as the+      next item. */++      if (add_after_mark != 0)+        {+        *parsed_pattern++ = add_after_mark;+        add_after_mark = 0;+        }+      break;++      case CHAR_BACKSLASH:+      if ((options & PCRE2_ALT_VERBNAMES) != 0)+        {+        escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,+          cb->cx->extra_options, FALSE, cb);+        if (errorcode != 0) goto FAILED;+        }+      else escape = 0;   /* Treat all as literal */++      switch(escape)+        {+        case 0:                    /* Don't use PARSED_LITERAL() because it */+#if PCRE2_CODE_UNIT_WIDTH == 32    /* sets okquantifier. */+        if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;+#endif+        *parsed_pattern++ = c;+        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. The+  whitespace characters are those designated as "Pattern White Space" by+  Unicode, which are the isspace() characters plus CHAR_NEL (newline), which is+  U+0085 in Unicode, plus U+200E, U+200F, U+2028, and U+2029. These are a+  subset of space characters that match \h and \v. */++  if ((options & PCRE2_EXTENDED) != 0)+    {+    if (c < 256 && (cb->ctypes[c] & ctype_space) != 0) continue;+#ifdef SUPPORT_UNICODE+    if (c == CHAR_NEL || (c|1) == 0x200f || (c|1) == 0x2029) continue;+#endif+    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 || ptr[0] == CHAR_ASTERISK);+    if (ok)+      {+      if (ptr[0] == CHAR_ASTERISK)  /* New alpha assertion format, possibly */+        {+        ok = MAX_255(ptr[1]) && (cb->ctypes[ptr[1]] & ctype_lcletter) != 0;+        }+      else switch(ptr[1])  /* Traditional symbolic format */+        {+        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:+        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,+      cb->cx->extra_options, FALSE, cb);+    if (errorcode != 0)+      {+      ESCAPE_FAILED:+      if ((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, utf, 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;+      }++    /* Most (*VERB)s are not allowed to be quantified, but an ungreedy+    quantifier can be useful for (*ACCEPT) - meaning "succeed on backtrack", a+    sort of negated (*COMMIT). We therefore allow (*ACCEPT) to be quantified by+    wrapping it in non-capturing brackets, but we have to allow for a preceding+    (*MARK) for when (*ACCEPT) has an argument. */++    if (parsed_pattern[-1] == META_ACCEPT)+      {+      uint32_t *p;+      for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0];+      *verbstartptr = META_NOCAPTURE;+      parsed_pattern[1] = META_KET;+      parsed_pattern += 2;+      }++    /* 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;+++    /* ---- Character class ---- */++    case CHAR_LEFT_SQUARE_BRACKET:+    okquantifier = TRUE;++    /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is+    used for "start of word" and "end of word". As these are otherwise illegal+    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. */++    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,+          cb->cx->extra_options, TRUE, cb);++        if (errorcode != 0)+          {+          if ((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 */+          }++        switch(escape)+          {+          case 0:  /* Escaped character code point is in c */+          char_is_literal = FALSE;+          goto CLASS_LITERAL;++          case ESC_b:+          c = CHAR_BS;    /* \b is backspace in a class */+          char_is_literal = FALSE;+          goto CLASS_LITERAL;++          case ESC_Q:+          inescq = TRUE;  /* Enter literal mode */+          goto CLASS_CONTINUE;++          case ESC_E:     /* Ignore orphan \E */+          goto CLASS_CONTINUE;++          case ESC_B:     /* Always an error in a class */+          case ESC_R:+          case ESC_X:+          errorcode = ERR7;+          ptr--;+          goto FAILED;+          }++        /* The second part of a range can be a single-character escape+        sequence (detected above), but not any of the other escapes. Perl+        treats a hyphen as a literal in such circumstances. However, in Perl's+        warning mode, a warning is given, so PCRE now faults it, as it is+        almost certainly a mistake on the user's part. */++        if (class_range_state == RANGE_STARTED)+          {+          errorcode = ERR50;+          goto FAILED;  /* Not CLASS_ESCAPE_FAILED; always an error */+          }++        /* Of the remaining escapes, only those that define characters are+        allowed in a class. None may start a range. */++        class_range_state = RANGE_NO;+        switch(escape)+          {+          case ESC_N:+          errorcode = ERR71;+          goto 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 FAILED;+#endif+          break;  /* End \P and \p */++          default:    /* All others are not allowed in a class */+          errorcode = ERR7;+          ptr--;+          goto 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 */++    /* -] at the end of a class is a literal '-' */++    if (class_range_state == RANGE_STARTED)+      {+      parsed_pattern[-1] = CHAR_MINUS;+      class_range_state = RANGE_NO;+      }++    *parsed_pattern++ = META_CLASS_END;+    break;  /* End of character class */+++    /* ---- 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 or an+    alpha assertion or a positive non-atomic lookahead. */++    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)+          {+          if (cb->bracount >= MAX_GROUP_NUMBER)+            {+            errorcode = ERR97;+            goto FAILED;+            }+          cb->bracount++;+          *parsed_pattern++ = META_CAPTURE | cb->bracount;+          }+        else *parsed_pattern++ = META_NOCAPTURE;+        }++      /* Do nothing for (* followed by end of pattern or ) so it gives a "bad+      quantifier" error rather than "(*MARK) must have an argument". */++      else if (ptrend - ptr <= 1 || (c = ptr[1]) == CHAR_RIGHT_PARENTHESIS)+        break;++      /* Handle "alpha assertions" such as (*pla:...). Most of these are+      synonyms for the historical symbolic assertions, but the script run and+      non-atomic lookaround ones are new. They are distinguished by starting+      with a lower case letter. Checking both ends of the alphabet makes this+      work in all character codes. */++      else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0)+        {+        uint32_t meta;++        vn = alasnames;+        if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen,+          &errorcode, cb)) goto FAILED;+        if (ptr >= ptrend || *ptr != CHAR_COLON)+          {+          errorcode = ERR95;  /* Malformed */+          goto FAILED;+          }++        /* Scan the table of alpha assertion names */++        for (i = 0; i < alascount; i++)+          {+          if (namelen == alasmeta[i].len &&+              PRIV(strncmp_c8)(name, vn, namelen) == 0)+            break;+          vn += alasmeta[i].len + 1;+          }++        if (i >= alascount)+          {+          errorcode = ERR95;  /* Alpha assertion not recognized */+          goto FAILED;+          }++        /* Check for expecting an assertion condition. If so, only atomic+        lookaround assertions are valid. */++        meta = alasmeta[i].meta;+        if (prev_expect_cond_assert > 0 &&+            (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT))+          {+          errorcode = (meta == META_LOOKAHEAD_NA || meta == META_LOOKBEHIND_NA)?+            ERR98 : ERR28;  /* (Atomic) assertion expected */+          goto FAILED;+          }++        /* The lookaround alphabetic synonyms can mostly be handled by jumping+        to the code that handles the traditional symbolic forms. */++        switch(meta)+          {+          default:+          errorcode = ERR89;  /* Unknown code; should never occur because */+          goto FAILED;        /* the meta values come from a table above. */++          case META_ATOMIC:+          goto ATOMIC_GROUP;++          case META_LOOKAHEAD:+          goto POSITIVE_LOOK_AHEAD;++          case META_LOOKAHEAD_NA:+          goto POSITIVE_NONATOMIC_LOOK_AHEAD;++          case META_LOOKAHEADNOT:+          goto NEGATIVE_LOOK_AHEAD;++          case META_LOOKBEHIND:+          case META_LOOKBEHINDNOT:+          case META_LOOKBEHIND_NA:+          *parsed_pattern++ = meta;+          ptr--;+          goto POST_LOOKBEHIND;++          /* The script run facilities are handled here. Unicode support is+          required (give an error if not, as this is a security issue). Always+          record a META_SCRIPT_RUN item. Then, for the atomic version, insert+          META_ATOMIC and remember that we need two META_KETs at the end. */++          case META_SCRIPT_RUN:+          case META_ATOMIC_SCRIPT_RUN:+#ifdef SUPPORT_UNICODE+          *parsed_pattern++ = META_SCRIPT_RUN;+          nest_depth++;+          ptr++;+          if (meta == META_ATOMIC_SCRIPT_RUN)+            {+            *parsed_pattern++ = META_ATOMIC;+            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_ATOMICSR;+            top_nest->options = options & PARSE_TRACKED_OPTIONS;+            }+          break;+#else  /* SUPPORT_UNICODE */+          errorcode = ERR96;+          goto FAILED;+#endif+          }+        }+++      /* ---- Handle (*VERB) and (*VERB:NAME) ---- */++      else+        {+        vn = verbnames;+        if (!read_name(&ptr, ptrend, utf, 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;+          }++        /* Remember where this verb, possibly with a preceding (*MARK), starts,+        for handling quantified (*ACCEPT). */++        verbstartptr = parsed_pattern;+        okquantifier = (verbs[i].meta == META_ACCEPT);++        /* 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 ) */+          {+          /* Some optional arguments can be treated as a preceding (*MARK) */++          if (verbs[i].has_arg < 0)+            {+            add_after_mark = verbs[i].meta;+            *parsed_pattern++ = META_MARK;+            }++          /* The remaining verbs with arguments (except *MARK) need a different+          opcode. */++          else+            {+            *parsed_pattern++ = verbs[i].meta ++              ((verbs[i].meta != META_MARK)? 0x00010000u:0);+            }++          /* Set up for reading the name in the main loop. */++          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+        {+        BOOL hyphenok = TRUE;+        uint32_t oldoptions = options;++        top_nest->reset_group = 0;+        top_nest->max_group = 0;+        set = unset = 0;+        optset = &set;++        /* ^ at the start unsets imnsx and disables the subsequent use of - */++        if (ptr < ptrend && *ptr == CHAR_CIRCUMFLEX_ACCENT)+          {+          options &= ~(PCRE2_CASELESS|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE|+                       PCRE2_DOTALL|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE);+          hyphenok = FALSE;+          ptr++;+          }++        while (ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS &&+                               *ptr != CHAR_COLON)+          {+          switch (*ptr++)+            {+            case CHAR_MINUS:+            if (!hyphenok)+              {+              errorcode = ERR94;+              ptr--;  /* Correct the offset */+              goto FAILED;+              }+            optset = &unset;+            hyphenok = FALSE;+            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 (options != oldoptions)+          {+          *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, utf, 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, utf, 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 ? or * 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 || *ptr == CHAR_ASTERISK)+        {+        *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;+          minor = (*ptr++ - CHAR_0) * 10;+          if (ptr >= ptrend) goto BAD_VERSION_CONDITION;+          if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0;+          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, utf, 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:+      ATOMIC_GROUP:                          /* Come from (*atomic: */+      *parsed_pattern++ = META_ATOMIC;+      nest_depth++;+      ptr++;+      break;+++      /* ---- Lookahead assertions ---- */++      case CHAR_EQUALS_SIGN:+      POSITIVE_LOOK_AHEAD:                   /* Come from (*pla: */+      *parsed_pattern++ = META_LOOKAHEAD;+      ptr++;+      goto POST_ASSERTION;++      case CHAR_ASTERISK:+      POSITIVE_NONATOMIC_LOOK_AHEAD:         /* Come from (?* */+      *parsed_pattern++ = META_LOOKAHEAD_NA;+      ptr++;+      goto POST_ASSERTION;++      case CHAR_EXCLAMATION_MARK:+      NEGATIVE_LOOK_AHEAD:                   /* Come from (*nla: */+      *parsed_pattern++ = META_LOOKAHEADNOT;+      ptr++;+      goto POST_ASSERTION;+++      /* ---- Lookbehind assertions ---- */++      /* (?< followed by = or ! 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 &&+          ptr[1] != CHAR_ASTERISK))+        {+        terminator = CHAR_GREATER_THAN_SIGN;+        goto DEFINE_NAME;+        }+      *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?+        META_LOOKBEHIND : (ptr[1] == CHAR_EXCLAMATION_MARK)?+        META_LOOKBEHINDNOT : META_LOOKBEHIND_NA;++      POST_LOOKBEHIND:           /* Come from (*plb: (*naplb: and (*nlb: */+      *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, utf, 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. */++      if (cb->bracount >= MAX_GROUP_NUMBER)+        {+        errorcode = ERR97;+        goto FAILED;+        }+      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->flags & NSF_ATOMICSR) != 0)+        {+        *parsed_pattern++ = META_KET;+        }++      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)+  {+  errorcode = ERR60;+  goto FAILED;+  }++/* 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 ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0)+  {+  *parsed_pattern++ = META_KET;+  *parsed_pattern++ = META_DOLLAR;+  }+else if ((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;+}++++/*************************************************+*       Find first significant opcode            *+*************************************************/++/* This is called by several functions that scan a compiled expression looking+for a fixed first character, or an anchoring opcode etc. It skips over things+that do not influence this. For some calls, it makes sense to skip negative+forward and all backward assertions, and also the \b assertion; for others it+does not.++Arguments:+  code         pointer to the start of the group+  skipassert   TRUE if certain assertions are to be skipped++Returns:       pointer to the first significant opcode+*/++static const PCRE2_UCHAR*+first_significant_code(PCRE2_SPTR code, BOOL skipassert)+{+for (;;)+  {+  switch ((int)*code)+    {+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    case OP_ASSERTBACK_NA:+    if (!skipassert) return code;+    do code += GET(code, 1); while (*code == OP_ALT);+    code += PRIV(OP_lengths)[*code];+    break;++    case OP_WORD_BOUNDARY:+    case OP_NOT_WORD_BOUNDARY:+    if (!skipassert) return code;+    /* Fall through */++    case OP_CALLOUT:+    case OP_CREF:+    case OP_DNCREF:+    case OP_RREF:+    case OP_DNRREF:+    case OP_FALSE:+    case OP_TRUE:+    code += PRIV(OP_lengths)[*code];+    break;++    case OP_CALLOUT_STR:+    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;++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_SKIP_ARG:+    case OP_THEN_ARG:+    code += code[1] + PRIV(OP_lengths)[*code];+    break;++    default:+    return code;+    }+  }+/* Control never reaches here */+}++++#ifdef SUPPORT_UNICODE+/*************************************************+*           Get othercase range                  *+*************************************************/++/* This function is passed the start and end of a class range in UCP mode. 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 (internal) *+*************************************************/++/* This function packages up the logic of adding a character or range of+characters to a class. The character values in the arguments will be within the+valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is+called only from within the "add to class" group of functions, some of which+are recursive and mutually recursive. The external entry point is+add_to_class().++Arguments:+  classbits     the bit map for characters < 256+  uchardptr     points to the pointer for extra data+  options       the options 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_internal(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|PCRE2_UCP)) != 0)+    {+    int rc;+    uint32_t oc, od;++    options &= ~PCRE2_CASELESS;   /* Remove for recursive calls */+    c = start;++    while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 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++;+    }+  }++/* Now handle the originally supplied range. Adjust the final value according+to the bit length - this means that the same lists of (e.g.) horizontal spaces+can be used in all cases. */++if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR)+  end = MAX_NON_UTF_CHAR;++if (start > cb->class_range_start && end < cb->class_range_end) return n8;++/* Use the bitmap for characters < 256. Otherwise use extra data.*/++for (c = start; c <= classbits_end; c++)+  {+  /* Regardless of start, c will always be <= 255. */+  SETBIT(classbits, c);+  n8++;+  }++#ifdef SUPPORT_WIDE_CHARS+if (start <= 0xff) start = 0xff + 1;++if (end >= start)+  {+  PCRE2_UCHAR *uchardata = *uchardptr;++#ifdef SUPPORT_UNICODE+  if ((options & PCRE2_UTF) != 0)+    {+    if (start < end)+      {+      *uchardata++ = XCL_RANGE;+      uchardata += PRIV(ord2utf)(start, uchardata);+      uchardata += PRIV(ord2utf)(end, uchardata);+      }+    else if (start == end)+      {+      *uchardata++ = XCL_SINGLE;+      uchardata += PRIV(ord2utf)(start, uchardata);+      }+    }+  else+#endif  /* SUPPORT_UNICODE */++  /* Without UTF support, character values are constrained by the bit length,+  and can only be > 256 for 16-bit and 32-bit libraries. */++#if PCRE2_CODE_UNIT_WIDTH == 8+    {}+#else+  if (start < end)+    {+    *uchardata++ = XCL_RANGE;+    *uchardata++ = start;+    *uchardata++ = end;+    }+  else if (start == end)+    {+    *uchardata++ = XCL_SINGLE;+    *uchardata++ = start;+    }+#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */+  *uchardptr = uchardata;   /* Updata extra data pointer */+  }+#else  /* SUPPORT_WIDE_CHARS */+  (void)uchardptr;          /* Avoid compiler warning */+#endif /* SUPPORT_WIDE_CHARS */++return n8;    /* Number of 8-bit characters */+}++++#ifdef SUPPORT_UNICODE+/*************************************************+* Add a list of characters to a class (internal) *+*************************************************/++/* This function is used for adding a list of case-equivalent characters to a+class when in UTF mode. This function is called only from within+add_to_class_internal(), with which it is mutually recursive.++Arguments:+  classbits     the bit map for characters < 256+  uchardptr     points to the pointer for extra data+  options       the options 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_internal(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_internal(classbits, uchardptr, options, cb, p[0], p[n]);+    }+  p += n + 1;+  }+return n8;+}+#endif++++/*************************************************+*   External entry point for add range to class  *+*************************************************/++/* This function sets the overall range so that the internal functions can try+to avoid duplication when handling case-independence.++Arguments:+  classbits     the bit map for characters < 256+  uchardptr     points to the pointer for extra data+  options       the options 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)+{+cb->class_range_start = start;+cb->class_range_end = end;+return add_to_class_internal(classbits, uchardptr, options, cb, start, end);+}+++/*************************************************+*   External entry point for add list to class   *+*************************************************/++/* This function is used for adding a list of horizontal or vertical whitespace+characters to a class. The list must be in order so that ranges of characters+can be detected and handled appropriately. This function sets the overall range+so that the internal functions can try to avoid duplication when handling+case-independence.++Arguments:+  classbits     the bit map for characters < 256+  uchardptr     points to the pointer for extra data+  options       the options 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++;+    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;+  }++/* 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)+  {+  *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 had_accept = FALSE;+BOOL matched_char = FALSE;+BOOL previous_matched_char = FALSE;+BOOL reset_caseful = FALSE;+const uint8_t *cbits = cb->cbits;+uint8_t classbits[32];++/* We can fish out the UTF setting once and for all into a BOOL, but we must+not do this for other options (e.g. PCRE2_EXTENDED) because they may change+dynamically as we process the pattern. */++#ifdef SUPPORT_UNICODE+BOOL utf = (options & PCRE2_UTF) != 0;+BOOL ucp = (options & PCRE2_UCP) != 0;+#else  /* No Unicode 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)+    {+    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;+      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 = 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 && !had_accept) 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 or UCP mode, check whether this character has more+      than one other case. If so, generate a special OP_NOTPROP item instead of+      OP_NOTI. */++#ifdef SUPPORT_UNICODE+      if ((utf||ucp) && (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 there are exactly two characters in a positive class, see if+    they are case partners. This can be optimized to generate a caseless single+    character match (which also sets first/required code units if relevant). */++    if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END &&+        pptr[3] == META_CLASS_END)+      {+      uint32_t c = pptr[1];++#ifdef SUPPORT_UNICODE+      if (UCD_CASESET(c) == 0)+#endif+        {+        uint32_t d;++#ifdef SUPPORT_UNICODE+        if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else+#endif+          {+#if PCRE2_CODE_UNIT_WIDTH != 8+          if (c > 255) d = c; else+#endif+          d = TABLE_GET(c, cb->fcc, c);+          }++        if (c != d && pptr[2] == d)+          {+          pptr += 3;                 /* Move on to class end */+          meta = c;+          if ((options & PCRE2_CASELESS) == 0)+            {+            reset_caseful = TRUE;+            options |= PCRE2_CASELESS;+            req_caseopt = REQ_CASELESS;+            }+          goto CLASS_CASELESS_CHAR;+          }+        }+      }++    /* If a non-extended class contains a negative special such as \S, we need+    to flip the negation flag at the end, so that support for characters > 255+    works correctly (they are all included in the class). An extended class may+    need to insert specific matching or non-matching code for wide characters.+    */++    should_flip_negation = match_all_or_no_wide_chars = FALSE;++    /* Extended class (xclass) will be used when characters > 255+    might match. */++#ifdef SUPPORT_WIDE_CHARS+    xclass = FALSE;+    class_uchardata = code + LINK_SIZE + 2;   /* For XCLASS items */+    class_uchardata_base = class_uchardata;   /* Save the start */+#endif++    /* For optimization purposes, we track some properties of the class:+    class_has_8bitchar will be non-zero if the class contains at least one+    character with a code point less than 256; xclass_has_prop will be TRUE if+    Unicode property checks are present in the class. */++    class_has_8bitchar = 0;+#ifdef SUPPORT_WIDE_CHARS+    xclass_has_prop = FALSE;+#endif++    /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map+    in a temporary bit of memory, in case the class contains fewer than two+    8-bit characters because in that case the compiled code doesn't use the bit+    map. */++    memset(classbits, 0, 32 * sizeof(uint8_t));++    /* Process items until META_CLASS_END is reached. */++    while ((meta = *(++pptr)) != META_CLASS_END)+      {+      /* Handle POSIX classes such as [:alpha:] etc. */++      if (meta == META_POSIX || meta == META_POSIX_NEG)+        {+        BOOL local_negate = (meta == META_POSIX_NEG);+        int posix_class = *(++pptr);+        int taboffset, tabopt;+        uint8_t pbits[32];++        should_flip_negation = local_negate;  /* Note negative special */++        /* If matching is caseless, upper and lower are converted to alpha.+        This relies on the fact that the class table starts with alpha,+        lower, upper as the first 3 entries. */++        if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2)+          posix_class = 0;++        /* When PCRE2_UCP is set, some of the POSIX classes are converted to+        different escape sequences that use Unicode properties \p or \P.+        Others that are not available via \p or \P have to generate+        XCL_PROP/XCL_NOTPROP directly, which is done here. */++#ifdef SUPPORT_UNICODE+        if ((options & PCRE2_UCP) != 0) 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 &&+               (c <= CHAR_z) == (d <= CHAR_z))+            {+            uint32_t uc = (d <= CHAR_z)? 0 : 64;+            uint32_t C = c - uc;+            uint32_t D = d - uc;++            if (C <= CHAR_i)+              {+              class_has_8bitchar +=+                add_to_class(classbits, &class_uchardata, options, 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 workspace (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;+        (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,+          CU2BYTES(class_uchardata - code));+        if (negate_class && !xclass_has_prop)+          {+          /* Using 255 ^ instead of ~ avoids clang sanitize warning. */+          for (i = 0; i < 32; i++) classbits[i] = 255 ^ 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)+        {+       /* Using 255 ^ instead of ~ avoids clang sanitize warning. */+       for (i = 0; i < 32; i++) classbits[i] = 255 ^ 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 = 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);+        }+      }+    *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:+    case META_COMMIT_ARG:+    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++)+      {+      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. Its 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;++    case META_LOOKAHEAD_NA:+    bravalue = OP_ASSERT_NA;+    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_LOOKBEHIND_NA:+    bravalue = OP_ASSERTBACK_NA;+    cb->assert_depth += 1;+    goto GROUP_PROCESS;++    case META_ATOMIC:+    bravalue = OP_ONCE;+    goto GROUP_PROCESS_NOTE_EMPTY;++    case META_SCRIPT_RUN:+    bravalue = OP_SCRIPT_RUN;+    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_NA)+      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 || bravalue == OP_ASSERT_NA) &&+             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 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. */++          cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;+          if (groupnumber > cb->top_backref)+            cb->top_backref = groupnumber;+          }+        }++      /* 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;++    /* 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. If the repeat+    minimum and the repeat maximum are both 1, we can ignore the quantifier for+    non-parenthesized items, as they have only one alternative. For anything in+    parentheses, we must not ignore if {1} is possessive. */++    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:+      if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;+      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_max == 1 && repeat_min == 1) 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:+      if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)+        goto END_REPEAT;++      /* 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. */++      (void)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_ASSERT_NA:+      case OP_ASSERTBACK:+      case OP_ASSERTBACK_NOT:+      case OP_ASSERTBACK_NA:+      case OP_ONCE:+      case OP_SCRIPT_RUN:+      case OP_BRA:+      case OP_CBRA:+      case OP_COND:+        {+        int len = (int)(code - previous);+        PCRE2_UCHAR *bralink = NULL;+        PCRE2_UCHAR *brazeroptr = NULL;++        if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)+          goto END_REPEAT;++        /* 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;++        /* Perl allows all assertions to be quantified, and when they contain+        capturing parentheses and/or are optional there are potential uses for+        this feature. PCRE2 used to force the maximum quantifier to 1 on the+        invalid grounds that further repetition was never useful. This was+        always a bit pointless, since an assertion could be wrapped with a+        repeated group to achieve the effect. General repetition is now+        permitted, but if the maximum is unlimited it is set to one more than+        the minimum. */++        if (op_previous < OP_ONCE)    /* Assertion */+          {+          if (repeat_max == REPEAT_UNLIMITED) repeat_max = repeat_min + 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)+            {+            (void)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;+            (void)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+        SCRIPT_RUN and 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+        and SCRIPT_RUN 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 and for SCRIPT_RUN brackets, all we need+          to do is to set the KET. */++          if (*bracode == OP_ONCE || *bracode == OP_SCRIPT_RUN)+            *ketcode = OP_KETRMAX + repeat_type;++          /* Handle non-SCRIPT_RUN and 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);+                (void)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;++        if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;++        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+          {+          (void)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;+    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. */++    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;+    zerofirstcu = firstcu;+    zerofirstcuflags = firstcuflags;+    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;++      /* The special case of \p{Any} is compiled to OP_ALLANY so as to benefit+      from the auto-anchoring code. */++      if (meta_arg == ESC_p && ptype == PT_ANY)+        {+        *code++ = OP_ALLANY;+        }+      else+        {+        *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 or UCP mode, check whether this character has more than+    one other case. If so, generate a special OP_PROP item instead of OP_CHARI.+    */++#ifdef SUPPORT_UNICODE+    if ((utf||ucp) && (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 caseless and not one of the multicase characters. We+    come here by goto in the case of a positive class that contains only+    case-partners of a character with just two cases; matched_char has already+    been set TRUE and options fudged if necessary. */++    CLASS_CASELESS_CHAR:++    /* 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 a single+      firstcu only if it is not to be matched caselessly. Multiple possible+      starting code units may be picked up later in the studying code. */++      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;+        }+      }++    /* If caselessness was temporarily instated, reset it. */++    if (reset_caseful)+      {+      options &= ~PCRE2_CASELESS;+      req_caseopt = 0;+      reset_caseful = FALSE;+      }++    break;    /* End literal character 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;+  }++/* 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 workspace 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 ||+             *code == OP_ASSERTBACK_NA;++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.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 group from this branch's value. */++    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 present */+        }+      }+    }++  /* 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, remove the block from the chain. */++    if (capnumber > 0) 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 || op == OP_ASSERT_NA)+     {+     if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;+     }++   /* Condition. If there is no second branch, it can't be anchored. */++   else if (op == OP_COND || op == OP_SCOND)+     {+     if (scode[GET(scode,1)] != OP_ALT) return FALSE;+     if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))+       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 || op == OP_ASSERT_NA)+     {+     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;+}++++/*************************************************+*   Scan compiled regex for recursion reference  *+*************************************************/++/* This function scans through a compiled pattern until it finds an instance of+OP_RECURSE.++Arguments:+  code        points to start of expression+  utf         TRUE in UTF mode++Returns:      pointer to the opcode for OP_RECURSE, or NULL if not found+*/++static PCRE2_SPTR+find_recurse(PCRE2_SPTR code, BOOL utf)+{+for (;;)+  {+  PCRE2_UCHAR c = *code;+  if (c == OP_END) return NULL;+  if (c == OP_RECURSE) return code;++  /* XCLASS is used for classes that cannot be represented just by a bit map.+  This includes negated single high-valued characters. CALLOUT_STR is used for+  callouts with string arguments. In both cases the length in the table is+  zero; the actual length is stored in the compiled code. */++  if (c == OP_XCLASS) code += GET(code, 1);+    else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);++  /* 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 code units of parameters, and for MARK/PRUNE/SKIP/THEN with an argument,+  we must add in its length. */++  else+    {+    switch(c)+      {+      case OP_TYPESTAR:+      case OP_TYPEMINSTAR:+      case OP_TYPEPLUS:+      case OP_TYPEMINPLUS:+      case OP_TYPEQUERY:+      case OP_TYPEMINQUERY:+      case OP_TYPEPOSSTAR:+      case OP_TYPEPOSPLUS:+      case OP_TYPEPOSQUERY:+      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;+      break;++      case OP_TYPEPOSUPTO:+      case OP_TYPEUPTO:+      case OP_TYPEMINUPTO:+      case OP_TYPEEXACT:+      if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)+        code += 2;+      break;++      case OP_MARK:+      case OP_COMMIT_ARG:+      case OP_PRUNE_ARG:+      case OP_SKIP_ARG:+      case OP_THEN_ARG:+      code += code[1];+      break;+      }++    /* Add in the fixed length from the table */++    code += PRIV(OP_lengths)[c];++    /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may+    be followed by a multi-unit character. The length in the table is a+    minimum, so we have to arrange to skip the extra units. */++#ifdef MAYBE_UTF_MULTI+    if (utf) switch(c)+      {+      case OP_CHAR:+      case OP_CHARI:+      case OP_NOT:+      case OP_NOTI:+      case OP_EXACT:+      case OP_EXACTI:+      case OP_NOTEXACT:+      case OP_NOTEXACTI:+      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:+      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_PLUS:+      case OP_PLUSI:+      case OP_NOTPLUS:+      case OP_NOTPLUSI:+      case OP_MINPLUS:+      case OP_MINPLUSI:+      case OP_NOTMINPLUS:+      case OP_NOTMINPLUSI:+      case OP_POSPLUS:+      case OP_POSPLUSI:+      case OP_NOTPOSPLUS:+      case OP_NOTPOSPLUSI:+      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 (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);+      break;+      }+#else+    (void)(utf);  /* Keep compiler happy by referencing function argument */+#endif  /* MAYBE_UTF_MULTI */+    }+  }+}++++/*************************************************+*    Check for asserted fixed first code unit    *+*************************************************/++/* During compilation, the "first code unit" settings from forward assertions+are discarded, because they can cause conflicts with actual literals that+follow. However, if we end up without a first code unit setting for an+unanchored pattern, it is worth scanning the regex to see if there is an+initial asserted first code unit. If all branches start with the same asserted+code unit, or with a non-conditional bracket all of whose alternatives start+with the same asserted code unit (recurse ad lib), then we return that code+unit, with the flags set to zero or REQ_CASELESS; otherwise return zero with+REQ_NONE in the flags.++Arguments:+  code       points to start of compiled pattern+  flags      points to the first code unit flags+  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, uint32_t inassert)+{+uint32_t c = 0;+int cflags = REQ_NONE;++*flags = REQ_NONE;+do {+   uint32_t d;+   int dflags;+   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);+   PCRE2_UCHAR op = *scode;++   switch(op)+     {+     default:+     return 0;++     case OP_BRA:+     case OP_BRAPOS:+     case OP_CBRA:+     case OP_SCBRA:+     case OP_CBRAPOS:+     case OP_SCBRAPOS:+     case OP_ASSERT:+     case OP_ASSERT_NA:+     case OP_ONCE:+     case OP_SCRIPT_RUN:+     d = find_firstassertedcu(scode, &dflags, inassert ++       ((op == OP_ASSERT || op == OP_ASSERT_NA)?1:0));+     if (dflags < 0)+       return 0;+     if (cflags < 0) { c = d; cflags = dflags; }+       else if (c != d || cflags != dflags) return 0;+     break;++     case OP_EXACT:+     scode += IMM2_SIZE;+     /* Fall through */++     case OP_CHAR:+     case OP_PLUS:+     case OP_MINPLUS:+     case OP_POSPLUS:+     if (inassert == 0) return 0;+     if (cflags < 0) { c = scode[1]; cflags = 0; }+       else if (c != scode[1]) return 0;+     break;++     case OP_EXACTI:+     scode += IMM2_SIZE;+     /* Fall through */++     case OP_CHARI:+     case OP_PLUSI:+     case OP_MINPLUSI:+     case OP_POSPLUSI:+     if (inassert == 0) return 0;++     /* If the character is more than one code unit long, we cannot set its+     first code unit when matching caselessly. Later scanning may pick up+     multiple code units. */++#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+     if (scode[1] >= 0x80) return 0;+#elif PCRE2_CODE_UNIT_WIDTH == 16+     if (scode[1] >= 0xd800 && scode[1] <= 0xdfff) return 0;+#endif+#endif++     if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; }+       else if (c != scode[1]) return 0;+     break;+     }++   code += GET(code, 1);+   }+while (*code == OP_ALT);++*flags = cflags;+return c;+}++++/*************************************************+*     Add an entry to the name/number table      *+*************************************************/++/* This function is called between compiling passes to add an entry to the+name/number table, maintaining alphabetical order. Checking for permitted+and forbidden duplicates has already been done.++Arguments:+  cb           the compile data block+  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, uint32_t tablecount)+{+uint32_t i;+PCRE2_UCHAR *slot = cb->name_table;++for (i = 0; i < tablecount; i++)+  {+  int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length));+  if (crc == 0 && slot[IMM2_SIZE+length] != 0)+    crc = -1; /* Current name is a substring */++  /* Make space in the table and break the loop for an earlier name. For a+  duplicate or later name, carry on. We do this for duplicates so that in the+  simple case (when ?(| is not used) they are in order of their numbers. In all+  cases they are in the order in which they appear in the pattern. */++  if (crc < 0)+    {+    (void)memmove(slot + cb->name_entry_size, slot,+      CU2BYTES((tablecount - i) * cb->name_entry_size));+    break;+    }++  /* Continue the loop for a later or duplicate name */++  slot += cb->name_entry_size;+  }++PUT2(slot, 0, groupno);+memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));++/* 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+memory when saving serialized compiled patterns. */++memset(slot + IMM2_SIZE + length, 0,+  CU2BYTES(cb->name_entry_size - length - IMM2_SIZE));+}++++/*************************************************+*             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 or+(DEFINE) group, 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_COMMIT_ARG:+    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_LOOKAHEAD_NA:+    case META_LOOKBEHIND:+    case META_LOOKBEHINDNOT:+    case META_LOOKBEHIND_NA:+    case META_NOCAPTURE:+    case META_SCRIPT_RUN:+    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. 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_COMMIT_ARG:+    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 do not contribute to the length of this branch, but they may+    contain lookbehinds within them whose lengths need to be set. */++    case META_LOOKAHEAD:+    case META_LOOKAHEADNOT:+    case META_LOOKAHEAD_NA:+    *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb);+    if (*errcodeptr != 0) return -1;++    /* Ignore any qualifiers that follow a lookahead assertion. */++    switch (pptr[1])+      {+      case META_ASTERISK:+      case META_ASTERISK_PLUS:+      case META_ASTERISK_QUERY:+      case META_PLUS:+      case META_PLUS_PLUS:+      case META_PLUS_QUERY:+      case META_QUERY:+      case META_QUERY_PLUS:+      case META_QUERY_QUERY:+      pptr++;+      break;++      case META_MINMAX:+      case META_MINMAX_PLUS:+      case META_MINMAX_QUERY:+      pptr += 3;+      break;++      default:+      break;+      }+    break;++    /* A nested lookbehind does not contribute any length to this lookbehind,+    but must itself be checked and have its lengths set. */++    case META_LOOKBEHIND:+    case META_LOOKBEHINDNOT:+    case META_LOOKBEHIND_NA:+    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;++    /* A (DEFINE) group is never obeyed inline and so it does not contribute to+    the length of this branch. Skip from the following item to the next+    unpaired ket. */++    case META_COND_DEFINE:+    pptr = parsed_skip(pptr + 1, PSKIP_KET);+    break;++    /* Check other 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:+    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:+    case META_SCRIPT_RUN:+    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])+      {+      switch(pptr[1])+        {+        case 0:+        branchlength -= lastitemlength;+        break;++        case 1:+        itemlength = 0;+        break;++        default:  /* Check for integer overflow */+        if (lastitemlength != 0 &&  /* Should not occur, but just in case */+            INT_MAX/lastitemlength < pptr[1] - 1)+          {+          *errcodeptr = ERR87;  /* Integer overflow; lookbehind too big */+          return -1;+          }+        itemlength = (pptr[1] - 1) * lastitemlength;+        break;+        }+      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, checking for integer overflow and+  for the branch length exceeding the limit. */++  if (INT_MAX - branchlength < (int)itemlength ||+      (branchlength += itemlength) > LOOKBEHIND_MAX)+    {+    *errcodeptr = ERR87;+    return -1;+    }++  /* Save this item length for use if the next item is a quantifier. */++  lastitemlength = itemlength;+  }++EXIT:+*pptrptr = pptr;+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.++The function also maintains the max_lookbehind value. Any lookbehind branch+that contains a nested lookbehind may actually look further back than the+length of the branch. The additional amount is passed back from+get_branchlength() as an "extra" value.++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;+    }+  if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;+  *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.++This function is called recursively from get_branchlength() for lookaheads in+order to process any lookbehinds that they may contain. It stops when it hits a+non-nested closing parenthesis in this case, returning a pointer to it.++Arguments+  pptr      points to where to start (start of pattern or start of lookahead)+  retptr    if not NULL, return the ket pointer here+  recurses  chain of recurse_check to catch mutual recursion+  cb        points to the compile block++Returns:    0 on success, or an errorcode (cb->erroroffset will be set)+*/++static int+check_lookbehinds(uint32_t *pptr, uint32_t **retptr,+  parsed_recurse_check *recurses, compile_block *cb)+{+int errorcode = 0;+int loopcount = 0;+int nestlevel = 0;++cb->erroroffset = PCRE2_UNSET;++for (; *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_KET:+    if (--nestlevel < 0)+      {+      if (retptr != NULL) *retptr = pptr;+      return 0;+      }+    break;++    case META_ATOMIC:+    case META_CAPTURE:+    case META_COND_ASSERT:+    case META_LOOKAHEAD:+    case META_LOOKAHEADNOT:+    case META_LOOKAHEAD_NA:+    case META_NOCAPTURE:+    case META_SCRIPT_RUN:+    nestlevel++;+    break;++    case META_ACCEPT:+    case META_ALT:+    case META_ASTERISK:+    case META_ASTERISK_PLUS:+    case META_ASTERISK_QUERY:+    case META_BACKREF:+    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_DOLLAR:+    case META_DOT:+    case META_FAIL:+    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_RECURSE_BYNAME:+    pptr += 1 + SIZEOFFSET;+    break;++    case META_COND_DEFINE:+    pptr += SIZEOFFSET;+    nestlevel++;+    break;++    case META_COND_NAME:+    case META_COND_NUMBER:+    case META_COND_RNAME:+    case META_COND_RNUMBER:+    pptr += 1 + SIZEOFFSET;+    nestlevel++;+    break;++    case META_COND_VERSION:+    pptr += 3;+    nestlevel++;+    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:+    pptr += 3;+    break;++    case META_MARK:+    case META_COMMIT_ARG:+    case META_PRUNE_ARG:+    case META_SKIP_ARG:+    case META_THEN_ARG:+    pptr += 1 + pptr[1];+    break;++    case META_LOOKBEHIND:+    case META_LOOKBEHINDNOT:+    case META_LOOKBEHIND_NA:+    if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, recurses, cb))+      return errorcode;+    break;+    }+  }++return 0;+}++++/*************************************************+*     External function to compile a pattern     *+*************************************************/++/* This function reads a regular expression in the form of a string and returns+a pointer to a block of store holding a compiled version of the expression.++Arguments:+  pattern       the regular expression+  patlen        the length of the pattern, or PCRE2_ZERO_TERMINATED+  options       option bits+  errorptr      pointer to errorcode+  erroroffset   pointer to error offset+  ccontext      points to a compile context or is NULL++Returns:        pointer to compiled data block, or NULL on error,+                with errorcode and erroroffset set+*/++PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION+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 */+BOOL ucp;                             /* Set TRUE for UCP 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 */+uint32_t *pptr;                       /* Current pointer in parsed pattern */++PCRE2_SIZE length = 1;                /* Allow for final END opcode */+PCRE2_SIZE usedlength;                /* Actual length used */+PCRE2_SIZE re_blocksize;              /* Size of memory block */+PCRE2_SIZE big32count = 0;            /* 32-bit literals >= 0x80000000 */+PCRE2_SIZE parsed_size_needed;        /* Needed for parsed pattern */++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_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 regexrc;                          /* Return from compile */++uint32_t i;                           /* Local loop counter */++/* Comments at the head of this file explain about these variables. */++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 parsing scan. */++uint32_t c16workspace[C16_WORK_SIZE];+PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c16workspace;+++/* -------------- Check arguments and set up the pattern ----------------- */++/* There must be error code and offset pointers. */++if (errorptr == NULL || erroroffset == NULL) return NULL;+*errorptr = ERR0;+*erroroffset = 0;++/* There must be a pattern! */++if (pattern == NULL)+  {+  *errorptr = ERR16;+  return NULL;+  }++/* A NULL compile context means "use a default context" */++if (ccontext == NULL)+  ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context));++/* PCRE2_MATCH_INVALID_UTF implies UTF */++if ((options & PCRE2_MATCH_INVALID_UTF) != 0) options |= PCRE2_UTF;++/* Check that all undefined public option bits are zero. */++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;+  }++/* 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);++cb.lcc = tables + lcc_offset;          /* Individual */+cb.fcc = tables + fcc_offset;          /*   character */+cb.cbits = tables + cbits_offset;      /*      tables */+cb.ctypes = tables + ctypes_offset;++cb.assert_depth = 0;+cb.bracount = 0;+cb.cx = ccontext;+cb.dupnames = FALSE;+cb.end_pattern = pattern + patlen;+cb.erroroffset = 0;+cb.external_flags = 0;+cb.external_options = options;+cb.groupinfo = stack_groupinfo;+cb.had_recurse = FALSE;+cb.lastcapture = 0;+cb.max_lookbehind = 0;+cb.name_entry_size = 0;+cb.name_table = NULL;+cb.named_groups = named_groups;+cb.named_group_list_size = NAMED_GROUP_LIST_SIZE;+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;+cb.start_workspace = cworkspace;+cb.workspace_size = COMPILE_WORK_SIZE;++/* Maximum back reference and backref bitmap. The bitmap records up to 31 back+references to help in deciding whether (.*) can be treated as anchored or not.+*/++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 --------------- */++/* 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;++if ((options & PCRE2_LITERAL) == 0)+  {+  while (patlen - skipatstart >= 2 &&+         ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&+         ptr[skipatstart+1] == CHAR_ASTERISK)+    {+    for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)+      {+      uint32_t c, pp;+      pso *p = pso_list + i;++      if (patlen - skipatstart - 2 >= p->length &&+          PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name),+            p->length) == 0)+        {+        skipatstart += p->length + 2;+        switch(p->type)+          {+          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;+          }+        break;   /* Out of the table scan loop */+        }+      }+    if (i >= sizeof(pso_list)/sizeof(pso)) break;   /* Out of pso loop */+    }+  }++/* End of pattern-start options; advance to start of real regex. */++ptr += skipatstart;++/* Can't support UTF or UCP if PCRE2 was built without Unicode support. */++#ifndef SUPPORT_UNICODE+if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0)+  {+  errorcode = ERR32;+  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. 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)+  {+  if ((options & PCRE2_NEVER_UTF) != 0)+    {+    errorcode = ERR74;+    goto HAD_EARLY_ERROR;+    }+  if ((options & PCRE2_NO_UTF_CHECK) == 0 &&+       (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0)+    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. */++ucp = (cb.external_options & PCRE2_UCP) != 0;+if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0)+  {+  errorcode = ERR75;+  goto HAD_EARLY_ERROR;+  }++/* Process the BSR setting. */++if (bsr == 0) bsr = ccontext->bsr_convention;++/* Process the newline setting. */++if (newline == 0) newline = ccontext->newline_convention;+cb.nltype = NLTYPE_FIXED;+switch(newline)+  {+  case PCRE2_NEWLINE_CR:+  cb.nllen = 1;+  cb.nl[0] = CHAR_CR;+  break;++  case PCRE2_NEWLINE_LF:+  cb.nllen = 1;+  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;+  cb.nl[1] = CHAR_NL;+  break;++  case PCRE2_NEWLINE_ANY:+  cb.nltype = NLTYPE_ANY;+  break;++  case PCRE2_NEWLINE_ANYCRLF:+  cb.nltype = NLTYPE_ANYCRLF;+  break;++  default:+  errorcode = ERR56;+  goto HAD_EARLY_ERROR;+  }++/* 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).++In all but one case, when PCRE2_AUTO_CALLOUT is not set, the number of unsigned+32-bit ints in the parsed pattern is bounded by the length of the pattern plus+one (for the terminator) plus four if PCRE2_EXTRA_WORD or PCRE2_EXTRA_LINE is+set. The exceptional case is when running in 32-bit, non-UTF mode, when literal+characters greater than META_END (0x80000000) have to be coded as two units. In+this case, therefore, we scan the pattern to check for such values. */++#if PCRE2_CODE_UNIT_WIDTH == 32+if (!utf)+  {+  PCRE2_SPTR p;+  for (p = ptr; p < cb.end_pattern; p++) if (*p >= META_END) big32count++;+  }+#endif++/* Ensure that the parsed pattern buffer is big enough. 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.parsed_pattern, NULL, NULL, &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.bracount);+  for (i = 0; i < cb.names_found; i++, ng++)+    {+    fprintf(stderr, "+++%3d %.*s\n", ng->number, ng->length, ng->name);+    }+  }+#endif++/* 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+workspace (cworkspace) for it to compile parts of the pattern into; the+compiled code is discarded when it is no longer needed, so hopefully this+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,+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, &pptr, &errorcode, 0, &firstcu,+   &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, &length);++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_CB_ERROR;+  }++/* Compute the size of, and then get and initialize, the data block for storing+the compiled pattern and names table. Integer overflow should no longer be+possible because nowadays we limit the maximum value of cb.names_found and+cb.name_entry_size. */++re_blocksize = sizeof(pcre2_real_code) ++  CU2BYTES(length ++  (PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);+re = (pcre2_real_code *)+  ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);+if (re == NULL)+  {+  errorcode = ERR21;+  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;+memset(re->start_bitmap, 0, 32 * sizeof(uint8_t));+re->blocksize = re_blocksize;+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_depth = limit_depth;+re->first_codeunit = 0;+re->last_codeunit = 0;+re->bsr_convention = bsr;+re->newline_convention = newline;+re->max_lookbehind = 0;+re->minlength = 0;+re->top_bracket = 0;+re->top_backref = 0;+re->name_entry_size = cb.name_entry_size;+re->name_count = cb.names_found;++/* The basic block is immediately followed by the name table, and the compiled+code follows after that. */++codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) ++  re->name_entry_size * re->name_count;++/* 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. */++cb.parens_depth = 0;+cb.assert_depth = 0;+cb.lastcapture = 0;+cb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));+cb.start_code = codestart;+cb.req_varyopt = 0;+cb.had_accept = FALSE;+cb.had_pruneorskip = FALSE;+cb.open_caps = NULL;++/* If any named groups were found, create the name/number table from the list+created in the pre-pass. */++if (cb.names_found > 0)+  {+  named_group *ng = cb.named_groups;+  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. */++pptr = cb.parsed_pattern;+code = (PCRE2_UCHAR *)codestart;+*code = OP_BRA;+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;++if (cb.had_accept)+  {+  reqcu = 0;                     /* Must disable after (*ACCEPT) */+  reqcuflags = REQ_NONE;+  re->flags |= PCRE2_HASACCEPT;  /* Disables minimum length */+  }++/* Fill in the final opcode and check for disastrous overflow. If no overflow,+but the estimated length exceeds the really used length, adjust the value of+re->blocksize, and if valgrind support is configured, mark the extra allocated+memory as unaddressable, so that any out-of-bound reads can be detected. */++*code++ = OP_END;+usedlength = code - codestart;+if (usedlength > length) errorcode = ERR23; else+  {+  re->blocksize -= CU2BYTES(length - usedlength);+#ifdef SUPPORT_VALGRIND+  VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength));+#endif+  }++/* Scan the pattern for recursion/subroutine calls and convert the group+numbers into offsets. Maintain a small cache so that repeated groups containing+recursions are efficiently handled. */++#define RSCAN_CACHE_SIZE 8++if (errorcode == 0 && cb.had_recurse)+  {+  PCRE2_UCHAR *rcode;+  PCRE2_SPTR rgroup;+  unsigned int ccount = 0;+  int start = RSCAN_CACHE_SIZE;+  recurse_cache rc[RSCAN_CACHE_SIZE];++  for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf);+       rcode != NULL;+       rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf))+    {+    int p, groupnumber;++    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 (groupnumber == rc[p].groupnumber)+          {+          rgroup = rc[p].group;+          break;+          }++        /* Group n+1 must always start to the right of group n, so we can save+        search time below when the new group number is greater than any of the+        previously found groups. */++        if (groupnumber > rc[p].groupnumber) search_from = rc[p].group;+        }++      if (rgroup == NULL)+        {+        rgroup = PRIV(find_bracket)(search_from, utf, groupnumber);+        if (rgroup == NULL)+          {+          errorcode = ERR53;+          break;+          }+        if (--start < 0) start = RSCAN_CACHE_SIZE - 1;+        rc[start].groupnumber = groupnumber;+        rc[start].group = rgroup;+        if (ccount < RSCAN_CACHE_SIZE) ccount++;+        }+      }++    PUT(rcode, 1, rgroup - codestart);+    }+  }++/* In rare debugging situations we sometimes need to look at the compiled code+at this stage. */++#ifdef DEBUG_CALL_PRINTINT+pcre2_printint(re, stderr, TRUE);+fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength);+#endif++/* 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 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)+  {+  PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;+  if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80;+  }++/* Failed to compile, or error while post-processing. */++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+or anything else, such as starting with non-atomic .* when DOTALL is set and+there are no occurrences of *PRUNE or *SKIP (though there is an option to+disable this case). */++if ((re->overall_options & PCRE2_ANCHORED) == 0 &&+     is_anchored(codestart, 0, &cb, 0, FALSE))+  re->overall_options |= PCRE2_ANCHORED;++/* 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_NO_START_OPTIMIZE) == 0)+  {+  int minminlength = 0;  /* For minimal minlength from first/required CU */++  /* 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, 0);++  /* Save the data for a first code unit. The existence of one means the+  minimum length must be at least 1. */++  if (firstcuflags >= 0)+    {+    re->first_codeunit = firstcu;+    re->flags |= PCRE2_FIRSTSET;+    minminlength++;++    /* Handle caseless first code units. */++    if ((firstcuflags & REQ_CASELESS) != 0)+      {+      if (firstcu < 128 || (!utf && !ucp && firstcu < 255))+        {+        if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS;+        }++      /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise.+      In 8-bit UTF mode, codepoints in the range 128-255 are introductory code+      points and cannot have another case, but if UCP is set they may do. */++#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+      else if (ucp && !utf && UCD_OTHERCASE(firstcu) != firstcu)+        re->flags |= PCRE2_FIRSTCASELESS;+#else+      else if ((utf || ucp) && firstcu <= MAX_UTF_CODE_POINT &&+               UCD_OTHERCASE(firstcu) != firstcu)+        re->flags |= PCRE2_FIRSTCASELESS;+#endif+#endif  /* SUPPORT_UNICODE */+      }+    }++  /* 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 ((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 UTF case we can+  increment the minimum minimum length only if we are sure this really is a+  different character and not a non-starting code unit of the first character,+  because the minimum length count is in characters, not code units. */++  if (reqcuflags >= 0)+    {+#if PCRE2_CODE_UNIT_WIDTH == 16+    if ((re->overall_options & PCRE2_UTF) == 0 ||   /* Not UTF */+        firstcuflags < 0 ||                         /* First not set */+        (firstcu & 0xf800) != 0xd800 ||             /* First not surrogate */+        (reqcu & 0xfc00) != 0xdc00)                 /* Req not low surrogate */+#elif PCRE2_CODE_UNIT_WIDTH == 8+    if ((re->overall_options & PCRE2_UTF) == 0 ||   /* Not UTF */+        firstcuflags < 0 ||                         /* First not set */+        (firstcu & 0x80) == 0 ||                    /* First is ASCII */+        (reqcu & 0x80) == 0)                        /* Req is ASCII */+#endif+      {+      minminlength++;+      }++    /* In the case of an anchored pattern, set up the value only if it follows+    a variable length item in the pattern. */++    if ((re->overall_options & PCRE2_ANCHORED) == 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 (reqcu < 128 || (!utf && !ucp && reqcu < 255))+          {+          if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;+          }+#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+      else if (ucp && !utf && UCD_OTHERCASE(reqcu) != reqcu)+        re->flags |= PCRE2_LASTCASELESS;+#else+      else if ((utf || ucp) && reqcu <= MAX_UTF_CODE_POINT &&+               UCD_OTHERCASE(reqcu) != reqcu)+        re->flags |= PCRE2_LASTCASELESS;+#endif+#endif  /* SUPPORT_UNICODE */+        }+      }+    }++  /* Study the compiled pattern to set up information such as a bitmap of+  starting code units and a minimum matching length. */++  if (PRIV(study)(re) != 0)+    {+    errorcode = ERR31;+    goto HAD_CB_ERROR;+    }++  /* If study() set a bitmap of starting code units, it implies a minimum+  length of at least one. */++  if ((re->flags & PCRE2_FIRSTMAPSET) != 0 && minminlength == 0)+    minminlength = 1;++  /* If the minimum length set (or not set) by study() is less than the minimum+  implied by required code units, override it. */++  if (re->minlength < minminlength) re->minlength = minminlength;+  }   /* End of start-of-match optimizations. */++/* 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:+#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 != 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 */
+ src/c/pcre2/src/pcre2_config.c view
@@ -0,0 +1,252 @@+/*************************************************+*      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-2020 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++/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes+its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to+be in code units. */++static int configured_link_size = LINK_SIZE;++#include "pcre2_internal.h"++/* These macros are the standard way of turning unquoted text into C strings.+They allow macros like PCRE2_MAJOR to be defined without quotes, which is+convenient for user programs that want to test their values. */++#define STRING(a)  # a+#define XSTRING(s) STRING(s)+++/*************************************************+* Return info about what features are configured *+*************************************************/++/* If where is NULL, the length of memory required is returned.++Arguments:+  what             what information is required+  where            where to put the information++Returns:           0 if a numerical value is returned+                   >= 0 if a string value+                   PCRE2_ERROR_BADOPTION if "where" not recognized+                     or JIT target requested when JIT not enabled+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_config(uint32_t what, void *where)+{+if (where == NULL)  /* Requests a length */+  {+  switch(what)+    {+    default:+    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_STACKRECURSE:    /* Obsolete */+    case PCRE2_CONFIG_TABLES_LENGTH:+    case PCRE2_CONFIG_UNICODE:+    return sizeof(uint32_t);++    /* These are handled below */++    case PCRE2_CONFIG_JITTARGET:+    case PCRE2_CONFIG_UNICODE_VERSION:+    case PCRE2_CONFIG_VERSION:+    break;+    }+  }++switch (what)+  {+  default:+  return PCRE2_ERROR_BADOPTION;++  case PCRE2_CONFIG_BSR:+#ifdef BSR_ANYCRLF+  *((uint32_t *)where) = PCRE2_BSR_ANYCRLF;+#else+  *((uint32_t *)where) = PCRE2_BSR_UNICODE;+#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;+#else+  *((uint32_t *)where) = 0;+#endif+  break;++  case PCRE2_CONFIG_JITTARGET:+#ifdef SUPPORT_JIT+    {+    const char *v = PRIV(jit_get_target)();+    return (int)(1 + ((where == NULL)?+      strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));+    }+#else+  return PCRE2_ERROR_BADOPTION;+#endif++  case PCRE2_CONFIG_LINKSIZE:+  *((uint32_t *)where) = (uint32_t)configured_link_size;+  break;++  case PCRE2_CONFIG_MATCHLIMIT:+  *((uint32_t *)where) = MATCH_LIMIT;+  break;++  case PCRE2_CONFIG_NEWLINE:+  *((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;++  /* This is now obsolete. The stack is no longer used via recursion for+  handling backtracking in pcre2_match(). */++  case PCRE2_CONFIG_STACKRECURSE:+  *((uint32_t *)where) = 0;+  break;++  case PCRE2_CONFIG_TABLES_LENGTH:+  *((uint32_t *)where) = TABLES_LENGTH;+  break;++  case PCRE2_CONFIG_UNICODE_VERSION:+    {+#if defined SUPPORT_UNICODE+    const char *v = PRIV(unicode_version);+#else+    const char *v = "Unicode not supported";+#endif+    return (int)(1 + ((where == NULL)?+      strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));+   }+  break;++  case PCRE2_CONFIG_UNICODE:+#if defined SUPPORT_UNICODE+  *((uint32_t *)where) = 1;+#else+  *((uint32_t *)where) = 0;+#endif+  break;++  /* The hackery in setting "v" below is to cope with the case when+  PCRE2_PRERELEASE is set to an empty string (which it is for real releases).+  If the second alternative is used in this case, it does not leave a space+  before the date. On the other hand, if all four macros are put into a single+  XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted.+  There are problems using an "obvious" approach like this:++     XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR)+     XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE)++  because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion+  of STRING(). The C standard states: "If (before argument substitution) any+  argument consists of no preprocessing tokens, the behavior is undefined." It+  turns out the gcc treats this case as a single empty string - which is what+  we really want - but Visual C grumbles about the lack of an argument for the+  macro. Unfortunately, both are within their rights. As there seems to be no+  way to test for a macro's value being empty at compile time, we have to+  resort to a runtime test. */++  case PCRE2_CONFIG_VERSION:+    {+    const char *v = (XSTRING(Z PCRE2_PRERELEASE)[1] == 0)?+      XSTRING(PCRE2_MAJOR.PCRE2_MINOR PCRE2_DATE) :+      XSTRING(PCRE2_MAJOR.PCRE2_MINOR) XSTRING(PCRE2_PRERELEASE PCRE2_DATE);+    return (int)(1 + ((where == NULL)?+      strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));+    }+  }++return 0;+}++/* End of pcre2_config.c */
+ src/c/pcre2/src/pcre2_context.c view
@@ -0,0 +1,488 @@+/*************************************************+*      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.+-----------------------------------------------------------------------------+*/+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"++++/*************************************************+*          Default malloc/free functions         *+*************************************************/++/* Ignore the "user data" argument in each case. */++static void *default_malloc(size_t size, void *data)+{+(void)data;+return malloc(size);+}+++static void default_free(void *block, void *data)+{+(void)data;+free(block);+}++++/*************************************************+*        Get a block and save memory control     *+*************************************************/++/* This internal function is called to get a block of memory in which the+memory control data is to be stored at the start for future use.++Arguments:+  size        amount of memory required+  memctl      pointer to a memctl block or NULL++Returns:      pointer to memory or NULL on failure+*/++extern void *+PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl)+{+pcre2_memctl *newmemctl;+void *yield = (memctl == NULL)? malloc(size) :+  memctl->malloc(size, memctl->memory_data);+if (yield == NULL) return NULL;+newmemctl = (pcre2_memctl *)yield;+if (memctl == NULL)+  {+  newmemctl->malloc = default_malloc;+  newmemctl->free = default_free;+  newmemctl->memory_data = NULL;+  }+else *newmemctl = *memctl;+return yield;+}++++/*************************************************+*          Create and initialize contexts        *+*************************************************/++/* Initializing for compile and match contexts is done in separate, private+functions so that these can be called from functions such as pcre2_compile()+when an external context is not supplied. The initializing functions have an+option to set up default memory management. */++PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION+pcre2_general_context_create(void *(*private_malloc)(size_t, void *),+  void (*private_free)(void *, void *), void *memory_data)+{+pcre2_general_context *gcontext;+if (private_malloc == NULL) private_malloc = default_malloc;+if (private_free == NULL) private_free = default_free;+gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);+if (gcontext == NULL) return NULL;+gcontext->memctl.malloc = private_malloc;+gcontext->memctl.free = private_free;+gcontext->memctl.memory_data = memory_data;+return gcontext;+}+++/* A default compile context is set up to save having to initialize at run time+when no context is supplied to the compile function. */++const pcre2_compile_context PRIV(default_compile_context) = {+  { default_malloc, default_free, NULL },    /* Default memory handling */+  NULL,                                      /* Stack guard */+  NULL,                                      /* Stack guard data */+  PRIV(default_tables),                      /* Character tables */+  PCRE2_UNSET,                               /* Max pattern length */+  BSR_DEFAULT,                               /* Backslash R default */+  NEWLINE_DEFAULT,                           /* Newline convention */+  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. */++PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION+pcre2_compile_context_create(pcre2_general_context *gcontext)+{+pcre2_compile_context *ccontext = PRIV(memctl_malloc)(+  sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext);+if (ccontext == NULL) return NULL;+*ccontext = PRIV(default_compile_context);+if (gcontext != NULL)+  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);+return ccontext;+}+++/* A default match context is set up to save having to initialize at run time+when no context is supplied to a match function. */++const pcre2_match_context PRIV(default_match_context) = {+  { default_malloc, default_free, NULL },+#ifdef SUPPORT_JIT+  NULL,          /* JIT callback */+  NULL,          /* JIT callback data */+#endif+  NULL,          /* Callout function */+  NULL,          /* Callout data */+  NULL,          /* Substitute callout function */+  NULL,          /* Substitute callout data */+  PCRE2_UNSET,   /* Offset limit */+  HEAP_LIMIT,+  MATCH_LIMIT,+  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. */++PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION+pcre2_match_context_create(pcre2_general_context *gcontext)+{+pcre2_match_context *mcontext = PRIV(memctl_malloc)(+  sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext);+if (mcontext == NULL) return NULL;+*mcontext = PRIV(default_match_context);+if (gcontext != NULL)+  *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext);+return mcontext;+}+++/* A default convert context is set up to save having to initialize at run time+when no context is supplied to the convert function. */++const pcre2_convert_context PRIV(default_convert_context) = {+  { 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            *+*************************************************/++PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION+pcre2_general_context_copy(pcre2_general_context *gcontext)+{+pcre2_general_context *new =+  gcontext->memctl.malloc(sizeof(pcre2_real_general_context),+  gcontext->memctl.memory_data);+if (new == NULL) return NULL;+memcpy(new, gcontext, sizeof(pcre2_real_general_context));+return new;+}+++PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION+pcre2_compile_context_copy(pcre2_compile_context *ccontext)+{+pcre2_compile_context *new =+  ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),+  ccontext->memctl.memory_data);+if (new == NULL) return NULL;+memcpy(new, ccontext, sizeof(pcre2_real_compile_context));+return new;+}+++PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION+pcre2_match_context_copy(pcre2_match_context *mcontext)+{+pcre2_match_context *new =+  mcontext->memctl.malloc(sizeof(pcre2_real_match_context),+  mcontext->memctl.memory_data);+if (new == NULL) return NULL;+memcpy(new, mcontext, sizeof(pcre2_real_match_context));+return new;+}++++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)+{+if (gcontext != NULL)+  gcontext->memctl.free(gcontext, gcontext->memctl.memory_data);+}+++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_compile_context_free(pcre2_compile_context *ccontext)+{+if (ccontext != NULL)+  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);+}+++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_match_context_free(pcre2_match_context *mcontext)+{+if (mcontext != NULL)+  mcontext->memctl.free(mcontext, mcontext->memctl.memory_data);+}+++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);+}+++/*************************************************+*             Set values in contexts             *+*************************************************/++/* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid+data is given. Only some of the functions are able to test the validity of the+data. */+++/* ------------ Compile context ------------ */++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_character_tables(pcre2_compile_context *ccontext,+  const uint8_t *tables)+{+ccontext->tables = tables;+return 0;+}++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value)+{+switch(value)+  {+  case PCRE2_BSR_ANYCRLF:+  case PCRE2_BSR_UNICODE:+  ccontext->bsr_convention = value;+  return 0;++  default:+  return PCRE2_ERROR_BADDATA;+  }+}++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)+{+ccontext->max_pattern_length = length;+return 0;+}++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)+{+switch(newline)+  {+  case PCRE2_NEWLINE_CR:+  case PCRE2_NEWLINE_LF:+  case PCRE2_NEWLINE_CRLF:+  case PCRE2_NEWLINE_ANY:+  case PCRE2_NEWLINE_ANYCRLF:+  case PCRE2_NEWLINE_NUL:+  ccontext->newline_convention = newline;+  return 0;++  default:+  return PCRE2_ERROR_BADDATA;+  }+}++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)+{+ccontext->parens_nest_limit = limit;+return 0;+}++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)+{+ccontext->stack_guard = guard;+ccontext->stack_guard_data = user_data;+return 0;+}+++/* ------------ Match context ------------ */++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_callout(pcre2_match_context *mcontext,+  int (*callout)(pcre2_callout_block *, void *), void *callout_data)+{+mcontext->callout = callout;+mcontext->callout_data = callout_data;+return 0;+}++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_substitute_callout(pcre2_match_context *mcontext,+  int (*substitute_callout)(pcre2_substitute_callout_block *, void *),+    void *substitute_callout_data)+{+mcontext->substitute_callout = substitute_callout;+mcontext->substitute_callout_data = substitute_callout_data;+return 0;+}++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;+return 0;+}++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)+{+return pcre2_set_depth_limit(mcontext, limit);+}++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,+  void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),+  void *mydata)+{+(void)mcontext;+(void)mymalloc;+(void)myfree;+(void)mydata;+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 */+
+ src/c/pcre2/src/pcre2_convert.c view
@@ -0,0 +1,1182 @@+/*************************************************+*      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.+-----------------------------------------------------------------------------+*/+++#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)+  {+  *bufflenptr = 0;  /* Error offset */+  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:+    *bufflenptr = 0;  /* Error offset */+    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 */
+ src/c/pcre2/src/pcre2_dfa_match.c view
@@ -0,0 +1,3982 @@+/*************************************************+*      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-2020 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 the external function pcre2_dfa_match(), which is an+alternative matching function that uses a sort of DFA algorithm (not a true+FSM). This is NOT Perl-compatible, but it has advantages in certain+applications. */+++/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved+the performance of his patterns greatly. I could not use it as it stood, as it+was not thread safe, and made assumptions about pattern sizes. Also, it caused+test 7 to loop, and test 9 to crash with a segfault.++The issue is the check for duplicate states, which is done by a simple linear+search up the state list. (Grep for "duplicate" below to find the code.) For+many patterns, there will never be many states active at one time, so a simple+linear search is fine. In patterns that have many active states, it might be a+bottleneck. The suggested code used an indexing scheme to remember which states+had previously been used for each character, and avoided the linear search when+it knew there was no chance of a duplicate. This was implemented when adding+states to the state lists.++I wrote some thread-safe, not-limited code to try something similar at the time+of checking for duplicates (instead of when adding states), using index vectors+on the stack. It did give a 13% improvement with one specially constructed+pattern for certain subject strings, but on other strings and on many of the+simpler patterns in the test suite it did worse. The major problem, I think,+was the extra time to initialize the index. This had to be done for each call+of internal_dfa_match(). (The supplied patch used a static vector, initialized+only once - I suspect this was the cause of the problems with the tests.)++Overall, I concluded that the gains in some cases did not outweigh the losses+in others, so I abandoned this code. */+++#ifdef HAVE_CONFIG_H+#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 */++#include "pcre2_internal.h"++#define PUBLIC_DFA_MATCH_OPTIONS \+  (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| \+   PCRE2_COPY_MATCHED_SUBJECT)+++/*************************************************+*      Code parameters and static tables         *+*************************************************/++/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes+into others, under special conditions. A gap of 20 between the blocks should be+enough. The resulting opcodes don't have to be less than 256 because they are+never stored, so we push them well clear of the normal opcodes. */++#define OP_PROP_EXTRA       300+#define OP_EXTUNI_EXTRA     320+#define OP_ANYNL_EXTRA      340+#define OP_HSPACE_EXTRA     360+#define OP_VSPACE_EXTRA     380+++/* This table identifies those opcodes that are followed immediately by a+character that is to be tested in some way. This makes it possible to+centralize the loading of these characters. In the case of Type * etc, the+"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a+small value. Non-zero values in the table are the offsets from the opcode where+the character is to be found. ***NOTE*** If the start of this table is+modified, the three tables that follow must also be modified. */++static const uint8_t coptable[] = {+  0,                             /* End                                    */+  0, 0, 0, 0, 0,                 /* \A, \G, \K, \B, \b                     */+  0, 0, 0, 0, 0, 0,              /* \D, \d, \S, \s, \W, \w                 */+  0, 0, 0,                       /* Any, AllAny, Anybyte                   */+  0, 0,                          /* \P, \p                                 */+  0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */+  0,                             /* \X                                     */+  0, 0, 0, 0, 0, 0,              /* \Z, \z, $, $M, ^, ^M                   */+  1,                             /* Char                                   */+  1,                             /* Chari                                  */+  1,                             /* not                                    */+  1,                             /* noti                                   */+  /* Positive single-char repeats                                          */+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */+  1+IMM2_SIZE, 1+IMM2_SIZE,      /* upto, minupto                          */+  1+IMM2_SIZE,                   /* exact                                  */+  1, 1, 1, 1+IMM2_SIZE,          /* *+, ++, ?+, upto+                      */+  1, 1, 1, 1, 1, 1,              /* *I, *?I, +I, +?I, ?I, ??I              */+  1+IMM2_SIZE, 1+IMM2_SIZE,      /* upto I, minupto I                      */+  1+IMM2_SIZE,                   /* exact I                                */+  1, 1, 1, 1+IMM2_SIZE,          /* *+I, ++I, ?+I, upto+I                  */+  /* Negative single-char repeats - only for chars < 256                   */+  1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */+  1+IMM2_SIZE, 1+IMM2_SIZE,      /* NOT upto, minupto                      */+  1+IMM2_SIZE,                   /* NOT exact                              */+  1, 1, 1, 1+IMM2_SIZE,          /* NOT *+, ++, ?+, upto+                  */+  1, 1, 1, 1, 1, 1,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */+  1+IMM2_SIZE, 1+IMM2_SIZE,      /* NOT upto I, minupto I                  */+  1+IMM2_SIZE,                   /* NOT exact I                            */+  1, 1, 1, 1+IMM2_SIZE,          /* NOT *+I, ++I, ?+I, upto+I              */+  /* Positive type repeats                                                 */+  1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */+  1+IMM2_SIZE, 1+IMM2_SIZE,      /* Type upto, minupto                     */+  1+IMM2_SIZE,                   /* Type exact                             */+  1, 1, 1, 1+IMM2_SIZE,          /* Type *+, ++, ?+, upto+                 */+  /* Character class & ref repeats                                         */+  0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */+  0, 0,                          /* CRRANGE, CRMINRANGE                    */+  0, 0, 0, 0,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */+  0,                             /* CLASS                                  */+  0,                             /* NCLASS                                 */+  0,                             /* XCLASS - variable length               */+  0,                             /* REF                                    */+  0,                             /* REFI                                   */+  0,                             /* DNREF                                  */+  0,                             /* DNREFI                                 */+  0,                             /* RECURSE                                */+  0,                             /* CALLOUT                                */+  0,                             /* CALLOUT_STR                            */+  0,                             /* Alt                                    */+  0,                             /* Ket                                    */+  0,                             /* KetRmax                                */+  0,                             /* KetRmin                                */+  0,                             /* KetRpos                                */+  0,                             /* Reverse                                */+  0,                             /* Assert                                 */+  0,                             /* Assert not                             */+  0,                             /* Assert behind                          */+  0,                             /* Assert behind not                      */+  0,                             /* NA assert                              */+  0,                             /* NA assert behind                       */+  0,                             /* ONCE                                   */+  0,                             /* SCRIPT_RUN                             */+  0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */+  0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */+  0, 0,                          /* CREF, DNCREF                           */+  0, 0,                          /* RREF, DNRREF                           */+  0, 0,                          /* FALSE, TRUE                            */+  0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */+  0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */+  0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG         */+  0, 0,                          /* COMMIT, COMMIT_ARG                     */+  0, 0, 0,                       /* FAIL, ACCEPT, ASSERT_ACCEPT            */+  0, 0, 0                        /* CLOSE, SKIPZERO, DEFINE                */+};++/* This table identifies those opcodes that inspect a character. It is used to+remember the fact that a character could have been inspected when the end of+the subject is reached. ***NOTE*** If the start of this table is modified, the+two tables that follow must also be modified. */++static const uint8_t poptable[] = {+  0,                             /* End                                    */+  0, 0, 0, 1, 1,                 /* \A, \G, \K, \B, \b                     */+  1, 1, 1, 1, 1, 1,              /* \D, \d, \S, \s, \W, \w                 */+  1, 1, 1,                       /* Any, AllAny, Anybyte                   */+  1, 1,                          /* \P, \p                                 */+  1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */+  1,                             /* \X                                     */+  0, 0, 0, 0, 0, 0,              /* \Z, \z, $, $M, ^, ^M                   */+  1,                             /* Char                                   */+  1,                             /* Chari                                  */+  1,                             /* not                                    */+  1,                             /* noti                                   */+  /* Positive single-char repeats                                          */+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */+  1, 1, 1,                       /* upto, minupto, exact                   */+  1, 1, 1, 1,                    /* *+, ++, ?+, upto+                      */+  1, 1, 1, 1, 1, 1,              /* *I, *?I, +I, +?I, ?I, ??I              */+  1, 1, 1,                       /* upto I, minupto I, exact I             */+  1, 1, 1, 1,                    /* *+I, ++I, ?+I, upto+I                  */+  /* Negative single-char repeats - only for chars < 256                   */+  1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */+  1, 1, 1,                       /* NOT upto, minupto, exact               */+  1, 1, 1, 1,                    /* NOT *+, ++, ?+, upto+                  */+  1, 1, 1, 1, 1, 1,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */+  1, 1, 1,                       /* NOT upto I, minupto I, exact I         */+  1, 1, 1, 1,                    /* NOT *+I, ++I, ?+I, upto+I              */+  /* Positive type repeats                                                 */+  1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */+  1, 1, 1,                       /* Type upto, minupto, exact              */+  1, 1, 1, 1,                    /* Type *+, ++, ?+, upto+                 */+  /* Character class & ref repeats                                         */+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */+  1, 1,                          /* CRRANGE, CRMINRANGE                    */+  1, 1, 1, 1,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */+  1,                             /* CLASS                                  */+  1,                             /* NCLASS                                 */+  1,                             /* XCLASS - variable length               */+  0,                             /* REF                                    */+  0,                             /* REFI                                   */+  0,                             /* DNREF                                  */+  0,                             /* DNREFI                                 */+  0,                             /* RECURSE                                */+  0,                             /* CALLOUT                                */+  0,                             /* CALLOUT_STR                            */+  0,                             /* Alt                                    */+  0,                             /* Ket                                    */+  0,                             /* KetRmax                                */+  0,                             /* KetRmin                                */+  0,                             /* KetRpos                                */+  0,                             /* Reverse                                */+  0,                             /* Assert                                 */+  0,                             /* Assert not                             */+  0,                             /* Assert behind                          */+  0,                             /* Assert behind not                      */+  0,                             /* NA assert                              */+  0,                             /* NA assert behind                       */+  0,                             /* ONCE                                   */+  0,                             /* SCRIPT_RUN                             */+  0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */+  0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */+  0, 0,                          /* CREF, DNCREF                           */+  0, 0,                          /* RREF, DNRREF                           */+  0, 0,                          /* FALSE, TRUE                            */+  0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */+  0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */+  0, 0, 0, 0,                    /* SKIP, SKIP_ARG, THEN, THEN_ARG         */+  0, 0,                          /* COMMIT, COMMIT_ARG                     */+  0, 0, 0,                       /* FAIL, ACCEPT, ASSERT_ACCEPT            */+  0, 0, 0                        /* CLOSE, SKIPZERO, DEFINE                */+};++/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,+and \w */++static const uint8_t toptable1[] = {+  0, 0, 0, 0, 0, 0,+  ctype_digit, ctype_digit,+  ctype_space, ctype_space,+  ctype_word,  ctype_word,+  0, 0                            /* OP_ANY, OP_ALLANY */+};++static const uint8_t toptable2[] = {+  0, 0, 0, 0, 0, 0,+  ctype_digit, 0,+  ctype_space, 0,+  ctype_word,  0,+  1, 1                            /* OP_ANY, OP_ALLANY */+};+++/* Structure for holding data about a particular state, which is in effect the+current data for an active path through the match tree. It must consist+entirely of ints because the working vector we are passed, and which we put+these structures in, is a vector of ints. */++typedef struct stateblock {+  int offset;                     /* Offset to opcode (-ve has meaning) */+  int count;                      /* Count for repeats */+  int data;                       /* Some use extra data */+} stateblock;++#define INTS_PER_STATEBLOCK  (int)(sizeof(stateblock)/sizeof(int))+++/* Before version 10.32 the recursive calls of internal_dfa_match() were passed+local working space and output vectors that were created on the stack. This has+caused issues for some patterns, especially in small-stack environments such as+Windows. A new scheme is now in use which sets up a vector on the stack, but if+this is too small, heap memory is used, up to the heap_limit. The main+parameters are all numbers of ints because the workspace is a vector of ints.++The size of the starting stack vector, DFA_START_RWS_SIZE, is in bytes, and is+defined in pcre2_internal.h so as to be available to pcre2test when it is+finding the minimum heap requirement for a match. */++#define OVEC_UNIT  (sizeof(PCRE2_SIZE)/sizeof(int))++#define RWS_BASE_SIZE   (DFA_START_RWS_SIZE/sizeof(int))  /* Stack vector */+#define RWS_RSIZE       1000                    /* Work size for recursion */+#define RWS_OVEC_RSIZE  (1000*OVEC_UNIT)        /* Ovector for recursion */+#define RWS_OVEC_OSIZE  (2*OVEC_UNIT)           /* Ovector in other cases */++/* This structure is at the start of each workspace block. */++typedef struct RWS_anchor {+  struct RWS_anchor *next;+  uint32_t size;  /* Number of ints */+  uint32_t free;  /* Number of ints */+} RWS_anchor;++#define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int))++++/*************************************************+*               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);+}++++/*************************************************+*         Expand local workspace memory          *+*************************************************/++/* This function is called when internal_dfa_match() is about to be called+recursively and there is insufficient working space left in the current+workspace block. If there's an existing next block, use it; otherwise get a new+block unless the heap limit is reached.++Arguments:+  rwsptr     pointer to block pointer (updated)+  ovecsize   space needed for an ovector+  mb         the match block++Returns:     0 rwsptr has been updated+            !0 an error code+*/++static int+more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)+{+RWS_anchor *rws = *rwsptr;+RWS_anchor *new;++if (rws->next != NULL)+  {+  new = rws->next;+  }++/* Sizes in the RWS_anchor blocks are in units of sizeof(int), but+mb->heap_limit and mb->heap_used are in kibibytes. Play carefully, to avoid+overflow. */++else+  {+  uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2;+  uint32_t newsizeK = newsize/(1024/sizeof(int));++  if (newsizeK + mb->heap_used > mb->heap_limit)+    newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used);+  newsize = newsizeK*(1024/sizeof(int));++  if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)+    return PCRE2_ERROR_HEAPLIMIT;+  new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);+  if (new == NULL) return PCRE2_ERROR_NOMEMORY;+  mb->heap_used += newsizeK;+  new->next = NULL;+  new->size = newsize;+  rws->next = new;+  }++new->free = new->size - RWS_ANCHOR_SIZE;+*rwsptr = new;+return 0;+}++++/*************************************************+*     Match a Regular Expression - DFA engine    *+*************************************************/++/* This internal function applies a compiled pattern to a subject string,+starting at a given point, using a DFA engine. This function is called from the+external one, possibly multiple times if the pattern is not anchored. The+function calls itself recursively for some kinds of subpattern.++Arguments:+  mb                the match_data block with fixed information+  this_start_code   the opening bracket of this subexpression's code+  current_subject   where we currently are in the subject string+  start_offset      start offset in the subject string+  offsets           vector to contain the matching string offsets+  offsetcount       size of same+  workspace         vector of workspace+  wscount           size of same+  rlevel            function call recursion level++Returns:            > 0 => number of match offset pairs placed in offsets+                    = 0 => offsets overflowed; longest matches are present+                     -1 => failed to match+                   < -1 => some kind of unexpected problem++The following macros are used for adding states to the two state vectors (one+for the current character, one for the following character). */++#define ADD_ACTIVE(x,y) \+  if (active_count++ < wscount) \+    { \+    next_active_state->offset = (x); \+    next_active_state->count  = (y); \+    next_active_state++; \+    } \+  else return PCRE2_ERROR_DFA_WSSIZE++#define ADD_ACTIVE_DATA(x,y,z) \+  if (active_count++ < wscount) \+    { \+    next_active_state->offset = (x); \+    next_active_state->count  = (y); \+    next_active_state->data   = (z); \+    next_active_state++; \+    } \+  else return PCRE2_ERROR_DFA_WSSIZE++#define ADD_NEW(x,y) \+  if (new_count++ < wscount) \+    { \+    next_new_state->offset = (x); \+    next_new_state->count  = (y); \+    next_new_state++; \+    } \+  else return PCRE2_ERROR_DFA_WSSIZE++#define ADD_NEW_DATA(x,y,z) \+  if (new_count++ < wscount) \+    { \+    next_new_state->offset = (x); \+    next_new_state->count  = (y); \+    next_new_state->data   = (z); \+    next_new_state++; \+    } \+  else return PCRE2_ERROR_DFA_WSSIZE++/* And now, here is the code */++static int+internal_dfa_match(+  dfa_match_block *mb,+  PCRE2_SPTR this_start_code,+  PCRE2_SPTR current_subject,+  PCRE2_SIZE start_offset,+  PCRE2_SIZE *offsets,+  uint32_t offsetcount,+  int *workspace,+  int wscount,+  uint32_t rlevel,+  int *RWS)+{+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;+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+independent variables in the hope that this will perform better. */++PCRE2_SPTR start_subject = mb->start_subject;+PCRE2_SPTR end_subject = mb->end_subject;+PCRE2_SPTR start_code = mb->start_code;++#ifdef SUPPORT_UNICODE+BOOL utf = (mb->poptions & PCRE2_UTF) != 0;+BOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0;+#else+BOOL utf = FALSE;+#endif++BOOL reset_could_continue = FALSE;++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;+wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /+          (2 * INTS_PER_STATEBLOCK);++ctypes = mb->tables + ctypes_offset;+lcc = mb->tables + lcc_offset;+fcc = mb->tables + fcc_offset;++match_count = PCRE2_ERROR_NOMATCH;   /* A negative number */++active_states = (stateblock *)(workspace + 2);+next_new_state = new_states = active_states + wscount;+new_count = 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 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 (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)+  {+  size_t max_back = 0;+  size_t gone_back;++  end_code = this_start_code;+  do+    {+    size_t back = (size_t)GET(end_code, 2+LINK_SIZE);+    if (back > max_back) max_back = back;+    end_code += GET(end_code, 1);+    }+  while (*end_code == OP_ALT);++  /* If we can't go back the amount required for the longest lookbehind+  pattern, go back as far as we can; some alternatives may still be viable. */++#ifdef SUPPORT_UNICODE+  /* In character mode we have to step back character by character */++  if (utf)+    {+    for (gone_back = 0; gone_back < max_back; gone_back++)+      {+      if (current_subject <= start_subject) break;+      current_subject--;+      ACROSSCHAR(current_subject > start_subject, current_subject,+        current_subject--);+      }+    }+  else+#endif++  /* In byte-mode we can do this quickly. */++    {+    size_t current_offset = (size_t)(current_subject - start_subject);+    gone_back = (current_offset < max_back)? current_offset : max_back;+    current_subject -= gone_back;+    }++  /* Save the earliest consulted character */++  if (current_subject < mb->start_used_ptr)+    mb->start_used_ptr = current_subject;++  /* 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+    {+    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 + 1 + LINK_SIZE + revlen);+      ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back));+      }+    end_code += GET(end_code, 1);+    }+  while (*end_code == OP_ALT);+ }++/* This is the code for a "normal" subpattern (not a backward assertion). The+start of a whole pattern is always one of these. If we are at the top level,+we may be asked to restart matching from the same point that we reached for a+previous partial match. We still have to scan through the top-level branches to+find the end state. */++else+  {+  end_code = this_start_code;++  /* Restarting */++  if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0)+    {+    do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);+    new_count = workspace[1];+    if (!workspace[0])+      memcpy(new_states, active_states, (size_t)new_count * sizeof(stateblock));+    }++  /* Not restarting */++  else+    {+    int length = 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);+    do+      {+      ADD_NEW((int)(end_code - start_code + length), 0);+      end_code += GET(end_code, 1);+      length = 1 + LINK_SIZE;+      }+    while (*end_code == OP_ALT);+    }+  }++workspace[0] = 0;    /* Bit indicating which vector is current */++/* Loop for scanning the subject */++ptr = current_subject;+for (;;)+  {+  int i, j;+  int clen, dlen;+  uint32_t c, d;+  int forced_fail = 0;+  BOOL partial_newline = FALSE;+  BOOL could_continue = reset_could_continue;+  reset_could_continue = FALSE;++  if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr;++  /* Make the new state list into the active state list and empty the+  new state list. */++  temp_states = active_states;+  active_states = new_states;+  new_states = temp_states;+  active_count = new_count;+  new_count = 0;++  workspace[0] ^= 1;              /* Remember for the restarting feature */+  workspace[1] = active_count;++  /* Set the pointers for adding new states */++  next_active_state = active_states + active_count;+  next_new_state = new_states;++  /* Load the current character from the subject outside the loop, as many+  different states may want to look at it, and we assume that at least one+  will. */++  if (ptr < end_subject)+    {+    clen = 1;        /* Number of data items in the character */+#ifdef SUPPORT_UNICODE+    GETCHARLENTEST(c, ptr, clen);+#else+    c = *ptr;+#endif  /* SUPPORT_UNICODE */+    }+  else+    {+    clen = 0;        /* This indicates the end of the subject */+    c = NOTACHAR;    /* This value should never actually be used */+    }++  /* Scan up the active states and act on each one. The result of an action+  may be to add more states to the currently active list (e.g. on hitting a+  parenthesis) or it may be to put states on the new list, for considering+  when we move the character pointer on. */++  for (i = 0; i < active_count; i++)+    {+    stateblock *current_state = active_states + i;+    BOOL caseless = FALSE;+    PCRE2_SPTR code;+    uint32_t codevalue;+    int state_offset = current_state->offset;+    int rrc;+    int count;++    /* A negative offset is a special case meaning "hold off going to this+    (negated) state until the number of characters in the data field have+    been skipped". If the could_continue flag was passed over from a previous+    state, arrange for it to passed on. */++    if (state_offset < 0)+      {+      if (current_state->data > 0)+        {+        ADD_NEW_DATA(state_offset, current_state->count,+          current_state->data - 1);+        if (could_continue) reset_could_continue = TRUE;+        continue;+        }+      else+        {+        current_state->offset = state_offset = -state_offset;+        }+      }++    /* Check for a duplicate state with the same count, and skip if found.+    See the note at the head of this module about the possibility of improving+    performance here. */++    for (j = 0; j < i; j++)+      {+      if (active_states[j].offset == state_offset &&+          active_states[j].count == current_state->count)+        goto NEXT_ACTIVE_STATE;+      }++    /* The state offset is the offset to the opcode */++    code = start_code + state_offset;+    codevalue = *code;++    /* If this opcode inspects a character, but we are at the end of the+    subject, remember the fact for use when testing for a partial match. */++    if (clen == 0 && poptable[codevalue] != 0)+      could_continue = TRUE;++    /* If this opcode is followed by an inline character, load it. It is+    tempting to test for the presence of a subject character here, but that+    is wrong, because sometimes zero repetitions of the subject are+    permitted.++    We also use this mechanism for opcodes such as OP_TYPEPLUS that take an+    argument that is not a data character - but is always one byte long because+    the values are small. We have to take special action to deal with  \P, \p,+    \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert+    these ones to new opcodes. */++    if (coptable[codevalue] > 0)+      {+      dlen = 1;+#ifdef SUPPORT_UNICODE+      if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else+#endif  /* SUPPORT_UNICODE */+      d = code[coptable[codevalue]];+      if (codevalue >= OP_TYPESTAR)+        {+        switch(d)+          {+          case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM;+          case OP_NOTPROP:+          case OP_PROP: codevalue += OP_PROP_EXTRA; break;+          case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;+          case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;+          case OP_NOT_HSPACE:+          case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;+          case OP_NOT_VSPACE:+          case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;+          default: break;+          }+        }+      }+    else+      {+      dlen = 0;         /* Not strictly necessary, but compilers moan */+      d = NOTACHAR;     /* if these variables are not set. */+      }+++    /* Now process the individual opcodes */++    switch (codevalue)+      {+/* ========================================================================== */+      /* These cases are never obeyed. This is a fudge that causes a compile-+      time error if the vectors coptable or poptable, which are indexed by+      opcode, are not the correct length. It seems to be the only way to do+      such a check at compile time, as the sizeof() operator does not work+      in the C preprocessor. */++      case OP_TABLE_LENGTH:+      case OP_TABLE_LENGTH ++        ((sizeof(coptable) == OP_TABLE_LENGTH) &&+         (sizeof(poptable) == OP_TABLE_LENGTH)):+      return 0;++/* ========================================================================== */+      /* Reached a closing bracket. If not at the end of the pattern, carry+      on with the next opcode. For repeating opcodes, also add the repeat+      state. Note that KETRPOS will always be encountered at the end of the+      subpattern, because the possessive subpattern repeats are always handled+      using recursive calls. Thus, it never adds any new states.++      At the end of the (sub)pattern, unless we have an empty string and+      PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the+      start of the subject, save the match data, shifting up all previous+      matches so we always have the longest first. */++      case OP_KET:+      case OP_KETRMIN:+      case OP_KETRMAX:+      case OP_KETRPOS:+      if (code != end_code)+        {+        ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);+        if (codevalue != OP_KET)+          {+          ADD_ACTIVE(state_offset - (int)GET(code, 1), 0);+          }+        }+      else+        {+        if (ptr > current_subject ||+            ((mb->moptions & PCRE2_NOTEMPTY) == 0 &&+              ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 ||+                current_subject > start_subject + mb->start_offset)))+          {+          if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;+            else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)+              match_count = 0;+          count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;+          if (count > 0) (void)memmove(offsets + 2, offsets,+            (size_t)count * sizeof(PCRE2_SIZE));+          if (offsetcount >= 2)+            {+            offsets[0] = (PCRE2_SIZE)(current_subject - start_subject);+            offsets[1] = (PCRE2_SIZE)(ptr - start_subject);+            }+          if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count;+          }+        }+      break;++/* ========================================================================== */+      /* These opcodes add to the current list of states without looking+      at the current character. */++      /*-----------------------------------------------------------------*/+      case OP_ALT:+      do { code += GET(code, 1); } while (*code == OP_ALT);+      ADD_ACTIVE((int)(code - start_code), 0);+      break;++      /*-----------------------------------------------------------------*/+      case OP_BRA:+      case OP_SBRA:+      do+        {+        ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);+        code += GET(code, 1);+        }+      while (*code == OP_ALT);+      break;++      /*-----------------------------------------------------------------*/+      case OP_CBRA:+      case OP_SCBRA:+      ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE),  0);+      code += GET(code, 1);+      while (*code == OP_ALT)+        {+        ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE),  0);+        code += GET(code, 1);+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_BRAZERO:+      case OP_BRAMINZERO:+      ADD_ACTIVE(state_offset + 1, 0);+      code += 1 + GET(code, 2);+      while (*code == OP_ALT) code += GET(code, 1);+      ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);+      break;++      /*-----------------------------------------------------------------*/+      case OP_SKIPZERO:+      code += 1 + GET(code, 2);+      while (*code == OP_ALT) code += GET(code, 1);+      ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);+      break;++      /*-----------------------------------------------------------------*/+      case OP_CIRC:+      if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0)+        { ADD_ACTIVE(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_CIRCM:+      if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) ||+          ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 )+            && WAS_NEWLINE(ptr)))+        { ADD_ACTIVE(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_EOD:+      if (ptr >= end_subject)+        {+        if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)+          return PCRE2_ERROR_PARTIAL;+        else { ADD_ACTIVE(state_offset + 1, 0); }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_SOD:+      if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_SOM:+      if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }+      break;+++/* ========================================================================== */+      /* These opcodes inspect the next subject character, and sometimes+      the previous one as well, but do not have an argument. The variable+      clen contains the length of the current character and is zero if we are+      at the end of the subject. */++      /*-----------------------------------------------------------------*/+      case OP_ANY:+      if (clen > 0 && !IS_NEWLINE(ptr))+        {+        if (ptr + 1 >= mb->end_subject &&+            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&+            NLBLOCK->nltype == NLTYPE_FIXED &&+            NLBLOCK->nllen == 2 &&+            c == NLBLOCK->nl[0])+          {+          could_continue = partial_newline = TRUE;+          }+        else+          {+          ADD_NEW(state_offset + 1, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_ALLANY:+      if (clen > 0)+        { ADD_NEW(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_EODN:+      if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))+        {+        if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)+          return PCRE2_ERROR_PARTIAL;+        ADD_ACTIVE(state_offset + 1, 0);+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_DOLL:+      if ((mb->moptions & PCRE2_NOTEOL) == 0)+        {+        if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)+          could_continue = TRUE;+        else if (clen == 0 ||+            ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&+               (ptr == end_subject - mb->nllen)+            ))+          { ADD_ACTIVE(state_offset + 1, 0); }+        else if (ptr + 1 >= mb->end_subject &&+                 (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&+                 NLBLOCK->nltype == NLTYPE_FIXED &&+                 NLBLOCK->nllen == 2 &&+                 c == NLBLOCK->nl[0])+          {+          if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)+            {+            reset_could_continue = TRUE;+            ADD_NEW_DATA(-(state_offset + 1), 0, 1);+            }+          else could_continue = partial_newline = TRUE;+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_DOLLM:+      if ((mb->moptions & PCRE2_NOTEOL) == 0)+        {+        if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)+          could_continue = TRUE;+        else if (clen == 0 ||+            ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))+          { ADD_ACTIVE(state_offset + 1, 0); }+        else if (ptr + 1 >= mb->end_subject &&+                 (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&+                 NLBLOCK->nltype == NLTYPE_FIXED &&+                 NLBLOCK->nllen == 2 &&+                 c == NLBLOCK->nl[0])+          {+          if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)+            {+            reset_could_continue = TRUE;+            ADD_NEW_DATA(-(state_offset + 1), 0, 1);+            }+          else could_continue = partial_newline = TRUE;+          }+        }+      else if (IS_NEWLINE(ptr))+        { ADD_ACTIVE(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/++      case OP_DIGIT:+      case OP_WHITESPACE:+      case OP_WORDCHAR:+      if (clen > 0 && c < 256 &&+            ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)+        { ADD_NEW(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_NOT_DIGIT:+      case OP_NOT_WHITESPACE:+      case OP_NOT_WORDCHAR:+      if (clen > 0 && (c >= 256 ||+            ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))+        { ADD_NEW(state_offset + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_WORD_BOUNDARY:+      case OP_NOT_WORD_BOUNDARY:+        {+        int left_word, right_word;++        if (ptr > start_subject)+          {+          PCRE2_SPTR temp = ptr - 1;+          if (temp < mb->start_used_ptr) mb->start_used_ptr = temp;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+          if (utf) { BACKCHAR(temp); }+#endif+          GETCHARTEST(d, temp);+#ifdef SUPPORT_UNICODE+          if ((mb->poptions & PCRE2_UCP) != 0)+            {+            if (d == '_') left_word = TRUE; else+              {+              uint32_t cat = UCD_CATEGORY(d);+              left_word = (cat == ucp_L || cat == ucp_N);+              }+            }+          else+#endif+          left_word = d < 256 && (ctypes[d] & ctype_word) != 0;+          }+        else left_word = FALSE;++        if (clen > 0)+          {+          if (ptr >= mb->last_used_ptr)+            {+            PCRE2_SPTR temp = ptr + 1;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+            if (utf) { FORWARDCHARTEST(temp, mb->end_subject); }+#endif+            mb->last_used_ptr = temp;+            }+#ifdef SUPPORT_UNICODE+          if ((mb->poptions & PCRE2_UCP) != 0)+            {+            if (c == '_') right_word = TRUE; else+              {+              uint32_t cat = UCD_CATEGORY(c);+              right_word = (cat == ucp_L || cat == ucp_N);+              }+            }+          else+#endif+          right_word = c < 256 && (ctypes[c] & ctype_word) != 0;+          }+        else right_word = FALSE;++        if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))+          { ADD_ACTIVE(state_offset + 1, 0); }+        }+      break;+++      /*-----------------------------------------------------------------*/+      /* 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.+      */++#ifdef SUPPORT_UNICODE+      case OP_PROP:+      case OP_NOTPROP:+      if (clen > 0)+        {+        BOOL OK;+        const uint32_t *cp;+        const ucd_record * prop = GET_UCD(c);+        switch(code[1])+          {+          case PT_ANY:+          OK = TRUE;+          break;++          case PT_LAMP:+          OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||+               prop->chartype == ucp_Lt;+          break;++          case PT_GC:+          OK = PRIV(ucp_gentype)[prop->chartype] == code[2];+          break;++          case PT_PC:+          OK = prop->chartype == code[2];+          break;++          case PT_SC:+          OK = prop->script == code[2];+          break;++          /* These are specials for combination cases. */++          case PT_ALNUM:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N;+          break;++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          switch(c)+            {+            HSPACE_CASES:+            VSPACE_CASES:+            OK = TRUE;+            break;++            default:+            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;+            break;+            }+          break;++          case PT_WORD:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||+               c == CHAR_UNDERSCORE;+          break;++          case PT_CLIST:+          cp = PRIV(ucd_caseless_sets) + code[2];+          for (;;)+            {+            if (c < *cp) { OK = FALSE; break; }+            if (c == *cp++) { OK = TRUE; break; }+            }+          break;++          case PT_UCNC:+          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||+               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||+               c >= 0xe000;+          break;++          /* Should never occur, but keep compilers from grumbling. */++          default:+          OK = codevalue != OP_PROP;+          break;+          }++        if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }+        }+      break;+#endif++++/* ========================================================================== */+      /* These opcodes likewise inspect the subject character, but have an+      argument that is not a data character. It is one of these opcodes:+      OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,+      OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */++      case OP_TYPEPLUS:+      case OP_TYPEMINPLUS:+      case OP_TYPEPOSPLUS:+      count = current_state->count;  /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }+      if (clen > 0)+        {+        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&+            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&+            NLBLOCK->nltype == NLTYPE_FIXED &&+            NLBLOCK->nllen == 2 &&+            c == NLBLOCK->nl[0])+          {+          could_continue = partial_newline = TRUE;+          }+        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||+            (c < 256 &&+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))+          {+          if (count > 0 && codevalue == OP_TYPEPOSPLUS)+            {+            active_count--;            /* Remove non-match possibility */+            next_active_state--;+            }+          count++;+          ADD_NEW(state_offset, count);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_TYPEQUERY:+      case OP_TYPEMINQUERY:+      case OP_TYPEPOSQUERY:+      ADD_ACTIVE(state_offset + 2, 0);+      if (clen > 0)+        {+        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&+            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&+            NLBLOCK->nltype == NLTYPE_FIXED &&+            NLBLOCK->nllen == 2 &&+            c == NLBLOCK->nl[0])+          {+          could_continue = partial_newline = TRUE;+          }+        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||+            (c < 256 &&+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))+          {+          if (codevalue == OP_TYPEPOSQUERY)+            {+            active_count--;            /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW(state_offset + 2, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_TYPESTAR:+      case OP_TYPEMINSTAR:+      case OP_TYPEPOSSTAR:+      ADD_ACTIVE(state_offset + 2, 0);+      if (clen > 0)+        {+        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&+            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&+            NLBLOCK->nltype == NLTYPE_FIXED &&+            NLBLOCK->nllen == 2 &&+            c == NLBLOCK->nl[0])+          {+          could_continue = partial_newline = TRUE;+          }+        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||+            (c < 256 &&+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))+          {+          if (codevalue == OP_TYPEPOSSTAR)+            {+            active_count--;            /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW(state_offset, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_TYPEEXACT:+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&+            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&+            NLBLOCK->nltype == NLTYPE_FIXED &&+            NLBLOCK->nllen == 2 &&+            c == NLBLOCK->nl[0])+          {+          could_continue = partial_newline = TRUE;+          }+        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||+            (c < 256 &&+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))+          {+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }+          else+            { ADD_NEW(state_offset, count); }+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_TYPEUPTO:+      case OP_TYPEMINUPTO:+      case OP_TYPEPOSUPTO:+      ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        if (d == OP_ANY && ptr + 1 >= mb->end_subject &&+            (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&+            NLBLOCK->nltype == NLTYPE_FIXED &&+            NLBLOCK->nllen == 2 &&+            c == NLBLOCK->nl[0])+          {+          could_continue = partial_newline = TRUE;+          }+        else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||+            (c < 256 &&+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))+          {+          if (codevalue == OP_TYPEPOSUPTO)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }+          else+            { ADD_NEW(state_offset, count); }+          }+        }+      break;++/* ========================================================================== */+      /* These are virtual opcodes that are used when something like+      OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its+      argument. It keeps the code above fast for the other cases. The argument+      is in the d variable. */++#ifdef SUPPORT_UNICODE+      case OP_PROP_EXTRA + OP_TYPEPLUS:+      case OP_PROP_EXTRA + OP_TYPEMINPLUS:+      case OP_PROP_EXTRA + OP_TYPEPOSPLUS:+      count = current_state->count;           /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }+      if (clen > 0)+        {+        BOOL OK;+        const uint32_t *cp;+        const ucd_record * prop = GET_UCD(c);+        switch(code[2])+          {+          case PT_ANY:+          OK = TRUE;+          break;++          case PT_LAMP:+          OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||+            prop->chartype == ucp_Lt;+          break;++          case PT_GC:+          OK = PRIV(ucp_gentype)[prop->chartype] == code[3];+          break;++          case PT_PC:+          OK = prop->chartype == code[3];+          break;++          case PT_SC:+          OK = prop->script == code[3];+          break;++          /* These are specials for combination cases. */++          case PT_ALNUM:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N;+          break;++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          switch(c)+            {+            HSPACE_CASES:+            VSPACE_CASES:+            OK = TRUE;+            break;++            default:+            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;+            break;+            }+          break;++          case PT_WORD:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||+               c == CHAR_UNDERSCORE;+          break;++          case PT_CLIST:+          cp = PRIV(ucd_caseless_sets) + code[3];+          for (;;)+            {+            if (c < *cp) { OK = FALSE; break; }+            if (c == *cp++) { OK = TRUE; break; }+            }+          break;++          case PT_UCNC:+          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||+               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||+               c >= 0xe000;+          break;++          /* Should never occur, but keep compilers from grumbling. */++          default:+          OK = codevalue != OP_PROP;+          break;+          }++        if (OK == (d == OP_PROP))+          {+          if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          count++;+          ADD_NEW(state_offset, count);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_EXTUNI_EXTRA + OP_TYPEPLUS:+      case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:+      case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:+      count = current_state->count;  /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }+      if (clen > 0)+        {+        int ncount = 0;+        if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)+          {+          active_count--;           /* Remove non-match possibility */+          next_active_state--;+          }+        (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,+          &ncount);+        count++;+        ADD_NEW_DATA(-state_offset, count, ncount);+        }+      break;+#endif++      /*-----------------------------------------------------------------*/+      case OP_ANYNL_EXTRA + OP_TYPEPLUS:+      case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:+      case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:+      count = current_state->count;  /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }+      if (clen > 0)+        {+        int ncount = 0;+        switch (c)+          {+          case CHAR_VT:+          case CHAR_FF:+          case CHAR_NEL:+#ifndef EBCDIC+          case 0x2028:+          case 0x2029:+#endif  /* Not EBCDIC */+          if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;+          goto ANYNL01;++          case CHAR_CR:+          if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;+          /* Fall through */++          ANYNL01:+          case CHAR_LF:+          if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          count++;+          ADD_NEW_DATA(-state_offset, count, ncount);+          break;++          default:+          break;+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_VSPACE_EXTRA + OP_TYPEPLUS:+      case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:+      case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:+      count = current_state->count;  /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }+      if (clen > 0)+        {+        BOOL OK;+        switch (c)+          {+          VSPACE_CASES:+          OK = TRUE;+          break;++          default:+          OK = FALSE;+          break;+          }++        if (OK == (d == OP_VSPACE))+          {+          if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          count++;+          ADD_NEW_DATA(-state_offset, count, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_HSPACE_EXTRA + OP_TYPEPLUS:+      case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:+      case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:+      count = current_state->count;  /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }+      if (clen > 0)+        {+        BOOL OK;+        switch (c)+          {+          HSPACE_CASES:+          OK = TRUE;+          break;++          default:+          OK = FALSE;+          break;+          }++        if (OK == (d == OP_HSPACE))+          {+          if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          count++;+          ADD_NEW_DATA(-state_offset, count, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+#ifdef SUPPORT_UNICODE+      case OP_PROP_EXTRA + OP_TYPEQUERY:+      case OP_PROP_EXTRA + OP_TYPEMINQUERY:+      case OP_PROP_EXTRA + OP_TYPEPOSQUERY:+      count = 4;+      goto QS1;++      case OP_PROP_EXTRA + OP_TYPESTAR:+      case OP_PROP_EXTRA + OP_TYPEMINSTAR:+      case OP_PROP_EXTRA + OP_TYPEPOSSTAR:+      count = 0;++      QS1:++      ADD_ACTIVE(state_offset + 4, 0);+      if (clen > 0)+        {+        BOOL OK;+        const uint32_t *cp;+        const ucd_record * prop = GET_UCD(c);+        switch(code[2])+          {+          case PT_ANY:+          OK = TRUE;+          break;++          case PT_LAMP:+          OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||+            prop->chartype == ucp_Lt;+          break;++          case PT_GC:+          OK = PRIV(ucp_gentype)[prop->chartype] == code[3];+          break;++          case PT_PC:+          OK = prop->chartype == code[3];+          break;++          case PT_SC:+          OK = prop->script == code[3];+          break;++          /* These are specials for combination cases. */++          case PT_ALNUM:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N;+          break;++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          switch(c)+            {+            HSPACE_CASES:+            VSPACE_CASES:+            OK = TRUE;+            break;++            default:+            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;+            break;+            }+          break;++          case PT_WORD:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||+               c == CHAR_UNDERSCORE;+          break;++          case PT_CLIST:+          cp = PRIV(ucd_caseless_sets) + code[3];+          for (;;)+            {+            if (c < *cp) { OK = FALSE; break; }+            if (c == *cp++) { OK = TRUE; break; }+            }+          break;++          case PT_UCNC:+          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||+               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||+               c >= 0xe000;+          break;++          /* Should never occur, but keep compilers from grumbling. */++          default:+          OK = codevalue != OP_PROP;+          break;+          }++        if (OK == (d == OP_PROP))+          {+          if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||+              codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW(state_offset + count, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_EXTUNI_EXTRA + OP_TYPEQUERY:+      case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:+      case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:+      count = 2;+      goto QS2;++      case OP_EXTUNI_EXTRA + OP_TYPESTAR:+      case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:+      case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:+      count = 0;++      QS2:++      ADD_ACTIVE(state_offset + 2, 0);+      if (clen > 0)+        {+        int ncount = 0;+        if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||+            codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)+          {+          active_count--;           /* Remove non-match possibility */+          next_active_state--;+          }+        (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,+          &ncount);+        ADD_NEW_DATA(-(state_offset + count), 0, ncount);+        }+      break;+#endif++      /*-----------------------------------------------------------------*/+      case OP_ANYNL_EXTRA + OP_TYPEQUERY:+      case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:+      case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:+      count = 2;+      goto QS3;++      case OP_ANYNL_EXTRA + OP_TYPESTAR:+      case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:+      case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:+      count = 0;++      QS3:+      ADD_ACTIVE(state_offset + 2, 0);+      if (clen > 0)+        {+        int ncount = 0;+        switch (c)+          {+          case CHAR_VT:+          case CHAR_FF:+          case CHAR_NEL:+#ifndef EBCDIC+          case 0x2028:+          case 0x2029:+#endif  /* Not EBCDIC */+          if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;+          goto ANYNL02;++          case CHAR_CR:+          if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;+          /* Fall through */++          ANYNL02:+          case CHAR_LF:+          if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||+              codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount);+          break;++          default:+          break;+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_VSPACE_EXTRA + OP_TYPEQUERY:+      case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:+      case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:+      count = 2;+      goto QS4;++      case OP_VSPACE_EXTRA + OP_TYPESTAR:+      case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:+      case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:+      count = 0;++      QS4:+      ADD_ACTIVE(state_offset + 2, 0);+      if (clen > 0)+        {+        BOOL OK;+        switch (c)+          {+          VSPACE_CASES:+          OK = TRUE;+          break;++          default:+          OK = FALSE;+          break;+          }+        if (OK == (d == OP_VSPACE))+          {+          if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||+              codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_HSPACE_EXTRA + OP_TYPEQUERY:+      case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:+      case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:+      count = 2;+      goto QS5;++      case OP_HSPACE_EXTRA + OP_TYPESTAR:+      case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:+      case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:+      count = 0;++      QS5:+      ADD_ACTIVE(state_offset + 2, 0);+      if (clen > 0)+        {+        BOOL OK;+        switch (c)+          {+          HSPACE_CASES:+          OK = TRUE;+          break;++          default:+          OK = FALSE;+          break;+          }++        if (OK == (d == OP_HSPACE))+          {+          if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||+              codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+#ifdef SUPPORT_UNICODE+      case OP_PROP_EXTRA + OP_TYPEEXACT:+      case OP_PROP_EXTRA + OP_TYPEUPTO:+      case OP_PROP_EXTRA + OP_TYPEMINUPTO:+      case OP_PROP_EXTRA + OP_TYPEPOSUPTO:+      if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)+        { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        BOOL OK;+        const uint32_t *cp;+        const ucd_record * prop = GET_UCD(c);+        switch(code[1 + IMM2_SIZE + 1])+          {+          case PT_ANY:+          OK = TRUE;+          break;++          case PT_LAMP:+          OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||+            prop->chartype == ucp_Lt;+          break;++          case PT_GC:+          OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];+          break;++          case PT_PC:+          OK = prop->chartype == code[1 + IMM2_SIZE + 2];+          break;++          case PT_SC:+          OK = prop->script == code[1 + IMM2_SIZE + 2];+          break;++          /* These are specials for combination cases. */++          case PT_ALNUM:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N;+          break;++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          switch(c)+            {+            HSPACE_CASES:+            VSPACE_CASES:+            OK = TRUE;+            break;++            default:+            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;+            break;+            }+          break;++          case PT_WORD:+          OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||+               c == CHAR_UNDERSCORE;+          break;++          case PT_CLIST:+          cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];+          for (;;)+            {+            if (c < *cp) { OK = FALSE; break; }+            if (c == *cp++) { OK = TRUE; break; }+            }+          break;++          case PT_UCNC:+          OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||+               c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||+               c >= 0xe000;+          break;++          /* Should never occur, but keep compilers from grumbling. */++          default:+          OK = codevalue != OP_PROP;+          break;+          }++        if (OK == (d == OP_PROP))+          {+          if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }+          else+            { ADD_NEW(state_offset, count); }+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_EXTUNI_EXTRA + OP_TYPEEXACT:+      case OP_EXTUNI_EXTRA + OP_TYPEUPTO:+      case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:+      case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:+      if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)+        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        PCRE2_SPTR nptr;+        int ncount = 0;+        if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)+          {+          active_count--;           /* Remove non-match possibility */+          next_active_state--;+          }+        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))+          { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }+        else+          { ADD_NEW_DATA(-state_offset, count, ncount); }+        }+      break;+#endif++      /*-----------------------------------------------------------------*/+      case OP_ANYNL_EXTRA + OP_TYPEEXACT:+      case OP_ANYNL_EXTRA + OP_TYPEUPTO:+      case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:+      case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:+      if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)+        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        int ncount = 0;+        switch (c)+          {+          case CHAR_VT:+          case CHAR_FF:+          case CHAR_NEL:+#ifndef EBCDIC+          case 0x2028:+          case 0x2029:+#endif  /* Not EBCDIC */+          if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;+          goto ANYNL03;++          case CHAR_CR:+          if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;+          /* Fall through */++          ANYNL03:+          case CHAR_LF:+          if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }+          else+            { ADD_NEW_DATA(-state_offset, count, ncount); }+          break;++          default:+          break;+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_VSPACE_EXTRA + OP_TYPEEXACT:+      case OP_VSPACE_EXTRA + OP_TYPEUPTO:+      case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:+      case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:+      if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)+        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        BOOL OK;+        switch (c)+          {+          VSPACE_CASES:+          OK = TRUE;+          break;++          default:+          OK = FALSE;+          }++        if (OK == (d == OP_VSPACE))+          {+          if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }+          else+            { ADD_NEW_DATA(-state_offset, count, 0); }+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_HSPACE_EXTRA + OP_TYPEEXACT:+      case OP_HSPACE_EXTRA + OP_TYPEUPTO:+      case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:+      case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:+      if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)+        { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        BOOL OK;+        switch (c)+          {+          HSPACE_CASES:+          OK = TRUE;+          break;++          default:+          OK = FALSE;+          break;+          }++        if (OK == (d == OP_HSPACE))+          {+          if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)+            {+            active_count--;           /* Remove non-match possibility */+            next_active_state--;+            }+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }+          else+            { ADD_NEW_DATA(-state_offset, count, 0); }+          }+        }+      break;++/* ========================================================================== */+      /* These opcodes are followed by a character that is usually compared+      to the current subject character; it is loaded into d. We still get+      here even if there is no subject character, because in some cases zero+      repetitions are permitted. */++      /*-----------------------------------------------------------------*/+      case OP_CHAR:+      if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      case OP_CHARI:+      if (clen == 0) break;++#ifdef SUPPORT_UNICODE+      if (utf_or_ucp)+        {+        if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else+          {+          unsigned int othercase;+          if (c < 128)+            othercase = fcc[c];+          else+            othercase = UCD_OTHERCASE(c);+          if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }+          }+        }+      else+#endif  /* SUPPORT_UNICODE */+      /* Not UTF or UCP mode */+        {+        if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))+          { ADD_NEW(state_offset + 2, 0); }+        }+      break;+++#ifdef SUPPORT_UNICODE+      /*-----------------------------------------------------------------*/+      /* This is a tricky one because it can match more than one character.+      Find out how many characters to skip, and then set up a negative state+      to wait for them to pass before continuing. */++      case OP_EXTUNI:+      if (clen > 0)+        {+        int ncount = 0;+        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);+        }+      break;+#endif++      /*-----------------------------------------------------------------*/+      /* This is a tricky like EXTUNI because it too can match more than one+      character (when CR is followed by LF). In this case, set up a negative+      state to wait for one character to pass before continuing. */++      case OP_ANYNL:+      if (clen > 0) switch(c)+        {+        case CHAR_VT:+        case CHAR_FF:+        case CHAR_NEL:+#ifndef EBCDIC+        case 0x2028:+        case 0x2029:+#endif  /* Not EBCDIC */+        if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;+        /* Fall through */++        case CHAR_LF:+        ADD_NEW(state_offset + 1, 0);+        break;++        case CHAR_CR:+        if (ptr + 1 >= end_subject)+          {+          ADD_NEW(state_offset + 1, 0);+          if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)+            reset_could_continue = TRUE;+          }+        else if (UCHAR21TEST(ptr + 1) == CHAR_LF)+          {+          ADD_NEW_DATA(-(state_offset + 1), 0, 1);+          }+        else+          {+          ADD_NEW(state_offset + 1, 0);+          }+        break;+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_NOT_VSPACE:+      if (clen > 0) switch(c)+        {+        VSPACE_CASES:+        break;++        default:+        ADD_NEW(state_offset + 1, 0);+        break;+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_VSPACE:+      if (clen > 0) switch(c)+        {+        VSPACE_CASES:+        ADD_NEW(state_offset + 1, 0);+        break;++        default:+        break;+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_NOT_HSPACE:+      if (clen > 0) switch(c)+        {+        HSPACE_CASES:+        break;++        default:+        ADD_NEW(state_offset + 1, 0);+        break;+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_HSPACE:+      if (clen > 0) switch(c)+        {+        HSPACE_CASES:+        ADD_NEW(state_offset + 1, 0);+        break;++        default:+        break;+        }+      break;++      /*-----------------------------------------------------------------*/+      /* Match a negated single character casefully. */++      case OP_NOT:+      if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }+      break;++      /*-----------------------------------------------------------------*/+      /* Match a negated single character caselessly. */++      case OP_NOTI:+      if (clen > 0)+        {+        uint32_t otherd;+#ifdef SUPPORT_UNICODE+        if (utf_or_ucp && d >= 128)+          otherd = UCD_OTHERCASE(d);+        else+#endif  /* SUPPORT_UNICODE */+        otherd = TABLE_GET(d, fcc, d);+        if (c != d && c != otherd)+          { ADD_NEW(state_offset + dlen + 1, 0); }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_PLUSI:+      case OP_MINPLUSI:+      case OP_POSPLUSI:+      case OP_NOTPLUSI:+      case OP_NOTMINPLUSI:+      case OP_NOTPOSPLUSI:+      caseless = TRUE;+      codevalue -= OP_STARI - OP_STAR;++      /* Fall through */+      case OP_PLUS:+      case OP_MINPLUS:+      case OP_POSPLUS:+      case OP_NOTPLUS:+      case OP_NOTMINPLUS:+      case OP_NOTPOSPLUS:+      count = current_state->count;  /* Already matched */+      if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }+      if (clen > 0)+        {+        uint32_t otherd = NOTACHAR;+        if (caseless)+          {+#ifdef SUPPORT_UNICODE+          if (utf_or_ucp && d >= 128)+            otherd = UCD_OTHERCASE(d);+          else+#endif  /* SUPPORT_UNICODE */+          otherd = TABLE_GET(d, fcc, d);+          }+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))+          {+          if (count > 0 &&+              (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))+            {+            active_count--;             /* Remove non-match possibility */+            next_active_state--;+            }+          count++;+          ADD_NEW(state_offset, count);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_QUERYI:+      case OP_MINQUERYI:+      case OP_POSQUERYI:+      case OP_NOTQUERYI:+      case OP_NOTMINQUERYI:+      case OP_NOTPOSQUERYI:+      caseless = TRUE;+      codevalue -= OP_STARI - OP_STAR;+      /* Fall through */+      case OP_QUERY:+      case OP_MINQUERY:+      case OP_POSQUERY:+      case OP_NOTQUERY:+      case OP_NOTMINQUERY:+      case OP_NOTPOSQUERY:+      ADD_ACTIVE(state_offset + dlen + 1, 0);+      if (clen > 0)+        {+        uint32_t otherd = NOTACHAR;+        if (caseless)+          {+#ifdef SUPPORT_UNICODE+          if (utf_or_ucp && d >= 128)+            otherd = UCD_OTHERCASE(d);+          else+#endif  /* SUPPORT_UNICODE */+          otherd = TABLE_GET(d, fcc, d);+          }+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))+          {+          if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)+            {+            active_count--;            /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW(state_offset + dlen + 1, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_STARI:+      case OP_MINSTARI:+      case OP_POSSTARI:+      case OP_NOTSTARI:+      case OP_NOTMINSTARI:+      case OP_NOTPOSSTARI:+      caseless = TRUE;+      codevalue -= OP_STARI - OP_STAR;+      /* Fall through */+      case OP_STAR:+      case OP_MINSTAR:+      case OP_POSSTAR:+      case OP_NOTSTAR:+      case OP_NOTMINSTAR:+      case OP_NOTPOSSTAR:+      ADD_ACTIVE(state_offset + dlen + 1, 0);+      if (clen > 0)+        {+        uint32_t otherd = NOTACHAR;+        if (caseless)+          {+#ifdef SUPPORT_UNICODE+          if (utf_or_ucp && d >= 128)+            otherd = UCD_OTHERCASE(d);+          else+#endif  /* SUPPORT_UNICODE */+          otherd = TABLE_GET(d, fcc, d);+          }+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))+          {+          if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)+            {+            active_count--;            /* Remove non-match possibility */+            next_active_state--;+            }+          ADD_NEW(state_offset, 0);+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_EXACTI:+      case OP_NOTEXACTI:+      caseless = TRUE;+      codevalue -= OP_STARI - OP_STAR;+      /* Fall through */+      case OP_EXACT:+      case OP_NOTEXACT:+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        uint32_t otherd = NOTACHAR;+        if (caseless)+          {+#ifdef SUPPORT_UNICODE+          if (utf_or_ucp && d >= 128)+            otherd = UCD_OTHERCASE(d);+          else+#endif  /* SUPPORT_UNICODE */+          otherd = TABLE_GET(d, fcc, d);+          }+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))+          {+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }+          else+            { ADD_NEW(state_offset, count); }+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_UPTOI:+      case OP_MINUPTOI:+      case OP_POSUPTOI:+      case OP_NOTUPTOI:+      case OP_NOTMINUPTOI:+      case OP_NOTPOSUPTOI:+      caseless = TRUE;+      codevalue -= OP_STARI - OP_STAR;+      /* Fall through */+      case OP_UPTO:+      case OP_MINUPTO:+      case OP_POSUPTO:+      case OP_NOTUPTO:+      case OP_NOTMINUPTO:+      case OP_NOTPOSUPTO:+      ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);+      count = current_state->count;  /* Number already matched */+      if (clen > 0)+        {+        uint32_t otherd = NOTACHAR;+        if (caseless)+          {+#ifdef SUPPORT_UNICODE+          if (utf_or_ucp && d >= 128)+            otherd = UCD_OTHERCASE(d);+          else+#endif  /* SUPPORT_UNICODE */+          otherd = TABLE_GET(d, fcc, d);+          }+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))+          {+          if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)+            {+            active_count--;             /* Remove non-match possibility */+            next_active_state--;+            }+          if (++count >= (int)GET2(code, 1))+            { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }+          else+            { ADD_NEW(state_offset, count); }+          }+        }+      break;+++/* ========================================================================== */+      /* These are the class-handling opcodes */++      case OP_CLASS:+      case OP_NCLASS:+      case OP_XCLASS:+        {+        BOOL isinclass = FALSE;+        int next_state_offset;+        PCRE2_SPTR ecode;++        /* For a simple class, there is always just a 32-byte table, and we+        can set isinclass from it. */++        if (codevalue != OP_XCLASS)+          {+          ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR));+          if (clen > 0)+            {+            isinclass = (c > 255)? (codevalue == OP_NCLASS) :+              ((((uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0);+            }+          }++        /* An extended class may have a table or a list of single characters,+        ranges, or both, and it may be positive or negative. There's a+        function that sorts all this out. */++        else+         {+         ecode = code + GET(code, 1);+         if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);+         }++        /* At this point, isinclass is set for all kinds of class, and ecode+        points to the byte after the end of the class. If there is a+        quantifier, this is where it will be. */++        next_state_offset = (int)(ecode - start_code);++        switch (*ecode)+          {+          case OP_CRSTAR:+          case OP_CRMINSTAR:+          case OP_CRPOSSTAR:+          ADD_ACTIVE(next_state_offset + 1, 0);+          if (isinclass)+            {+            if (*ecode == OP_CRPOSSTAR)+              {+              active_count--;           /* Remove non-match possibility */+              next_active_state--;+              }+            ADD_NEW(state_offset, 0);+            }+          break;++          case OP_CRPLUS:+          case OP_CRMINPLUS:+          case OP_CRPOSPLUS:+          count = current_state->count;  /* Already matched */+          if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }+          if (isinclass)+            {+            if (count > 0 && *ecode == OP_CRPOSPLUS)+              {+              active_count--;           /* Remove non-match possibility */+              next_active_state--;+              }+            count++;+            ADD_NEW(state_offset, count);+            }+          break;++          case OP_CRQUERY:+          case OP_CRMINQUERY:+          case OP_CRPOSQUERY:+          ADD_ACTIVE(next_state_offset + 1, 0);+          if (isinclass)+            {+            if (*ecode == OP_CRPOSQUERY)+              {+              active_count--;           /* Remove non-match possibility */+              next_active_state--;+              }+            ADD_NEW(next_state_offset + 1, 0);+            }+          break;++          case OP_CRRANGE:+          case OP_CRMINRANGE:+          case OP_CRPOSRANGE:+          count = current_state->count;  /* Already matched */+          if (count >= (int)GET2(ecode, 1))+            { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }+          if (isinclass)+            {+            int max = (int)GET2(ecode, 1 + IMM2_SIZE);++            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+              { ADD_NEW(state_offset, count); }+            }+          break;++          default:+          if (isinclass) { ADD_NEW(next_state_offset, 0); }+          break;+          }+        }+      break;++/* ========================================================================== */+      /* These are the opcodes for fancy brackets of various kinds. We have+      to use recursion in order to handle them. The "always failing" assertion+      (?!) is optimised to OP_FAIL when compiling, so we have to support that,+      though the other "backtracking verbs" are not supported. */++      case OP_FAIL:+      forced_fail++;    /* Count FAILs for multiple states */+      break;++      case OP_ASSERT:+      case OP_ASSERT_NOT:+      case OP_ASSERTBACK:+      case OP_ASSERTBACK_NOT:+        {+        int rc;+        int *local_workspace;+        PCRE2_SIZE *local_offsets;+        PCRE2_SPTR endasscode = code + GET(code, 1);+        RWS_anchor *rws = (RWS_anchor *)RWS;++        if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)+          {+          rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);+          if (rc != 0) return rc;+          RWS = (int *)rws;+          }++        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);+        local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;+        rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;++        while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);++        rc = internal_dfa_match(+          mb,                                   /* static match data */+          code,                                 /* this subexpression's code */+          ptr,                                  /* where we currently are */+          (PCRE2_SIZE)(ptr - start_subject),    /* start offset */+          local_offsets,                        /* offset vector */+          RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */+          local_workspace,                      /* workspace vector */+          RWS_RSIZE,                            /* size of same */+          rlevel,                               /* function recursion level */+          RWS);                                 /* recursion workspace */++        rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;++        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); }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_COND:+      case OP_SCOND:+        {+        int codelink = (int)GET(code, 1);+        PCRE2_UCHAR condcode;++        /* Because of the way auto-callout works during compile, a callout item+        is inserted between OP_COND and an assertion condition. This does not+        happen for the other conditions. */++        if (code[LINK_SIZE + 1] == OP_CALLOUT+            || code[LINK_SIZE + 1] == OP_CALLOUT_STR)+          {+          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 */+          }++        condcode = code[LINK_SIZE+1];++        /* Back reference conditions and duplicate named recursion conditions+        are not supported */++        if (condcode == OP_CREF || condcode == OP_DNCREF ||+            condcode == OP_DNRREF)+          return PCRE2_ERROR_DFA_UCOND;++        /* The DEFINE condition is always false, and the assertion (?!) is+        converted to OP_FAIL. */++        if (condcode == OP_FALSE || condcode == OP_FAIL)+          { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }++        /* There is also an always-true condition */++        else if (condcode == OP_TRUE)+          { ADD_ACTIVE(state_offset + LINK_SIZE + 2, 0); }++        /* The only supported version of OP_RREF is for the value RREF_ANY,+        which means "test if in any recursion". We can't test for specifically+        recursed groups. */++        else if (condcode == OP_RREF)+          {+          unsigned int value = GET2(code, LINK_SIZE + 2);+          if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND;+          if (mb->recursive != NULL)+            { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }+          else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }+          }++        /* Otherwise, the condition is an assertion */++        else+          {+          int rc;+          int *local_workspace;+          PCRE2_SIZE *local_offsets;+          PCRE2_SPTR asscode = code + LINK_SIZE + 1;+          PCRE2_SPTR endasscode = asscode + GET(asscode, 1);+          RWS_anchor *rws = (RWS_anchor *)RWS;++          if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)+            {+            rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);+            if (rc != 0) return rc;+            RWS = (int *)rws;+            }++          local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);+          local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;+          rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;++          while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);++          rc = internal_dfa_match(+            mb,                                   /* fixed match data */+            asscode,                              /* this subexpression's code */+            ptr,                                  /* where we currently are */+            (PCRE2_SIZE)(ptr - start_subject),    /* start offset */+            local_offsets,                        /* offset vector */+            RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */+            local_workspace,                      /* workspace vector */+            RWS_RSIZE,                            /* size of same */+            rlevel,                               /* function recursion level */+            RWS);                                 /* recursion workspace */++          rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;++          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); }+          else+            { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_RECURSE:+        {+        int rc;+        int *local_workspace;+        PCRE2_SIZE *local_offsets;+        RWS_anchor *rws = (RWS_anchor *)RWS;+        dfa_recursion_info *ri;+        PCRE2_SPTR callpat = start_code + GET(code, 1);+        uint32_t recno = (callpat == mb->start_code)? 0 :+          GET2(callpat, 1 + LINK_SIZE);++        if (rws->free < RWS_RSIZE + RWS_OVEC_RSIZE)+          {+          rc = more_workspace(&rws, RWS_OVEC_RSIZE, mb);+          if (rc != 0) return rc;+          RWS = (int *)rws;+          }++        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);+        local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE;+        rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;++        /* Check for repeating a 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 && ptr == ri->subject_position)+            return PCRE2_ERROR_RECURSELOOP;++        /* Remember this recursion and where we started it so as to+        catch infinite loops. */++        new_recursive.group_num = recno;+        new_recursive.subject_position = ptr;+        new_recursive.prevrec = mb->recursive;+        mb->recursive = &new_recursive;++        rc = internal_dfa_match(+          mb,                                   /* fixed match data */+          callpat,                              /* this subexpression's code */+          ptr,                                  /* where we currently are */+          (PCRE2_SIZE)(ptr - start_subject),    /* start offset */+          local_offsets,                        /* offset vector */+          RWS_OVEC_RSIZE/OVEC_UNIT,             /* size of same */+          local_workspace,                      /* workspace vector */+          RWS_RSIZE,                            /* size of same */+          rlevel,                               /* function recursion level */+          RWS);                                 /* recursion workspace */++        rws->free += RWS_RSIZE + RWS_OVEC_RSIZE;+        mb->recursive = new_recursive.prevrec;  /* Done this recursion */++        /* Ran out of internal offsets */++        if (rc == 0) return PCRE2_ERROR_DFA_RECURSE;++        /* For each successful matched substring, set up the next state with a+        count of characters to skip before trying it. Note that the count is in+        characters, not bytes. */++        if (rc > 0)+          {+          for (rc = rc*2 - 2; rc >= 0; rc -= 2)+            {+            PCRE2_SIZE charcount = local_offsets[rc+1] - local_offsets[rc];+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+            if (utf)+              {+              PCRE2_SPTR p = start_subject + local_offsets[rc];+              PCRE2_SPTR pp = start_subject + local_offsets[rc+1];+              while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;+              }+#endif+            if (charcount > 0)+              {+              ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0,+                (int)(charcount - 1));+              }+            else+              {+              ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);+              }+            }+          }+        else if (rc != PCRE2_ERROR_NOMATCH) return rc;+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_BRAPOS:+      case OP_SBRAPOS:+      case OP_CBRAPOS:+      case OP_SCBRAPOS:+      case OP_BRAPOSZERO:+        {+        int rc;+        int *local_workspace;+        PCRE2_SIZE *local_offsets;+        PCRE2_SIZE charcount, matched_count;+        PCRE2_SPTR local_ptr = ptr;+        RWS_anchor *rws = (RWS_anchor *)RWS;+        BOOL allow_zero;++        if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)+          {+          rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);+          if (rc != 0) return rc;+          RWS = (int *)rws;+          }++        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);+        local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;+        rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;++        if (codevalue == OP_BRAPOSZERO)+          {+          allow_zero = TRUE;+          codevalue = *(++code);  /* Codevalue will be one of above BRAs */+          }+        else allow_zero = FALSE;++        /* Loop to match the subpattern as many times as possible as if it were+        a complete pattern. */++        for (matched_count = 0;; matched_count++)+          {+          rc = internal_dfa_match(+            mb,                                   /* fixed match data */+            code,                                 /* this subexpression's code */+            local_ptr,                            /* where we currently are */+            (PCRE2_SIZE)(ptr - start_subject),    /* start offset */+            local_offsets,                        /* offset vector */+            RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */+            local_workspace,                      /* workspace vector */+            RWS_RSIZE,                            /* size of same */+            rlevel,                               /* function recursion level */+            RWS);                                 /* recursion workspace */++          /* Failed to match */++          if (rc < 0)+            {+            if (rc != PCRE2_ERROR_NOMATCH) return rc;+            break;+            }++          /* Matched: break the loop if zero characters matched. */++          charcount = local_offsets[1] - local_offsets[0];+          if (charcount == 0) break;+          local_ptr += charcount;    /* Advance temporary position ptr */+          }++        rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;++        /* At this point we have matched the subpattern matched_count+        times, and local_ptr is pointing to the character after the end of the+        last match. */++        if (matched_count > 0 || allow_zero)+          {+          PCRE2_SPTR end_subpattern = code;+          int next_state_offset;++          do { end_subpattern += GET(end_subpattern, 1); }+            while (*end_subpattern == OP_ALT);+          next_state_offset =+            (int)(end_subpattern - start_code + LINK_SIZE + 1);++          /* Optimization: if there are no more active states, and there+          are no new states yet set up, then skip over the subject string+          right here, to save looping. Otherwise, set up the new state to swing+          into action when the end of the matched substring is reached. */++          if (i + 1 >= active_count && new_count == 0)+            {+            ptr = local_ptr;+            clen = 0;+            ADD_NEW(next_state_offset, 0);+            }+          else+            {+            PCRE2_SPTR p = ptr;+            PCRE2_SPTR pp = local_ptr;+            charcount = (PCRE2_SIZE)(pp - p);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+            if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;+#endif+            ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));+            }+          }+        }+      break;++      /*-----------------------------------------------------------------*/+      case OP_ONCE:+        {+        int rc;+        int *local_workspace;+        PCRE2_SIZE *local_offsets;+        RWS_anchor *rws = (RWS_anchor *)RWS;++        if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)+          {+          rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);+          if (rc != 0) return rc;+          RWS = (int *)rws;+          }++        local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);+        local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;+        rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;++        rc = internal_dfa_match(+          mb,                                   /* fixed match data */+          code,                                 /* this subexpression's code */+          ptr,                                  /* where we currently are */+          (PCRE2_SIZE)(ptr - start_subject),    /* start offset */+          local_offsets,                        /* offset vector */+          RWS_OVEC_OSIZE/OVEC_UNIT,             /* size of same */+          local_workspace,                      /* workspace vector */+          RWS_RSIZE,                            /* size of same */+          rlevel,                               /* function recursion level */+          RWS);                                 /* recursion workspace */++        rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;++        if (rc >= 0)+          {+          PCRE2_SPTR end_subpattern = code;+          PCRE2_SIZE charcount = local_offsets[1] - local_offsets[0];+          int next_state_offset, repeat_state_offset;++          do { end_subpattern += GET(end_subpattern, 1); }+            while (*end_subpattern == OP_ALT);+          next_state_offset =+            (int)(end_subpattern - start_code + LINK_SIZE + 1);++          /* If the end of this subpattern is KETRMAX or KETRMIN, we must+          arrange for the repeat state also to be added to the relevant list.+          Calculate the offset, or set -1 for no repeat. */++          repeat_state_offset = (*end_subpattern == OP_KETRMAX ||+                                 *end_subpattern == OP_KETRMIN)?+            (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;++          /* If we have matched an empty string, add the next state at the+          current character pointer. This is important so that the duplicate+          checking kicks in, which is what breaks infinite loops that match an+          empty string. */++          if (charcount == 0)+            {+            ADD_ACTIVE(next_state_offset, 0);+            }++          /* Optimization: if there are no more active states, and there+          are no new states yet set up, then skip over the subject string+          right here, to save looping. Otherwise, set up the new state to swing+          into action when the end of the matched substring is reached. */++          else if (i + 1 >= active_count && new_count == 0)+            {+            ptr += charcount;+            clen = 0;+            ADD_NEW(next_state_offset, 0);++            /* If we are adding a repeat state at the new character position,+            we must fudge things so that it is the only current state.+            Otherwise, it might be a duplicate of one we processed before, and+            that would cause it to be skipped. */++            if (repeat_state_offset >= 0)+              {+              next_active_state = active_states;+              active_count = 0;+              i = -1;+              ADD_ACTIVE(repeat_state_offset, 0);+              }+            }+          else+            {+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+            if (utf)+              {+              PCRE2_SPTR p = start_subject + local_offsets[0];+              PCRE2_SPTR pp = start_subject + local_offsets[1];+              while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;+              }+#endif+            ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));+            if (repeat_state_offset >= 0)+              { ADD_NEW_DATA(-repeat_state_offset, 0, (int)(charcount - 1)); }+            }+          }+        else if (rc != PCRE2_ERROR_NOMATCH) return rc;+        }+      break;+++/* ========================================================================== */+      /* Handle callouts */++      case OP_CALLOUT:+      case OP_CALLOUT_STR:+        {+        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); }+        }+      break;+++/* ========================================================================== */+      default:        /* Unsupported opcode */+      return PCRE2_ERROR_DFA_UITEM;+      }++    NEXT_ACTIVE_STATE: continue;++    }      /* End of loop scanning active states */++  /* We have finished the processing at the current subject character. If no+  new states have been set for the next character, we have found all the+  matches that we are going to find. If partial matching has been requested,+  check for appropriate conditions.++  The "forced_ fail" variable counts the number of (*F) encountered for the+  character. If it is equal to the original active_count (saved in+  workspace[1]) it means that (*F) was found on every active state. In this+  case we don't want to give a partial match.++  The "could_continue" variable is true if a state could have continued but+  for the fact that the end of the subject was reached. */++  if (new_count <= 0)+    {+    if (could_continue &&                            /* Some could go on, and */+        forced_fail != workspace[1] &&               /* Not all forced fail & */+        (                                            /* either... */+        (mb->moptions & PCRE2_PARTIAL_HARD) != 0      /* Hard partial */+        ||                                           /* or... */+        ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 &&  /* Soft partial and */+         match_count < 0)                             /* no matches */+        ) &&                                         /* And... */+        (+        partial_newline ||                   /* Either partial NL */+          (                                  /* or ... */+          ptr >= end_subject &&              /* End of subject and */+            (                                  /* either */+            ptr > mb->start_used_ptr ||        /* Inspected non-empty string */+            mb->allowemptypartial              /* or pattern has lookbehind */+            )                                  /* or could match empty */+          )+        ))+      match_count = PCRE2_ERROR_PARTIAL;+    break;  /* Exit from loop along the subject string */+    }++  /* One or more states are active for the next character. */++  ptr += clen;    /* Advance to next subject character */+  }               /* Loop to move along the subject string */++/* 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;+}++++/*************************************************+*     Match a pattern using the DFA algorithm    *+*************************************************/++/* This function matches a compiled pattern to a subject string, using the+alternate matching algorithm that finds all matches at once.++Arguments:+  code          points to the compiled pattern+  subject       subject string+  length        length of subject string+  startoffset   where to start matching in the subject+  options       option bits+  match_data    points to a match data structure+  gcontext      points to a match context+  workspace     pointer to workspace+  wscount       size of workspace++Returns:        > 0 => number of match offset pairs placed in offsets+                = 0 => offsets overflowed; longest matches are present+                 -1 => failed to match+               < -1 => some kind of unexpected problem+*/++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, PCRE2_SIZE wscount)+{+int rc;+int was_zero_terminated = 0;++const pcre2_real_code *re = (const pcre2_real_code *)code;++PCRE2_SPTR start_match;+PCRE2_SPTR end_subject;+PCRE2_SPTR bumpalong_limit;+PCRE2_SPTR req_cu_ptr;++BOOL utf, anchored, startline, firstline;+BOOL has_first_cu = FALSE;+BOOL has_req_cu = FALSE;++#if PCRE2_CODE_UNIT_WIDTH == 8+BOOL memchr_not_found_first_cu = FALSE;+BOOL memchr_not_found_first_cu2 = FALSE;+#endif++PCRE2_UCHAR first_cu = 0;+PCRE2_UCHAR first_cu2 = 0;+PCRE2_UCHAR req_cu = 0;+PCRE2_UCHAR req_cu2 = 0;++const uint8_t *start_bits = 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_callout_block cb;+dfa_match_block actual_match_block;+dfa_match_block *mb = &actual_match_block;++/* Set up a starting block of memory for use during recursive calls to+internal_dfa_match(). By putting this on the stack, it minimizes resource use+in the case when it is not needed. If this is too small, more memory is+obtained from the heap. At the start of each block is an anchor structure.*/++int base_recursion_workspace[RWS_BASE_SIZE];+RWS_anchor *rws = (RWS_anchor *)base_recursion_workspace;+rws->next = NULL;+rws->size = RWS_BASE_SIZE;+rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE;++/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated+subject string. */++if (length == PCRE2_ZERO_TERMINATED)+  {+  length = PRIV(strlen)(subject);+  was_zero_terminated = 1;+  }++/* Plausibility checks */++if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;+if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)+  return PCRE2_ERROR_NULL;+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;++/* Invalid UTF support is not available for DFA matching. */++if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)+  return PCRE2_ERROR_DFA_UINVALID_UTF;++/* Check that the first field in the block is the magic number. If it is not,+return with PCRE2_ERROR_BADMAGIC. */++if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;++/* Check the code unit width. */++if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)+  return PCRE2_ERROR_BADMODE;++/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the+options variable for this function. Users of PCRE2 who are not calling the+function directly would like to have a way of setting these flags, in the same+way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with+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+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+occur. */++#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)+#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)+options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));+#undef FF+#undef OO++/* If restarting after a partial match, do some sanity checks on the contents+of the workspace. */++if ((options & PCRE2_DFA_RESTART) != 0)+  {+  if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||+    workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))+      return PCRE2_ERROR_DFA_BADRESTART;+  }++/* Set some local values */++utf = (re->overall_options & PCRE2_UTF) != 0;+start_match = subject + start_offset;+end_subject = subject + length;+req_cu_ptr = start_match - 1;+anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 ||+  (re->overall_options & PCRE2_ANCHORED) != 0;++/* The "must be at the start of a line" flags are used in a loop when finding+where to start. */++startline = (re->flags & PCRE2_STARTLINE) != 0;+firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;+bumpalong_limit = end_subject;++/* 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;+  mb->heap_limit = PRIV(default_match_context).heap_limit;+  }+else+  {+  if (mcontext->offset_limit != PCRE2_UNSET)+    {+    if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)+      return PCRE2_ERROR_BADOFFSETLIMIT;+    bumpalong_limit = subject + mcontext->offset_limit;+    }+  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;+  mb->heap_limit = mcontext->heap_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;++if (mb->heap_limit > re->limit_heap)+  mb->heap_limit = re->limit_heap;++mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) ++  re->name_count * re->name_entry_size;+mb->tables = re->tables;+mb->start_subject = subject;+mb->end_subject = end_subject;+mb->start_offset = start_offset;+mb->allowemptypartial = (re->max_lookbehind > 0) ||+  (re->flags & PCRE2_MATCH_EMPTY) != 0;+mb->moptions = options;+mb->poptions = re->overall_options;+mb->match_call_count = 0;+mb->heap_used = 0;++/* Process the \R and newline settings. */++mb->bsr_convention = re->bsr_convention;+mb->nltype = NLTYPE_FIXED;+switch(re->newline_convention)+  {+  case PCRE2_NEWLINE_CR:+  mb->nllen = 1;+  mb->nl[0] = CHAR_CR;+  break;++  case PCRE2_NEWLINE_LF:+  mb->nllen = 1;+  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;+  mb->nl[1] = CHAR_NL;+  break;++  case PCRE2_NEWLINE_ANY:+  mb->nltype = NLTYPE_ANY;+  break;++  case PCRE2_NEWLINE_ANYCRLF:+  mb->nltype = NLTYPE_ANYCRLF;+  break;++  default: return PCRE2_ERROR_INTERNAL;+  }++/* 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+be inspected during matching - from the offset minus the maximum back reference+to the given length. This saves time when a small part of a large subject is+being matched by the use of a starting offset. Note that the maximum lookbehind+is a number of characters, not code units. */++#ifdef SUPPORT_UNICODE+if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)+  {+  PCRE2_SPTR check_subject = start_match;  /* start_match includes offset */++  if (start_offset > 0)+    {+#if PCRE2_CODE_UNIT_WIDTH != 32+    unsigned int i;+    if (start_match < end_subject && NOT_FIRSTCU(*start_match))+      return PCRE2_ERROR_BADUTFOFFSET;+    for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)+      {+      check_subject--;+      while (check_subject > subject &&+#if PCRE2_CODE_UNIT_WIDTH == 8+      (*check_subject & 0xc0) == 0x80)+#else  /* 16-bit */+      (*check_subject & 0xfc00) == 0xdc00)+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+        check_subject--;+      }+#else   /* In the 32-bit library, one code unit equals one character. */+    check_subject -= re->max_lookbehind;+    if (check_subject < subject) check_subject = subject;+#endif  /* PCRE2_CODE_UNIT_WIDTH != 32 */+    }++  /* Validate the relevant portion of the subject. After an error, adjust the+  offset to be an absolute offset in the whole string. */++  match_data->rc = PRIV(valid_utf)(check_subject,+    length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));+  if (match_data->rc != 0)+    {+    match_data->startchar += (PCRE2_SIZE)(check_subject - subject);+    return match_data->rc;+    }+  }+#endif  /* SUPPORT_UNICODE */++/* 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->tables + fcc_offset, first_cu);+#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+    if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)+      first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);+#else+    if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))+      first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);+#endif+#endif  /* SUPPORT_UNICODE */+    }+  }+else+  if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)+    start_bits = re->start_bitmap;++/* There may be a "last known required code unit" set. */++if ((re->flags & PCRE2_LASTSET) != 0)+  {+  has_req_cu = TRUE;+  req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);+  if ((re->flags & PCRE2_LASTCASELESS) != 0)+    {+    req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);+#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+    if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)+      req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);+#else+    if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))+      req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);+#endif+#endif  /* SUPPORT_UNICODE */+    }+  }++/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,+free the memory that was obtained. */++if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)+  {+  match_data->memctl.free((void *)match_data->subject,+    match_data->memctl.memory_data);+  match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;+  }++/* Fill in fields that are always returned in the match data. */++match_data->code = re;+match_data->subject = NULL;  /* Default for no match */+match_data->mark = NULL;+match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER;++/* Call the main matching function, looping for a non-anchored regex after a+failed match. If not restarting, perform certain optimizations at the start of+a match. */++for (;;)+  {+  /* ----------------- Start of match optimizations ---------------- */++  /* There are some optimizations that avoid running the match if a known+  starting point is not found, or if a known later code unit is not present.+  However, there is an option (settable at compile time) that disables+  these, for testing and for ensuring that all callouts do actually occur.+  The optimizations must also be avoided when restarting a DFA match. */++  if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 &&+      (options & PCRE2_DFA_RESTART) == 0)+    {+    /* If firstline is TRUE, the start of the match is constrained to the first+    line of a multiline string. That is, the match must be before or at the+    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)+      {+      PCRE2_SPTR t = start_match;+#ifdef SUPPORT_UNICODE+      if (utf)+        {+        while (t < end_subject && !IS_NEWLINE(t))+          {+          t++;+          ACROSSCHAR(t < end_subject, t, t++);+          }+        }+      else+#endif+      while (t < end_subject && !IS_NEWLINE(t)) t++;+      end_subject = t;+      }++    /* 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 (anchored)+      {+      if (has_first_cu || start_bits != NULL)+        {+        BOOL ok = start_match < end_subject;+        if (ok)+          {+          PCRE2_UCHAR c = UCHAR21TEST(start_match);+          ok = has_first_cu && (c == first_cu || c == first_cu2);+          if (!ok && start_bits != NULL)+            {+#if PCRE2_CODE_UNIT_WIDTH != 8+            if (c > 255) c = 255;+#endif+            ok = (start_bits[c/8] & (1u << (c&7))) != 0;+            }+          }+        if (!ok) break;+        }+      }++    /* 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. If a call to memchr() that+    searches the rest of the subject fails to find one case, remember that in+    order not to keep on repeating the search. This can make a huge difference+    when the strings are very long and only one case is present. */++    else+      {+      if (has_first_cu)+        {+        if (first_cu != first_cu2)  /* Caseless */+          {+#if PCRE2_CODE_UNIT_WIDTH != 8+          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 = NULL;+          PCRE2_SPTR pp2 = NULL;+          PCRE2_SIZE cu2size = end_subject - start_match;++          if (!memchr_not_found_first_cu)+            {+            pp1 = memchr(start_match, first_cu, end_subject - start_match);+            if (pp1 == NULL) memchr_not_found_first_cu = TRUE;+              else cu2size = pp1 - start_match;+            }++          /* If pp1 is not NULL, we have arranged to search only as far as pp1,+          to see if the other case is earlier, so we can set "not found" only+          when both searches have returned NULL. */++          if (!memchr_not_found_first_cu2)+            {+            pp2 = memchr(start_match, first_cu2, cu2size);+            memchr_not_found_first_cu2 = (pp2 == NULL && pp1 == NULL);+            }++          if (pp1 == NULL)+            start_match = (pp2 == NULL)? end_subject : pp2;+          else+            start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;+#endif+          }++        /* The caseful case */++        else+          {+#if PCRE2_CODE_UNIT_WIDTH != 8+          while (start_match < end_subject && UCHAR21TEST(start_match) !=+                 first_cu)+            start_match++;+#else  /* 8-bit code units */+          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] & (1u << (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 = mb->end_subject;++    /* The following two optimizations are disabled for partial matching. */++    if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)+      {+      PCRE2_SPTR p;++      /* 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. */++      if (end_subject - start_match < re->minlength) goto NOMATCH_EXIT;++      /* 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. 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.++      The search can be skipped if the code unit was found later than the+      current starting point in a previous iteration of the bumpalong loop.++      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+      patterns. This showed up when somebody was matching something like+      /^\d+C/ on a 32-megabyte string... so we don't do this when the string is+      sufficiently long, but it's worth searching a lot more for unanchored+      patterns. */++      p = start_match + (has_first_cu? 1:0);+      if (has_req_cu && p > req_cu_ptr)+        {+        PCRE2_SIZE check_length = end_subject - start_match;++        if (check_length < REQ_CU_MAX ||+              (!anchored && check_length < REQ_CU_MAX * 1000))+          {+          if (req_cu != req_cu2)  /* Caseless */+            {+#if PCRE2_CODE_UNIT_WIDTH != 8+            while (p < end_subject)+              {+              uint32_t pp = UCHAR21INCTEST(p);+              if (pp == req_cu || pp == req_cu2) { p--; break; }+              }+#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 */+            }++          /* The caseful case */++          else+            {+#if PCRE2_CODE_UNIT_WIDTH != 8+            while (p < end_subject)+              {+              if (UCHAR21INCTEST(p) == req_cu) { p--; break; }+              }++#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,+          forcing a match failure. */++          if (p >= end_subject) break;++          /* 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. */++          req_cu_ptr = p;+          }+        }+      }+    }++  /* ------------ End of start of match optimizations ------------ */++  /* Give no match if we have passed the bumpalong limit. */++  if (start_match > bumpalong_limit) break;++  /* OK, now we can do the business */++  mb->start_used_ptr = start_match;+  mb->last_used_ptr = start_match;+  mb->recursive = NULL;++  rc = internal_dfa_match(+    mb,                           /* fixed match data */+    mb->start_code,               /* this subexpression's code */+    start_match,                  /* where we currently are */+    start_offset,                 /* start offset in subject */+    match_data->ovector,          /* offset vector */+    (uint32_t)match_data->oveccount * 2,  /* actual size of same */+    workspace,                    /* workspace vector */+    (int)wscount,                 /* size of same */+    0,                            /* function recurse level */+    base_recursion_workspace);    /* initial workspace for recursion */++  /* Anything other than "no match" means we are done, always; otherwise, carry+  on only if not anchored. */++  if (rc != PCRE2_ERROR_NOMATCH || anchored)+    {+    if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)+      {+      match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);+      match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);+      }+    match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);+    match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject);+    match_data->startchar = (PCRE2_SIZE)(start_match - subject);+    match_data->rc = rc;++    if (rc >= 0 &&(options & PCRE2_COPY_MATCHED_SUBJECT) != 0)+      {+      length = CU2BYTES(length + was_zero_terminated);+      match_data->subject = match_data->memctl.malloc(length,+        match_data->memctl.memory_data);+      if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;+      memcpy((void *)match_data->subject, subject, length);+      match_data->flags |= PCRE2_MD_COPIED_SUBJECT;+      }+    else+      {+      if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL) match_data->subject = subject;+      }+    goto EXIT;+    }++  /* Advance to the next subject character unless we are at the end of a line+  and firstline is set. */++  if (firstline && IS_NEWLINE(start_match)) break;+  start_match++;+#ifdef SUPPORT_UNICODE+  if (utf)+    {+    ACROSSCHAR(start_match < end_subject, start_match, start_match++);+    }+#endif+  if (start_match > end_subject) break;++  /* If we have just passed a CR and we are now at a LF, and the pattern does+  not contain any explicit matches for \r or \n, and the newline option is CRLF+  or ANY or ANYCRLF, advance the match position by one more character. */++  if (UCHAR21TEST(start_match - 1) == CHAR_CR &&+      start_match < end_subject &&+      UCHAR21TEST(start_match) == CHAR_NL &&+      (re->flags & PCRE2_HASCRORLF) == 0 &&+        (mb->nltype == NLTYPE_ANY ||+         mb->nltype == NLTYPE_ANYCRLF ||+         mb->nllen == 2))+    start_match++;++  }   /* "Bumpalong" loop */++NOMATCH_EXIT:+rc = PCRE2_ERROR_NOMATCH;++EXIT:+while (rws->next != NULL)+  {+  RWS_anchor *next = rws->next;+  rws->next = next->next;+  mb->memctl.free(next, mb->memctl.memory_data);+  }++return rc;+}++/* End of pcre2_dfa_match.c */
+ src/c/pcre2/src/pcre2_dftables.c view
@@ -0,0 +1,303 @@+/*************************************************+*      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-2020 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 is a freestanding support program to generate a file containing+character tables for PCRE2. The tables are built using the pcre2_maketables()+function, which is part of the PCRE2 API. By default, the system's "C" locale+is used rather than what the building user happens to have set, but the -L+option can be used to select the current locale from the LC_ALL environment+variable. By default, the tables are written in source form, but if -b is+given, they are written in binary. */++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include <ctype.h>+#include <stdio.h>+#include <string.h>+#include <locale.h>++#define PCRE2_CODE_UNIT_WIDTH 0   /* Must be set, but not relevant here */+#include "pcre2_internal.h"++#define PCRE2_DFTABLES            /* pcre2_maketables.c notices this */+#include "pcre2_maketables.c"+++static char *classlist[] =+  {+  "space", "xdigit", "digit", "upper", "lower",+  "word", "graph", "print", "punct", "cntrl"+  };++++/*************************************************+*                  Usage                         *+*************************************************/++static void+usage(void)+{+(void)fprintf(stderr,+  "Usage: pcre2_dftables [options] <output file>\n"+  "  -b    Write output in binary (default is source code)\n"+  "  -L    Use locale from LC_ALL (default is \"C\" locale)\n"+  );+}++++/*************************************************+*                Entry point                     *+*************************************************/++int main(int argc, char **argv)+{+FILE *f;+int i;+int nclass = 0;+BOOL binary = FALSE;+char *env = "C";+const unsigned char *tables;+const unsigned char *base_of_tables;++/* Process options */++for (i = 1; i < argc; i++)+  {+  unsigned char *arg = (unsigned char *)argv[i];+  if (*arg != '-') break;++  if (strcmp(arg, "-help") == 0 || strcmp(arg, "--help") == 0)+    {+    usage();+    return 0;+    }++  else if (strcmp(arg, "-L") == 0)+    {+    if (setlocale(LC_ALL, "") == NULL)+      {+      (void)fprintf(stderr, "pcre2_dftables: setlocale() failed\n");+      return 1;+      }+    env = getenv("LC_ALL");+    }++  else if (strcmp(arg, "-b") == 0)+    binary = TRUE;++  else+    {+    (void)fprintf(stderr, "pcre2_dftables: unrecognized option %s\n", arg);+    return 1;+    }+  }++if (i != argc - 1)+  {+  (void)fprintf(stderr, "pcre2_dftables: one filename argument is required\n");+  return 1;+  }++/* Make the tables */++tables = maketables();+base_of_tables = tables;++f = fopen(argv[i], "wb");+if (f == NULL)+  {+  fprintf(stderr, "pcre2_dftables: failed to open %s for writing\n", argv[1]);+  return 1;+  }++/* If -b was specified, we write the tables in binary. */++if (binary)+  {+  int yield = 0;+  size_t len = fwrite(tables, 1, TABLES_LENGTH, f);+  if (len != TABLES_LENGTH)+    {+    (void)fprintf(stderr, "pcre2_dftables: fwrite() returned wrong length %d "+     "instead of %d\n", (int)len, TABLES_LENGTH);+    yield = 1;+    }+  fclose(f);+  free((void *)base_of_tables);+  return yield;+  }++/* Write the tables as source code for inclusion in the PCRE2 library. There+are several fprintf() calls here, because gcc in pedantic mode complains about+the very long string otherwise. */++(void)fprintf(f,+  "/*************************************************\n"+  "*      Perl-Compatible Regular Expressions       *\n"+  "*************************************************/\n\n"+  "/* This file was automatically written by the pcre2_dftables auxiliary\n"+  "program. It contains character tables that are used when no external\n"+  "tables are passed to PCRE2 by the application that calls it. The tables\n"+  "are used only for characters whose code values are less than 256. */\n\n");++(void)fprintf(f,+  "/* This set of tables was written in the %s locale. */\n\n", env);++(void)fprintf(f,+  "/* The pcre2_ftables program (which is distributed with PCRE2) can be used\n"+  "to build alternative versions of this file. This is necessary if you are\n"+  "running in an EBCDIC environment, or if you want to default to a different\n"+  "encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates\n"+  "these tables in the \"C\" locale by default. This happens automatically if\n"+  "PCRE2 is configured with --enable-rebuild-chartables. However, you can run\n"+  "pcre2_dftables manually with the -L option to build tables using the LC_ALL\n"+  "locale. */\n\n");++/* Force config.h in z/OS */++#if defined NATIVE_ZOS+(void)fprintf(f,+  "/* For z/OS, config.h is forced */\n"+  "#ifndef HAVE_CONFIG_H\n"+  "#define HAVE_CONFIG_H 1\n"+  "#endif\n\n");+#endif++(void)fprintf(f,+  "/* The following #include is present because without it gcc 4.x may remove\n"+  "the array definition from the final binary if PCRE2 is built into a static\n"+  "library and dead code stripping is activated. This leads to link errors.\n"+  "Pulling in the header ensures that the array gets flagged as \"someone\n"+  "outside this compilation unit might reference this\" and so it will always\n"+  "be supplied to the linker. */\n\n");++(void)fprintf(f,+  "#ifdef HAVE_CONFIG_H\n"+  "#include \"config.h\"\n"+  "#endif\n\n"+  "#include \"pcre2_internal.h\"\n\n");++(void)fprintf(f,+  "const uint8_t PRIV(default_tables)[] = {\n\n"+  "/* This table is a lower casing table. */\n\n");++(void)fprintf(f, "  ");+for (i = 0; i < 256; i++)+  {+  if ((i & 7) == 0 && i != 0) fprintf(f, "\n  ");+  fprintf(f, "%3d", *tables++);+  if (i != 255) fprintf(f, ",");+  }+(void)fprintf(f, ",\n\n");++(void)fprintf(f, "/* This table is a case flipping table. */\n\n");++(void)fprintf(f, "  ");+for (i = 0; i < 256; i++)+  {+  if ((i & 7) == 0 && i != 0) fprintf(f, "\n  ");+  fprintf(f, "%3d", *tables++);+  if (i != 255) fprintf(f, ",");+  }+(void)fprintf(f, ",\n\n");++(void)fprintf(f,+  "/* This table contains bit maps for various character classes. Each map is 32\n"+  "bytes long and the bits run from the least significant end of each byte. The\n"+  "classes that have their own maps are: space, xdigit, digit, upper, lower, word,\n"+  "graph, print, punct, and cntrl. Other classes are built from combinations. */\n\n");++(void)fprintf(f, "  ");+for (i = 0; i < cbit_length; i++)+  {+  if ((i & 7) == 0 && i != 0)+    {+    if ((i & 31) == 0) (void)fprintf(f, "\n");+    if ((i & 24) == 8) (void)fprintf(f, "  /* %s */", classlist[nclass++]);+    (void)fprintf(f, "\n  ");+    }+  (void)fprintf(f, "0x%02x", *tables++);+  if (i != cbit_length - 1) (void)fprintf(f, ",");+  }+(void)fprintf(f, ",\n\n");++(void)fprintf(f,+  "/* This table identifies various classes of character by individual bits:\n"+  "  0x%02x   white space character\n"+  "  0x%02x   letter\n"+  "  0x%02x   lower case letter\n"+  "  0x%02x   decimal digit\n"+  "  0x%02x   alphanumeric or '_'\n*/\n\n",+  ctype_space, ctype_letter, ctype_lcletter, ctype_digit, ctype_word);++(void)fprintf(f, "  ");+for (i = 0; i < 256; i++)+  {+  if ((i & 7) == 0 && i != 0)+    {+    (void)fprintf(f, " /* ");+    if (isprint(i-8)) (void)fprintf(f, " %c -", i-8);+      else (void)fprintf(f, "%3d-", i-8);+    if (isprint(i-1)) (void)fprintf(f, " %c ", i-1);+      else (void)fprintf(f, "%3d", i-1);+    (void)fprintf(f, " */\n  ");+    }+  (void)fprintf(f, "0x%02x", *tables++);+  if (i != 255) (void)fprintf(f, ",");+  }++(void)fprintf(f, "};/* ");+if (isprint(i-8)) (void)fprintf(f, " %c -", i-8);+  else (void)fprintf(f, "%3d-", i-8);+if (isprint(i-1)) (void)fprintf(f, " %c ", i-1);+  else (void)fprintf(f, "%3d", i-1);+(void)fprintf(f, " */\n\n/* End of pcre2_chartables.c */\n");++fclose(f);+free((void *)base_of_tables);+return 0;+}++/* End of pcre2_dftables.c */
+ src/c/pcre2/src/pcre2_error.c view
@@ -0,0 +1,340 @@+/*************************************************+*      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-2019 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 STRING(a)  # a+#define XSTRING(s) STRING(s)++/* The texts of compile-time error messages. Compile-time error numbers start+at COMPILE_ERROR_BASE (100).++This used to be a table of strings, but in order to reduce the number of+relocations needed when a shared library is loaded dynamically, it is now one+long string. We cannot use a table of offsets, because the lengths of inserts+such as XSTRING(MAX_NAME_SIZE) are not known. Instead,+pcre2_get_error_message() counts through to the one it wants - this isn't a+performance issue because these strings are used only when there is an error.++Each substring ends with \0 to insert a null character. This includes the final+substring, so that the whole string ends with \0\0, which can be detected when+counting through. */++static const unsigned char compile_error_texts[] =+  "no error\0"+  "\\ at end of pattern\0"+  "\\c at end of pattern\0"+  "unrecognized character follows \\\0"+  "numbers out of order in {} quantifier\0"+  /* 5 */+  "number too big in {} quantifier\0"+  "missing terminating ] for character class\0"+  "escape sequence is invalid in character class\0"+  "range out of order in character class\0"+  "quantifier does not follow a repeatable item\0"+  /* 10 */+  "internal error: unexpected repeat\0"+  "unrecognized character after (? or (?-\0"+  "POSIX named classes are supported only within a class\0"+  "POSIX collating elements are not supported\0"+  "missing closing parenthesis\0"+  /* 15 */+  "reference to non-existent subpattern\0"+  "pattern passed as NULL\0"+  "unrecognised compile-time option bit(s)\0"+  "missing ) after (?# comment\0"+  "parentheses are too deeply nested\0"+  /* 20 */+  "regular expression is too large\0"+  "failed to allocate heap memory\0"+  "unmatched closing parenthesis\0"+  "internal error: code overflow\0"+  "missing closing parenthesis for condition\0"+  /* 25 */+  "lookbehind assertion is not fixed length\0"+  "a relative value of zero is not allowed\0"+  "conditional subpattern contains more than two branches\0"+  "assertion expected after (?( or (?(?C)\0"+  "digit expected after (?+ or (?-\0"+  /* 30 */+  "unknown POSIX class name\0"+  "internal error in pcre2_study(): should not occur\0"+  "this version of PCRE2 does not have Unicode support\0"+  "parentheses are too deeply nested (stack check)\0"+  "character code point value in \\x{} or \\o{} is too large\0"+  /* 35 */+  "lookbehind is too complicated\0"+  "\\C is not allowed in a lookbehind assertion in UTF-" XSTRING(PCRE2_CODE_UNIT_WIDTH) " mode\0"+  "PCRE2 does not support \\F, \\L, \\l, \\N{name}, \\U, or \\u\0"+  "number after (?C is greater than 255\0"+  "closing parenthesis for (?C expected\0"+  /* 40 */+  "invalid escape sequence in (*VERB) name\0"+  "unrecognized character after (?P\0"+  "syntax error in subpattern name (missing terminator?)\0"+  "two named subpatterns have the same name (PCRE2_DUPNAMES not set)\0"+  "subpattern name must start with a non-digit\0"+  /* 45 */+  "this version of PCRE2 does not have support for \\P, \\p, or \\X\0"+  "malformed \\P or \\p sequence\0"+  "unknown property name after \\P or \\p\0"+  "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " code units)\0"+  "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"+  /* 50 */+  "invalid range in character class\0"+  "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"+  "internal error: overran compiling workspace\0"+  "internal error: previously-checked referenced subpattern not found\0"+  "DEFINE subpattern contains more than one branch\0"+  /* 55 */+  "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"+  "(?R (recursive pattern call) must be followed by a closing parenthesis\0"+  /* "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" */+  "obsolete error (should not occur)\0"  /* Was the above */+  /* 60 */+  "(*VERB) not recognized or malformed\0"+  "subpattern number is too big\0"+  "subpattern name expected\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"+  "(*MARK) must have an argument\0"+  "non-hex character in \\x{} (closing brace missing?)\0"+#ifndef EBCDIC+  "\\c must be followed by a printable ASCII character\0"+#else+  "\\c must be followed by a letter or one of [\\]^_?\0"+#endif+  "\\k is not followed by a braced, angle-bracketed, or quoted name\0"+  /* 70 */+  "internal error: unknown meta code in check_lookbehinds()\0"+  "\\N is not supported in a class\0"+  "callout string is too long\0"+  "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"+  "using UTF is disabled by the application\0"+  /* 75 */+  "using UCP is disabled by the application\0"+  "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"+  "character code point value in \\u.... sequence is too large\0"+  "digits missing in \\x{} or \\o{} or \\N{U+}\0"+  "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"+  "unrecognized string delimiter follows (?C\0"+  "using \\C is disabled by the application\0"+  "(?| and/or (?J: or (?x: parentheses are too deeply nested\0"+  /* 85 */+  "using \\C is disabled in this PCRE2 library\0"+  "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"+  "\\N{U+dddd} is supported only in Unicode (UTF) mode\0"+  "invalid hyphen in option setting\0"+  /* 95 */+  "(*alpha_assertion) not recognized\0"+  "script runs require Unicode support, which this version of PCRE2 does not have\0"+  "too many capturing groups (maximum 65535)\0"+  "atomic assertion expected after (?( or (?(?C)\0"+  ;++/* Match-time and UTF error texts are in the same format. */++static const unsigned char match_error_texts[] =+  "no error\0"+  "no match\0"+  "partial match\0"+  "UTF-8 error: 1 byte missing at end\0"+  "UTF-8 error: 2 bytes missing at end\0"+  /* 5 */+  "UTF-8 error: 3 bytes missing at end\0"+  "UTF-8 error: 4 bytes missing at end\0"+  "UTF-8 error: 5 bytes missing at end\0"+  "UTF-8 error: byte 2 top bits not 0x80\0"+  "UTF-8 error: byte 3 top bits not 0x80\0"+  /* 10 */+  "UTF-8 error: byte 4 top bits not 0x80\0"+  "UTF-8 error: byte 5 top bits not 0x80\0"+  "UTF-8 error: byte 6 top bits not 0x80\0"+  "UTF-8 error: 5-byte character is not allowed (RFC 3629)\0"+  "UTF-8 error: 6-byte character is not allowed (RFC 3629)\0"+  /* 15 */+  "UTF-8 error: code points greater than 0x10ffff are not defined\0"+  "UTF-8 error: code points 0xd800-0xdfff are not defined\0"+  "UTF-8 error: overlong 2-byte sequence\0"+  "UTF-8 error: overlong 3-byte sequence\0"+  "UTF-8 error: overlong 4-byte sequence\0"+  /* 20 */+  "UTF-8 error: overlong 5-byte sequence\0"+  "UTF-8 error: overlong 6-byte sequence\0"+  "UTF-8 error: isolated byte with 0x80 bit set\0"+  "UTF-8 error: illegal byte (0xfe or 0xff)\0"+  "UTF-16 error: missing low surrogate at end\0"+  /* 25 */+  "UTF-16 error: invalid low surrogate\0"+  "UTF-16 error: isolated low surrogate\0"+  "UTF-32 error: code points 0xd800-0xdfff are not defined\0"+  "UTF-32 error: code points greater than 0x10ffff are not defined\0"+  "bad data value\0"+  /* 30 */+  "patterns do not all use the same character tables\0"+  "magic number missing\0"+  "pattern compiled in wrong mode: 8/16/32-bit error\0"+  "bad offset value\0"+  "bad option value\0"+  /* 35 */+  "invalid replacement string\0"+  "bad offset into UTF string\0"+  "callout error code\0"              /* Never returned by PCRE2 itself */+  "invalid data in workspace for DFA restart\0"+  "too much recursion for DFA matching\0"+  /* 40 */+  "backreference condition or recursion test is not supported for DFA matching\0"+  "function is not supported for DFA matching\0"+  "pattern contains an item that is not supported for DFA matching\0"+  "workspace size exceeded in DFA matching\0"+  "internal error - pattern overwritten?\0"+  /* 45 */+  "bad JIT option\0"+  "JIT stack limit reached\0"+  "match limit exceeded\0"+  "no more memory\0"+  "unknown substring\0"+  /* 50 */+  "non-unique substring name\0"+  "NULL argument passed\0"+  "nested recursion at the same subject position\0"+  "matching depth limit exceeded\0"+  "requested value is not available\0"+  /* 55 */+  "requested value is not set\0"+  "offset limit set without PCRE2_USE_OFFSET_LIMIT\0"+  "bad escape sequence in replacement string\0"+  "expected closing curly bracket in replacement string\0"+  "bad substitution in replacement string\0"+  /* 60 */+  "match with end before start or start moved backwards is not supported\0"+  "too many replacements (more than INT_MAX)\0"+  "bad serialized data\0"+  "heap limit exceeded\0"+  "invalid syntax\0"+  /* 65 */+  "internal error - duplicate substitution match\0"+  "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0"+  ;+++/*************************************************+*            Return error message                *+*************************************************/++/* This function copies an error message into a buffer whose units are of an+appropriate width. Error numbers are positive for compile-time errors, and+negative for match-time errors (except for UTF errors), but the numbers are all+distinct.++Arguments:+  enumber       error number+  buffer        where to put the message (zero terminated)+  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, PCRE2_SIZE size)+{+const unsigned char *message;+PCRE2_SIZE i;+int n;++if (size == 0) return PCRE2_ERROR_NOMEMORY;++if (enumber >= COMPILE_ERROR_BASE)  /* Compile error */+  {+  message = compile_error_texts;+  n = enumber - COMPILE_ERROR_BASE;+  }+else if (enumber < 0)               /* Match or UTF error */+  {+  message = match_error_texts;+  n = -enumber;+  }+else                                /* Invalid error number */+  {+  message = (unsigned char *)"\0";  /* Empty message list */+  n = 1;+  }++for (; n > 0; n--)+  {+  while (*message++ != CHAR_NUL) {};+  if (*message == CHAR_NUL) return PCRE2_ERROR_BADDATA;+  }++for (i = 0; *message != 0; i++)+  {+  if (i >= size - 1)+    {+    buffer[i] = 0;     /* Terminate partial message */+    return PCRE2_ERROR_NOMEMORY;+    }+  buffer[i] = *message++;+  }++buffer[i] = 0;+return (int)i;+}++/* End of pcre2_error.c */
+ src/c/pcre2/src/pcre2_extuni.c view
@@ -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-2019 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] & (1u << 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 or ZWJ follows Extended_Pictographic, do not update lgb; this+  allows any number of them before a following Extended_Pictographic. */++  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||+       lgb != ucp_gbExtended_Pictographic)+    lgb = rgb;++  eptr += len;+  if (xcount != NULL) *xcount += 1;+  }++return eptr;+}++#endif  /* SUPPORT_UNICODE */++/* End of pcre2_extuni.c */
+ src/c/pcre2/src/pcre2_find_bracket.c view
@@ -0,0 +1,219 @@+/*************************************************+*      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 a single function that scans through a compiled pattern+until it finds a capturing bracket with the given number, or, if the number is+negative, an instance of OP_REVERSE for a lookbehind. The function is called+from pcre2_compile.c and also from pcre2_study.c when finding the minimum+matching length. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"+++/*************************************************+*    Scan compiled regex for specific bracket    *+*************************************************/++/*+Arguments:+  code        points to start of expression+  utf         TRUE in UTF mode+  number      the required bracket number or negative to find a lookbehind++Returns:      pointer to the opcode for the bracket, or NULL if not found+*/++PCRE2_SPTR+PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number)+{+for (;;)+  {+  PCRE2_UCHAR c = *code;++  if (c == OP_END) return NULL;++  /* XCLASS is used for classes that cannot be represented just by a bit map.+  This includes negated single high-valued characters. CALLOUT_STR is used for+  callouts with string arguments. In both cases the length in the table is+  zero; the actual length is stored in the compiled code. */++  if (c == OP_XCLASS) code += GET(code, 1);+    else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);++  /* Handle lookbehind */++  else if (c == OP_REVERSE)+    {+    if (number < 0) return (PCRE2_UCHAR *)code;+    code += PRIV(OP_lengths)[c];+    }++  /* Handle capturing bracket */++  else if (c == OP_CBRA || c == OP_SCBRA ||+           c == OP_CBRAPOS || c == OP_SCBRAPOS)+    {+    int n = (int)GET2(code, 1+LINK_SIZE);+    if (n == number) return (PCRE2_UCHAR *)code;+    code += PRIV(OP_lengths)[c];+    }++  /* 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. */++  else+    {+    switch(c)+      {+      case OP_TYPESTAR:+      case OP_TYPEMINSTAR:+      case OP_TYPEPLUS:+      case OP_TYPEMINPLUS:+      case OP_TYPEQUERY:+      case OP_TYPEMINQUERY:+      case OP_TYPEPOSSTAR:+      case OP_TYPEPOSPLUS:+      case OP_TYPEPOSQUERY:+      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;+      break;++      case OP_TYPEUPTO:+      case OP_TYPEMINUPTO:+      case OP_TYPEEXACT:+      case OP_TYPEPOSUPTO:+      if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)+        code += 2;+      break;++      case OP_MARK:+      case OP_COMMIT_ARG:+      case OP_PRUNE_ARG:+      case OP_SKIP_ARG:+      case OP_THEN_ARG:+      code += code[1];+      break;+      }++    /* Add in the fixed length from the table */++    code += PRIV(OP_lengths)[c];++  /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be+  followed by a multi-byte character. The length in the table is a minimum, so+  we have to arrange to skip the extra bytes. */++#ifdef MAYBE_UTF_MULTI+    if (utf) switch(c)+      {+      case OP_CHAR:+      case OP_CHARI:+      case OP_NOT:+      case OP_NOTI:+      case OP_EXACT:+      case OP_EXACTI:+      case OP_NOTEXACT:+      case OP_NOTEXACTI:+      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:+      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_PLUS:+      case OP_PLUSI:+      case OP_NOTPLUS:+      case OP_NOTPLUSI:+      case OP_MINPLUS:+      case OP_MINPLUSI:+      case OP_NOTMINPLUS:+      case OP_NOTMINPLUSI:+      case OP_POSPLUS:+      case OP_POSPLUSI:+      case OP_NOTPOSPLUS:+      case OP_NOTPOSPLUSI:+      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 (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);+      break;+      }+#else+    (void)(utf);  /* Keep compiler happy by referencing function argument */+#endif  /* MAYBE_UTF_MULTI */+    }+  }+}++/* End of pcre2_find_bracket.c */
+ src/c/pcre2/src/pcre2_fuzzsupport.c view
@@ -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 */
+ src/c/pcre2/src/pcre2_internal.h view
@@ -0,0 +1,2004 @@+/*************************************************+*      Perl-Compatible Regular Expressions       *+*************************************************/++/* PCRE2 is a library of functions to support regular expressions whose syntax+and semantics are as close as possible to those of the Perl 5 language.++                       Written by Philip Hazel+     Original API code Copyright (c) 1997-2012 University of Cambridge+          New API code Copyright (c) 2016-2020 University of Cambridge++-----------------------------------------------------------------------------+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright notice,+      this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above copyright+      notice, this list of conditions and the following disclaimer in the+      documentation and/or other materials provided with the distribution.++    * Neither the name of the University of Cambridge nor the names of its+      contributors may be used to endorse or promote products derived from+      this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.+-----------------------------------------------------------------------------+*/++#ifndef PCRE2_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+in this file, because the first part is not width-dependent, and is included by+pcre2test.c with CODE_UNIT_WIDTH == 0. */++#if defined EBCDIC && defined SUPPORT_UNICODE+#error The use of both EBCDIC and SUPPORT_UNICODE is not supported.+#endif++/* Standard C headers */++#include <ctype.h>+#include <limits.h>+#include <stddef.h>+#include <stdio.h>+#include <stdlib.h>+#include <string.h>++/* Macros to make boolean values more obvious. The #ifndef is to pacify+compiler warnings in environments where these macros are defined elsewhere.+Unfortunately, there is no way to do the same for the typedef. */++typedef int BOOL;+#ifndef FALSE+#define FALSE   0+#define TRUE    1+#endif++/* Valgrind (memcheck) support */++#ifdef SUPPORT_VALGRIND+#include <valgrind/memcheck.h>+#endif++/* -ftrivial-auto-var-init support supports initializing all local variables+to avoid some classes of bug, but this can cause an unacceptable slowdown+for large on-stack arrays in hot functions. This macro lets us annotate+such arrays. */++#ifdef HAVE_ATTRIBUTE_UNINITIALIZED+#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized))+#else+#define PCRE2_KEEP_UNINITIALIZED+#endif++/* Older versions of MSVC lack snprintf(). This define allows for+warning/error-free compilation and testing with MSVC compilers back to at least+MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */++#if defined(_MSC_VER) && (_MSC_VER < 1900)+#define snprintf _snprintf+#endif++/* When compiling a DLL for Windows, the exported symbols have to be declared+using some MS magic. I found some useful information on this web page:+http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the+information there, using __declspec(dllexport) without "extern" we have a+definition; with "extern" we have a declaration. The settings here override the+setting in pcre2.h (which is included below); it defines only PCRE2_EXP_DECL,+which is all that is needed for applications (they just import the symbols). We+use:++  PCRE2_EXP_DECL    for declarations+  PCRE2_EXP_DEFN    for definitions++The reason for wrapping this in #ifndef PCRE2_EXP_DECL is so that pcre2test,+which is an application, but needs to import this file in order to "peek" at+internals, can #include pcre2.h first to get an application's-eye view.++In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,+special-purpose environments) might want to stick other stuff in front of+exported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN+only if it is not already set. */++#ifndef PCRE2_EXP_DECL+#  ifdef _WIN32+#    ifndef PCRE2_STATIC+#      define PCRE2_EXP_DECL       extern __declspec(dllexport)+#      define PCRE2_EXP_DEFN       __declspec(dllexport)+#    else+#      define PCRE2_EXP_DECL       extern+#      define PCRE2_EXP_DEFN+#    endif+#  else+#    ifdef __cplusplus+#      define PCRE2_EXP_DECL       extern "C"+#    else+#      define PCRE2_EXP_DECL       extern+#    endif+#    ifndef PCRE2_EXP_DEFN+#      define PCRE2_EXP_DEFN       PCRE2_EXP_DECL+#    endif+#  endif+#endif++/* Include the public PCRE2 header and the definitions of UCP character+property values. This must follow the setting of PCRE2_EXP_DECL above. */++#include "pcre2.h"+#include "pcre2_ucp.h"++/* When PCRE2 is compiled as a C++ library, the subject pointer can be replaced+with a custom type. This makes it possible, for example, to allow pcre2_match()+to process subject strings that are discontinuous by using a smart pointer+class. It must always be possible to inspect all of the subject string in+pcre2_match() because of the way it backtracks. */++/* WARNING: This is as yet untested for PCRE2. */++#ifdef CUSTOM_SUBJECT_PTR+#undef PCRE2_SPTR+#define PCRE2_SPTR CUSTOM_SUBJECT_PTR+#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+arithmetic. Handle this by defining a macro for the appropriate type. */++#if defined INT64_MAX || defined int64_t+#define INT64_OR_DOUBLE int64_t+#else+#define INT64_OR_DOUBLE double+#endif++/* External (in the C sense) functions and tables that are private to the+libraries are always referenced using the PRIV macro. This makes it possible+for pcre2test.c to include some of the source files from the libraries using a+different PRIV definition to avoid name clashes. It also makes it clear in the+code that a non-static object is being referenced. */++#ifndef PRIV+#define PRIV(name) _pcre2_##name+#endif++/* When compiling for use with the Virtual Pascal compiler, these functions+need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT+option on the command line. */++#ifdef VPCOMPAT+#define strlen(s)        _strlen(s)+#define strncmp(s1,s2,m) _strncmp(s1,s2,m)+#define memcmp(s,c,n)    _memcmp(s,c,n)+#define memcpy(d,s,n)    _memcpy(d,s,n)+#define memmove(d,s,n)   _memmove(d,s,n)+#define memset(s,c,n)    _memset(s,c,n)+#else  /* VPCOMPAT */++/* Otherwise, to cope with SunOS4 and other systems that lack memmove(), define+a macro that calls an emulating function. */++#ifndef HAVE_MEMMOVE+#undef  memmove          /* Some systems may have a macro */+#define memmove(a, b, c) PRIV(memmove)(a, b, c)+#endif   /* not HAVE_MEMMOVE */+#endif   /* not VPCOMPAT */++/* This is an unsigned int value that no UTF character can ever have, as+Unicode doesn't go beyond 0x0010ffff. */++#define NOTACHAR 0xffffffff++/* This is the largest valid UTF/Unicode code point. */++#define MAX_UTF_CODE_POINT 0x10ffff++/* Compile-time positive error numbers (all except UTF errors, which are+negative) start at this value. It should probably never be changed, in case+some application is checking for specific numbers. There is a copy of this+#define in pcre2posix.c (which now no longer includes this file). Ideally, a+way of having a single definition should be found, but as the number is+unlikely to change, this is not a pressing issue. The original reason for+having a base other than 0 was to keep the absolute values of compile-time and+run-time error numbers numerically different, but in the event the code does+not rely on this. */++#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 20KiB 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++/* Similarly, for DFA matching, an initial internal workspace vector is+allocated on the stack. */++#define DFA_START_RWS_SIZE 30720++/* Define the default BSR convention. */++#ifdef BSR_ANYCRLF+#define BSR_DEFAULT PCRE2_BSR_ANYCRLF+#else+#define BSR_DEFAULT PCRE2_BSR_UNICODE+#endif+++/* ---------------- Basic UTF-8 macros ---------------- */++/* These UTF-8 macros are always defined because they are used in pcre2test for+handling wide characters in 16-bit and 32-bit modes, even if an 8-bit library+is not supported. */++/* Tests whether a UTF-8 code point needs extra bytes to decode. */++#define HASUTF8EXTRALEN(c) ((c) >= 0xc0)++/* The following macros were originally written in the form of loops that used+data from the tables whose names start with PRIV(utf8_table). They were+rewritten by a user so as not to use loops, because in some environments this+gives a significant performance advantage, and it seems never to do any harm.+*/++/* Base macro to pick up the remaining bytes of a UTF-8 character, not+advancing the pointer. */++#define GETUTF8(c, eptr) \+    { \+    if ((c & 0x20u) == 0) \+      c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \+    else if ((c & 0x10u) == 0) \+      c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \+    else if ((c & 0x08u) == 0) \+      c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \+      ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \+    else if ((c & 0x04u) == 0) \+      c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \+          ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \+          (eptr[4] & 0x3fu); \+    else \+      c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \+          ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \+          ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \+    }++/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing+the pointer. */++#define GETUTF8INC(c, eptr) \+    { \+    if ((c & 0x20u) == 0) \+      c = ((c & 0x1fu) << 6) | (*eptr++ & 0x3fu); \+    else if ((c & 0x10u) == 0) \+      { \+      c = ((c & 0x0fu) << 12) | ((*eptr & 0x3fu) << 6) | (eptr[1] & 0x3fu); \+      eptr += 2; \+      } \+    else if ((c & 0x08u) == 0) \+      { \+      c = ((c & 0x07u) << 18) | ((*eptr & 0x3fu) << 12) | \+          ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \+      eptr += 3; \+      } \+    else if ((c & 0x04u) == 0) \+      { \+      c = ((c & 0x03u) << 24) | ((*eptr & 0x3fu) << 18) | \+          ((eptr[1] & 0x3fu) << 12) | ((eptr[2] & 0x3fu) << 6) | \+          (eptr[3] & 0x3fu); \+      eptr += 4; \+      } \+    else \+      { \+      c = ((c & 0x01u) << 30) | ((*eptr & 0x3fu) << 24) | \+          ((eptr[1] & 0x3fu) << 18) | ((eptr[2] & 0x3fu) << 12) | \+          ((eptr[3] & 0x3fu) << 6) | (eptr[4] & 0x3fu); \+      eptr += 5; \+      } \+    }++/* Base macro to pick up the remaining bytes of a UTF-8 character, not+advancing the pointer, incrementing the length. */++#define GETUTF8LEN(c, eptr, len) \+    { \+    if ((c & 0x20u) == 0) \+      { \+      c = ((c & 0x1fu) << 6) | (eptr[1] & 0x3fu); \+      len++; \+      } \+    else if ((c & 0x10u)  == 0) \+      { \+      c = ((c & 0x0fu) << 12) | ((eptr[1] & 0x3fu) << 6) | (eptr[2] & 0x3fu); \+      len += 2; \+      } \+    else if ((c & 0x08u)  == 0) \+      {\+      c = ((c & 0x07u) << 18) | ((eptr[1] & 0x3fu) << 12) | \+          ((eptr[2] & 0x3fu) << 6) | (eptr[3] & 0x3fu); \+      len += 3; \+      } \+    else if ((c & 0x04u)  == 0) \+      { \+      c = ((c & 0x03u) << 24) | ((eptr[1] & 0x3fu) << 18) | \+          ((eptr[2] & 0x3fu) << 12) | ((eptr[3] & 0x3fu) << 6) | \+          (eptr[4] & 0x3fu); \+      len += 4; \+      } \+    else \+      {\+      c = ((c & 0x01u) << 30) | ((eptr[1] & 0x3fu) << 24) | \+          ((eptr[2] & 0x3fu) << 18) | ((eptr[3] & 0x3fu) << 12) | \+          ((eptr[4] & 0x3fu) << 6) | (eptr[5] & 0x3fu); \+      len += 5; \+      } \+    }++/* --------------- Whitespace macros ---------------- */++/* Tests for Unicode horizontal and vertical whitespace characters must check a+number of different values. Using a switch statement for this generates the+fastest code (no loop, no memory access), and there are several places in the+interpreter code where this happens. In order to ensure that all the case lists+remain in step, we use macros so that there is only one place where the lists+are defined.++These values are also required as lists in pcre2_compile.c when processing \h,+\H, \v and \V in a character class. The lists are defined in pcre2_tables.c,+but macros that define the values are here so that all the definitions are+together. The lists must be in ascending character order, terminated by+NOTACHAR (which is 0xffffffff).++Any changes should ensure that the various macros are kept in step with each+other. NOTE: The values also appear in pcre2_jit_compile.c. */++/* -------------- ASCII/Unicode environments -------------- */++#ifndef EBCDIC++/* Character U+180E (Mongolian Vowel Separator) is not included in the list of+spaces in the Unicode file PropList.txt, and Perl does not recognize it as a+space. However, in many other sources it is listed as a space and has been in+PCRE (both APIs) for a long time. */++#define HSPACE_LIST \+  CHAR_HT, CHAR_SPACE, CHAR_NBSP, \+  0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \+  0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \+  NOTACHAR++#define HSPACE_MULTIBYTE_CASES \+  case 0x1680:  /* OGHAM SPACE MARK */ \+  case 0x180e:  /* MONGOLIAN VOWEL SEPARATOR */ \+  case 0x2000:  /* EN QUAD */ \+  case 0x2001:  /* EM QUAD */ \+  case 0x2002:  /* EN SPACE */ \+  case 0x2003:  /* EM SPACE */ \+  case 0x2004:  /* THREE-PER-EM SPACE */ \+  case 0x2005:  /* FOUR-PER-EM SPACE */ \+  case 0x2006:  /* SIX-PER-EM SPACE */ \+  case 0x2007:  /* FIGURE SPACE */ \+  case 0x2008:  /* PUNCTUATION SPACE */ \+  case 0x2009:  /* THIN SPACE */ \+  case 0x200A:  /* HAIR SPACE */ \+  case 0x202f:  /* NARROW NO-BREAK SPACE */ \+  case 0x205f:  /* MEDIUM MATHEMATICAL SPACE */ \+  case 0x3000   /* IDEOGRAPHIC SPACE */++#define HSPACE_BYTE_CASES \+  case CHAR_HT: \+  case CHAR_SPACE: \+  case CHAR_NBSP++#define HSPACE_CASES \+  HSPACE_BYTE_CASES: \+  HSPACE_MULTIBYTE_CASES++#define VSPACE_LIST \+  CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR++#define VSPACE_MULTIBYTE_CASES \+  case 0x2028:    /* LINE SEPARATOR */ \+  case 0x2029     /* PARAGRAPH SEPARATOR */++#define VSPACE_BYTE_CASES \+  case CHAR_LF: \+  case CHAR_VT: \+  case CHAR_FF: \+  case CHAR_CR: \+  case CHAR_NEL++#define VSPACE_CASES \+  VSPACE_BYTE_CASES: \+  VSPACE_MULTIBYTE_CASES++/* -------------- EBCDIC environments -------------- */++#else+#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR++#define HSPACE_BYTE_CASES \+  case CHAR_HT: \+  case CHAR_SPACE: \+  case CHAR_NBSP++#define HSPACE_CASES HSPACE_BYTE_CASES++#ifdef EBCDIC_NL25+#define VSPACE_LIST \+  CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR+#else+#define VSPACE_LIST \+  CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR+#endif++#define VSPACE_BYTE_CASES \+  case CHAR_LF: \+  case CHAR_VT: \+  case CHAR_FF: \+  case CHAR_CR: \+  case CHAR_NEL++#define VSPACE_CASES VSPACE_BYTE_CASES+#endif  /* EBCDIC */++/* -------------- End of whitespace macros -------------- */+++/* PCRE2 is able to support several different kinds of newline (CR, LF, CRLF,+"any" and "anycrlf" at present). The following macros are used to package up+testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various+modules to indicate in which datablock the parameters exist, and what the+start/end of string field names are. */++#define NLTYPE_FIXED    0     /* Newline is a fixed length string */+#define NLTYPE_ANY      1     /* Newline is any Unicode line ending */+#define NLTYPE_ANYCRLF  2     /* Newline is CR, LF, or CRLF */++/* This macro checks for a newline at the given position */++#define IS_NEWLINE(p) \+  ((NLBLOCK->nltype != NLTYPE_FIXED)? \+    ((p) < NLBLOCK->PSEND && \+     PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \+       &(NLBLOCK->nllen), utf)) \+    : \+    ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \+     UCHAR21TEST(p) == NLBLOCK->nl[0] && \+     (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1])       \+    ) \+  )++/* This macro checks for a newline immediately preceding the given position */++#define WAS_NEWLINE(p) \+  ((NLBLOCK->nltype != NLTYPE_FIXED)? \+    ((p) > NLBLOCK->PSSTART && \+     PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \+       &(NLBLOCK->nllen), utf)) \+    : \+    ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \+     UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] &&              \+     (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \+    ) \+  )++/* Private flags containing information about the compiled pattern. The first+three must not be changed, because whichever is set is actually the number of+bytes in a code unit in that mode. */++#define PCRE2_MODE8         0x00000001  /* compiled in 8 bit mode */+#define PCRE2_MODE16        0x00000002  /* compiled in 16 bit mode */+#define PCRE2_MODE32        0x00000004  /* compiled in 32 bit mode */+#define PCRE2_FIRSTSET      0x00000010  /* first_code unit is set */+#define PCRE2_FIRSTCASELESS 0x00000020  /* caseless first code unit */+#define PCRE2_FIRSTMAPSET   0x00000040  /* bitmap of first code units is set */+#define PCRE2_LASTSET       0x00000080  /* last code unit is set */+#define PCRE2_LASTCASELESS  0x00000100  /* caseless last code unit */+#define PCRE2_STARTLINE     0x00000200  /* start after \n for multiline */+#define PCRE2_JCHANGED      0x00000400  /* j option used in pattern */+#define PCRE2_HASCRORLF     0x00000800  /* explicit \r or \n in pattern */+#define PCRE2_HASTHEN       0x00001000  /* pattern contains (*THEN) */+#define PCRE2_MATCH_EMPTY   0x00002000  /* pattern can match empty string */+#define PCRE2_BSR_SET       0x00004000  /* BSR was set in the pattern */+#define PCRE2_NL_SET        0x00008000  /* newline was set in the pattern */+#define PCRE2_NOTEMPTY_SET  0x00010000  /* (*NOTEMPTY) used        ) keep */+#define PCRE2_NE_ATST_SET   0x00020000  /* (*NOTEMPTY_ATSTART) used) together */+#define PCRE2_DEREF_TABLES  0x00040000  /* release character tables */+#define PCRE2_NOJIT         0x00080000  /* (*NOJIT) used */+#define PCRE2_HASBKPORX     0x00100000  /* contains \P, \p, or \X */+#define PCRE2_DUPCAPUSED    0x00200000  /* contains (?| */+#define PCRE2_HASBKC        0x00400000  /* contains \C */+#define PCRE2_HASACCEPT     0x00800000  /* contains (*ACCEPT) */++#define PCRE2_MODE_MASK     (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32)++/* Values for the matchedby field in a match data block. */++enum { PCRE2_MATCHEDBY_INTERPRETER,     /* pcre2_match() */+       PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */+       PCRE2_MATCHEDBY_JIT };           /* pcre2_jit_match() */++/* Values for the flags field in a match data block. */++#define PCRE2_MD_COPIED_SUBJECT  0x01u++/* Magic number to provide a small check against being handed junk. */++#define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */++/* The maximum remaining length of subject we are prepared to search for a+req_unit match from an anchored pattern. 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       5000+#else+#define REQ_CU_MAX       2000+#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+these tables. */++#define cbit_space     0      /* [:space:] or \s */+#define cbit_xdigit   32      /* [:xdigit:] */+#define cbit_digit    64      /* [:digit:] or \d */+#define cbit_upper    96      /* [:upper:] */+#define cbit_lower   128      /* [:lower:] */+#define cbit_word    160      /* [:word:] or \w */+#define cbit_graph   192      /* [:graph:] */+#define cbit_print   224      /* [:print:] */+#define cbit_punct   256      /* [:punct:] */+#define cbit_cntrl   288      /* [:cntrl:] */+#define cbit_length  320      /* Length of the cbits table */++/* Bit definitions for entries in the ctypes table. Do not change these values+without checking pcre2_jit_compile.c, which has an assertion to ensure that+ctype_word has the value 16. */++#define ctype_space    0x01+#define ctype_letter   0x02+#define ctype_lcletter 0x04+#define ctype_digit    0x08+#define ctype_word     0x10    /* alphanumeric or '_' */++/* Offsets of the various tables from the base tables pointer, and+total length of the tables. */++#define lcc_offset      0                           /* Lower case */+#define fcc_offset    256                           /* Flip case */+#define cbits_offset  512                           /* Character classes */+#define ctypes_offset (cbits_offset + cbit_length)  /* Character types */+#define TABLES_LENGTH (ctypes_offset + 256)+++/* -------------------- Character and string names ------------------------ */++/* If PCRE2 is to support UTF-8 on EBCDIC platforms, we cannot use normal+character constants like '*' because the compiler would emit their EBCDIC code,+which is different from their ASCII/UTF-8 code. Instead we define macros for+the characters so that they always use the ASCII/UTF-8 code when UTF-8 support+is enabled. When UTF-8 support is not enabled, the definitions use character+literals. Both character and string versions of each character are needed, and+there are some longer strings as well.++This means that, on EBCDIC platforms, the PCRE2 library can handle either+EBCDIC, or UTF-8, but not both. To support both in the same compiled library+would need different lookups depending on whether PCRE2_UTF was set or not.+This would make it impossible to use characters in switch/case statements,+which would reduce performance. For a theoretical use (which nobody has asked+for) in a minority area (EBCDIC platforms), this is not sensible. Any+application that did need both could compile two versions of the library, using+macros to give the functions distinct names. */++#ifndef SUPPORT_UNICODE++/* UTF-8 support is not enabled; use the platform-dependent character literals+so that PCRE2 works in both ASCII and EBCDIC environments, but only in non-UTF+mode. Newline characters are problematic in EBCDIC. Though it has CR and LF+characters, a common practice has been to use its NL (0x15) character as the+line terminator in C-like processing environments. However, sometimes the LF+(0x25) character is used instead, according to this Unicode document:++http://unicode.org/standard/reports/tr13/tr13-5.html++PCRE2 defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25+instead. Whichever is *not* chosen is defined as NEL.++In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the+same code point. */++#ifdef EBCDIC++#ifndef EBCDIC_NL25+#define CHAR_NL                     '\x15'+#define CHAR_NEL                    '\x25'+#define STR_NL                      "\x15"+#define STR_NEL                     "\x25"+#else+#define CHAR_NL                     '\x25'+#define CHAR_NEL                    '\x15'+#define STR_NL                      "\x25"+#define STR_NEL                     "\x15"+#endif++#define CHAR_LF                     CHAR_NL+#define STR_LF                      STR_NL++#define CHAR_ESC                    '\047'+#define CHAR_DEL                    '\007'+#define CHAR_NBSP                   ((unsigned char)'\x41')+#define STR_ESC                     "\047"+#define STR_DEL                     "\007"++#else  /* Not EBCDIC */++/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for+compatibility. NEL is the Unicode newline character; make sure it is+a positive value. */++#define CHAR_LF                     '\n'+#define CHAR_NL                     CHAR_LF+#define CHAR_NEL                    ((unsigned char)'\x85')+#define CHAR_ESC                    '\033'+#define CHAR_DEL                    '\177'+#define CHAR_NBSP                   ((unsigned char)'\xa0')++#define STR_LF                      "\n"+#define STR_NL                      STR_LF+#define STR_NEL                     "\x85"+#define STR_ESC                     "\033"+#define STR_DEL                     "\177"++#endif  /* EBCDIC */++/* The remaining definitions work in both environments. */++#define CHAR_NUL                    '\0'+#define CHAR_HT                     '\t'+#define CHAR_VT                     '\v'+#define CHAR_FF                     '\f'+#define CHAR_CR                     '\r'+#define CHAR_BS                     '\b'+#define CHAR_BEL                    '\a'++#define CHAR_SPACE                  ' '+#define CHAR_EXCLAMATION_MARK       '!'+#define CHAR_QUOTATION_MARK         '"'+#define CHAR_NUMBER_SIGN            '#'+#define CHAR_DOLLAR_SIGN            '$'+#define CHAR_PERCENT_SIGN           '%'+#define CHAR_AMPERSAND              '&'+#define CHAR_APOSTROPHE             '\''+#define CHAR_LEFT_PARENTHESIS       '('+#define CHAR_RIGHT_PARENTHESIS      ')'+#define CHAR_ASTERISK               '*'+#define CHAR_PLUS                   '+'+#define CHAR_COMMA                  ','+#define CHAR_MINUS                  '-'+#define CHAR_DOT                    '.'+#define CHAR_SLASH                  '/'+#define CHAR_0                      '0'+#define CHAR_1                      '1'+#define CHAR_2                      '2'+#define CHAR_3                      '3'+#define CHAR_4                      '4'+#define CHAR_5                      '5'+#define CHAR_6                      '6'+#define CHAR_7                      '7'+#define CHAR_8                      '8'+#define CHAR_9                      '9'+#define CHAR_COLON                  ':'+#define CHAR_SEMICOLON              ';'+#define CHAR_LESS_THAN_SIGN         '<'+#define CHAR_EQUALS_SIGN            '='+#define CHAR_GREATER_THAN_SIGN      '>'+#define CHAR_QUESTION_MARK          '?'+#define CHAR_COMMERCIAL_AT          '@'+#define CHAR_A                      'A'+#define CHAR_B                      'B'+#define CHAR_C                      'C'+#define CHAR_D                      'D'+#define CHAR_E                      'E'+#define CHAR_F                      'F'+#define CHAR_G                      'G'+#define CHAR_H                      'H'+#define CHAR_I                      'I'+#define CHAR_J                      'J'+#define CHAR_K                      'K'+#define CHAR_L                      'L'+#define CHAR_M                      'M'+#define CHAR_N                      'N'+#define CHAR_O                      'O'+#define CHAR_P                      'P'+#define CHAR_Q                      'Q'+#define CHAR_R                      'R'+#define CHAR_S                      'S'+#define CHAR_T                      'T'+#define CHAR_U                      'U'+#define CHAR_V                      'V'+#define CHAR_W                      'W'+#define CHAR_X                      'X'+#define CHAR_Y                      'Y'+#define CHAR_Z                      'Z'+#define CHAR_LEFT_SQUARE_BRACKET    '['+#define CHAR_BACKSLASH              '\\'+#define CHAR_RIGHT_SQUARE_BRACKET   ']'+#define CHAR_CIRCUMFLEX_ACCENT      '^'+#define CHAR_UNDERSCORE             '_'+#define CHAR_GRAVE_ACCENT           '`'+#define CHAR_a                      'a'+#define CHAR_b                      'b'+#define CHAR_c                      'c'+#define CHAR_d                      'd'+#define CHAR_e                      'e'+#define CHAR_f                      'f'+#define CHAR_g                      'g'+#define CHAR_h                      'h'+#define CHAR_i                      'i'+#define CHAR_j                      'j'+#define CHAR_k                      'k'+#define CHAR_l                      'l'+#define CHAR_m                      'm'+#define CHAR_n                      'n'+#define CHAR_o                      'o'+#define CHAR_p                      'p'+#define CHAR_q                      'q'+#define CHAR_r                      'r'+#define CHAR_s                      's'+#define CHAR_t                      't'+#define CHAR_u                      'u'+#define CHAR_v                      'v'+#define CHAR_w                      'w'+#define CHAR_x                      'x'+#define CHAR_y                      'y'+#define CHAR_z                      'z'+#define CHAR_LEFT_CURLY_BRACKET     '{'+#define CHAR_VERTICAL_LINE          '|'+#define CHAR_RIGHT_CURLY_BRACKET    '}'+#define CHAR_TILDE                  '~'++#define STR_HT                      "\t"+#define STR_VT                      "\v"+#define STR_FF                      "\f"+#define STR_CR                      "\r"+#define STR_BS                      "\b"+#define STR_BEL                     "\a"++#define STR_SPACE                   " "+#define STR_EXCLAMATION_MARK        "!"+#define STR_QUOTATION_MARK          "\""+#define STR_NUMBER_SIGN             "#"+#define STR_DOLLAR_SIGN             "$"+#define STR_PERCENT_SIGN            "%"+#define STR_AMPERSAND               "&"+#define STR_APOSTROPHE              "'"+#define STR_LEFT_PARENTHESIS        "("+#define STR_RIGHT_PARENTHESIS       ")"+#define STR_ASTERISK                "*"+#define STR_PLUS                    "+"+#define STR_COMMA                   ","+#define STR_MINUS                   "-"+#define STR_DOT                     "."+#define STR_SLASH                   "/"+#define STR_0                       "0"+#define STR_1                       "1"+#define STR_2                       "2"+#define STR_3                       "3"+#define STR_4                       "4"+#define STR_5                       "5"+#define STR_6                       "6"+#define STR_7                       "7"+#define STR_8                       "8"+#define STR_9                       "9"+#define STR_COLON                   ":"+#define STR_SEMICOLON               ";"+#define STR_LESS_THAN_SIGN          "<"+#define STR_EQUALS_SIGN             "="+#define STR_GREATER_THAN_SIGN       ">"+#define STR_QUESTION_MARK           "?"+#define STR_COMMERCIAL_AT           "@"+#define STR_A                       "A"+#define STR_B                       "B"+#define STR_C                       "C"+#define STR_D                       "D"+#define STR_E                       "E"+#define STR_F                       "F"+#define STR_G                       "G"+#define STR_H                       "H"+#define STR_I                       "I"+#define STR_J                       "J"+#define STR_K                       "K"+#define STR_L                       "L"+#define STR_M                       "M"+#define STR_N                       "N"+#define STR_O                       "O"+#define STR_P                       "P"+#define STR_Q                       "Q"+#define STR_R                       "R"+#define STR_S                       "S"+#define STR_T                       "T"+#define STR_U                       "U"+#define STR_V                       "V"+#define STR_W                       "W"+#define STR_X                       "X"+#define STR_Y                       "Y"+#define STR_Z                       "Z"+#define STR_LEFT_SQUARE_BRACKET     "["+#define STR_BACKSLASH               "\\"+#define STR_RIGHT_SQUARE_BRACKET    "]"+#define STR_CIRCUMFLEX_ACCENT       "^"+#define STR_UNDERSCORE              "_"+#define STR_GRAVE_ACCENT            "`"+#define STR_a                       "a"+#define STR_b                       "b"+#define STR_c                       "c"+#define STR_d                       "d"+#define STR_e                       "e"+#define STR_f                       "f"+#define STR_g                       "g"+#define STR_h                       "h"+#define STR_i                       "i"+#define STR_j                       "j"+#define STR_k                       "k"+#define STR_l                       "l"+#define STR_m                       "m"+#define STR_n                       "n"+#define STR_o                       "o"+#define STR_p                       "p"+#define STR_q                       "q"+#define STR_r                       "r"+#define STR_s                       "s"+#define STR_t                       "t"+#define STR_u                       "u"+#define STR_v                       "v"+#define STR_w                       "w"+#define STR_x                       "x"+#define STR_y                       "y"+#define STR_z                       "z"+#define STR_LEFT_CURLY_BRACKET      "{"+#define STR_VERTICAL_LINE           "|"+#define STR_RIGHT_CURLY_BRACKET     "}"+#define STR_TILDE                   "~"++#define STRING_ACCEPT0               "ACCEPT\0"+#define STRING_COMMIT0               "COMMIT\0"+#define STRING_F0                    "F\0"+#define STRING_FAIL0                 "FAIL\0"+#define STRING_MARK0                 "MARK\0"+#define STRING_PRUNE0                "PRUNE\0"+#define STRING_SKIP0                 "SKIP\0"+#define STRING_THEN                  "THEN"++#define STRING_atomic0               "atomic\0"+#define STRING_pla0                  "pla\0"+#define STRING_plb0                  "plb\0"+#define STRING_napla0                "napla\0"+#define STRING_naplb0                "naplb\0"+#define STRING_nla0                  "nla\0"+#define STRING_nlb0                  "nlb\0"+#define STRING_sr0                   "sr\0"+#define STRING_asr0                  "asr\0"+#define STRING_positive_lookahead0   "positive_lookahead\0"+#define STRING_positive_lookbehind0  "positive_lookbehind\0"+#define STRING_non_atomic_positive_lookahead0   "non_atomic_positive_lookahead\0"+#define STRING_non_atomic_positive_lookbehind0  "non_atomic_positive_lookbehind\0"+#define STRING_negative_lookahead0   "negative_lookahead\0"+#define STRING_negative_lookbehind0  "negative_lookbehind\0"+#define STRING_script_run0           "script_run\0"+#define STRING_atomic_script_run     "atomic_script_run"++#define STRING_alpha0                "alpha\0"+#define STRING_lower0                "lower\0"+#define STRING_upper0                "upper\0"+#define STRING_alnum0                "alnum\0"+#define STRING_ascii0                "ascii\0"+#define STRING_blank0                "blank\0"+#define STRING_cntrl0                "cntrl\0"+#define STRING_digit0                "digit\0"+#define STRING_graph0                "graph\0"+#define STRING_print0                "print\0"+#define STRING_punct0                "punct\0"+#define STRING_space0                "space\0"+#define STRING_word0                 "word\0"+#define STRING_xdigit                "xdigit"++#define STRING_DEFINE                "DEFINE"+#define STRING_VERSION               "VERSION"+#define STRING_WEIRD_STARTWORD       "[:<:]]"+#define STRING_WEIRD_ENDWORD         "[:>:]]"++#define STRING_CR_RIGHTPAR                "CR)"+#define STRING_LF_RIGHTPAR                "LF)"+#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)"+#define STRING_UTF16_RIGHTPAR             "UTF16)"+#define STRING_UTF32_RIGHTPAR             "UTF32)"+#define STRING_UTF_RIGHTPAR               "UTF)"+#define STRING_UCP_RIGHTPAR               "UCP)"+#define STRING_NO_AUTO_POSSESS_RIGHTPAR   "NO_AUTO_POSSESS)"+#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR "NO_DOTSTAR_ANCHOR)"+#define STRING_NO_JIT_RIGHTPAR            "NO_JIT)"+#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"++#else  /* SUPPORT_UNICODE */++/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This+works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode+only. */++#define CHAR_HT                     '\011'+#define CHAR_VT                     '\013'+#define CHAR_FF                     '\014'+#define CHAR_CR                     '\015'+#define CHAR_LF                     '\012'+#define CHAR_NL                     CHAR_LF+#define CHAR_NEL                    ((unsigned char)'\x85')+#define CHAR_BS                     '\010'+#define CHAR_BEL                    '\007'+#define CHAR_ESC                    '\033'+#define CHAR_DEL                    '\177'++#define CHAR_NUL                    '\0'+#define CHAR_SPACE                  '\040'+#define CHAR_EXCLAMATION_MARK       '\041'+#define CHAR_QUOTATION_MARK         '\042'+#define CHAR_NUMBER_SIGN            '\043'+#define CHAR_DOLLAR_SIGN            '\044'+#define CHAR_PERCENT_SIGN           '\045'+#define CHAR_AMPERSAND              '\046'+#define CHAR_APOSTROPHE             '\047'+#define CHAR_LEFT_PARENTHESIS       '\050'+#define CHAR_RIGHT_PARENTHESIS      '\051'+#define CHAR_ASTERISK               '\052'+#define CHAR_PLUS                   '\053'+#define CHAR_COMMA                  '\054'+#define CHAR_MINUS                  '\055'+#define CHAR_DOT                    '\056'+#define CHAR_SLASH                  '\057'+#define CHAR_0                      '\060'+#define CHAR_1                      '\061'+#define CHAR_2                      '\062'+#define CHAR_3                      '\063'+#define CHAR_4                      '\064'+#define CHAR_5                      '\065'+#define CHAR_6                      '\066'+#define CHAR_7                      '\067'+#define CHAR_8                      '\070'+#define CHAR_9                      '\071'+#define CHAR_COLON                  '\072'+#define CHAR_SEMICOLON              '\073'+#define CHAR_LESS_THAN_SIGN         '\074'+#define CHAR_EQUALS_SIGN            '\075'+#define CHAR_GREATER_THAN_SIGN      '\076'+#define CHAR_QUESTION_MARK          '\077'+#define CHAR_COMMERCIAL_AT          '\100'+#define CHAR_A                      '\101'+#define CHAR_B                      '\102'+#define CHAR_C                      '\103'+#define CHAR_D                      '\104'+#define CHAR_E                      '\105'+#define CHAR_F                      '\106'+#define CHAR_G                      '\107'+#define CHAR_H                      '\110'+#define CHAR_I                      '\111'+#define CHAR_J                      '\112'+#define CHAR_K                      '\113'+#define CHAR_L                      '\114'+#define CHAR_M                      '\115'+#define CHAR_N                      '\116'+#define CHAR_O                      '\117'+#define CHAR_P                      '\120'+#define CHAR_Q                      '\121'+#define CHAR_R                      '\122'+#define CHAR_S                      '\123'+#define CHAR_T                      '\124'+#define CHAR_U                      '\125'+#define CHAR_V                      '\126'+#define CHAR_W                      '\127'+#define CHAR_X                      '\130'+#define CHAR_Y                      '\131'+#define CHAR_Z                      '\132'+#define CHAR_LEFT_SQUARE_BRACKET    '\133'+#define CHAR_BACKSLASH              '\134'+#define CHAR_RIGHT_SQUARE_BRACKET   '\135'+#define CHAR_CIRCUMFLEX_ACCENT      '\136'+#define CHAR_UNDERSCORE             '\137'+#define CHAR_GRAVE_ACCENT           '\140'+#define CHAR_a                      '\141'+#define CHAR_b                      '\142'+#define CHAR_c                      '\143'+#define CHAR_d                      '\144'+#define CHAR_e                      '\145'+#define CHAR_f                      '\146'+#define CHAR_g                      '\147'+#define CHAR_h                      '\150'+#define CHAR_i                      '\151'+#define CHAR_j                      '\152'+#define CHAR_k                      '\153'+#define CHAR_l                      '\154'+#define CHAR_m                      '\155'+#define CHAR_n                      '\156'+#define CHAR_o                      '\157'+#define CHAR_p                      '\160'+#define CHAR_q                      '\161'+#define CHAR_r                      '\162'+#define CHAR_s                      '\163'+#define CHAR_t                      '\164'+#define CHAR_u                      '\165'+#define CHAR_v                      '\166'+#define CHAR_w                      '\167'+#define CHAR_x                      '\170'+#define CHAR_y                      '\171'+#define CHAR_z                      '\172'+#define CHAR_LEFT_CURLY_BRACKET     '\173'+#define CHAR_VERTICAL_LINE          '\174'+#define CHAR_RIGHT_CURLY_BRACKET    '\175'+#define CHAR_TILDE                  '\176'+#define CHAR_NBSP                   ((unsigned char)'\xa0')++#define STR_HT                      "\011"+#define STR_VT                      "\013"+#define STR_FF                      "\014"+#define STR_CR                      "\015"+#define STR_NL                      "\012"+#define STR_BS                      "\010"+#define STR_BEL                     "\007"+#define STR_ESC                     "\033"+#define STR_DEL                     "\177"++#define STR_SPACE                   "\040"+#define STR_EXCLAMATION_MARK        "\041"+#define STR_QUOTATION_MARK          "\042"+#define STR_NUMBER_SIGN             "\043"+#define STR_DOLLAR_SIGN             "\044"+#define STR_PERCENT_SIGN            "\045"+#define STR_AMPERSAND               "\046"+#define STR_APOSTROPHE              "\047"+#define STR_LEFT_PARENTHESIS        "\050"+#define STR_RIGHT_PARENTHESIS       "\051"+#define STR_ASTERISK                "\052"+#define STR_PLUS                    "\053"+#define STR_COMMA                   "\054"+#define STR_MINUS                   "\055"+#define STR_DOT                     "\056"+#define STR_SLASH                   "\057"+#define STR_0                       "\060"+#define STR_1                       "\061"+#define STR_2                       "\062"+#define STR_3                       "\063"+#define STR_4                       "\064"+#define STR_5                       "\065"+#define STR_6                       "\066"+#define STR_7                       "\067"+#define STR_8                       "\070"+#define STR_9                       "\071"+#define STR_COLON                   "\072"+#define STR_SEMICOLON               "\073"+#define STR_LESS_THAN_SIGN          "\074"+#define STR_EQUALS_SIGN             "\075"+#define STR_GREATER_THAN_SIGN       "\076"+#define STR_QUESTION_MARK           "\077"+#define STR_COMMERCIAL_AT           "\100"+#define STR_A                       "\101"+#define STR_B                       "\102"+#define STR_C                       "\103"+#define STR_D                       "\104"+#define STR_E                       "\105"+#define STR_F                       "\106"+#define STR_G                       "\107"+#define STR_H                       "\110"+#define STR_I                       "\111"+#define STR_J                       "\112"+#define STR_K                       "\113"+#define STR_L                       "\114"+#define STR_M                       "\115"+#define STR_N                       "\116"+#define STR_O                       "\117"+#define STR_P                       "\120"+#define STR_Q                       "\121"+#define STR_R                       "\122"+#define STR_S                       "\123"+#define STR_T                       "\124"+#define STR_U                       "\125"+#define STR_V                       "\126"+#define STR_W                       "\127"+#define STR_X                       "\130"+#define STR_Y                       "\131"+#define STR_Z                       "\132"+#define STR_LEFT_SQUARE_BRACKET     "\133"+#define STR_BACKSLASH               "\134"+#define STR_RIGHT_SQUARE_BRACKET    "\135"+#define STR_CIRCUMFLEX_ACCENT       "\136"+#define STR_UNDERSCORE              "\137"+#define STR_GRAVE_ACCENT            "\140"+#define STR_a                       "\141"+#define STR_b                       "\142"+#define STR_c                       "\143"+#define STR_d                       "\144"+#define STR_e                       "\145"+#define STR_f                       "\146"+#define STR_g                       "\147"+#define STR_h                       "\150"+#define STR_i                       "\151"+#define STR_j                       "\152"+#define STR_k                       "\153"+#define STR_l                       "\154"+#define STR_m                       "\155"+#define STR_n                       "\156"+#define STR_o                       "\157"+#define STR_p                       "\160"+#define STR_q                       "\161"+#define STR_r                       "\162"+#define STR_s                       "\163"+#define STR_t                       "\164"+#define STR_u                       "\165"+#define STR_v                       "\166"+#define STR_w                       "\167"+#define STR_x                       "\170"+#define STR_y                       "\171"+#define STR_z                       "\172"+#define STR_LEFT_CURLY_BRACKET      "\173"+#define STR_VERTICAL_LINE           "\174"+#define STR_RIGHT_CURLY_BRACKET     "\175"+#define STR_TILDE                   "\176"++#define STRING_ACCEPT0               STR_A STR_C STR_C STR_E STR_P STR_T "\0"+#define STRING_COMMIT0               STR_C STR_O STR_M STR_M STR_I STR_T "\0"+#define STRING_F0                    STR_F "\0"+#define STRING_FAIL0                 STR_F STR_A STR_I STR_L "\0"+#define STRING_MARK0                 STR_M STR_A STR_R STR_K "\0"+#define STRING_PRUNE0                STR_P STR_R STR_U STR_N STR_E "\0"+#define STRING_SKIP0                 STR_S STR_K STR_I STR_P "\0"+#define STRING_THEN                  STR_T STR_H STR_E STR_N++#define STRING_atomic0               STR_a STR_t STR_o STR_m STR_i STR_c "\0"+#define STRING_pla0                  STR_p STR_l STR_a "\0"+#define STRING_plb0                  STR_p STR_l STR_b "\0"+#define STRING_napla0                STR_n STR_a STR_p STR_l STR_a "\0"+#define STRING_naplb0                STR_n STR_a STR_p STR_l STR_b "\0"+#define STRING_nla0                  STR_n STR_l STR_a "\0"+#define STRING_nlb0                  STR_n STR_l STR_b "\0"+#define STRING_sr0                   STR_s STR_r "\0"+#define STRING_asr0                  STR_a STR_s STR_r "\0"+#define STRING_positive_lookahead0   STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"+#define STRING_positive_lookbehind0  STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"+#define STRING_non_atomic_positive_lookahead0   STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"+#define STRING_non_atomic_positive_lookbehind0  STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"+#define STRING_negative_lookahead0   STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"+#define STRING_negative_lookbehind0  STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"+#define STRING_script_run0           STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0"+#define STRING_atomic_script_run     STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n++#define STRING_alpha0                STR_a STR_l STR_p STR_h STR_a "\0"+#define STRING_lower0                STR_l STR_o STR_w STR_e STR_r "\0"+#define STRING_upper0                STR_u STR_p STR_p STR_e STR_r "\0"+#define STRING_alnum0                STR_a STR_l STR_n STR_u STR_m "\0"+#define STRING_ascii0                STR_a STR_s STR_c STR_i STR_i "\0"+#define STRING_blank0                STR_b STR_l STR_a STR_n STR_k "\0"+#define STRING_cntrl0                STR_c STR_n STR_t STR_r STR_l "\0"+#define STRING_digit0                STR_d STR_i STR_g STR_i STR_t "\0"+#define STRING_graph0                STR_g STR_r STR_a STR_p STR_h "\0"+#define STRING_print0                STR_p STR_r STR_i STR_n STR_t "\0"+#define STRING_punct0                STR_p STR_u STR_n STR_c STR_t "\0"+#define STRING_space0                STR_s STR_p STR_a STR_c STR_e "\0"+#define STRING_word0                 STR_w STR_o STR_r STR_d       "\0"+#define STRING_xdigit                STR_x STR_d STR_i STR_g STR_i STR_t++#define STRING_DEFINE                STR_D STR_E STR_F STR_I STR_N STR_E+#define STRING_VERSION               STR_V STR_E STR_R STR_S STR_I STR_O STR_N+#define STRING_WEIRD_STARTWORD       STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET+#define STRING_WEIRD_ENDWORD         STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET++#define STRING_CR_RIGHTPAR                STR_C STR_R STR_RIGHT_PARENTHESIS+#define STRING_LF_RIGHTPAR                STR_L STR_F STR_RIGHT_PARENTHESIS+#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+#define STRING_UTF16_RIGHTPAR             STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS+#define STRING_UTF32_RIGHTPAR             STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS+#define STRING_UTF_RIGHTPAR               STR_U STR_T STR_F STR_RIGHT_PARENTHESIS+#define STRING_UCP_RIGHTPAR               STR_U STR_C STR_P STR_RIGHT_PARENTHESIS+#define STRING_NO_AUTO_POSSESS_RIGHTPAR   STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS+#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_D STR_O STR_T STR_S STR_T STR_A STR_R STR_UNDERSCORE STR_A STR_N STR_C STR_H STR_O STR_R STR_RIGHT_PARENTHESIS+#define STRING_NO_JIT_RIGHTPAR            STR_N STR_O STR_UNDERSCORE STR_J STR_I STR_T STR_RIGHT_PARENTHESIS+#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++#endif  /* SUPPORT_UNICODE */++/* -------------------- End of character and string names -------------------*/++/* -------------------- Definitions for compiled patterns -------------------*/++/* Codes for different types of Unicode property */++#define PT_ANY        0    /* Any property - matches all chars */+#define PT_LAMP       1    /* L& - the union of Lu, Ll, Lt */+#define PT_GC         2    /* Specified general characteristic (e.g. L) */+#define PT_PC         3    /* Specified particular characteristic (e.g. Lu) */+#define PT_SC         4    /* Script (e.g. Han) */+#define PT_ALNUM      5    /* Alphanumeric - the union of L and N */+#define PT_SPACE      6    /* Perl space - Z plus 9,10,12,13 */+#define PT_PXSPACE    7    /* POSIX space - Z plus 9,10,11,12,13 */+#define PT_WORD       8    /* Word - L plus N plus underscore */+#define PT_CLIST      9    /* Pseudo-property: match character list */+#define PT_UCNC      10    /* Universal Character nameable character */+#define PT_TABSIZE   11    /* Size of square table for autopossessify tests */++/* The following special properties are used only in XCLASS items, when POSIX+classes are specified and PCRE2_UCP is set - in other words, for Unicode+handling of these classes. They are not available via the \p or \P escapes like+those in the above list, and so they do not take part in the autopossessifying+table. */++#define PT_PXGRAPH   11    /* [:graph:] - characters that mark the paper */+#define PT_PXPRINT   12    /* [:print:] - [:graph:] plus non-control spaces */+#define PT_PXPUNCT   13    /* [:punct:] - punctuation characters */++/* Flag bits and data types for the extended class (OP_XCLASS) for classes that+contain characters with values greater than 255. */++#define XCL_NOT       0x01    /* Flag: this is a negative class */+#define XCL_MAP       0x02    /* Flag: a 32-byte map is present */+#define XCL_HASPROP   0x04    /* Flag: property checks are present. */++#define XCL_END       0    /* Marks end of individual items */+#define XCL_SINGLE    1    /* Single item (one multibyte char) follows */+#define XCL_RANGE     2    /* A range (two multibyte chars) follows */+#define XCL_PROP      3    /* Unicode property (2-byte property code follows) */+#define XCL_NOTPROP   4    /* Unicode inverted property (ditto) */++/* These are escaped items that aren't just an encoding of a particular data+value such as \n. They must have non-zero values, as check_escape() returns 0+for a data character. In the escapes[] table in pcre2_compile.c their values+are negated in order to distinguish them from data values.++They must appear here in the same order as in the opcode definitions below, up+to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL+mode rather than an escape sequence. It is also used for [^] in JavaScript+compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves+like \N.++Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in+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 };+++/********************** Opcode definitions ******************/++/****** NOTE NOTE NOTE ******++Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in+order to the list of escapes immediately above. Furthermore, values up to+OP_DOLLM must not be changed without adjusting the table called autoposstab in+pcre2_auto_possess.c.++Whenever this list is updated, the two macro definitions that follow must be+updated to match. The possessification table called "opcode_possessify" in+pcre2_compile.c must also be updated, and also the tables called "coptable"+and "poptable" in pcre2_dfa_match.c.++****** NOTE NOTE NOTE ******/+++/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,+are used in a table for deciding whether a repeated character type can be+auto-possessified. */++#define FIRST_AUTOTAB_OP       OP_NOT_DIGIT+#define LAST_AUTOTAB_LEFT_OP   OP_EXTUNI+#define LAST_AUTOTAB_RIGHT_OP  OP_DOLLM++enum {+  OP_END,            /* 0 End of pattern */++  /* Values corresponding to backslashed metacharacters */++  OP_SOD,            /* 1 Start of data: \A */+  OP_SOM,            /* 2 Start of match (subject + offset): \G */+  OP_SET_SOM,        /* 3 Set start of match (\K) */+  OP_NOT_WORD_BOUNDARY,  /*  4 \B */+  OP_WORD_BOUNDARY,      /*  5 \b */+  OP_NOT_DIGIT,          /*  6 \D */+  OP_DIGIT,              /*  7 \d */+  OP_NOT_WHITESPACE,     /*  8 \S */+  OP_WHITESPACE,         /*  9 \s */+  OP_NOT_WORDCHAR,       /* 10 \W */+  OP_WORDCHAR,           /* 11 \w */++  OP_ANY,            /* 12 Match any character except newline (\N) */+  OP_ALLANY,         /* 13 Match any character */+  OP_ANYBYTE,        /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */+  OP_NOTPROP,        /* 15 \P (not Unicode property) */+  OP_PROP,           /* 16 \p (Unicode property) */+  OP_ANYNL,          /* 17 \R (any newline sequence) */+  OP_NOT_HSPACE,     /* 18 \H (not horizontal whitespace) */+  OP_HSPACE,         /* 19 \h (horizontal whitespace) */+  OP_NOT_VSPACE,     /* 20 \V (not vertical whitespace) */+  OP_VSPACE,         /* 21 \v (vertical whitespace) */+  OP_EXTUNI,         /* 22 \X (extended Unicode sequence */+  OP_EODN,           /* 23 End of data or \n at end of data (\Z) */+  OP_EOD,            /* 24 End of data (\z) */++  /* Line end assertions */++  OP_DOLL,           /* 25 End of line - not multiline */+  OP_DOLLM,          /* 26 End of line - multiline */+  OP_CIRC,           /* 27 Start of line - not multiline */+  OP_CIRCM,          /* 28 Start of line - multiline */++  /* 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 */+  OP_NOT,            /* 31 Match one character, not the given one, casefully */+  OP_NOTI,           /* 32 Match one character, not the given one, caselessly */++  /* The following sets of 13 opcodes must always be kept in step because+  the offset from the first one is used to generate the others. */++  /* Repeated characters; caseful must precede the caseless ones */++  OP_STAR,           /* 33 The maximizing and minimizing versions of */+  OP_MINSTAR,        /* 34 these six opcodes must come in pairs, with */+  OP_PLUS,           /* 35 the minimizing one second. */+  OP_MINPLUS,        /* 36 */+  OP_QUERY,          /* 37 */+  OP_MINQUERY,       /* 38 */++  OP_UPTO,           /* 39 From 0 to n matches of one character, caseful*/+  OP_MINUPTO,        /* 40 */+  OP_EXACT,          /* 41 Exactly n matches */++  OP_POSSTAR,        /* 42 Possessified star, caseful */+  OP_POSPLUS,        /* 43 Possessified plus, caseful */+  OP_POSQUERY,       /* 44 Posesssified query, caseful */+  OP_POSUPTO,        /* 45 Possessified upto, caseful */++  /* Repeated characters; caseless must follow the caseful ones */++  OP_STARI,          /* 46 */+  OP_MINSTARI,       /* 47 */+  OP_PLUSI,          /* 48 */+  OP_MINPLUSI,       /* 49 */+  OP_QUERYI,         /* 50 */+  OP_MINQUERYI,      /* 51 */++  OP_UPTOI,          /* 52 From 0 to n matches of one character, caseless */+  OP_MINUPTOI,       /* 53 */+  OP_EXACTI,         /* 54 */++  OP_POSSTARI,       /* 55 Possessified star, caseless */+  OP_POSPLUSI,       /* 56 Possessified plus, caseless */+  OP_POSQUERYI,      /* 57 Posesssified query, caseless */+  OP_POSUPTOI,       /* 58 Possessified upto, caseless */++  /* The negated ones must follow the non-negated ones, and match them */+  /* Negated repeated character, caseful; must precede the caseless ones */++  OP_NOTSTAR,        /* 59 The maximizing and minimizing versions of */+  OP_NOTMINSTAR,     /* 60 these six opcodes must come in pairs, with */+  OP_NOTPLUS,        /* 61 the minimizing one second. They must be in */+  OP_NOTMINPLUS,     /* 62 exactly the same order as those above. */+  OP_NOTQUERY,       /* 63 */+  OP_NOTMINQUERY,    /* 64 */++  OP_NOTUPTO,        /* 65 From 0 to n matches, caseful */+  OP_NOTMINUPTO,     /* 66 */+  OP_NOTEXACT,       /* 67 Exactly n matches */++  OP_NOTPOSSTAR,     /* 68 Possessified versions, caseful */+  OP_NOTPOSPLUS,     /* 69 */+  OP_NOTPOSQUERY,    /* 70 */+  OP_NOTPOSUPTO,     /* 71 */++  /* Negated repeated character, caseless; must follow the caseful ones */++  OP_NOTSTARI,       /* 72 */+  OP_NOTMINSTARI,    /* 73 */+  OP_NOTPLUSI,       /* 74 */+  OP_NOTMINPLUSI,    /* 75 */+  OP_NOTQUERYI,      /* 76 */+  OP_NOTMINQUERYI,   /* 77 */++  OP_NOTUPTOI,       /* 78 From 0 to n matches, caseless */+  OP_NOTMINUPTOI,    /* 79 */+  OP_NOTEXACTI,      /* 80 Exactly n matches */++  OP_NOTPOSSTARI,    /* 81 Possessified versions, caseless */+  OP_NOTPOSPLUSI,    /* 82 */+  OP_NOTPOSQUERYI,   /* 83 */+  OP_NOTPOSUPTOI,    /* 84 */++  /* Character types */++  OP_TYPESTAR,       /* 85 The maximizing and minimizing versions of */+  OP_TYPEMINSTAR,    /* 86 these six opcodes must come in pairs, with */+  OP_TYPEPLUS,       /* 87 the minimizing one second. These codes must */+  OP_TYPEMINPLUS,    /* 88 be in exactly the same order as those above. */+  OP_TYPEQUERY,      /* 89 */+  OP_TYPEMINQUERY,   /* 90 */++  OP_TYPEUPTO,       /* 91 From 0 to n matches */+  OP_TYPEMINUPTO,    /* 92 */+  OP_TYPEEXACT,      /* 93 Exactly n matches */++  OP_TYPEPOSSTAR,    /* 94 Possessified versions */+  OP_TYPEPOSPLUS,    /* 95 */+  OP_TYPEPOSQUERY,   /* 96 */+  OP_TYPEPOSUPTO,    /* 97 */++  /* These are used for character classes and back references; only the+  first six are the same as the sets above. */++  OP_CRSTAR,         /* 98 The maximizing and minimizing versions of */+  OP_CRMINSTAR,      /* 99 all these opcodes must come in pairs, with */+  OP_CRPLUS,         /* 100 the minimizing one second. These codes must */+  OP_CRMINPLUS,      /* 101 be in exactly the same order as those above. */+  OP_CRQUERY,        /* 102 */+  OP_CRMINQUERY,     /* 103 */++  OP_CRRANGE,        /* 104 These are different to the three sets above. */+  OP_CRMINRANGE,     /* 105 */++  OP_CRPOSSTAR,      /* 106 Possessified versions */+  OP_CRPOSPLUS,      /* 107 */+  OP_CRPOSQUERY,     /* 108 */+  OP_CRPOSRANGE,     /* 109 */++  /* End of quantifier opcodes */++  OP_CLASS,          /* 110 Match a character class, chars < 256 only */+  OP_NCLASS,         /* 111 Same, but the bitmap was created from a negative+                              class - the difference is relevant only when a+                              character > 255 is encountered. */+  OP_XCLASS,         /* 112 Extended class for handling > 255 chars within the+                              class. This does both positive and negative. */+  OP_REF,            /* 113 Match a back reference, casefully */+  OP_REFI,           /* 114 Match a back reference, caselessly */+  OP_DNREF,          /* 115 Match a duplicate name backref, casefully */+  OP_DNREFI,         /* 116 Match a duplicate name backref, caselessly */+  OP_RECURSE,        /* 117 Match a numbered subpattern (possibly recursive) */+  OP_CALLOUT,        /* 118 Call out to external function if provided */+  OP_CALLOUT_STR,    /* 119 Call out with string argument */++  OP_ALT,            /* 120 Start of alternation */+  OP_KET,            /* 121 End of group that doesn't have an unbounded repeat */+  OP_KETRMAX,        /* 122 These two must remain together and in this */+  OP_KETRMIN,        /* 123 order. They are for groups the repeat for ever. */+  OP_KETRPOS,        /* 124 Possessive unlimited repeat. */++  /* The assertions must come before BRA, CBRA, ONCE, and COND. */++  OP_REVERSE,        /* 125 Move pointer back - used in lookbehind assertions */+  OP_ASSERT,         /* 126 Positive lookahead */+  OP_ASSERT_NOT,     /* 127 Negative lookahead */+  OP_ASSERTBACK,     /* 128 Positive lookbehind */+  OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */+  OP_ASSERT_NA,      /* 130 Positive non-atomic lookahead */+  OP_ASSERTBACK_NA,  /* 131 Positive non-atomic lookbehind */++  /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come+  immediately after the assertions, with ONCE first, as there's a test for >=+  ONCE for a subpattern that isn't an assertion. The POS versions must+  immediately follow the non-POS versions in each case. */++  OP_ONCE,           /* 132 Atomic group, contains captures */+  OP_SCRIPT_RUN,     /* 133 Non-capture, but check characters' scripts */+  OP_BRA,            /* 134 Start of non-capturing bracket */+  OP_BRAPOS,         /* 135 Ditto, with unlimited, possessive repeat */+  OP_CBRA,           /* 136 Start of capturing bracket */+  OP_CBRAPOS,        /* 137 Ditto, with unlimited, possessive repeat */+  OP_COND,           /* 138 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,           /* 139 Start of non-capturing bracket, check empty  */+  OP_SBRAPOS,        /* 149 Ditto, with unlimited, possessive repeat */+  OP_SCBRA,          /* 141 Start of capturing bracket, check empty */+  OP_SCBRAPOS,       /* 142 Ditto, with unlimited, possessive repeat */+  OP_SCOND,          /* 143 Conditional group, check empty */++  /* The next two pairs must (respectively) be kept together. */++  OP_CREF,           /* 144 Used to hold a capture number as condition */+  OP_DNCREF,         /* 145 Used to point to duplicate names as a condition */+  OP_RREF,           /* 146 Used to hold a recursion number as condition */+  OP_DNRREF,         /* 147 Used to point to duplicate names as a condition */+  OP_FALSE,          /* 148 Always false (used by DEFINE and VERSION) */+  OP_TRUE,           /* 149 Always true (used by VERSION) */++  OP_BRAZERO,        /* 150 These two must remain together and in this */+  OP_BRAMINZERO,     /* 151 order. */+  OP_BRAPOSZERO,     /* 152 */++  /* These are backtracking control verbs */++  OP_MARK,           /* 153 always has an argument */+  OP_PRUNE,          /* 154 */+  OP_PRUNE_ARG,      /* 155 same, but with argument */+  OP_SKIP,           /* 156 */+  OP_SKIP_ARG,       /* 157 same, but with argument */+  OP_THEN,           /* 158 */+  OP_THEN_ARG,       /* 159 same, but with argument */+  OP_COMMIT,         /* 160 */+  OP_COMMIT_ARG,     /* 161 same, but with argument */++  /* These are forced failure and success verbs. FAIL and ACCEPT do accept an+  argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL)+  without the need for a special opcode. */++  OP_FAIL,           /* 162 */+  OP_ACCEPT,         /* 163 */+  OP_ASSERT_ACCEPT,  /* 164 Used inside assertions */+  OP_CLOSE,          /* 165 Used before OP_ACCEPT to close open captures */++  /* This is used to skip a subpattern with a {0} quantifier */++  OP_SKIPZERO,       /* 166 */++  /* 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,         /* 167 */++  /* 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+  some in the past. */++  OP_TABLE_LENGTH++};++/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro+definitions that follow must also be updated to match. There are also tables+called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in+pcre2_dfa_match.c that must be updated. */+++/* This macro defines textual names for all the opcodes. These are used only+for debugging, and some of them are only partial names. The macro is referenced+only in pcre2_printint.c, which fills out the full names in many cases (and in+some cases doesn't actually use these names at all). */++#define OP_NAME_LIST \+  "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d",         \+  "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte",         \+  "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v",           \+  "extuni",  "\\Z", "\\z",                                        \+  "$", "$", "^", "^", "char", "chari", "not", "noti",             \+  "*", "*?", "+", "+?", "?", "??",                                \+  "{", "{", "{",                                                  \+  "*+","++", "?+", "{",                                           \+  "*", "*?", "+", "+?", "?", "??",                                \+  "{", "{", "{",                                                  \+  "*+","++", "?+", "{",                                           \+  "*", "*?", "+", "+?", "?", "??",                                \+  "{", "{", "{",                                                  \+  "*+","++", "?+", "{",                                           \+  "*", "*?", "+", "+?", "?", "??",                                \+  "{", "{", "{",                                                  \+  "*+","++", "?+", "{",                                           \+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",                 \+  "*+","++", "?+", "{",                                           \+  "*", "*?", "+", "+?", "?", "??", "{", "{",                      \+  "*+","++", "?+", "{",                                           \+  "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi",  \+  "Recurse", "Callout", "CalloutStr",                             \+  "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos",                  \+  "Reverse", "Assert", "Assert not",                              \+  "Assert back", "Assert back not",                               \+  "Non-atomic assert", "Non-atomic assert back",                  \+  "Once",                                                         \+  "Script run",                                                   \+  "Bra", "BraPos", "CBra", "CBraPos",                             \+  "Cond",                                                         \+  "SBra", "SBraPos", "SCBra", "SCBraPos",                         \+  "SCond",                                                        \+  "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec",             \+  "Cond false", "Cond true",                                      \+  "Brazero", "Braminzero", "Braposzero",                          \+  "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP",                  \+  "*THEN", "*THEN", "*COMMIT", "*COMMIT", "*FAIL",                \+  "*ACCEPT", "*ASSERT_ACCEPT",                                    \+  "Close", "Skip zero", "Define"+++/* This macro defines the length of fixed length operations in the compiled+regex. The lengths are used when searching for specific things, and also in the+debugging printing of a compiled regex. We use a macro so that it can be+defined close to the definitions of the opcodes themselves.++As things have been extended, some of these are no longer fixed lenths, but are+minima instead. For example, the length of a single-character repeat may vary+in UTF-8 mode. The code that uses this table must know about such things. */++#define OP_LENGTHS \+  1,                             /* End                                    */ \+  1, 1, 1, 1, 1,                 /* \A, \G, \K, \B, \b                     */ \+  1, 1, 1, 1, 1, 1,              /* \D, \d, \S, \s, \W, \w                 */ \+  1, 1, 1,                       /* Any, AllAny, Anybyte                   */ \+  3, 3,                          /* \P, \p                                 */ \+  1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */ \+  1,                             /* \X                                     */ \+  1, 1, 1, 1, 1, 1,              /* \Z, \z, $, $M ^, ^M                    */ \+  2,                             /* Char  - the minimum length             */ \+  2,                             /* Chari  - the minimum length            */ \+  2,                             /* not                                    */ \+  2,                             /* noti                                   */ \+  /* Positive single-char repeats                             ** These are */ \+  2, 2, 2, 2, 2, 2,              /* *, *?, +, +?, ?, ??       ** minima in */ \+  2+IMM2_SIZE, 2+IMM2_SIZE,      /* upto, minupto             ** mode      */ \+  2+IMM2_SIZE,                   /* exact                                  */ \+  2, 2, 2, 2+IMM2_SIZE,          /* *+, ++, ?+, upto+                      */ \+  2, 2, 2, 2, 2, 2,              /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8     */ \+  2+IMM2_SIZE, 2+IMM2_SIZE,      /* upto I, minupto I                      */ \+  2+IMM2_SIZE,                   /* exact I                                */ \+  2, 2, 2, 2+IMM2_SIZE,          /* *+I, ++I, ?+I, upto+I                  */ \+  /* Negative single-char repeats - only for chars < 256                   */ \+  2, 2, 2, 2, 2, 2,              /* NOT *, *?, +, +?, ?, ??                */ \+  2+IMM2_SIZE, 2+IMM2_SIZE,      /* NOT upto, minupto                      */ \+  2+IMM2_SIZE,                   /* NOT exact                              */ \+  2, 2, 2, 2+IMM2_SIZE,          /* Possessive NOT *, +, ?, upto           */ \+  2, 2, 2, 2, 2, 2,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */ \+  2+IMM2_SIZE, 2+IMM2_SIZE,      /* NOT upto I, minupto I                  */ \+  2+IMM2_SIZE,                   /* NOT exact I                            */ \+  2, 2, 2, 2+IMM2_SIZE,          /* Possessive NOT *I, +I, ?I, upto I      */ \+  /* Positive type repeats                                                 */ \+  2, 2, 2, 2, 2, 2,              /* Type *, *?, +, +?, ?, ??               */ \+  2+IMM2_SIZE, 2+IMM2_SIZE,      /* Type upto, minupto                     */ \+  2+IMM2_SIZE,                   /* Type exact                             */ \+  2, 2, 2, 2+IMM2_SIZE,          /* Possessive *+, ++, ?+, upto+           */ \+  /* Character class & ref repeats                                         */ \+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */ \+  1+2*IMM2_SIZE, 1+2*IMM2_SIZE,  /* CRRANGE, CRMINRANGE                    */ \+  1, 1, 1, 1+2*IMM2_SIZE,        /* Possessive *+, ++, ?+, CRPOSRANGE      */ \+  1+(32/sizeof(PCRE2_UCHAR)),    /* CLASS                                  */ \+  1+(32/sizeof(PCRE2_UCHAR)),    /* NCLASS                                 */ \+  0,                             /* XCLASS - variable length               */ \+  1+IMM2_SIZE,                   /* REF                                    */ \+  1+IMM2_SIZE,                   /* REFI                                   */ \+  1+2*IMM2_SIZE,                 /* DNREF                                  */ \+  1+2*IMM2_SIZE,                 /* DNREFI                                 */ \+  1+LINK_SIZE,                   /* RECURSE                                */ \+  1+2*LINK_SIZE+1,               /* CALLOUT                                */ \+  0,                             /* CALLOUT_STR - variable length          */ \+  1+LINK_SIZE,                   /* Alt                                    */ \+  1+LINK_SIZE,                   /* Ket                                    */ \+  1+LINK_SIZE,                   /* KetRmax                                */ \+  1+LINK_SIZE,                   /* KetRmin                                */ \+  1+LINK_SIZE,                   /* KetRpos                                */ \+  1+LINK_SIZE,                   /* Reverse                                */ \+  1+LINK_SIZE,                   /* Assert                                 */ \+  1+LINK_SIZE,                   /* Assert not                             */ \+  1+LINK_SIZE,                   /* Assert behind                          */ \+  1+LINK_SIZE,                   /* Assert behind not                      */ \+  1+LINK_SIZE,                   /* NA Assert                              */ \+  1+LINK_SIZE,                   /* NA Assert behind                       */ \+  1+LINK_SIZE,                   /* ONCE                                   */ \+  1+LINK_SIZE,                   /* SCRIPT_RUN                             */ \+  1+LINK_SIZE,                   /* BRA                                    */ \+  1+LINK_SIZE,                   /* BRAPOS                                 */ \+  1+LINK_SIZE+IMM2_SIZE,         /* CBRA                                   */ \+  1+LINK_SIZE+IMM2_SIZE,         /* CBRAPOS                                */ \+  1+LINK_SIZE,                   /* COND                                   */ \+  1+LINK_SIZE,                   /* SBRA                                   */ \+  1+LINK_SIZE,                   /* SBRAPOS                                */ \+  1+LINK_SIZE+IMM2_SIZE,         /* SCBRA                                  */ \+  1+LINK_SIZE+IMM2_SIZE,         /* SCBRAPOS                               */ \+  1+LINK_SIZE,                   /* SCOND                                  */ \+  1+IMM2_SIZE, 1+2*IMM2_SIZE,    /* CREF, DNCREF                           */ \+  1+IMM2_SIZE, 1+2*IMM2_SIZE,    /* RREF, DNRREF                           */ \+  1, 1,                          /* FALSE, TRUE                            */ \+  1, 1, 1,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */ \+  3, 1, 3,                       /* MARK, PRUNE, PRUNE_ARG                 */ \+  1, 3,                          /* SKIP, SKIP_ARG                         */ \+  1, 3,                          /* THEN, THEN_ARG                         */ \+  1, 3,                          /* COMMIT, COMMIT_ARG                     */ \+  1, 1, 1,                       /* FAIL, ACCEPT, ASSERT_ACCEPT            */ \+  1+IMM2_SIZE, 1,                /* CLOSE, SKIPZERO                        */ \+  1                              /* DEFINE                                 */++/* A magic value for OP_RREF to indicate the "any recursion" condition. */++#define RREF_ANY  0xffff+++/* ---------- Private structures that are mode-independent. ---------- */++/* Structure to hold data for custom memory management. */++typedef struct pcre2_memctl {+  void *    (*malloc)(size_t, void *);+  void      (*free)(void *, void *);+  void      *memory_data;+} pcre2_memctl;++/* Structure for building a chain of open capturing subpatterns during+compiling, so that instructions to close them can be compiled when (*ACCEPT) is+encountered. */++typedef struct open_capitem {+  struct open_capitem *next;    /* Chain link */+  uint16_t number;              /* Capture number */+  uint16_t assert_depth;        /* Assertion depth when opened */+} open_capitem;++/* Layout of the UCP type table that translates property names into types and+codes. Each entry used to point directly to a name, but to reduce the number of+relocations in shared libraries, it now has an offset into a single string+instead. */++typedef struct {+  uint16_t name_offset;+  uint16_t type;+  uint16_t value;+} ucp_type_table;++/* Unicode character database (UCD) record format */++typedef struct {+  uint8_t script;     /* ucp_Arabic, etc. */+  uint8_t chartype;   /* ucp_Cc, etc. (general categories) */+  uint8_t gbprop;     /* ucp_gbControl, etc. (grapheme break property) */+  uint8_t caseset;    /* offset to multichar other cases or zero */+  int32_t other_case; /* offset to other case, or zero if none */+  int16_t scriptx;    /* script extension value */+  int16_t dummy;      /* spare - to round to multiple of 4 bytes */+} ucd_record;++/* UCD access macros */++#define UCD_BLOCK_SIZE 128+#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)]+#define UCD_GRAPHBREAK(ch)  GET_UCD(ch)->gbprop+#define UCD_CASESET(ch)     GET_UCD(ch)->caseset+#define UCD_OTHERCASE(ch)   ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case)))+#define UCD_SCRIPTX(ch)     GET_UCD(ch)->scriptx++/* Header for serialized pcre2 codes. */++typedef struct pcre2_serialized_data {+  uint32_t magic;+  uint32_t version;+  uint32_t config;+  int32_t  number_of_codes;+} pcre2_serialized_data;++++/* ----------------- Items that need PCRE2_CODE_UNIT_WIDTH ----------------- */++/* When this file is included by pcre2test, PCRE2_CODE_UNIT_WIDTH is defined as+0, so the following items are omitted. */++#if defined PCRE2_CODE_UNIT_WIDTH && PCRE2_CODE_UNIT_WIDTH != 0++/* EBCDIC is supported only for the 8-bit library. */++#if defined EBCDIC && PCRE2_CODE_UNIT_WIDTH != 8+#error EBCDIC is not supported for the 16-bit or 32-bit libraries+#endif++/* This is the largest non-UTF code point. */++#define MAX_NON_UTF_CHAR (0xffffffffU >> (32 - PCRE2_CODE_UNIT_WIDTH))++/* Internal shared data tables and variables. These are used by more than one+of the exported public functions. They have to be "external" in the C sense,+but are not part of the PCRE2 public API. Although the data for some of them is+identical in all libraries, they must have different names so that multiple+libraries can be simultaneously linked to a single application. However, UTF-8+tables are needed only when compiling the 8-bit library. */++#if PCRE2_CODE_UNIT_WIDTH == 8+extern const int              PRIV(utf8_table1)[];+extern const int              PRIV(utf8_table1_size);+extern const int              PRIV(utf8_table2)[];+extern const int              PRIV(utf8_table3)[];+extern const uint8_t          PRIV(utf8_table4)[];+#endif++#define _pcre2_OP_lengths              PCRE2_SUFFIX(_pcre2_OP_lengths_)+#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_)+#define _pcre2_ucd_digit_sets          PCRE2_SUFFIX(_pcre2_ucd_digit_sets_)+#define _pcre2_ucd_script_sets         PCRE2_SUFFIX(_pcre2_ucd_script_sets_)+#define _pcre2_ucd_records             PCRE2_SUFFIX(_pcre2_ucd_records_)+#define _pcre2_ucd_stage1              PCRE2_SUFFIX(_pcre2_ucd_stage1_)+#define _pcre2_ucd_stage2              PCRE2_SUFFIX(_pcre2_ucd_stage2_)+#define _pcre2_ucp_gbtable             PCRE2_SUFFIX(_pcre2_ucp_gbtable_)+#define _pcre2_ucp_gentype             PCRE2_SUFFIX(_pcre2_ucp_gentype_)+#define _pcre2_ucp_typerange           PCRE2_SUFFIX(_pcre2_ucp_typerange_)+#define _pcre2_unicode_version         PCRE2_SUFFIX(_pcre2_unicode_version_)+#define _pcre2_utt                     PCRE2_SUFFIX(_pcre2_utt_)+#define _pcre2_utt_names               PCRE2_SUFFIX(_pcre2_utt_names_)+#define _pcre2_utt_size                PCRE2_SUFFIX(_pcre2_utt_size_)++extern const uint8_t                   PRIV(OP_lengths)[];+extern const uint32_t                  PRIV(callout_end_delims)[];+extern const uint32_t                  PRIV(callout_start_delims)[];+extern const pcre2_compile_context     PRIV(default_compile_context);+extern const pcre2_convert_context     PRIV(default_convert_context);+extern const pcre2_match_context       PRIV(default_match_context);+extern 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 uint32_t                  PRIV(ucd_digit_sets)[];+extern const uint8_t                   PRIV(ucd_script_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 uint16_t                  PRIV(ucd_stage1)[];+extern const uint16_t                  PRIV(ucd_stage2)[];+extern const uint32_t                  PRIV(ucp_gbtable)[];+extern const uint32_t                  PRIV(ucp_gentype)[];+#ifdef SUPPORT_JIT+extern const int                       PRIV(ucp_typerange)[];+#endif+extern const char                     *PRIV(unicode_version);+extern const ucp_type_table            PRIV(utt)[];+extern const char                      PRIV(utt_names)[];+extern const size_t                    PRIV(utt_size);++/* Mode-dependent macros and hidden and private structures are defined in a+separate file so that pcre2test can include them at all supported widths. When+compiling the library, PCRE2_CODE_UNIT_WIDTH will be defined, and we can+include them at the appropriate width, after setting up suffix macros for the+private structures. */++#define branch_chain                 PCRE2_SUFFIX(branch_chain_)+#define compile_block                PCRE2_SUFFIX(compile_block_)+#define dfa_match_block              PCRE2_SUFFIX(dfa_match_block_)+#define match_block                  PCRE2_SUFFIX(match_block_)+#define named_group                  PCRE2_SUFFIX(named_group_)++#include "pcre2_intmodedep.h"++/* Private "external" functions. These are internal functions that are called+from modules other than the one in which they are defined. They have to be+"external" in the C sense, but are not part of the PCRE2 public API. They are+not referenced from pcre2test, and must not be defined when no code unit width+is available. */++#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_)+#define _pcre2_jit_free              PCRE2_SUFFIX(_pcre2_jit_free_)+#define _pcre2_jit_get_size          PCRE2_SUFFIX(_pcre2_jit_get_size_)+#define _pcre2_jit_get_target        PCRE2_SUFFIX(_pcre2_jit_get_target_)+#define _pcre2_memctl_malloc         PCRE2_SUFFIX(_pcre2_memctl_malloc_)+#define _pcre2_ord2utf               PCRE2_SUFFIX(_pcre2_ord2utf_)+#define _pcre2_script_run            PCRE2_SUFFIX(_pcre2_script_run_)+#define _pcre2_strcmp                PCRE2_SUFFIX(_pcre2_strcmp_)+#define _pcre2_strcmp_c8             PCRE2_SUFFIX(_pcre2_strcmp_c8_)+#define _pcre2_strcpy_c8             PCRE2_SUFFIX(_pcre2_strcpy_c8_)+#define _pcre2_strlen                PCRE2_SUFFIX(_pcre2_strlen_)+#define _pcre2_strncmp               PCRE2_SUFFIX(_pcre2_strncmp_)+#define _pcre2_strncmp_c8            PCRE2_SUFFIX(_pcre2_strncmp_c8_)+#define _pcre2_study                 PCRE2_SUFFIX(_pcre2_study_)+#define _pcre2_valid_utf             PCRE2_SUFFIX(_pcre2_valid_utf_)+#define _pcre2_was_newline           PCRE2_SUFFIX(_pcre2_was_newline_)+#define _pcre2_xclass                PCRE2_SUFFIX(_pcre2_xclass_)++extern int          _pcre2_auto_possessify(PCRE2_UCHAR *,+                      const compile_block *);+extern int          _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,+                      int *, uint32_t, uint32_t, BOOL, compile_block *);+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);+extern void         _pcre2_jit_free_rodata(void *, void *);+extern void         _pcre2_jit_free(void *, pcre2_memctl *);+extern size_t       _pcre2_jit_get_size(void *);+const char *        _pcre2_jit_get_target(void);+extern void *       _pcre2_memctl_malloc(size_t, pcre2_memctl *);+extern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *);+extern BOOL         _pcre2_script_run(PCRE2_SPTR, PCRE2_SPTR, BOOL);+extern int          _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR);+extern int          _pcre2_strcmp_c8(PCRE2_SPTR, const char *);+extern PCRE2_SIZE   _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *);+extern PCRE2_SIZE   _pcre2_strlen(PCRE2_SPTR);+extern int          _pcre2_strncmp(PCRE2_SPTR, PCRE2_SPTR, size_t);+extern int          _pcre2_strncmp_c8(PCRE2_SPTR, const char *, size_t);+extern int          _pcre2_study(pcre2_real_code *);+extern int          _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *);+extern BOOL         _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,+                      uint32_t *, BOOL);+extern BOOL         _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL);++/* This function is needed only when memmove() is not available. */++#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)+#define _pcre2_memmove               PCRE2_SUFFIX(_pcre2_memmove)+extern void *       _pcre2_memmove(void *, const void *, size_t);+#endif++#endif  /* PCRE2_CODE_UNIT_WIDTH */+#endif  /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */++/* End of pcre2_internal.h */
+ src/c/pcre2/src/pcre2_intmodedep.h view
@@ -0,0 +1,923 @@+/*************************************************+*      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 mode-dependent macro and structure definitions. The+file is #included by pcre2_internal.h if PCRE2_CODE_UNIT_WIDTH is defined.+These mode-dependent items are kept in a separate file so that they can also be+#included multiple times for different code unit widths by pcre2test in order+to have access to the hidden structures at all supported widths.++Some of the mode-dependent macros are required at different widths for+different parts of the pcre2test code (in particular, the included+pcre_printint.c file). We undefine them here so that they can be re-defined for+multiple inclusions. Not all of these are used in pcre2test, but it's easier+just to undefine them all. */++#undef ACROSSCHAR+#undef BACKCHAR+#undef BYTES2CU+#undef CHMAX_255+#undef CU2BYTES+#undef FORWARDCHAR+#undef FORWARDCHARTEST+#undef GET+#undef GET2+#undef GETCHAR+#undef GETCHARINC+#undef GETCHARINCTEST+#undef GETCHARLEN+#undef GETCHARLENTEST+#undef GETCHARTEST+#undef GET_EXTRALEN+#undef HAS_EXTRALEN+#undef IMM2_SIZE+#undef MAX_255+#undef MAX_MARK+#undef MAX_PATTERN_SIZE+#undef MAX_UTF_SINGLE_CU+#undef NOT_FIRSTCU+#undef PUT+#undef PUT2+#undef PUT2INC+#undef PUTCHAR+#undef PUTINC+#undef TABLE_GET++++/* -------------------------- MACROS ----------------------------- */++/* PCRE keeps offsets in its compiled code as at least 16-bit quantities+(always stored in big-endian order in 8-bit mode) by default. These are used,+for example, to link from the start of a subpattern to its alternatives and its+end. The use of 16 bits per offset limits the size of an 8-bit compiled regex+to around 64K, which is big enough for almost everybody. However, I received a+request for an even bigger limit. For this reason, and also to make the code+easier to maintain, the storing and loading of offsets from the compiled code+unit string is now handled by the macros that are defined here.++The macros are controlled by the value of LINK_SIZE. This defaults to 2, but+values of 3 or 4 are also supported. */++/* ------------------- 8-bit support  ------------------ */++#if PCRE2_CODE_UNIT_WIDTH == 8++#if LINK_SIZE == 2+#define PUT(a,n,d)   \+  (a[n] = (PCRE2_UCHAR)((d) >> 8)), \+  (a[(n)+1] = (PCRE2_UCHAR)((d) & 255))+#define GET(a,n) \+  (unsigned int)(((a)[n] << 8) | (a)[(n)+1])+#define MAX_PATTERN_SIZE (1 << 16)++#elif LINK_SIZE == 3+#define PUT(a,n,d)       \+  (a[n] = (PCRE2_UCHAR)((d) >> 16)),    \+  (a[(n)+1] = (PCRE2_UCHAR)((d) >> 8)), \+  (a[(n)+2] = (PCRE2_UCHAR)((d) & 255))+#define GET(a,n) \+  (unsigned int)(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])+#define MAX_PATTERN_SIZE (1 << 24)++#elif LINK_SIZE == 4+#define PUT(a,n,d)        \+  (a[n] = (PCRE2_UCHAR)((d) >> 24)),     \+  (a[(n)+1] = (PCRE2_UCHAR)((d) >> 16)), \+  (a[(n)+2] = (PCRE2_UCHAR)((d) >> 8)),  \+  (a[(n)+3] = (PCRE2_UCHAR)((d) & 255))+#define GET(a,n) \+  (unsigned int)(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])+#define MAX_PATTERN_SIZE (1 << 30)   /* Keep it positive */++#else+#error LINK_SIZE must be 2, 3, or 4+#endif+++/* ------------------- 16-bit support  ------------------ */++#elif PCRE2_CODE_UNIT_WIDTH == 16++#if LINK_SIZE == 2+#undef LINK_SIZE+#define LINK_SIZE 1+#define PUT(a,n,d)   \+  (a[n] = (PCRE2_UCHAR)(d))+#define GET(a,n) \+  (a[n])+#define MAX_PATTERN_SIZE (1 << 16)++#elif LINK_SIZE == 3 || LINK_SIZE == 4+#undef LINK_SIZE+#define LINK_SIZE 2+#define PUT(a,n,d)   \+  (a[n] = (PCRE2_UCHAR)((d) >> 16)), \+  (a[(n)+1] = (PCRE2_UCHAR)((d) & 65535))+#define GET(a,n) \+  (unsigned int)(((a)[n] << 16) | (a)[(n)+1])+#define MAX_PATTERN_SIZE (1 << 30)  /* Keep it positive */++#else+#error LINK_SIZE must be 2, 3, or 4+#endif+++/* ------------------- 32-bit support  ------------------ */++#elif PCRE2_CODE_UNIT_WIDTH == 32+#undef LINK_SIZE+#define LINK_SIZE 1+#define PUT(a,n,d)   \+  (a[n] = (d))+#define GET(a,n) \+  (a[n])+#define MAX_PATTERN_SIZE (1 << 30)  /* Keep it positive */++#else+#error Unsupported compiling mode+#endif+++/* --------------- Other mode-specific macros ----------------- */++/* PCRE uses some other (at least) 16-bit quantities that do not change when+the size of offsets changes. There are used for repeat counts and for other+things such as capturing parenthesis numbers in back references.++Define the number of code units required to hold a 16-bit count/offset, and+macros to load and store such a value. For reasons that I do not understand,+the expression in the 8-bit GET2 macro is treated by gcc as a signed+expression, even when a is declared as unsigned. It seems that any kind of+arithmetic results in a signed value. Hence the cast. */++#if PCRE2_CODE_UNIT_WIDTH == 8+#define IMM2_SIZE 2+#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1])+#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255++#else  /* Code units are 16 or 32 bits */+#define IMM2_SIZE 1+#define GET2(a,n) a[n]+#define PUT2(a,n,d) a[n] = d+#endif++/* Other macros that are different for 8-bit mode. The MAX_255 macro checks+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. Its argument is a code unit. 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)+#define TABLE_GET(c, table, default) ((table)[c])+#ifdef SUPPORT_UNICODE+#define SUPPORT_WIDE_CHARS+#define CHMAX_255(c) ((c) <= 255u)+#else+#define CHMAX_255(c) TRUE+#endif  /* SUPPORT_UNICODE */++#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+#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))+#endif+++/* ----------------- Character-handling macros ----------------- */++/* There is a proposed future special "UTF-21" mode, in which only the lowest+21 bits of a 32-bit character are interpreted as UTF, with the remaining 11+high-order bits available to the application for other uses. In preparation for+the future implementation of this mode, there are macros that load a data item+and, if in this special mode, mask it to 21 bits. These macros all have names+starting with UCHAR21. In all other modes, including the normal 32-bit+library, the macros all have the same simple definitions. When the new mode is+implemented, it is expected that these definitions will be varied appropriately+using #ifdef when compiling the library that supports the special mode. */++#define UCHAR21(eptr)        (*(eptr))+#define UCHAR21TEST(eptr)    (*(eptr))+#define UCHAR21INC(eptr)     (*(eptr)++)+#define UCHAR21INCTEST(eptr) (*(eptr)++)++/* When UTF encoding is being used, a character is no longer just a single+byte in 8-bit mode or a single short in 16-bit mode. The macros for character+handling generate simple sequences when used in the basic mode, and more+complicated ones for UTF characters. GETCHARLENTEST and other macros are not+used when UTF is not supported. To make sure they can never even appear when+UTF support is omitted, we don't even define them. */++#ifndef SUPPORT_UNICODE++/* #define MAX_UTF_SINGLE_CU */+/* #define HAS_EXTRALEN(c) */+/* #define GET_EXTRALEN(c) */+/* #define NOT_FIRSTCU(c) */+#define GETCHAR(c, eptr) c = *eptr;+#define GETCHARTEST(c, eptr) c = *eptr;+#define GETCHARINC(c, eptr) c = *eptr++;+#define GETCHARINCTEST(c, eptr) c = *eptr++;+#define GETCHARLEN(c, eptr, len) c = *eptr;+#define PUTCHAR(c, p) (*p = c, 1)+/* #define GETCHARLENTEST(c, eptr, len) */+/* #define BACKCHAR(eptr) */+/* #define FORWARDCHAR(eptr) */+/* #define FORWARCCHARTEST(eptr,end) */+/* #define ACROSSCHAR(condition, eptr, action) */++#else   /* SUPPORT_UNICODE */++/* ------------------- 8-bit support  ------------------ */++#if PCRE2_CODE_UNIT_WIDTH == 8+#define MAYBE_UTF_MULTI          /* UTF chars may use multiple code units */++/* The largest UTF code point that can be encoded as a single code unit. */++#define MAX_UTF_SINGLE_CU 127++/* Tests whether the code point needs extra characters to decode. */++#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c)++/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.+Otherwise it has an undefined behaviour. */++#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3fu])++/* Returns TRUE, if the given value is not the first code unit of a UTF+sequence. */++#define NOT_FIRSTCU(c) (((c) & 0xc0u) == 0x80u)++/* Get the next UTF-8 character, not advancing the pointer. This is called when+we know we are in UTF-8 mode. */++#define GETCHAR(c, eptr) \+  c = *eptr; \+  if (c >= 0xc0u) GETUTF8(c, eptr);++/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the+pointer. */++#define GETCHARTEST(c, eptr) \+  c = *eptr; \+  if (utf && c >= 0xc0u) GETUTF8(c, eptr);++/* Get the next UTF-8 character, advancing the pointer. This is called when we+know we are in UTF-8 mode. */++#define GETCHARINC(c, eptr) \+  c = *eptr++; \+  if (c >= 0xc0u) GETUTF8INC(c, eptr);++/* Get the next character, testing for UTF-8 mode, and advancing the pointer.+This is called when we don't know if we are in UTF-8 mode. */++#define GETCHARINCTEST(c, eptr) \+  c = *eptr++; \+  if (utf && c >= 0xc0u) GETUTF8INC(c, eptr);++/* Get the next UTF-8 character, not advancing the pointer, incrementing length+if there are extra bytes. This is called when we know we are in UTF-8 mode. */++#define GETCHARLEN(c, eptr, len) \+  c = *eptr; \+  if (c >= 0xc0u) GETUTF8LEN(c, eptr, len);++/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the+pointer, incrementing length if there are extra bytes. This is called when we+do not know if we are in UTF-8 mode. */++#define GETCHARLENTEST(c, eptr, len) \+  c = *eptr; \+  if (utf && c >= 0xc0u) GETUTF8LEN(c, eptr, len);++/* If the pointer is not at the start of a character, move it back until+it is. This is called only in UTF-8 mode - we don't put a test within the macro+because almost all calls are already within a block of UTF-8 only code. */++#define BACKCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr--++/* Same as above, just in the other direction. */+#define FORWARDCHAR(eptr) while((*eptr & 0xc0u) == 0x80u) eptr+++#define FORWARDCHARTEST(eptr,end) while(eptr < end && (*eptr & 0xc0u) == 0x80u) eptr++++/* Same as above, but it allows a fully customizable form. */+#define ACROSSCHAR(condition, eptr, action) \+  while((condition) && ((*eptr) & 0xc0u) == 0x80u) action++/* Deposit a character into memory, returning the number of code units. */++#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \+  PRIV(ord2utf)(c,p) : (*p = c, 1))+++/* ------------------- 16-bit support  ------------------ */++#elif PCRE2_CODE_UNIT_WIDTH == 16+#define MAYBE_UTF_MULTI          /* UTF chars may use multiple code units */++/* The largest UTF code point that can be encoded as a single code unit. */++#define MAX_UTF_SINGLE_CU 65535++/* Tests whether the code point needs extra characters to decode. */++#define HAS_EXTRALEN(c) (((c) & 0xfc00u) == 0xd800u)++/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.+Otherwise it has an undefined behaviour. */++#define GET_EXTRALEN(c) 1++/* Returns TRUE, if the given value is not the first code unit of a UTF+sequence. */++#define NOT_FIRSTCU(c) (((c) & 0xfc00u) == 0xdc00u)++/* Base macro to pick up the low surrogate of a UTF-16 character, not+advancing the pointer. */++#define GETUTF16(c, eptr) \+   { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; }++/* Get the next UTF-16 character, not advancing the pointer. This is called when+we know we are in UTF-16 mode. */++#define GETCHAR(c, eptr) \+  c = *eptr; \+  if ((c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);++/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the+pointer. */++#define GETCHARTEST(c, eptr) \+  c = *eptr; \+  if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16(c, eptr);++/* Base macro to pick up the low surrogate of a UTF-16 character, advancing+the pointer. */++#define GETUTF16INC(c, eptr) \+   { c = (((c & 0x3ffu) << 10) | (*eptr++ & 0x3ffu)) + 0x10000u; }++/* Get the next UTF-16 character, advancing the pointer. This is called when we+know we are in UTF-16 mode. */++#define GETCHARINC(c, eptr) \+  c = *eptr++; \+  if ((c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);++/* Get the next character, testing for UTF-16 mode, and advancing the pointer.+This is called when we don't know if we are in UTF-16 mode. */++#define GETCHARINCTEST(c, eptr) \+  c = *eptr++; \+  if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16INC(c, eptr);++/* Base macro to pick up the low surrogate of a UTF-16 character, not+advancing the pointer, incrementing the length. */++#define GETUTF16LEN(c, eptr, len) \+   { c = (((c & 0x3ffu) << 10) | (eptr[1] & 0x3ffu)) + 0x10000u; len++; }++/* Get the next UTF-16 character, not advancing the pointer, incrementing+length if there is a low surrogate. This is called when we know we are in+UTF-16 mode. */++#define GETCHARLEN(c, eptr, len) \+  c = *eptr; \+  if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);++/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the+pointer, incrementing length if there is a low surrogate. This is called when+we do not know if we are in UTF-16 mode. */++#define GETCHARLENTEST(c, eptr, len) \+  c = *eptr; \+  if (utf && (c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len);++/* If the pointer is not at the start of a character, move it back until+it is. This is called only in UTF-16 mode - we don't put a test within the+macro because almost all calls are already within a block of UTF-16 only+code. */++#define BACKCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr--++/* Same as above, just in the other direction. */+#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00u) == 0xdc00u) eptr+++#define FORWARDCHARTEST(eptr,end) if (eptr < end && (*eptr & 0xfc00u) == 0xdc00u) eptr++++/* Same as above, but it allows a fully customizable form. */+#define ACROSSCHAR(condition, eptr, action) \+  if ((condition) && ((*eptr) & 0xfc00u) == 0xdc00u) action++/* Deposit a character into memory, returning the number of code units. */++#define PUTCHAR(c, p) ((utf && c > MAX_UTF_SINGLE_CU)? \+  PRIV(ord2utf)(c,p) : (*p = c, 1))+++/* ------------------- 32-bit support  ------------------ */++#else++/* These are trivial for the 32-bit library, since all UTF-32 characters fit+into one PCRE2_UCHAR unit. */++#define MAX_UTF_SINGLE_CU (0x10ffffu)+#define HAS_EXTRALEN(c) (0)+#define GET_EXTRALEN(c) (0)+#define NOT_FIRSTCU(c) (0)++/* Get the next UTF-32 character, not advancing the pointer. This is called when+we know we are in UTF-32 mode. */++#define GETCHAR(c, eptr) \+  c = *(eptr);++/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the+pointer. */++#define GETCHARTEST(c, eptr) \+  c = *(eptr);++/* Get the next UTF-32 character, advancing the pointer. This is called when we+know we are in UTF-32 mode. */++#define GETCHARINC(c, eptr) \+  c = *((eptr)++);++/* Get the next character, testing for UTF-32 mode, and advancing the pointer.+This is called when we don't know if we are in UTF-32 mode. */++#define GETCHARINCTEST(c, eptr) \+  c = *((eptr)++);++/* Get the next UTF-32 character, not advancing the pointer, not incrementing+length (since all UTF-32 is of length 1). This is called when we know we are in+UTF-32 mode. */++#define GETCHARLEN(c, eptr, len) \+  GETCHAR(c, eptr)++/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the+pointer, not incrementing the length (since all UTF-32 is of length 1).+This is called when we do not know if we are in UTF-32 mode. */++#define GETCHARLENTEST(c, eptr, len) \+  GETCHARTEST(c, eptr)++/* If the pointer is not at the start of a character, move it back until+it is. This is called only in UTF-32 mode - we don't put a test within the+macro because almost all calls are already within a block of UTF-32 only+code.++These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */++#define BACKCHAR(eptr) do { } while (0)++/* Same as above, just in the other direction. */++#define FORWARDCHAR(eptr) do { } while (0)+#define FORWARDCHARTEST(eptr,end) do { } while (0)++/* Same as above, but it allows a fully customizable form. */++#define ACROSSCHAR(condition, eptr, action) do { } while (0)++/* Deposit a character into memory, returning the number of code units. */++#define PUTCHAR(c, p) (*p = c, 1)++#endif  /* UTF-32 character handling */+#endif  /* SUPPORT_UNICODE */+++/* Mode-dependent macros that have the same definition in all modes. */++#define CU2BYTES(x)     ((x)*((PCRE2_CODE_UNIT_WIDTH/8)))+#define BYTES2CU(x)     ((x)/((PCRE2_CODE_UNIT_WIDTH/8)))+#define PUTINC(a,n,d)   PUT(a,n,d), a += LINK_SIZE+#define PUT2INC(a,n,d)  PUT2(a,n,d), a += IMM2_SIZE+++/* ----------------------- HIDDEN STRUCTURES ----------------------------- */++/* NOTE: All these structures *must* start with a pcre2_memctl structure. The+code that uses them is simpler because it assumes this. */++/* The real general context structure. At present it holds only data for custom+memory control. */++typedef struct pcre2_real_general_context {+  pcre2_memctl memctl;+} pcre2_real_general_context;++/* The real compile context structure */++typedef struct pcre2_real_compile_context {+  pcre2_memctl memctl;+  int (*stack_guard)(uint32_t, void *);+  void *stack_guard_data;+  const uint8_t *tables;+  PCRE2_SIZE max_pattern_length;+  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 SUPPORT_JIT+  pcre2_jit_callback jit_callback;+  void *jit_callback_data;+#endif+  int    (*callout)(pcre2_callout_block *, void *);+  void    *callout_data;+  int    (*substitute_callout)(pcre2_substitute_callout_block *, void *);+  void    *substitute_callout_data;+  PCRE2_SIZE offset_limit;+  uint32_t heap_limit;+  uint32_t match_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+type. Use a macro rather than a typedef to avoid compiler warnings when this+file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the+largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit+argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field+here.) */++#undef  CODE_BLOCKSIZE_TYPE+#define CODE_BLOCKSIZE_TYPE size_t++#undef  LOOKBEHIND_MAX+#define LOOKBEHIND_MAX UINT16_MAX++typedef struct pcre2_real_code {+  pcre2_memctl memctl;            /* Memory control fields */+  const uint8_t *tables;          /* The character tables */+  void    *executable_jit;        /* Pointer to JIT code */+  uint8_t  start_bitmap[32];      /* Bitmap for starting code unit < 256 */+  CODE_BLOCKSIZE_TYPE blocksize;  /* Total (bytes) that was malloc-ed */+  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_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 */+  uint16_t newline_convention;    /* What is a newline? */+  uint16_t max_lookbehind;        /* Longest lookbehind (characters) */+  uint16_t minlength;             /* Minimum length of match */+  uint16_t top_bracket;           /* Highest numbered group */+  uint16_t top_backref;           /* Highest numbered back reference */+  uint16_t name_entry_size;       /* Size (code units) of table entries */+  uint16_t name_count;            /* Number of name entries in the table */+} pcre2_real_code;++/* 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;+  const pcre2_real_code *code;    /* The pattern used for the match */+  PCRE2_SPTR       subject;       /* The subject that was matched */+  PCRE2_SPTR       mark;          /* Pointer to last mark */+  PCRE2_SIZE       leftchar;      /* Offset to leftmost code unit */+  PCRE2_SIZE       rightchar;     /* Offset to rightmost code unit */+  PCRE2_SIZE       startchar;     /* Offset to starting code unit */+  uint8_t          matchedby;     /* Type of match (normal, JIT, DFA) */+  uint8_t          flags;         /* Various flags */+  uint16_t         oveccount;     /* Number of pairs */+  int              rc;            /* The return code from the match */+  PCRE2_SIZE       ovector[131072]; /* Must be last in the structure */+} pcre2_real_match_data;+++/* ----------------------- PRIVATE STRUCTURES ----------------------------- */++/* These structures are not needed for pcre2test. */++#ifndef PCRE2_PCRE2TEST++/* 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 groupnumber;+} recurse_cache;++/* Structure for maintaining a chain of pointers to the currently incomplete+branches, for testing for left recursion while compiling. */++typedef struct branch_chain {+  struct branch_chain *outer;+  PCRE2_UCHAR *current_branch;+} branch_chain;++/* Structure for building a list of named groups during the first pass of+compiling. */++typedef struct named_group {+  PCRE2_SPTR   name;          /* Points to the name in the pattern */+  uint32_t     number;        /* Group number */+  uint16_t     length;        /* Length of the name */+  uint16_t     isdup;         /* TRUE if a duplicate */+} named_group;++/* Structure for passing "static" information around between the functions+doing the compiling, so that they are thread-safe. */++typedef struct compile_block {+  pcre2_real_compile_context *cx;  /* Points to the compile context */+  const uint8_t *lcc;              /* Points to lower casing table */+  const uint8_t *fcc;              /* Points to case-flipping table */+  const uint8_t *cbits;            /* Points to character type table */+  const uint8_t *ctypes;           /* Points to table of type maps */+  PCRE2_SPTR start_workspace;      /* The start of working space */+  PCRE2_SPTR start_code;           /* The start of the compiled code */+  PCRE2_SPTR start_pattern;        /* The start of the pattern */+  PCRE2_SPTR end_pattern;          /* The end of the pattern */+  PCRE2_UCHAR *name_table;         /* The name/number table */+  PCRE2_SIZE workspace_size;       /* Size of workspace */+  PCRE2_SIZE small_ref_offset[10]; /* Offsets for \1 to \9 */+  PCRE2_SIZE erroroffset;          /* Offset of error in pattern */+  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 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  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 dupnames;                   /* Duplicate names exist */+} compile_block;++/* Structure for keeping the properties of the in-memory stack used+by the JIT matcher. */++typedef struct pcre2_real_jit_stack {+  pcre2_memctl memctl;+  void* stack;+} pcre2_real_jit_stack;++/* Structure for items in a linked list that represents an explicit recursive+call within the pattern when running pcre_dfa_match(). */++typedef struct dfa_recursion_info {+  struct dfa_recursion_info *prevrec;+  PCRE2_SPTR subject_position;+  uint32_t group_num;+} dfa_recursion_info;++/* 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 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 */++  /* At this point, the structure is 16-bit aligned. On most architectures+  the alignment requirement for a pointer will ensure that the eptr field below+  is 32-bit or 64-bit aligned. However, on m68k it is fine to have a pointer+  that is 16-bit aligned. We must therefore ensure that what comes between here+  and eptr is an odd multiple of 16 bits so as to get back into 32-bit+  alignment. This happens naturally when PCRE2_UCHAR is 8 bits wide, but needs+  fudges in the other cases. In the 32-bit case the padding comes first so that+  the occu field itself is 32-bit aligned. Without the padding, this structure+  is no longer a multiple of PCRE2_SIZE on m68k, and the check below fails. */++#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 */+  uint8_t unused[2];         /* Ensure 32-bit alignment (see above) */+#else+  uint8_t unused[2];         /* Ensure 32-bit alignment (see above) */+  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;++/* This typedef is a check that the size of the heapframe structure is a+multiple of PCRE2_SIZE. See various comments above. */++typedef char check_heapframe_size[+  ((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)];++/* 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 */+  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_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) */+  BOOL allowemptypartial;         /* Allow empty hard partial */+  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 start_offset;        /* The start offset value */+  PCRE2_SIZE end_offset_top;      /* Highwater mark at end of match */+  uint16_t partial;               /* PARTIAL options */+  uint16_t bsr_convention;        /* \R interpretation */+  uint16_t name_count;            /* Number of names in name table */+  uint16_t name_entry_size;       /* Size of entry in names table */+  PCRE2_SPTR name_table;          /* Table of group names */+  PCRE2_SPTR start_code;          /* For use when recursing */+  PCRE2_SPTR start_subject;       /* Start of the subject string */+  PCRE2_SPTR check_subject;       /* Where UTF-checked from */+  PCRE2_SPTR end_subject;         /* End of the subject 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 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 skip_arg_count;        /* For counting SKIP_ARGs */+  uint32_t ignore_skip_arg;       /* For re-run when SKIP arg name not found */+  uint32_t nltype;                /* Newline type */+  uint32_t nllen;                 /* Newline string length */+  PCRE2_UCHAR nl[4];              /* Newline string when fixed */+  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 */+} match_block;++/* A similar structure is used for the same purpose by the DFA matching+functions. */++typedef struct dfa_match_block {+  pcre2_memctl memctl;            /* For general use */+  PCRE2_SPTR start_code;          /* Start of the compiled pattern */+  PCRE2_SPTR start_subject ;      /* Start of the subject string */+  PCRE2_SPTR end_subject;         /* End of subject string */+  PCRE2_SPTR start_used_ptr;      /* Earliest consulted character */+  PCRE2_SPTR last_used_ptr;       /* Latest consulted character */+  const uint8_t *tables;          /* Character tables */+  PCRE2_SIZE start_offset;        /* The start offset value */+  PCRE2_SIZE heap_limit;          /* As it says */+  PCRE2_SIZE heap_used;           /* As it says */+  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 */+  BOOL allowemptypartial;         /* Allow empty hard partial */+  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 */+} dfa_match_block;++#endif  /* PCRE2_PCRE2TEST */++/* End of pcre2_intmodedep.h */
+ src/c/pcre2/src/pcre2_jit_compile.c view
@@ -0,0 +1,14252 @@+/*************************************************+*      Perl-Compatible Regular Expressions       *+*************************************************/++/* PCRE is a library of functions to support regular expressions whose syntax+and semantics are as close as possible to those of the Perl 5 language.++                       Written by Philip Hazel+                    This module by Zoltan Herczeg+     Original API code Copyright (c) 1997-2012 University of Cambridge+          New API code Copyright (c) 2016-2019 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"++#ifdef SUPPORT_JIT++/* All-in-one: Since we use the JIT compiler only from here,+we just include it. This way we don't need to touch the build+system files. */++#define SLJIT_CONFIG_AUTO 1+#define SLJIT_CONFIG_STATIC 1+#define SLJIT_VERBOSE 0++#ifdef PCRE2_DEBUG+#define SLJIT_DEBUG 1+#else+#define SLJIT_DEBUG 0+#endif++#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)+#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)++static void * pcre2_jit_malloc(size_t size, void *allocator_data)+{+pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);+return allocator->malloc(size, allocator->memory_data);+}++static void pcre2_jit_free(void *ptr, void *allocator_data)+{+pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);+allocator->free(ptr, allocator->memory_data);+}++#include "sljit/sljitLir.c"++#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED+#error Unsupported architecture+#endif++/* Defines for debugging purposes. */++/* 1 - Use unoptimized capturing brackets.+   2 - Enable capture_last_ptr (includes option 1). */+/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */++/* 1 - Always have a control head. */+/* #define DEBUG_FORCE_CONTROL_HEAD 1 */++/* Allocate memory for the regex stack on the real machine stack.+Fast, but limited size. */+#define MACHINE_STACK_SIZE 32768++/* Growth rate for stack allocated by the OS. Should be the multiply+of page size. */+#define STACK_GROWTH_RATE 8192++/* Enable to check that the allocation could destroy temporaries. */+#if defined SLJIT_DEBUG && SLJIT_DEBUG+#define DESTROY_REGISTERS 1+#endif++/*+Short summary about the backtracking mechanism empolyed by the jit code generator:++The code generator follows the recursive nature of the PERL compatible regular+expressions. The basic blocks of regular expressions are condition checkers+whose execute different commands depending on the result of the condition check.+The relationship between the operators can be horizontal (concatenation) and+vertical (sub-expression) (See struct backtrack_common for more details).++  'ab' - 'a' and 'b' regexps are concatenated+  'a+' - 'a' is the sub-expression of the '+' operator++The condition checkers are boolean (true/false) checkers. Machine code is generated+for the checker itself and for the actions depending on the result of the checker.+The 'true' case is called as the matching path (expected path), and the other is called as+the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken+branches on the matching path.++ Greedy star operator (*) :+   Matching path: match happens.+   Backtrack path: match failed.+ Non-greedy star operator (*?) :+   Matching path: no need to perform a match.+   Backtrack path: match is required.++The following example shows how the code generated for a capturing bracket+with two alternatives. Let A, B, C, D are arbirary regular expressions, and+we have the following regular expression:++   A(B|C)D++The generated code will be the following:++ A matching path+ '(' matching path (pushing arguments to the stack)+ B matching path+ ')' matching path (pushing arguments to the stack)+ D matching path+ return with successful match++ D backtrack path+ ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")+ B backtrack path+ C expected path+ jump to D matching path+ C backtrack path+ A backtrack path++ Notice, that the order of backtrack code paths are the opposite of the fast+ code paths. In this way the topmost value on the stack is always belong+ to the current backtrack code path. The backtrack path must check+ whether there is a next alternative. If so, it needs to jump back to+ the matching path eventually. Otherwise it needs to clear out its own stack+ frame and continue the execution on the backtrack code paths.+*/++/*+Saved stack frames:++Atomic blocks and asserts require reloading the values of private data+when the backtrack mechanism performed. Because of OP_RECURSE, the data+are not necessarly known in compile time, thus we need a dynamic restore+mechanism.++The stack frames are stored in a chain list, and have the following format:+([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]++Thus we can restore the private data to a particular point in the stack.+*/++typedef struct jit_arguments {+  /* Pointers first. */+  struct sljit_stack *stack;+  PCRE2_SPTR str;+  PCRE2_SPTR begin;+  PCRE2_SPTR end;+  pcre2_match_data *match_data;+  PCRE2_SPTR startchar_ptr;+  PCRE2_UCHAR *mark_ptr;+  int (*callout)(pcre2_callout_block *, void *);+  void *callout_data;+  /* Everything else after. */+  sljit_uw offset_limit;+  sljit_u32 limit_match;+  sljit_u32 oveccount;+  sljit_u32 options;+} jit_arguments;++#define JIT_NUMBER_OF_COMPILE_MODES 3++typedef struct executable_functions {+  void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];+  void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];+  sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];+  sljit_u32 top_bracket;+  sljit_u32 limit_match;+} executable_functions;++typedef struct jump_list {+  struct sljit_jump *jump;+  struct jump_list *next;+} jump_list;++typedef struct stub_list {+  struct sljit_jump *start;+  struct sljit_label *quit;+  struct stub_list *next;+} stub_list;++enum frame_types {+  no_frame = -1,+  no_stack = -2+};++enum control_types {+  type_mark = 0,+  type_then_trap = 1+};++enum  early_fail_types {+  type_skip = 0,+  type_fail = 1,+  type_fail_range = 2+};++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+the arguments for compile_backtrackingpath. Must be the first member+of its descendants. */+typedef struct backtrack_common {+  /* Concatenation stack. */+  struct backtrack_common *prev;+  jump_list *nextbacktracks;+  /* Internal stack (for component operators). */+  struct backtrack_common *top;+  jump_list *topbacktracks;+  /* Opcode pointer. */+  PCRE2_SPTR cc;+} backtrack_common;++typedef struct assert_backtrack {+  backtrack_common common;+  jump_list *condfailed;+  /* Less than 0 if a frame is not needed. */+  int framesize;+  /* Points to our private memory word on the stack. */+  int private_data_ptr;+  /* For iterators. */+  struct sljit_label *matchingpath;+} assert_backtrack;++typedef struct bracket_backtrack {+  backtrack_common common;+  /* Where to coninue if an alternative is successfully matched. */+  struct sljit_label *alternative_matchingpath;+  /* For rmin and rmax iterators. */+  struct sljit_label *recursive_matchingpath;+  /* For greedy ? operator. */+  struct sljit_label *zero_matchingpath;+  /* Contains the branches of a failed condition. */+  union {+    /* Both for OP_COND, OP_SCOND. */+    jump_list *condfailed;+    assert_backtrack *assert;+    /* For OP_ONCE. Less than 0 if not needed. */+    int framesize;+    /* For brackets with >3 alternatives. */+    struct sljit_put_label *matching_put_label;+  } u;+  /* Points to our private memory word on the stack. */+  int private_data_ptr;+} bracket_backtrack;++typedef struct bracketpos_backtrack {+  backtrack_common common;+  /* Points to our private memory word on the stack. */+  int private_data_ptr;+  /* Reverting stack is needed. */+  int framesize;+  /* Allocated stack size. */+  int stacksize;+} bracketpos_backtrack;++typedef struct braminzero_backtrack {+  backtrack_common common;+  struct sljit_label *matchingpath;+} braminzero_backtrack;++typedef struct char_iterator_backtrack {+  backtrack_common common;+  /* Next iteration. */+  struct sljit_label *matchingpath;+  union {+    jump_list *backtracks;+    struct {+      unsigned int othercasebit;+      PCRE2_UCHAR chr;+      BOOL enabled;+    } charpos;+  } u;+} char_iterator_backtrack;++typedef struct ref_iterator_backtrack {+  backtrack_common common;+  /* Next iteration. */+  struct sljit_label *matchingpath;+} ref_iterator_backtrack;++typedef struct recurse_entry {+  struct recurse_entry *next;+  /* 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;++#define OP_THEN_TRAP OP_TABLE_LENGTH++typedef struct then_trap_backtrack {+  backtrack_common common;+  /* If then_trap is not NULL, this structure contains the real+  then_trap for the backtracking path. */+  struct then_trap_backtrack *then_trap;+  /* Points to the starting opcode. */+  sljit_sw start;+  /* Exit point for the then opcodes of this alternative. */+  jump_list *quit;+  /* Frame size of the current alternative. */+  int framesize;+} then_trap_backtrack;++#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. */+  sljit_s32 *private_data_ptrs;+  /* Chain list of read-only data ptrs. */+  void *read_only_data_head;+  /* Tells whether the capturing bracket is optimized. */+  sljit_u8 *optimized_cbracket;+  /* Tells whether the starting offset is a target of then. */+  sljit_u8 *then_offsets;+  /* Current position where a THEN must jump. */+  then_trap_backtrack *then_trap;+  /* Starting offset of private data for capturing brackets. */+  sljit_s32 cbra_ptr;+  /* Output vector starting point. Must be divisible by 2. */+  sljit_s32 ovector_start;+  /* Points to the starting character of the current match. */+  sljit_s32 start_ptr;+  /* Last known position of the requested byte. */+  sljit_s32 req_char_ptr;+  /* Head of the last recursion. */+  sljit_s32 recursive_head_ptr;+  /* First inspected character for partial matching.+     (Needed for avoiding zero length partial matches.) */+  sljit_s32 start_used_ptr;+  /* Starting pointer for partial soft matches. */+  sljit_s32 hit_start;+  /* Pointer of the match end position. */+  sljit_s32 match_end_ptr;+  /* Points to the marked string. */+  sljit_s32 mark_ptr;+  /* Recursive control verb management chain. */+  sljit_s32 control_head_ptr;+  /* Points to the last matched capture block index. */+  sljit_s32 capture_last_ptr;+  /* Fast forward skipping byte code pointer. */+  PCRE2_SPTR fast_forward_bc_ptr;+  /* Locals used by fast fail optimization. */+  sljit_s32 early_fail_start_ptr;+  sljit_s32 early_fail_end_ptr;++  /* Flipped and lower case tables. */+  const sljit_u8 *fcc;+  sljit_sw lcc;+  /* Mode can be PCRE2_JIT_COMPLETE and others. */+  int mode;+  /* TRUE, when empty match is accepted for partial matching. */+  BOOL allow_empty_partial;+  /* TRUE, when minlength is greater than 0. */+  BOOL might_be_empty;+  /* \K is found in the pattern. */+  BOOL has_set_som;+  /* (*SKIP:arg) is found in the pattern. */+  BOOL has_skip_arg;+  /* (*THEN) is found in the pattern. */+  BOOL has_then;+  /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */+  BOOL has_skip_in_assert_back;+  /* 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;+  sljit_u32 nlmin;+  int newline;+  int bsr_nltype;+  sljit_u32 bsr_nlmax;+  sljit_u32 bsr_nlmin;+  /* Dollar endonly. */+  int endonly;+  /* Tables. */+  sljit_sw ctypes;+  /* Named capturing brackets. */+  PCRE2_SPTR name_table;+  sljit_sw name_count;+  sljit_sw name_entry_size;++  /* Labels and jump lists. */+  struct sljit_label *partialmatchlabel;+  struct sljit_label *quit_label;+  struct sljit_label *abort_label;+  struct sljit_label *accept_label;+  struct sljit_label *ff_newline_shortcut;+  stub_list *stubs;+  recurse_entry *entries;+  recurse_entry *currententry;+  jump_list *partialmatch;+  jump_list *quit;+  jump_list *positive_assertion_quit;+  jump_list *abort;+  jump_list *failed_match;+  jump_list *accept;+  jump_list *calllimit;+  jump_list *stackalloc;+  jump_list *revertframes;+  jump_list *wordboundary;+  jump_list *anynewline;+  jump_list *hspace;+  jump_list *vspace;+  jump_list *casefulcmp;+  jump_list *caselesscmp;+  jump_list *reset_match;+  BOOL unset_backref;+  BOOL alt_circumflex;+#ifdef SUPPORT_UNICODE+  BOOL utf;+  BOOL invalid_utf;+  BOOL ucp;+  /* Points to saving area for iref. */+  sljit_s32 iref_ptr;+  jump_list *getucd;+  jump_list *getucdtype;+#if PCRE2_CODE_UNIT_WIDTH == 8+  jump_list *utfreadchar;+  jump_list *utfreadtype8;+  jump_list *utfpeakcharback;+#endif+#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16+  jump_list *utfreadchar_invalid;+  jump_list *utfreadnewline_invalid;+  jump_list *utfmoveback_invalid;+  jump_list *utfpeakcharback_invalid;+#endif+#endif /* SUPPORT_UNICODE */+} compiler_common;++/* For byte_sequence_compare. */++typedef struct compare_context {+  int length;+  int sourcereg;+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED+  int ucharptr;+  union {+    sljit_s32 asint;+    sljit_u16 asushort;+#if PCRE2_CODE_UNIT_WIDTH == 8+    sljit_u8 asbyte;+    sljit_u8 asuchars[4];+#elif PCRE2_CODE_UNIT_WIDTH == 16+    sljit_u16 asuchars[2];+#elif PCRE2_CODE_UNIT_WIDTH == 32+    sljit_u32 asuchars[1];+#endif+  } c;+  union {+    sljit_s32 asint;+    sljit_u16 asushort;+#if PCRE2_CODE_UNIT_WIDTH == 8+    sljit_u8 asbyte;+    sljit_u8 asuchars[4];+#elif PCRE2_CODE_UNIT_WIDTH == 16+    sljit_u16 asuchars[2];+#elif PCRE2_CODE_UNIT_WIDTH == 32+    sljit_u32 asuchars[1];+#endif+  } oc;+#endif+} compare_context;++/* Undefine sljit macros. */+#undef CMP++/* Used for accessing the elements of the stack. */+#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+#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+#define RETURN_ADDR   SLJIT_R4++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+#define HAS_VIRTUAL_REGISTERS 1+#else+#define HAS_VIRTUAL_REGISTERS 0+#endif++/* Local space layout. */+/* These two locals can be used by the current opcode. */+#define LOCALS0          (0 * sizeof(sljit_sw))+#define LOCALS1          (1 * sizeof(sljit_sw))+/* Two local variables for possessive quantifiers (char1 cannot use them). */+#define POSSESSIVE0      (2 * sizeof(sljit_sw))+#define POSSESSIVE1      (3 * sizeof(sljit_sw))+/* Max limit of recursions. */+#define LIMIT_MATCH      (4 * sizeof(sljit_sw))+/* The output vector is stored on the stack, and contains pointers+to characters. The vector data is divided into two groups: the first+group contains the start / end character pointers, and the second is+the start pointers when the end of the capturing group has not yet reached. */+#define OVECTOR_START    (common->ovector_start)+#define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))+#define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))+#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])++#if PCRE2_CODE_UNIT_WIDTH == 8+#define MOV_UCHAR  SLJIT_MOV_U8+#define IN_UCHARS(x) (x)+#elif PCRE2_CODE_UNIT_WIDTH == 16+#define MOV_UCHAR  SLJIT_MOV_U16+#define UCHAR_SHIFT (1)+#define IN_UCHARS(x) ((x) * 2)+#elif PCRE2_CODE_UNIT_WIDTH == 32+#define MOV_UCHAR  SLJIT_MOV_U32+#define UCHAR_SHIFT (2)+#define IN_UCHARS(x) ((x) * 4)+#else+#error Unsupported compiling mode+#endif++/* Shortcuts. */+#define DEFINE_COMPILER \+  struct sljit_compiler *compiler = common->compiler+#define OP1(op, dst, dstw, src, srcw) \+  sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))+#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \+  sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))+#define OP_SRC(op, src, srcw) \+  sljit_emit_op_src(compiler, (op), (src), (srcw))+#define LABEL() \+  sljit_emit_label(compiler)+#define JUMP(type) \+  sljit_emit_jump(compiler, (type))+#define JUMPTO(type, label) \+  sljit_set_label(sljit_emit_jump(compiler, (type)), (label))+#define JUMPHERE(jump) \+  sljit_set_label((jump), sljit_emit_label(compiler))+#define SET_LABEL(jump, label) \+  sljit_set_label((jump), (label))+#define CMP(type, src1, src1w, src2, src2w) \+  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, 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 -1+#define UNASSIGNED_UTF_CHAR 888++#if defined SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8++#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \+  { \+  if (ptr[0] <= 0x7f) \+    c = *ptr++; \+  else if (ptr + 1 < end && ptr[1] >= 0x80 && ptr[1] < 0xc0) \+    { \+    c = ptr[1] - 0x80; \+    \+    if (ptr[0] >= 0xc2 && ptr[0] <= 0xdf) \+      { \+      c |= (ptr[0] - 0xc0) << 6; \+      ptr += 2; \+      } \+    else if (ptr + 2 < end && ptr[2] >= 0x80 && ptr[2] < 0xc0) \+      { \+      c = c << 6 | (ptr[2] - 0x80); \+      \+      if (ptr[0] >= 0xe0 && ptr[0] <= 0xef) \+        { \+        c |= (ptr[0] - 0xe0) << 12; \+        ptr += 3; \+        \+        if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \+          { \+          invalid_action; \+          } \+        } \+      else if (ptr + 3 < end && ptr[3] >= 0x80 && ptr[3] < 0xc0) \+        { \+        c = c << 6 | (ptr[3] - 0x80); \+        \+        if (ptr[0] >= 0xf0 && ptr[0] <= 0xf4) \+          { \+          c |= (ptr[0] - 0xf0) << 18; \+          ptr += 4; \+          \+          if (c >= 0x110000 || c < 0x10000) \+            { \+            invalid_action; \+            } \+          } \+        else \+          { \+          invalid_action; \+          } \+        } \+      else \+        { \+        invalid_action; \+        } \+      } \+    else \+      { \+      invalid_action; \+      } \+    } \+  else \+    { \+    invalid_action; \+    } \+  }++#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \+  { \+  c = ptr[-1]; \+  if (c <= 0x7f) \+    ptr--; \+  else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \+    { \+    c -= 0x80; \+    \+    if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \+      { \+      c |= (ptr[-2] - 0xc0) << 6; \+      ptr -= 2; \+      } \+    else if (ptr - 2 > start && ptr[-2] >= 0x80 && ptr[-2] < 0xc0) \+      { \+      c = c << 6 | (ptr[-2] - 0x80); \+      \+      if (ptr[-3] >= 0xe0 && ptr[-3] <= 0xef) \+        { \+        c |= (ptr[-3] - 0xe0) << 12; \+        ptr -= 3; \+        \+        if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \+          { \+          invalid_action; \+          } \+        } \+      else if (ptr - 3 > start && ptr[-3] >= 0x80 && ptr[-3] < 0xc0) \+        { \+        c = c << 6 | (ptr[-3] - 0x80); \+        \+        if (ptr[-4] >= 0xf0 && ptr[-4] <= 0xf4) \+          { \+          c |= (ptr[-4] - 0xf0) << 18; \+          ptr -= 4; \+          \+          if (c >= 0x110000 || c < 0x10000) \+            { \+            invalid_action; \+            } \+          } \+        else \+          { \+          invalid_action; \+          } \+        } \+      else \+        { \+        invalid_action; \+        } \+      } \+    else \+      { \+      invalid_action; \+      } \+    } \+  else \+    { \+    invalid_action; \+    } \+  }++#elif PCRE2_CODE_UNIT_WIDTH == 16++#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \+  { \+  if (ptr[0] < 0xd800 || ptr[0] >= 0xe000) \+    c = *ptr++; \+  else if (ptr[0] < 0xdc00 && ptr + 1 < end && ptr[1] >= 0xdc00 && ptr[1] < 0xe000) \+    { \+    c = (((ptr[0] - 0xd800) << 10) | (ptr[1] - 0xdc00)) + 0x10000; \+    ptr += 2; \+    } \+  else \+    { \+    invalid_action; \+    } \+  }++#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \+  { \+  c = ptr[-1]; \+  if (c < 0xd800 || c >= 0xe000) \+    ptr--; \+  else if (c >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \+    { \+    c = (((ptr[-2] - 0xd800) << 10) | (c - 0xdc00)) + 0x10000; \+    ptr -= 2; \+    } \+  else \+    { \+    invalid_action; \+    } \+  }+++#elif PCRE2_CODE_UNIT_WIDTH == 32++#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \+  { \+  if (ptr[0] < 0xd800 || (ptr[0] >= 0xe000 && ptr[0] < 0x110000)) \+    c = *ptr++; \+  else \+    { \+    invalid_action; \+    } \+  }++#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \+  { \+  c = ptr[-1]; \+  if (ptr[-1] < 0xd800 || (ptr[-1] >= 0xe000 && ptr[-1] < 0x110000)) \+    ptr--; \+  else \+    { \+    invalid_action; \+    } \+  }++#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+#endif /* SUPPORT_UNICODE */++static PCRE2_SPTR bracketend(PCRE2_SPTR cc)+{+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND));+do cc += GET(cc, 1); while (*cc == OP_ALT);+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);+cc += 1 + LINK_SIZE;+return cc;+}++static int no_alternatives(PCRE2_SPTR cc)+{+int count = 0;+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND));+do+  {+  cc += GET(cc, 1);+  count++;+  }+while (*cc == OP_ALT);+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);+return count;+}++/* Functions whose might need modification for all new supported opcodes:+ next_opcode+ check_opcode_types+ set_private_data_ptrs+ get_framesize+ init_frame+ get_recurse_data_length+ copy_recurse_data+ compile_matchingpath+ compile_backtrackingpath+*/++static PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc)+{+SLJIT_UNUSED_ARG(common);+switch(*cc)+  {+  case OP_SOD:+  case OP_SOM:+  case OP_SET_SOM:+  case OP_NOT_WORD_BOUNDARY:+  case OP_WORD_BOUNDARY:+  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:+  case OP_NOTPROP:+  case OP_PROP:+  case OP_ANYNL:+  case OP_NOT_HSPACE:+  case OP_HSPACE:+  case OP_NOT_VSPACE:+  case OP_VSPACE:+  case OP_EXTUNI:+  case OP_EODN:+  case OP_EOD:+  case OP_CIRC:+  case OP_CIRCM:+  case OP_DOLL:+  case OP_DOLLM:+  case OP_CRSTAR:+  case OP_CRMINSTAR:+  case OP_CRPLUS:+  case OP_CRMINPLUS:+  case OP_CRQUERY:+  case OP_CRMINQUERY:+  case OP_CRRANGE:+  case OP_CRMINRANGE:+  case OP_CRPOSSTAR:+  case OP_CRPOSPLUS:+  case OP_CRPOSQUERY:+  case OP_CRPOSRANGE:+  case OP_CLASS:+  case OP_NCLASS:+  case OP_REF:+  case OP_REFI:+  case OP_DNREF:+  case OP_DNREFI:+  case OP_RECURSE:+  case OP_CALLOUT:+  case OP_ALT:+  case OP_KET:+  case OP_KETRMAX:+  case OP_KETRMIN:+  case OP_KETRPOS:+  case OP_REVERSE:+  case OP_ASSERT:+  case OP_ASSERT_NOT:+  case OP_ASSERTBACK:+  case OP_ASSERTBACK_NOT:+  case OP_ASSERT_NA:+  case OP_ASSERTBACK_NA:+  case OP_ONCE:+  case OP_SCRIPT_RUN:+  case OP_BRA:+  case OP_BRAPOS:+  case OP_CBRA:+  case OP_CBRAPOS:+  case OP_COND:+  case OP_SBRA:+  case OP_SBRAPOS:+  case OP_SCBRA:+  case OP_SCBRAPOS:+  case OP_SCOND:+  case OP_CREF:+  case OP_DNCREF:+  case OP_RREF:+  case OP_DNRREF:+  case OP_FALSE:+  case OP_TRUE:+  case OP_BRAZERO:+  case OP_BRAMINZERO:+  case OP_BRAPOSZERO:+  case OP_PRUNE:+  case OP_SKIP:+  case OP_THEN:+  case OP_COMMIT:+  case OP_FAIL:+  case OP_ACCEPT:+  case OP_ASSERT_ACCEPT:+  case OP_CLOSE:+  case OP_SKIPZERO:+  return cc + PRIV(OP_lengths)[*cc];++  case OP_CHAR:+  case OP_CHARI:+  case OP_NOT:+  case OP_NOTI:+  case OP_STAR:+  case OP_MINSTAR:+  case OP_PLUS:+  case OP_MINPLUS:+  case OP_QUERY:+  case OP_MINQUERY:+  case OP_UPTO:+  case OP_MINUPTO:+  case OP_EXACT:+  case OP_POSSTAR:+  case OP_POSPLUS:+  case OP_POSQUERY:+  case OP_POSUPTO:+  case OP_STARI:+  case OP_MINSTARI:+  case OP_PLUSI:+  case OP_MINPLUSI:+  case OP_QUERYI:+  case OP_MINQUERYI:+  case OP_UPTOI:+  case OP_MINUPTOI:+  case OP_EXACTI:+  case OP_POSSTARI:+  case OP_POSPLUSI:+  case OP_POSQUERYI:+  case OP_POSUPTOI:+  case OP_NOTSTAR:+  case OP_NOTMINSTAR:+  case OP_NOTPLUS:+  case OP_NOTMINPLUS:+  case OP_NOTQUERY:+  case OP_NOTMINQUERY:+  case OP_NOTUPTO:+  case OP_NOTMINUPTO:+  case OP_NOTEXACT:+  case OP_NOTPOSSTAR:+  case OP_NOTPOSPLUS:+  case OP_NOTPOSQUERY:+  case OP_NOTPOSUPTO:+  case OP_NOTSTARI:+  case OP_NOTMINSTARI:+  case OP_NOTPLUSI:+  case OP_NOTMINPLUSI:+  case OP_NOTQUERYI:+  case OP_NOTMINQUERYI:+  case OP_NOTUPTOI:+  case OP_NOTMINUPTOI:+  case OP_NOTEXACTI:+  case OP_NOTPOSSTARI:+  case OP_NOTPOSPLUSI:+  case OP_NOTPOSQUERYI:+  case OP_NOTPOSUPTOI:+  cc += PRIV(OP_lengths)[*cc];+#ifdef SUPPORT_UNICODE+  if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+  return cc;++  /* Special cases. */+  case OP_TYPESTAR:+  case OP_TYPEMINSTAR:+  case OP_TYPEPLUS:+  case OP_TYPEMINPLUS:+  case OP_TYPEQUERY:+  case OP_TYPEMINQUERY:+  case OP_TYPEUPTO:+  case OP_TYPEMINUPTO:+  case OP_TYPEEXACT:+  case OP_TYPEPOSSTAR:+  case OP_TYPEPOSPLUS:+  case OP_TYPEPOSQUERY:+  case OP_TYPEPOSUPTO:+  return cc + PRIV(OP_lengths)[*cc] - 1;++  case OP_ANYBYTE:+#ifdef SUPPORT_UNICODE+  if (common->utf) return NULL;+#endif+  return cc + 1;++  case OP_CALLOUT_STR:+  return cc + GET(cc, 1 + 2*LINK_SIZE);++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+  case OP_XCLASS:+  return cc + GET(cc, 1);+#endif++  case OP_MARK:+  case OP_COMMIT_ARG:+  case OP_PRUNE_ARG:+  case OP_SKIP_ARG:+  case OP_THEN_ARG:+  return cc + 1 + 2 + cc[1];++  default:+  SLJIT_UNREACHABLE();+  return NULL;+  }+}++static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend)+{+int count;+PCRE2_SPTR slot;+PCRE2_SPTR assert_back_end = cc - 1;+PCRE2_SPTR assert_na_end = cc - 1;++/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */+while (cc < ccend)+  {+  switch(*cc)+    {+    case OP_SET_SOM:+    common->has_set_som = TRUE;+    common->might_be_empty = TRUE;+    cc += 1;+    break;++    case OP_REFI:+#ifdef SUPPORT_UNICODE+    if (common->iref_ptr == 0)+      {+      common->iref_ptr = common->ovector_start;+      common->ovector_start += 3 * sizeof(sljit_sw);+      }+#endif /* SUPPORT_UNICODE */+    /* Fall through. */+    case OP_REF:+    common->optimized_cbracket[GET2(cc, 1)] = 0;+    cc += 1 + IMM2_SIZE;+    break;++    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    slot = bracketend(cc);+    if (slot > assert_na_end)+      assert_na_end = slot;+    cc += 1 + LINK_SIZE;+    break;++    case OP_CBRAPOS:+    case OP_SCBRAPOS:+    common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;+    cc += 1 + LINK_SIZE + IMM2_SIZE;+    break;++    case OP_COND:+    case OP_SCOND:+    /* Only AUTO_CALLOUT can insert this opcode. We do+       not intend to support this case. */+    if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR)+      return FALSE;+    cc += 1 + LINK_SIZE;+    break;++    case OP_CREF:+    common->optimized_cbracket[GET2(cc, 1)] = 0;+    cc += 1 + IMM2_SIZE;+    break;++    case OP_DNREF:+    case OP_DNREFI:+    case OP_DNCREF:+    count = GET2(cc, 1 + IMM2_SIZE);+    slot = common->name_table + GET2(cc, 1) * common->name_entry_size;+    while (count-- > 0)+      {+      common->optimized_cbracket[GET2(slot, 0)] = 0;+      slot += common->name_entry_size;+      }+    cc += 1 + 2 * IMM2_SIZE;+    break;++    case OP_RECURSE:+    /* Set its value only once. */+    if (common->recursive_head_ptr == 0)+      {+      common->recursive_head_ptr = common->ovector_start;+      common->ovector_start += sizeof(sljit_sw);+      }+    cc += 1 + LINK_SIZE;+    break;++    case OP_CALLOUT:+    case OP_CALLOUT_STR:+    if (common->capture_last_ptr == 0)+      {+      common->capture_last_ptr = common->ovector_start;+      common->ovector_start += sizeof(sljit_sw);+      }+    cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE);+    break;++    case OP_ASSERTBACK:+    slot = bracketend(cc);+    if (slot > assert_back_end)+      assert_back_end = slot;+    cc += 1 + LINK_SIZE;+    break;++    case OP_THEN_ARG:+    common->has_then = TRUE;+    common->control_head_ptr = 1;+    /* Fall through. */++    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    if (cc < assert_na_end)+      return FALSE;+    /* Fall through */+    case OP_MARK:+    if (common->mark_ptr == 0)+      {+      common->mark_ptr = common->ovector_start;+      common->ovector_start += sizeof(sljit_sw);+      }+    cc += 1 + 2 + cc[1];+    break;++    case OP_THEN:+    common->has_then = TRUE;+    common->control_head_ptr = 1;+    cc += 1;+    break;++    case OP_SKIP:+    if (cc < assert_back_end)+      common->has_skip_in_assert_back = TRUE;+    if (cc < assert_na_end)+      return FALSE;+    cc += 1;+    break;++    case OP_SKIP_ARG:+    common->control_head_ptr = 1;+    common->has_skip_arg = TRUE;+    if (cc < assert_back_end)+      common->has_skip_in_assert_back = TRUE;+    if (cc < assert_na_end)+      return FALSE;+    cc += 1 + 2 + cc[1];+    break;++    case OP_PRUNE:+    case OP_COMMIT:+    case OP_ASSERT_ACCEPT:+    if (cc < assert_na_end)+      return FALSE;+    cc++;+    break;++    default:+    cc = next_opcode(common, cc);+    if (cc == NULL)+      return FALSE;+    break;+    }+  }+return TRUE;+}++#define EARLY_FAIL_ENHANCE_MAX (1 + 1)++/*+start:+  0 - skip / early fail allowed+  1 - only early fail with range allowed+  >1 - (start - 1) early fail is processed++return: current number of iterators enhanced with fast fail+*/+static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth, int start)+{+PCRE2_SPTR next_alt;+PCRE2_SPTR end;+PCRE2_SPTR accelerated_start;+int result = 0;+int count;+BOOL fast_forward_allowed = TRUE;++SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA);+SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0);+SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX);++do+  {+  count = start;+  next_alt = cc + GET(cc, 1);+  cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);++  while (TRUE)+    {+    accelerated_start = NULL;++    switch(*cc)+      {+      case OP_SOD:+      case OP_SOM:+      case OP_SET_SOM:+      case OP_NOT_WORD_BOUNDARY:+      case OP_WORD_BOUNDARY:+      case OP_EODN:+      case OP_EOD:+      case OP_CIRC:+      case OP_CIRCM:+      case OP_DOLL:+      case OP_DOLLM:+      /* Zero width assertions. */+      cc++;+      continue;++      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:+      case OP_ANYBYTE:+      case OP_NOT_HSPACE:+      case OP_HSPACE:+      case OP_NOT_VSPACE:+      case OP_VSPACE:+      fast_forward_allowed = FALSE;+      cc++;+      continue;++      case OP_ANYNL:+      case OP_EXTUNI:+      fast_forward_allowed = FALSE;+      if (count == 0)+        count = 1;+      cc++;+      continue;++      case OP_NOTPROP:+      case OP_PROP:+      fast_forward_allowed = FALSE;+      cc += 1 + 2;+      continue;++      case OP_CHAR:+      case OP_CHARI:+      case OP_NOT:+      case OP_NOTI:+      fast_forward_allowed = FALSE;+      cc += 2;+#ifdef SUPPORT_UNICODE+      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+      continue;++      case OP_TYPESTAR:+      case OP_TYPEMINSTAR:+      case OP_TYPEPLUS:+      case OP_TYPEMINPLUS:+      case OP_TYPEPOSSTAR:+      case OP_TYPEPOSPLUS:+      /* The type or prop opcode is skipped in the next iteration. */+      cc += 1;++      if (cc[0] != OP_ANYNL && cc[0] != OP_EXTUNI)+        {+        accelerated_start = cc - 1;+        break;+        }++      if (count == 0)+        count = 1;+      fast_forward_allowed = FALSE;+      continue;++      case OP_TYPEUPTO:+      case OP_TYPEMINUPTO:+      case OP_TYPEEXACT:+      case OP_TYPEPOSUPTO:+      cc += IMM2_SIZE;+      /* Fall through */++      case OP_TYPEQUERY:+      case OP_TYPEMINQUERY:+      case OP_TYPEPOSQUERY:+      /* The type or prop opcode is skipped in the next iteration. */+      fast_forward_allowed = FALSE;+      if (count == 0)+        count = 1;+      cc += 1;+      continue;++      case OP_STAR:+      case OP_MINSTAR:+      case OP_PLUS:+      case OP_MINPLUS:+      case OP_POSSTAR:+      case OP_POSPLUS:++      case OP_STARI:+      case OP_MINSTARI:+      case OP_PLUSI:+      case OP_MINPLUSI:+      case OP_POSSTARI:+      case OP_POSPLUSI:++      case OP_NOTSTAR:+      case OP_NOTMINSTAR:+      case OP_NOTPLUS:+      case OP_NOTMINPLUS:+      case OP_NOTPOSSTAR:+      case OP_NOTPOSPLUS:++      case OP_NOTSTARI:+      case OP_NOTMINSTARI:+      case OP_NOTPLUSI:+      case OP_NOTMINPLUSI:+      case OP_NOTPOSSTARI:+      case OP_NOTPOSPLUSI:+      accelerated_start = cc;+      cc += 2;+#ifdef SUPPORT_UNICODE+      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+      break;++      case OP_UPTO:+      case OP_MINUPTO:+      case OP_EXACT:+      case OP_POSUPTO:+      case OP_UPTOI:+      case OP_MINUPTOI:+      case OP_EXACTI:+      case OP_POSUPTOI:+      case OP_NOTUPTO:+      case OP_NOTMINUPTO:+      case OP_NOTEXACT:+      case OP_NOTPOSUPTO:+      case OP_NOTUPTOI:+      case OP_NOTMINUPTOI:+      case OP_NOTEXACTI:+      case OP_NOTPOSUPTOI:+      cc += IMM2_SIZE;+      /* Fall through */++      case OP_QUERY:+      case OP_MINQUERY:+      case OP_POSQUERY:+      case OP_QUERYI:+      case OP_MINQUERYI:+      case OP_POSQUERYI:+      case OP_NOTQUERY:+      case OP_NOTMINQUERY:+      case OP_NOTPOSQUERY:+      case OP_NOTQUERYI:+      case OP_NOTMINQUERYI:+      case OP_NOTPOSQUERYI:+      fast_forward_allowed = FALSE;+      if (count == 0)+        count = 1;+      cc += 2;+#ifdef SUPPORT_UNICODE+      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+      continue;++      case OP_CLASS:+      case OP_NCLASS:+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+      case OP_XCLASS:+      accelerated_start = cc;+      cc += ((*cc == OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR))));+#else+      accelerated_start = cc;+      cc += (1 + (32 / sizeof(PCRE2_UCHAR)));+#endif++      switch (*cc)+        {+        case OP_CRSTAR:+        case OP_CRMINSTAR:+        case OP_CRPLUS:+        case OP_CRMINPLUS:+        case OP_CRPOSSTAR:+        case OP_CRPOSPLUS:+        cc++;+        break;++        case OP_CRRANGE:+        case OP_CRMINRANGE:+        case OP_CRPOSRANGE:+        cc += 2 * IMM2_SIZE;+        /* Fall through */+        case OP_CRQUERY:+        case OP_CRMINQUERY:+        case OP_CRPOSQUERY:+        cc++;+        if (count == 0)+          count = 1;+        /* Fall through */+        default:+        accelerated_start = NULL;+        fast_forward_allowed = FALSE;+        continue;+        }+      break;++      case OP_ONCE:+      case OP_BRA:+      case OP_CBRA:+      end = cc + GET(cc, 1);++      if (*end == OP_KET && PRIVATE_DATA(end) == 0)+        {+        if (*cc == OP_CBRA)+          {+          if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)+            break;+          cc += IMM2_SIZE;+          }++        cc += 1 + LINK_SIZE;+        continue;+        }++      fast_forward_allowed = FALSE;+      if (depth >= 4)+        break;++      end = bracketend(cc) - (1 + LINK_SIZE);+      if (*end != OP_KET || PRIVATE_DATA(end) != 0)+        break;++      if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)+        break;++      count = detect_early_fail(common, cc, private_data_start, depth + 1, count);+      if (count < EARLY_FAIL_ENHANCE_MAX)+        {+        cc = end + (1 + LINK_SIZE);+        continue;+        }+      break;++      case OP_KET:+      SLJIT_ASSERT(PRIVATE_DATA(cc) == 0);+      if (cc >= next_alt)+        break;+      cc += 1 + LINK_SIZE;+      continue;+      }++    if (accelerated_start != NULL)+      {+      if (count == 0)+        {+        count++;++        if (fast_forward_allowed && *next_alt == OP_KET)+          {+          common->fast_forward_bc_ptr = accelerated_start;+          common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip;+          *private_data_start += sizeof(sljit_sw);+          }+        else+          {+          common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail;++          if (common->early_fail_start_ptr == 0)+            common->early_fail_start_ptr = *private_data_start;++          *private_data_start += sizeof(sljit_sw);+          common->early_fail_end_ptr = *private_data_start;++          if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)+            return EARLY_FAIL_ENHANCE_MAX;+          }+        }+      else+        {+        common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range;++        if (common->early_fail_start_ptr == 0)+          common->early_fail_start_ptr = *private_data_start;++        *private_data_start += 2 * sizeof(sljit_sw);+        common->early_fail_end_ptr = *private_data_start;++        if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)+          return EARLY_FAIL_ENHANCE_MAX;+        }++      count++;++      if (count < EARLY_FAIL_ENHANCE_MAX)+        continue;+      }++    break;+    }++  if (*cc != OP_ALT && *cc != OP_KET)+    result = EARLY_FAIL_ENHANCE_MAX;+  else if (result < count)+    result = count;++  fast_forward_allowed = FALSE;+  cc = next_alt;+  }+while (*cc == OP_ALT);++return result;+}++static int get_class_iterator_size(PCRE2_SPTR cc)+{+sljit_u32 min;+sljit_u32 max;+switch(*cc)+  {+  case OP_CRSTAR:+  case OP_CRPLUS:+  return 2;++  case OP_CRMINSTAR:+  case OP_CRMINPLUS:+  case OP_CRQUERY:+  case OP_CRMINQUERY:+  return 1;++  case OP_CRRANGE:+  case OP_CRMINRANGE:+  min = GET2(cc, 1);+  max = GET2(cc, 1 + IMM2_SIZE);+  if (max == 0)+    return (*cc == OP_CRRANGE) ? 2 : 1;+  max -= min;+  if (max > 2)+    max = 2;+  return max;++  default:+  return 0;+  }+}++static BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin)+{+PCRE2_SPTR end = bracketend(begin);+PCRE2_SPTR next;+PCRE2_SPTR next_end;+PCRE2_SPTR max_end;+PCRE2_UCHAR type;+sljit_sw length = end - begin;+sljit_s32 min, max, i;++/* Detect fixed iterations first. */+if (end[-(1 + LINK_SIZE)] != OP_KET)+  return FALSE;++/* Already detected repeat. */+if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)+  return TRUE;++next = end;+min = 1;+while (1)+  {+  if (*next != *begin)+    break;+  next_end = bracketend(next);+  if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)+    break;+  next = next_end;+  min++;+  }++if (min == 2)+  return FALSE;++max = 0;+max_end = next;+if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)+  {+  type = *next;+  while (1)+    {+    if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)+      break;+    next_end = bracketend(next + 2 + LINK_SIZE);+    if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)+      break;+    next = next_end;+    max++;+    }++  if (next[0] == type && next[1] == *begin && max >= 1)+    {+    next_end = bracketend(next + 1);+    if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)+      {+      for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)+        if (*next_end != OP_KET)+          break;++      if (i == max)+        {+        common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;+        common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;+        /* +2 the original and the last. */+        common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;+        if (min == 1)+          return TRUE;+        min--;+        max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);+        }+      }+    }+  }++if (min >= 3)+  {+  common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;+  common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;+  common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;+  return TRUE;+  }++return FALSE;+}++#define CASE_ITERATOR_PRIVATE_DATA_1 \+    case OP_MINSTAR: \+    case OP_MINPLUS: \+    case OP_QUERY: \+    case OP_MINQUERY: \+    case OP_MINSTARI: \+    case OP_MINPLUSI: \+    case OP_QUERYI: \+    case OP_MINQUERYI: \+    case OP_NOTMINSTAR: \+    case OP_NOTMINPLUS: \+    case OP_NOTQUERY: \+    case OP_NOTMINQUERY: \+    case OP_NOTMINSTARI: \+    case OP_NOTMINPLUSI: \+    case OP_NOTQUERYI: \+    case OP_NOTMINQUERYI:++#define CASE_ITERATOR_PRIVATE_DATA_2A \+    case OP_STAR: \+    case OP_PLUS: \+    case OP_STARI: \+    case OP_PLUSI: \+    case OP_NOTSTAR: \+    case OP_NOTPLUS: \+    case OP_NOTSTARI: \+    case OP_NOTPLUSI:++#define CASE_ITERATOR_PRIVATE_DATA_2B \+    case OP_UPTO: \+    case OP_MINUPTO: \+    case OP_UPTOI: \+    case OP_MINUPTOI: \+    case OP_NOTUPTO: \+    case OP_NOTMINUPTO: \+    case OP_NOTUPTOI: \+    case OP_NOTMINUPTOI:++#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \+    case OP_TYPEMINSTAR: \+    case OP_TYPEMINPLUS: \+    case OP_TYPEQUERY: \+    case OP_TYPEMINQUERY:++#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \+    case OP_TYPESTAR: \+    case OP_TYPEPLUS:++#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \+    case OP_TYPEUPTO: \+    case OP_TYPEMINUPTO:++static void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend)+{+PCRE2_SPTR cc = common->start;+PCRE2_SPTR alternative;+PCRE2_SPTR end = NULL;+int private_data_ptr = *private_data_start;+int space, size, bracketlen;+BOOL repeat_check = TRUE;++while (cc < ccend)+  {+  space = 0;+  size = 0;+  bracketlen = 0;+  if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)+    break;++  if (repeat_check && (*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))+    {+    if (detect_repeat(common, cc))+      {+      /* These brackets are converted to repeats, so no global+      based single character repeat is allowed. */+      if (cc >= end)+        end = bracketend(cc);+      }+    }+  repeat_check = TRUE;++  switch(*cc)+    {+    case OP_KET:+    if (common->private_data_ptrs[cc + 1 - common->start] != 0)+      {+      common->private_data_ptrs[cc - common->start] = private_data_ptr;+      private_data_ptr += sizeof(sljit_sw);+      cc += common->private_data_ptrs[cc + 1 - common->start];+      }+    cc += 1 + LINK_SIZE;+    break;++    case OP_ASSERT:+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    case OP_ONCE:+    case OP_SCRIPT_RUN:+    case OP_BRAPOS:+    case OP_SBRA:+    case OP_SBRAPOS:+    case OP_SCOND:+    common->private_data_ptrs[cc - common->start] = private_data_ptr;+    private_data_ptr += sizeof(sljit_sw);+    bracketlen = 1 + LINK_SIZE;+    break;++    case OP_CBRAPOS:+    case OP_SCBRAPOS:+    common->private_data_ptrs[cc - common->start] = private_data_ptr;+    private_data_ptr += sizeof(sljit_sw);+    bracketlen = 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)+      {+      common->private_data_ptrs[cc - common->start] = private_data_ptr;+      private_data_ptr += sizeof(sljit_sw);+      }+    bracketlen = 1 + LINK_SIZE;+    break;++    case OP_BRA:+    bracketlen = 1 + LINK_SIZE;+    break;++    case OP_CBRA:+    case OP_SCBRA:+    bracketlen = 1 + LINK_SIZE + IMM2_SIZE;+    break;++    case OP_BRAZERO:+    case OP_BRAMINZERO:+    case OP_BRAPOSZERO:+    size = 1;+    repeat_check = FALSE;+    break;++    CASE_ITERATOR_PRIVATE_DATA_1+    size = -2;+    space = 1;+    break;++    CASE_ITERATOR_PRIVATE_DATA_2A+    size = -2;+    space = 2;+    break;++    CASE_ITERATOR_PRIVATE_DATA_2B+    size = -(2 + IMM2_SIZE);+    space = 2;+    break;++    CASE_ITERATOR_TYPE_PRIVATE_DATA_1+    size = 1;+    space = 1;+    break;++    CASE_ITERATOR_TYPE_PRIVATE_DATA_2A+    size = 1;+    if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)+      space = 2;+    break;++    case OP_TYPEUPTO:+    size = 1 + IMM2_SIZE;+    if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)+      space = 2;+    break;++    case OP_TYPEMINUPTO:+    size = 1 + IMM2_SIZE;+    space = 2;+    break;++    case OP_CLASS:+    case OP_NCLASS:+    size = 1 + 32 / sizeof(PCRE2_UCHAR);+    space = get_class_iterator_size(cc + size);+    break;++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+    case OP_XCLASS:+    size = GET(cc, 1);+    space = get_class_iterator_size(cc + size);+    break;+#endif++    default:+    cc = next_opcode(common, cc);+    SLJIT_ASSERT(cc != NULL);+    break;+    }++  /* Character iterators, which are not inside a repeated bracket,+     gets a private slot instead of allocating it on the stack. */+  if (space > 0 && cc >= end)+    {+    common->private_data_ptrs[cc - common->start] = private_data_ptr;+    private_data_ptr += sizeof(sljit_sw) * space;+    }++  if (size != 0)+    {+    if (size < 0)+      {+      cc += -size;+#ifdef SUPPORT_UNICODE+      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+      }+    else+      cc += size;+    }++  if (bracketlen > 0)+    {+    if (cc >= end)+      {+      end = bracketend(cc);+      if (end[-1 - LINK_SIZE] == OP_KET)+        end = NULL;+      }+    cc += bracketlen;+    }+  }+*private_data_start = private_data_ptr;+}++/* Returns with a frame_types (always < 0) if no need for frame. */+static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head)+{+int length = 0;+int possessive = 0;+BOOL stack_restore = FALSE;+BOOL setsom_found = recursive;+BOOL setmark_found = recursive;+/* The last capture is a local variable even for recursions. */+BOOL capture_last_found = FALSE;++#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD+SLJIT_ASSERT(common->control_head_ptr != 0);+*needs_control_head = TRUE;+#else+*needs_control_head = FALSE;+#endif++if (ccend == NULL)+  {+  ccend = bracketend(cc) - (1 + LINK_SIZE);+  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))+    {+    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;+    /* This is correct regardless of common->capture_last_ptr. */+    capture_last_found = TRUE;+    }+  cc = next_opcode(common, cc);+  }++SLJIT_ASSERT(cc != NULL);+while (cc < ccend)+  switch(*cc)+    {+    case OP_SET_SOM:+    SLJIT_ASSERT(common->has_set_som);+    stack_restore = TRUE;+    if (!setsom_found)+      {+      length += 2;+      setsom_found = TRUE;+      }+    cc += 1;+    break;++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_THEN_ARG:+    SLJIT_ASSERT(common->mark_ptr != 0);+    stack_restore = TRUE;+    if (!setmark_found)+      {+      length += 2;+      setmark_found = TRUE;+      }+    if (common->control_head_ptr != 0)+      *needs_control_head = TRUE;+    cc += 1 + 2 + cc[1];+    break;++    case OP_RECURSE:+    stack_restore = TRUE;+    if (common->has_set_som && !setsom_found)+      {+      length += 2;+      setsom_found = TRUE;+      }+    if (common->mark_ptr != 0 && !setmark_found)+      {+      length += 2;+      setmark_found = TRUE;+      }+    if (common->capture_last_ptr != 0 && !capture_last_found)+      {+      length += 2;+      capture_last_found = TRUE;+      }+    cc += 1 + LINK_SIZE;+    break;++    case OP_CBRA:+    case OP_CBRAPOS:+    case OP_SCBRA:+    case OP_SCBRAPOS:+    stack_restore = TRUE;+    if (common->capture_last_ptr != 0 && !capture_last_found)+      {+      length += 2;+      capture_last_found = TRUE;+      }+    length += 3;+    cc += 1 + LINK_SIZE + IMM2_SIZE;+    break;++    case OP_THEN:+    stack_restore = TRUE;+    if (common->control_head_ptr != 0)+      *needs_control_head = TRUE;+    cc ++;+    break;++    default:+    stack_restore = TRUE;+    /* Fall through. */++    case OP_NOT_WORD_BOUNDARY:+    case OP_WORD_BOUNDARY:+    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:+    case OP_ANYBYTE:+    case OP_NOTPROP:+    case OP_PROP:+    case OP_ANYNL:+    case OP_NOT_HSPACE:+    case OP_HSPACE:+    case OP_NOT_VSPACE:+    case OP_VSPACE:+    case OP_EXTUNI:+    case OP_EODN:+    case OP_EOD:+    case OP_CIRC:+    case OP_CIRCM:+    case OP_DOLL:+    case OP_DOLLM:+    case OP_CHAR:+    case OP_CHARI:+    case OP_NOT:+    case OP_NOTI:++    case OP_EXACT:+    case OP_POSSTAR:+    case OP_POSPLUS:+    case OP_POSQUERY:+    case OP_POSUPTO:++    case OP_EXACTI:+    case OP_POSSTARI:+    case OP_POSPLUSI:+    case OP_POSQUERYI:+    case OP_POSUPTOI:++    case OP_NOTEXACT:+    case OP_NOTPOSSTAR:+    case OP_NOTPOSPLUS:+    case OP_NOTPOSQUERY:+    case OP_NOTPOSUPTO:++    case OP_NOTEXACTI:+    case OP_NOTPOSSTARI:+    case OP_NOTPOSPLUSI:+    case OP_NOTPOSQUERYI:+    case OP_NOTPOSUPTOI:++    case OP_TYPEEXACT:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPOSPLUS:+    case OP_TYPEPOSQUERY:+    case OP_TYPEPOSUPTO:++    case OP_CLASS:+    case OP_NCLASS:+    case OP_XCLASS:++    case OP_CALLOUT:+    case OP_CALLOUT_STR:++    cc = next_opcode(common, cc);+    SLJIT_ASSERT(cc != NULL);+    break;+    }++/* Possessive quantifiers can use a special case. */+if (SLJIT_UNLIKELY(possessive == length))+  return stack_restore ? no_frame : no_stack;++if (length > 0)+  return length + 1;+return stack_restore ? no_frame : no_stack;+}++static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop)+{+DEFINE_COMPILER;+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;++/* >= 1 + shortest item size (2) */+SLJIT_UNUSED_ARG(stacktop);+SLJIT_ASSERT(stackpos >= stacktop + 2);++stackpos = STACK(stackpos);+if (ccend == NULL)+  {+  ccend = bracketend(cc) - (1 + LINK_SIZE);+  if (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)+    cc = next_opcode(common, cc);+  }++SLJIT_ASSERT(cc != NULL);+while (cc < ccend)+  switch(*cc)+    {+    case OP_SET_SOM:+    SLJIT_ASSERT(common->has_set_som);+    if (!setsom_found)+      {+      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);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);+      stackpos -= (int)sizeof(sljit_sw);+      setsom_found = TRUE;+      }+    cc += 1;+    break;++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_THEN_ARG:+    SLJIT_ASSERT(common->mark_ptr != 0);+    if (!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);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);+      stackpos -= (int)sizeof(sljit_sw);+      setmark_found = TRUE;+      }+    cc += 1 + 2 + cc[1];+    break;++    case OP_RECURSE:+    if (common->has_set_som && !setsom_found)+      {+      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);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);+      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);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);+      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);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);+      stackpos -= (int)sizeof(sljit_sw);+      capture_last_found = TRUE;+      }+    cc += 1 + LINK_SIZE;+    break;++    case OP_CBRA:+    case OP_CBRAPOS:+    case OP_SCBRA:+    case OP_SCBRAPOS:+    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);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);+      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);+    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);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);+    stackpos -= (int)sizeof(sljit_sw);++    cc += 1 + LINK_SIZE + IMM2_SIZE;+    break;++    default:+    cc = next_opcode(common, cc);+    SLJIT_ASSERT(cc != NULL);+    break;+    }++OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);+SLJIT_ASSERT(stackpos == STACK(stacktop));+}++#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 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)+      {+      length++;+      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_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    case OP_ONCE:+    case OP_SCRIPT_RUN:+    case OP_BRAPOS:+    case OP_SBRA:+    case OP_SBRAPOS:+    case OP_SCOND:+    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)+      length++;+    cc += 1 + LINK_SIZE + IMM2_SIZE;+    break;++    case OP_CBRAPOS:+    case OP_SCBRAPOS:+    length += 2 + 2;+    if (common->capture_last_ptr != 0)+      capture_last_found = TRUE;+    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)+      length++;+    cc += 1 + LINK_SIZE;+    break;++    CASE_ITERATOR_PRIVATE_DATA_1+    if (PRIVATE_DATA(cc) != 0)+      length++;+    cc += 2;+#ifdef SUPPORT_UNICODE+    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+    break;++    CASE_ITERATOR_PRIVATE_DATA_2A+    if (PRIVATE_DATA(cc) != 0)+      length += 2;+    cc += 2;+#ifdef SUPPORT_UNICODE+    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+    break;++    CASE_ITERATOR_PRIVATE_DATA_2B+    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]);+#endif+    break;++    CASE_ITERATOR_TYPE_PRIVATE_DATA_1+    if (PRIVATE_DATA(cc) != 0)+      length++;+    cc += 1;+    break;++    CASE_ITERATOR_TYPE_PRIVATE_DATA_2A+    if (PRIVATE_DATA(cc) != 0)+      length += 2;+    cc += 1;+    break;++    CASE_ITERATOR_TYPE_PRIVATE_DATA_2B+    if (PRIVATE_DATA(cc) != 0)+      length += 2;+    cc += 1 + IMM2_SIZE;+    break;++    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);+#else+    size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);+#endif+    if (PRIVATE_DATA(cc) != 0)+      length += get_class_iterator_size(cc + size);+    cc += size;+    break;++    case OP_MARK:+    case OP_COMMIT_ARG:+    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);+    break;+    }+  }+SLJIT_ASSERT(cc == ccend);++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;+}++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)+{+delayed_mem_copy_status status;+PCRE2_SPTR alternative;+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;++#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD+SLJIT_ASSERT(common->control_head_ptr != 0);+control_head_found = TRUE;+#endif++switch (type)+  {+  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;+  }++stackptr = STACK(stackptr);+stacktop = STACK(stacktop);++status.tmp_regs[0] = TMP1;+status.saved_tmp_regs[0] = TMP1;++if (base_reg != TMP2)+  {+  status.tmp_regs[1] = TMP2;+  status.saved_tmp_regs[1] = TMP2;+  }+else+  {+  status.saved_tmp_regs[1] = RETURN_ADDR;+  if (HAS_VIRTUAL_REGISTERS)+    status.tmp_regs[1] = STR_PTR;+  else+    status.tmp_regs[1] = RETURN_ADDR;+  }++status.saved_tmp_regs[2] = TMP3;+if (HAS_VIRTUAL_REGISTERS)+  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 OP_SET_SOM:+    SLJIT_ASSERT(common->has_set_som);+    if (has_quit && !setsom_found)+      {+      kept_shared_srcw[0] = OVECTOR(0);+      kept_shared_count = 1;+      setsom_found = TRUE;+      }+    cc += 1;+    break;++    case OP_RECURSE:+    if (has_quit)+      {+      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_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    case OP_ONCE:+    case OP_SCRIPT_RUN:+    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;+      }++    if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)+      {+      private_count = 1;+      private_srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));+      }+    cc += 1 + LINK_SIZE + IMM2_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;++    if (common->capture_last_ptr != 0 && !capture_last_found)+      {+      shared_srcw[2] = common->capture_last_ptr;+      shared_count = 3;+      capture_last_found = TRUE;+      }++    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)+      {+      private_count = 1;+      private_srcw[0] = PRIVATE_DATA(cc);+      }+    cc += 1 + LINK_SIZE;+    break;++    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]);+#endif+    break;++    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]);+#endif+    break;++    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]);+#endif+    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))+      {+      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))+      {+      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:+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+    case OP_XCLASS:+    i = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);+#else+    i = 1 + 32 / (int)sizeof(PCRE2_UCHAR);+#endif+    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:+        private_count = 2;+        private_srcw[0] = PRIVATE_DATA(cc);+        private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);+        break;++        default:+        SLJIT_UNREACHABLE();+        break;+        }+    cc += i;+    break;++    case OP_MARK:+    case OP_COMMIT_ARG:+    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)+      {+      private_srcw[0] = common->control_head_ptr;+      private_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)+      {+      private_srcw[0] = common->control_head_ptr;+      private_count = 1;+      control_head_found = TRUE;+      }+    cc++;+    break;++    default:+    cc = next_opcode(common, cc);+    SLJIT_ASSERT(cc != NULL);+    break;+    }++  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);++    for (i = 0; i < private_count; i++)+      {+      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)+    {+    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_swap_global);++    for (i = 0; i < shared_count; i++)+      {+      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);++delayed_mem_copy_finish(&status);+}++static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset)+{+PCRE2_SPTR end = bracketend(cc);+BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;++/* Assert captures then. */+if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA)+  current_offset = NULL;+/* Conditional block does not. */+if (*cc == OP_COND || *cc == OP_SCOND)+  has_alternatives = FALSE;++cc = next_opcode(common, cc);+if (has_alternatives)+  current_offset = common->then_offsets + (cc - common->start);++while (cc < end)+  {+  if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND))+    cc = set_then_offsets(common, cc, current_offset);+  else+    {+    if (*cc == OP_ALT && has_alternatives)+      current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);+    if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)+      *current_offset = 1;+    cc = next_opcode(common, cc);+    }+  }++return end;+}++#undef CASE_ITERATOR_PRIVATE_DATA_1+#undef CASE_ITERATOR_PRIVATE_DATA_2A+#undef CASE_ITERATOR_PRIVATE_DATA_2B+#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1+#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A+#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B++static SLJIT_INLINE BOOL is_powerof2(unsigned int value)+{+return (value & (value - 1)) == 0;+}++static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)+{+while (list)+  {+  /* sljit_set_label is clever enough to do nothing+  if either the jump or the label is NULL. */+  SET_LABEL(list->jump, label);+  list = list->next;+  }+}++static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)+{+jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));+if (list_item)+  {+  list_item->next = *list;+  list_item->jump = jump;+  *list = list_item;+  }+}++static void add_stub(compiler_common *common, struct sljit_jump *start)+{+DEFINE_COMPILER;+stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));++if (list_item)+  {+  list_item->start = start;+  list_item->quit = LABEL();+  list_item->next = common->stubs;+  common->stubs = list_item;+  }+}++static void flush_stubs(compiler_common *common)+{+DEFINE_COMPILER;+stub_list *list_item = common->stubs;++while (list_item)+  {+  JUMPHERE(list_item->start);+  add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));+  JUMPTO(SLJIT_JUMP, list_item->quit);+  list_item = list_item->next;+  }+common->stubs = NULL;+}++static SLJIT_INLINE void count_match(compiler_common *common)+{+DEFINE_COMPILER;++OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);+add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));+}++static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)+{+/* May destroy all locals and registers except TMP2. */+DEFINE_COMPILER;++SLJIT_ASSERT(size > 0);+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);+OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);+#endif+add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));+}++static SLJIT_INLINE void free_stack(compiler_common *common, int size)+{+DEFINE_COMPILER;++SLJIT_ASSERT(size > 0);+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)+{+DEFINE_COMPILER;+sljit_uw *result;++if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+  return NULL;++result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);+if (SLJIT_UNLIKELY(result == NULL))+  {+  sljit_set_compiler_memory_error(compiler);+  return NULL;+  }++*(void**)result = common->read_only_data_head;+common->read_only_data_head = (void *)result;+return result + 1;+}++static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)+{+DEFINE_COMPILER;+struct sljit_label *loop;+sljit_s32 i;++/* At this point we can freely use all temporary registers. */+SLJIT_ASSERT(length > 1);+/* TMP1 returns with begin - 1. */+OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));+if (length < 8)+  {+  for (i = 1; i < length; i++)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);+  }+else+  {+  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);+    }+  }+}++static SLJIT_INLINE void reset_early_fail(compiler_common *common)+{+DEFINE_COMPILER;+sljit_u32 size = (sljit_u32)(common->early_fail_end_ptr - common->early_fail_start_ptr);+sljit_u32 uncleared_size;+sljit_s32 src = SLJIT_IMM;+sljit_s32 i;+struct sljit_label *loop;++SLJIT_ASSERT(common->early_fail_start_ptr < common->early_fail_end_ptr);++if (size == sizeof(sljit_sw))+  {+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->early_fail_start_ptr, SLJIT_IMM, 0);+  return;+  }++if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER))+  {+  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);+  src = TMP3;+  }++if (size <= 6 * sizeof(sljit_sw))+  {+  for (i = common->early_fail_start_ptr; i < common->early_fail_end_ptr; i += sizeof(sljit_sw))+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, src, 0);+  return;+  }++GET_LOCAL_BASE(TMP1, 0, common->early_fail_start_ptr);++uncleared_size = ((size / sizeof(sljit_sw)) % 3) * sizeof(sljit_sw);++OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, size - uncleared_size);++loop = LABEL();+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -2 * (sljit_sw)sizeof(sljit_sw), src, 0);+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -1 * (sljit_sw)sizeof(sljit_sw), src, 0);+CMPTO(SLJIT_LESS, TMP1, 0, TMP2, 0, loop);++if (uncleared_size >= sizeof(sljit_sw))+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);++if (uncleared_size >= 2 * sizeof(sljit_sw))+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), sizeof(sljit_sw), src, 0);+}++static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)+{+DEFINE_COMPILER;+struct sljit_label *loop;+int i;++SLJIT_ASSERT(length > 1);+/* OVECTOR(1) contains the "string begin - 1" constant. */+if (length > 2)+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));+if (length < 8)+  {+  for (i = 2; i < length; i++)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);+  }+else+  {+  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);+    }+  }++if (!HAS_VIRTUAL_REGISTERS)+  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, stack));+else+  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);++if (common->mark_ptr != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);+if (common->control_head_ptr != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);+if (HAS_VIRTUAL_REGISTERS)+  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, end));+}++static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)+{+while (current != NULL)+  {+  switch (current[1])+    {+    case type_then_trap:+    break;++    case type_mark:+    if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[2]) == 0)+      return current[3];+    break;++    default:+    SLJIT_UNREACHABLE();+    break;+    }+  SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);+  current = (sljit_sw*)current[0];+  }+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));+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);++if (HAS_VIRTUAL_REGISTERS)+  {+  OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);+  OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);+  if (common->mark_ptr != 0)+    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);+  OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);+  if (common->mark_ptr != 0)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);+  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));+  }+else+  {+  OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);+  OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, match_data));+  if (common->mark_ptr != 0)+    OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);+  OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, oveccount));+  OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);+  if (common->mark_ptr != 0)+    OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R0, 0);+  OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));+  }++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(HAS_VIRTUAL_REGISTERS ? SLJIT_R0 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));++loop = LABEL();++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);+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)+  {+  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();+    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);+}++static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)+{+DEFINE_COMPILER;+sljit_s32 mov_opcode;+sljit_s32 arguments_reg = !HAS_VIRTUAL_REGISTERS ? ARGUMENTS : SLJIT_R1;++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));++if (arguments_reg != ARGUMENTS)+  OP1(SLJIT_MOV, arguments_reg, 0, ARGUMENTS, 0);+OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),+  common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr);+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);++/* Store match begin and end. */+OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, begin));+OP1(SLJIT_MOV, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);+OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(arguments_reg), 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_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_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+OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0);++JUMPTO(SLJIT_JUMP, quit);+}++static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)+{+/* May destroy TMP1. */+DEFINE_COMPILER;+struct sljit_jump *jump;++if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  {+  /* The value of -1 must be kept for start_used_ptr! */+  OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);+  /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting+  is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */+  jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);+  JUMPHERE(jump);+  }+else if (common->mode == PCRE2_JIT_PARTIAL_HARD)+  {+  jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);+  JUMPHERE(jump);+  }+}++static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc)+{+/* Detects if the character has an othercase. */+unsigned int c;++#ifdef SUPPORT_UNICODE+if (common->utf || common->ucp)+  {+  if (common->utf)+    {+    GETCHAR(c, cc);+    }+  else+    c = *cc;++  if (c > 127)+    return c != UCD_OTHERCASE(c);++  return common->fcc[c] != c;+  }+else+#endif+  c = *cc;+return MAX_255(c) ? common->fcc[c] != c : FALSE;+}++static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)+{+/* Returns with the othercase. */+#ifdef SUPPORT_UNICODE+if ((common->utf || common->ucp) && c > 127)+  return UCD_OTHERCASE(c);+#endif+return TABLE_GET(c, common->fcc, c);+}++static unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc)+{+/* Detects if the character and its othercase has only 1 bit difference. */+unsigned int c, oc, bit;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+int n;+#endif++#ifdef SUPPORT_UNICODE+if (common->utf || common->ucp)+  {+  if (common->utf)+    {+    GETCHAR(c, cc);+    }+  else+    c = *cc;++  if (c <= 127)+    oc = common->fcc[c];+  else+    oc = UCD_OTHERCASE(c);+  }+else+  {+  c = *cc;+  oc = TABLE_GET(c, common->fcc, c);+  }+#else+c = *cc;+oc = TABLE_GET(c, common->fcc, c);+#endif++SLJIT_ASSERT(c != oc);++bit = c ^ oc;+/* Optimized for English alphabet. */+if (c <= 127 && bit == 0x20)+  return (0 << 8) | 0x20;++/* Since c != oc, they must have at least 1 bit difference. */+if (!is_powerof2(bit))+  return 0;++#if PCRE2_CODE_UNIT_WIDTH == 8++#ifdef SUPPORT_UNICODE+if (common->utf && c > 127)+  {+  n = GET_EXTRALEN(*cc);+  while ((bit & 0x3f) == 0)+    {+    n--;+    bit >>= 6;+    }+  return (n << 8) | bit;+  }+#endif /* SUPPORT_UNICODE */+return (0 << 8) | bit;++#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32++#ifdef SUPPORT_UNICODE+if (common->utf && c > 65535)+  {+  if (bit >= (1u << 10))+    bit >>= 10;+  else+    return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));+  }+#endif /* SUPPORT_UNICODE */+return (bit < 256) ? ((0u << 8) | bit) : ((1u << 8) | (bit >> 8));++#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+}++static void check_partial(compiler_common *common, BOOL force)+{+/* Checks whether a partial matching is occurred. Does not modify registers. */+DEFINE_COMPILER;+struct sljit_jump *jump = NULL;++SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE);++if (common->mode == PCRE2_JIT_COMPLETE)+  return;++if (!force && !common->allow_empty_partial)+  jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);+else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);++if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);+else+  {+  if (common->partialmatchlabel != NULL)+    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);+  else+    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));+  }++if (jump != NULL)+  JUMPHERE(jump);+}++static void check_str_end(compiler_common *common, jump_list **end_reached)+{+/* Does not affect registers. Usually used in a tight spot. */+DEFINE_COMPILER;+struct sljit_jump *jump;++if (common->mode == PCRE2_JIT_COMPLETE)+  {+  add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));+  return;+  }++jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  {+  add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);+  add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));+  }+else+  {+  add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));+  if (common->partialmatchlabel != NULL)+    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);+  else+    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));+  }+JUMPHERE(jump);+}++static void detect_partial_match(compiler_common *common, jump_list **backtracks)+{+DEFINE_COMPILER;+struct sljit_jump *jump;++if (common->mode == PCRE2_JIT_COMPLETE)+  {+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));+  return;+  }++/* Partial matching mode. */+jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);+if (!common->allow_empty_partial)+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));+else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1));++if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  {+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);+  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));+  }+else+  {+  if (common->partialmatchlabel != NULL)+    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);+  else+    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));+  }+JUMPHERE(jump);+}++static void process_partial_match(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_jump *jump;++/* Partial matching mode. */+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)+  {+  jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);+  JUMPHERE(jump);+  }+else if (common->mode == PCRE2_JIT_PARTIAL_HARD)+  {+  if (common->partialmatchlabel != NULL)+    CMPTO(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0, common->partialmatchlabel);+  else+    add_jump(compiler, &common->partialmatch, CMP(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));+  }+}++static void detect_partial_match_to(compiler_common *common, struct sljit_label *label)+{+DEFINE_COMPILER;++CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, label);+process_partial_match(common);+}++static void peek_char(compiler_common *common, sljit_u32 max, sljit_s32 dst, sljit_sw dstw, jump_list **backtracks)+{+/* Reads the character into TMP1, keeps STR_PTR.+Does not check STR_END. TMP2, dst, RETURN_ADDR Destroyed. */+DEFINE_COMPILER;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+struct sljit_jump *jump;+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */++SLJIT_UNUSED_ARG(max);+SLJIT_UNUSED_ARG(dst);+SLJIT_UNUSED_ARG(dstw);+SLJIT_UNUSED_ARG(backtracks);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));++#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+if (common->utf)+  {+  if (max < 128) return;++  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);+  OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  add_jump(compiler, common->invalid_utf ? &common->utfreadchar_invalid : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));+  OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw);+  if (backtracks && common->invalid_utf)+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+  JUMPHERE(jump);+  }+#elif PCRE2_CODE_UNIT_WIDTH == 16+if (common->utf)+  {+  if (max < 0xd800) return;++  OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);++  if (common->invalid_utf)+    {+    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);+    OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));+    OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw);+    if (backtracks && common->invalid_utf)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+    }+  else+    {+    /* TMP2 contains the high surrogate. */+    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800);+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+    }++  JUMPHERE(jump);+  }+#elif PCRE2_CODE_UNIT_WIDTH == 32+if (common->invalid_utf)+  {+  if (max < 0xd800) return;++  if (backtracks != NULL)+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));+    }+  else+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);+    CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+    OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);+    CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+    }+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+#endif /* SUPPORT_UNICODE */+}++static void peek_char_back(compiler_common *common, sljit_u32 max, jump_list **backtracks)+{+/* Reads one character back without moving STR_PTR. TMP2 must+contain the start of the subject buffer. Affects TMP1, TMP2, and RETURN_ADDR. */+DEFINE_COMPILER;++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+struct sljit_jump *jump;+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */++SLJIT_UNUSED_ARG(max);+SLJIT_UNUSED_ARG(backtracks);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));++#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+if (common->utf)+  {+  if (max < 128) return;++  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);+  if (common->invalid_utf)+    {+    add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL));+    if (backtracks != NULL)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+    }+  else+    add_jump(compiler, &common->utfpeakcharback, JUMP(SLJIT_FAST_CALL));+  JUMPHERE(jump);+  }+#elif PCRE2_CODE_UNIT_WIDTH == 16+if (common->utf)+  {+  if (max < 0xd800) return;++  if (common->invalid_utf)+    {+    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);+    add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL));+    if (backtracks != NULL)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+    }+  else+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xdc00);+    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xdc00);+    /* TMP2 contains the low surrogate. */+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+    }+    JUMPHERE(jump);+  }+#elif PCRE2_CODE_UNIT_WIDTH == 32+if (common->invalid_utf)+  {+  OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));+  add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+#endif /* SUPPORT_UNICODE */+}++#define READ_CHAR_UPDATE_STR_PTR 0x1+#define READ_CHAR_UTF8_NEWLINE 0x2+#define READ_CHAR_NEWLINE (READ_CHAR_UPDATE_STR_PTR | READ_CHAR_UTF8_NEWLINE)+#define READ_CHAR_VALID_UTF 0x4++static void read_char(compiler_common *common, sljit_u32 min, sljit_u32 max,+  jump_list **backtracks, sljit_u32 options)+{+/* Reads the precise value of a character into TMP1, if the character is+between min and max (c >= min && c <= max). Otherwise it returns with a value+outside the range. Does not check STR_END. */+DEFINE_COMPILER;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+struct sljit_jump *jump;+#endif+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+struct sljit_jump *jump2;+#endif++SLJIT_UNUSED_ARG(min);+SLJIT_UNUSED_ARG(max);+SLJIT_UNUSED_ARG(backtracks);+SLJIT_UNUSED_ARG(options);+SLJIT_ASSERT(min <= max);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+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)+  {+  if (max < 128 && !(options & READ_CHAR_UPDATE_STR_PTR)) return;++  if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF))+    {+    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);++    if (options & READ_CHAR_UTF8_NEWLINE)+      add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL));+    else+      add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));++    if (backtracks != NULL)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+    JUMPHERE(jump);+    return;+    }++  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);+  if (min >= 0x10000)+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);+    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));+    if (!(options & READ_CHAR_UPDATE_STR_PTR))+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+    JUMPHERE(jump2);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);+    }+  else if (min >= 0x800 && max <= 0xffff)+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);+    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+    if (!(options & READ_CHAR_UPDATE_STR_PTR))+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+    JUMPHERE(jump2);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);+    }+  else if (max >= 0x800)+    {+    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));+    }+  else if (max < 128)+    {+    OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);+    }+  else+    {+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    if (!(options & READ_CHAR_UPDATE_STR_PTR))+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    else+      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);+    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);+    }+  JUMPHERE(jump);+  }+#elif PCRE2_CODE_UNIT_WIDTH == 16+if (common->utf)+  {+  if (max < 0xd800 && !(options & READ_CHAR_UPDATE_STR_PTR)) return;++  if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF))+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);++    if (options & READ_CHAR_UTF8_NEWLINE)+      add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL));+    else+      add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));++    if (backtracks != NULL)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+    JUMPHERE(jump);+    return;+    }++  if (max >= 0x10000)+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800);+    /* TMP2 contains the high surrogate. */+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+    JUMPHERE(jump);+    return;+    }++  /* Skip low surrogate if necessary. */+  OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);++  if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)+    {+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0);+    if (max >= 0xd800)+      CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000);+    }+  else+    {+    jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);+    if (options & READ_CHAR_UPDATE_STR_PTR)+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    if (max >= 0xd800)+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);+    JUMPHERE(jump);+    }+  }+#elif PCRE2_CODE_UNIT_WIDTH == 32+if (common->invalid_utf)+  {+  if (backtracks != NULL)+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));+    }+  else+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);+    CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+    OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);+    CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+    }+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+#endif /* SUPPORT_UNICODE */+}++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8++static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass)+{+/* Tells whether the character codes below 128 are enough+to determine a match. */+const sljit_u8 value = nclass ? 0xff : 0;+const sljit_u8 *end = bitset + 32;++bitset += 16;+do+  {+  if (*bitset++ != value)+    return FALSE;+  }+while (bitset < end);+return TRUE;+}++static void read_char7_type(compiler_common *common, jump_list **backtracks, BOOL negated)+{+/* Reads the precise character type of a character into TMP1, if the character+is less than 128. Otherwise it returns with zero. Does not check STR_END. The+full_read argument tells whether characters above max are accepted or not. */+DEFINE_COMPILER;+struct sljit_jump *jump;++SLJIT_ASSERT(common->utf);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++/* All values > 127 are zero in ctypes. */+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);++if (negated)+  {+  jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80);++  if (common->invalid_utf)+    {+    add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+    }+  else+    {+    OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);+    }+  JUMPHERE(jump);+  }+}++#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */++static void read_char8_type(compiler_common *common, jump_list **backtracks, BOOL negated)+{+/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */+DEFINE_COMPILER;+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+struct sljit_jump *jump;+#endif+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+struct sljit_jump *jump2;+#endif++SLJIT_UNUSED_ARG(backtracks);+SLJIT_UNUSED_ARG(negated);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+if (common->utf)+  {+  /* The result of this read may be unused, but saves an "else" part. */+  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);+  jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80);++  if (!negated)+    {+    if (common->invalid_utf)+      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));++    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);+    if (common->invalid_utf)+      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe0 - 0xc2));++    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);+    if (common->invalid_utf)+      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40));++    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);+    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);+    JUMPHERE(jump2);+    }+  else if (common->invalid_utf)+    {+    add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL));+    OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR));++    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+    jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);+    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);+    JUMPHERE(jump2);+    }+  else+    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));++  JUMPHERE(jump);+  return;+  }+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32+if (common->invalid_utf && negated)+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x110000));+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 */++#if PCRE2_CODE_UNIT_WIDTH != 8+/* The ctypes array contains only 256 values. */+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);+#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);+#if PCRE2_CODE_UNIT_WIDTH != 8+JUMPHERE(jump);+#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16+if (common->utf && negated)+  {+  /* Skip low surrogate if necessary. */+  if (!common->invalid_utf)+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);++    if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)+      {+      OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+      OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);+      CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0);+      }+    else+      {+      jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+      JUMPHERE(jump);+      }+    return;+    }++  OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);+  jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400));+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));++  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400));++  JUMPHERE(jump);+  return;+  }+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */+}++static void move_back(compiler_common *common, jump_list **backtracks, BOOL must_be_valid)+{+/* Goes one character back. Affects STR_PTR and TMP1. If must_be_valid is TRUE,+TMP2 is not used. Otherwise TMP2 must contain the start of the subject buffer,+and it is destroyed. Does not modify STR_PTR for invalid character sequences. */+DEFINE_COMPILER;++SLJIT_UNUSED_ARG(backtracks);+SLJIT_UNUSED_ARG(must_be_valid);++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+struct sljit_jump *jump;+#endif++#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+struct sljit_label *label;++if (common->utf)+  {+  if (!must_be_valid && common->invalid_utf)+    {+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));+    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80);+    add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL));+    if (backtracks != NULL)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));+    JUMPHERE(jump);+    return;+    }++  label = LABEL();+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);+  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);+  return;+  }+#elif PCRE2_CODE_UNIT_WIDTH == 16+if (common->utf)+  {+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++  if (!must_be_valid && common->invalid_utf)+    {+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);+    jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0xd800);+    add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL));+    if (backtracks != NULL)+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));+    JUMPHERE(jump);+    return;+    }++  /* Skip low surrogate if necessary. */+  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);+  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, UCHAR_SHIFT);+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+  return;+  }+#elif PCRE2_CODE_UNIT_WIDTH == 32+if (common->invalid_utf && !must_be_valid)+  {+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));+  if (backtracks != NULL)+    {+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));+    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    return;+    }++  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);+  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);+  OP2(SLJIT_SHL,  TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+  return;+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+#endif /* SUPPORT_UNICODE */+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+}++static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)+{+/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */+DEFINE_COMPILER;+struct sljit_jump *jump;++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)+  {+  if (jumpifmatch)+    {+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));+    }+  else+    {+    jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));+    JUMPHERE(jump);+    }+  }+else+  {+  SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);+  add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));+  }+}++#ifdef SUPPORT_UNICODE++#if PCRE2_CODE_UNIT_WIDTH == 8+static void do_utfreadchar(compiler_common *common)+{+/* Fast decoding a UTF-8 character. TMP1 contains the first byte+of the character (>= 0xc0). Return char value in TMP1. */+DEFINE_COMPILER;+struct sljit_jump *jump;++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++/* Searching for the first zero. */+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+jump = JUMP(SLJIT_NOT_ZERO);+/* Two byte sequence. */+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3000);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);+jump = JUMP(SLJIT_NOT_ZERO);+/* Three byte sequence. */+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0000);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Four byte sequence. */+JUMPHERE(jump);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0000);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfreadtype8(compiler_common *common)+{+/* Fast decoding a UTF-8 character type. TMP2 contains the first byte+of the character (>= 0xc0). Return value in TMP1. */+DEFINE_COMPILER;+struct sljit_jump *jump;+struct sljit_jump *compare;++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++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));+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);+/* The upper 5 bits are known at this point. */+compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);+OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(compare);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* We only have types for characters less than 256. */+JUMPHERE(jump);+OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfreadchar_invalid(compiler_common *common)+{+/* Slow decoding a UTF-8 character. TMP1 contains the first byte+of the character (>= 0xc0). Return char value in TMP1. STR_PTR is+undefined for invalid characters. */+DEFINE_COMPILER;+sljit_s32 i;+sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);+struct sljit_jump *jump;+struct sljit_jump *buffer_end_close;+struct sljit_label *three_byte_entry;+struct sljit_label *exit_invalid_label;+struct sljit_jump *exit_invalid[11];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc2);++/* Usually more than 3 characters remained in the subject buffer. */+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));++/* Not a valid start of a multi-byte sequence, no more bytes read. */+exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xf5 - 0xc2);++buffer_end_close = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);++OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+jump = JUMP(SLJIT_NOT_ZERO);++OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump);++/* Three-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40);+  CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000);+  exit_invalid[2] = NULL;+  }+else+  exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);++OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);+jump = JUMP(SLJIT_NOT_ZERO);++three_byte_entry = LABEL();++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+  CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800);+  exit_invalid[3] = NULL;+  }+else+  exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+  CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+  exit_invalid[4] = NULL;+  }+else+  exit_invalid[4] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump);++/* Four-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40);+  CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0);+  exit_invalid[5] = NULL;+  }+else+  exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x100000);+  CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000);+  exit_invalid[6] = NULL;+  }+else+  exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);++OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(buffer_end_close);+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+exit_invalid[7] = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);++/* Two-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+exit_invalid[8] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);++OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+jump = JUMP(SLJIT_NOT_ZERO);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Three-byte sequence. */+JUMPHERE(jump);+exit_invalid[9] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40);+  CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+  exit_invalid[10] = NULL;+  }+else+  exit_invalid[10] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);++/* One will be substracted from STR_PTR later. */+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));++/* Four byte sequences are not possible. */+CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x30000, three_byte_entry);++exit_invalid_label = LABEL();+for (i = 0; i < 11; i++)+  sljit_set_label(exit_invalid[i], exit_invalid_label);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfreadnewline_invalid(compiler_common *common)+{+/* Slow decoding a UTF-8 character, specialized for newlines.+TMP1 contains the first byte of the character (>= 0xc0). Return+char value in TMP1. */+DEFINE_COMPILER;+struct sljit_label *loop;+struct sljit_label *skip_start;+struct sljit_label *three_byte_exit;+struct sljit_jump *jump[5];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++if (common->nltype != NLTYPE_ANY)+  {+  SLJIT_ASSERT(common->nltype != NLTYPE_FIXED || common->newline < 128);++  /* All newlines are ascii, just skip intermediate octets. */+  jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+  loop = LABEL();+  if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)) == SLJIT_SUCCESS)+    sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+  else+    {+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    }++  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);+  CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++  JUMPHERE(jump[0]);++  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+  OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+  return;+  }++jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++jump[1] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xc2);+jump[2] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xe2);++skip_start = LABEL();+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);+jump[3] = CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80);++/* Skip intermediate octets. */+loop = LABEL();+jump[4] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);+CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);++JUMPHERE(jump[3]);+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++three_byte_exit = LABEL();+JUMPHERE(jump[0]);+JUMPHERE(jump[4]);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Two byte long newline: 0x85. */+JUMPHERE(jump[1]);+CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x85, skip_start);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x85);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Three byte long newlines: 0x2028 and 0x2029. */+JUMPHERE(jump[2]);+CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, skip_start);+CMPTO(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0, three_byte_exit);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++OP2(SLJIT_SUB, TMP1, 0, TMP2, 0, SLJIT_IMM, 0x80);+CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40, skip_start);++OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0x2000);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfmoveback_invalid(compiler_common *common)+{+/* Goes one character back. */+DEFINE_COMPILER;+sljit_s32 i;+struct sljit_jump *jump;+struct sljit_jump *buffer_start_close;+struct sljit_label *exit_ok_label;+struct sljit_label *exit_invalid_label;+struct sljit_jump *exit_invalid[7];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));+exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0);++/* Two-byte sequence. */+buffer_start_close = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);+jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x20);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Three-byte sequence. */+JUMPHERE(jump);+exit_invalid[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);+jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x10);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Four-byte sequence. */+JUMPHERE(jump);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80);+exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0);+exit_invalid[3] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x05);++exit_ok_label = LABEL();+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++/* Two-byte sequence. */+JUMPHERE(buffer_start_close);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));++exit_invalid[4] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);+CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20, exit_ok_label);++/* Three-byte sequence. */+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+exit_invalid[5] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40);+exit_invalid[6] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);+CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10, exit_ok_label);++/* Four-byte sequences are not possible. */++exit_invalid_label = LABEL();+sljit_set_label(exit_invalid[5], exit_invalid_label);+sljit_set_label(exit_invalid[6], exit_invalid_label);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(exit_invalid[4]);+/* -2 + 4 = 2 */+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));++exit_invalid_label = LABEL();+for (i = 0; i < 4; i++)+  sljit_set_label(exit_invalid[i], exit_invalid_label);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(4));+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfpeakcharback(compiler_common *common)+{+/* Peak a character back. Does not modify STR_PTR. */+DEFINE_COMPILER;+struct sljit_jump *jump[2];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);+jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0);+jump[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++JUMPHERE(jump[1]);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++JUMPHERE(jump[0]);+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfpeakcharback_invalid(compiler_common *common)+{+/* Peak a character back. Does not modify STR_PTR. */+DEFINE_COMPILER;+sljit_s32 i;+sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);+struct sljit_jump *jump[2];+struct sljit_label *two_byte_entry;+struct sljit_label *three_byte_entry;+struct sljit_label *exit_invalid_label;+struct sljit_jump *exit_invalid[8];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));+exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0);+jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);++/* Two-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);+jump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x1e);++two_byte_entry = LABEL();+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+/* If TMP1 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump[1]);+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);+exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++/* Three-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);+jump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x10);++three_byte_entry = LABEL();+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+  CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800);+  exit_invalid[2] = NULL;+  }+else+  exit_invalid[2] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);++OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);+if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);+  CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);+  exit_invalid[3] = NULL;+  }+else+  exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump[1]);+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0 - 0x80);+exit_invalid[4] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++/* Four-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);+/* ADD is used instead of OR because of the SUB 0x10000 above. */+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);++if (has_cmov)+  {+  OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x100000);+  CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000);+  exit_invalid[5] = NULL;+  }+else+  exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);++OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump[0]);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));+jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);++/* Two-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);+CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry);++OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);+exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);++/* Three-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);+CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x10, three_byte_entry);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump[0]);+exit_invalid[7] = CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0);++/* Two-byte sequence. */+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2);+CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry);++exit_invalid_label = LABEL();+for (i = 0; i < 8; i++)+  sljit_set_label(exit_invalid[i], exit_invalid_label);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */++#if PCRE2_CODE_UNIT_WIDTH == 16++static void do_utfreadchar_invalid(compiler_common *common)+{+/* Slow decoding a UTF-16 character. TMP1 contains the first half+of the character (>= 0xd800). Return char value in TMP1. STR_PTR is+undefined for invalid characters. */+DEFINE_COMPILER;+struct sljit_jump *exit_invalid[3];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++/* TMP2 contains the high surrogate. */+exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);+exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00);+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);+exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);++OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(exit_invalid[0]);+JUMPHERE(exit_invalid[1]);+JUMPHERE(exit_invalid[2]);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfreadnewline_invalid(compiler_common *common)+{+/* Slow decoding a UTF-16 character, specialized for newlines.+TMP1 contains the first half of the character (>= 0xd800). Return+char value in TMP1. */++DEFINE_COMPILER;+struct sljit_jump *exit_invalid[2];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++/* TMP2 contains the high surrogate. */+exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);++OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);+OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(exit_invalid[0]);+JUMPHERE(exit_invalid[1]);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfmoveback_invalid(compiler_common *common)+{+/* Goes one character back. */+DEFINE_COMPILER;+struct sljit_jump *exit_invalid[3];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400);+exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);++OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);+exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);++OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(exit_invalid[0]);+JUMPHERE(exit_invalid[1]);+JUMPHERE(exit_invalid[2]);++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_utfpeakcharback_invalid(compiler_common *common)+{+/* Peak a character back. Does not modify STR_PTR. */+DEFINE_COMPILER;+struct sljit_jump *jump;+struct sljit_jump *exit_invalid[3];++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000);+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));+exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);+exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0);++OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00);+OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);+exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);++JUMPHERE(jump);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(exit_invalid[0]);+JUMPHERE(exit_invalid[1]);+JUMPHERE(exit_invalid[2]);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */++/* UCD_BLOCK_SIZE must be 128 (see the assert below). */+#define UCD_BLOCK_MASK 127+#define UCD_BLOCK_SHIFT 7++static void do_getucd(compiler_common *common)+{+/* 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(UNASSIGNED_UTF_CHAR);+SLJIT_ASSERT(record->script == ucp_Unknown && 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) == 12);++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, UNASSIGNED_UTF_CHAR);+  JUMPHERE(jump);+  }+#endif++OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);+OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));+OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_getucdtype(compiler_common *common)+{+/* 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(UNASSIGNED_UTF_CHAR);+SLJIT_ASSERT(record->script == ucp_Unknown && 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) == 12);++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, UNASSIGNED_UTF_CHAR);+  JUMPHERE(jump);+  }+#endif++OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);+OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));+OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);++/* TMP2 is multiplied by 12. Same as (TMP2 << 2) + ((TMP2 << 2) << 1). */+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++#endif /* SUPPORT_UNICODE */++static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_label *mainloop;+struct sljit_label *newlinelabel = NULL;+struct sljit_jump *start;+struct sljit_jump *end = NULL;+struct sljit_jump *end2 = NULL;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+struct sljit_label *loop;+struct sljit_jump *jump;+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */+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;++if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0)+    && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))+  newlinecheck = TRUE;++SLJIT_ASSERT(common->abort_label == NULL);++if ((overall_options & PCRE2_FIRSTLINE) != 0)+  {+  /* Search for the end of the first line. */+  SLJIT_ASSERT(common->match_end_ptr != 0);+  OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);++  if (common->nltype == NLTYPE_FIXED && common->newline > 255)+    {+    mainloop = LABEL();+    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), IN_UCHARS(-1));+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);+    CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);+    JUMPHERE(end);+    OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    }+  else+    {+    end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+    mainloop = LABEL();+    /* Continual stores does not cause data dependency. */+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);+    read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);+    check_newlinechar(common, common->nltype, &newline, TRUE);+    CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);+    JUMPHERE(end);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);+    set_jumps(newline, LABEL());+    }++  OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);+  }+else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0)+  {+  /* Check whether offset limit is set and valid. */+  SLJIT_ASSERT(common->match_end_ptr != 0);++  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));+    }+  else+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, offset_limit));++  OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);+  end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET);+  if (HAS_VIRTUAL_REGISTERS)+    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);+  else+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));++#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32+  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);+#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */+  if (HAS_VIRTUAL_REGISTERS)+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));++  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);+  end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);+  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->abort, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));+  JUMPHERE(end);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0);+  }++start = JUMP(SLJIT_JUMP);++if (newlinecheck)+  {+  newlinelabel = LABEL();+  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_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 /* PCRE2_CODE_UNIT_WIDTH == [16|32] */+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+  end2 = JUMP(SLJIT_JUMP);+  }++mainloop = LABEL();++/* Increasing the STR_PTR here requires one less jump in the most common case. */+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+if (common->utf && !common->invalid_utf) readuchar = TRUE;+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */+if (newlinecheck) readuchar = TRUE;++if (readuchar)+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);++if (newlinecheck)+  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+#if PCRE2_CODE_UNIT_WIDTH == 8+if (common->invalid_utf)+  {+  /* Skip continuation code units. */+  loop = LABEL();+  jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80);+  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x40, loop);+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  JUMPHERE(jump);+  }+else if (common->utf)+  {+  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);+  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);+  JUMPHERE(jump);+  }+#elif PCRE2_CODE_UNIT_WIDTH == 16+if (common->invalid_utf)+  {+  /* Skip continuation code units. */+  loop = LABEL();+  jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00);+  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400, loop);+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  JUMPHERE(jump);+  }+else if (common->utf)+  {+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);++  if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))+    {+    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);+    CMOV(SLJIT_LESS, STR_PTR, TMP2, 0);+    }+  else+    {+    OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);+    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+    }+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */+JUMPHERE(start);++if (newlinecheck)+  {+  JUMPHERE(end);+  JUMPHERE(end2);+  }++return mainloop;+}+++static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, fast_forward_char_data *chars, BOOL last)+{+sljit_u32 i, count = chars->count;++if (count == 255)+  return;++if (count == 0)+  {+  chars->count = 1;+  chars->chars[0] = chr;++  if (last)+    chars->last_count = 1;+  return;+  }++for (i = 0; i < count; i++)+  if (chars->chars[i] == chr)+    return;++if (count >= MAX_DIFF_CHARS)+  {+  chars->count = 255;+  return;+  }++chars->chars[count] = chr;+chars->count = count + 1;++if (last)+  chars->last_count++;+}++static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars, int max_chars, sljit_u32 *rec_count)+{+/* Recursive function, which scans prefix literals. */+BOOL last, any, class, caseless;+int len, repeat, len_save, consumed = 0;+sljit_u32 chr; /* Any unicode character. */+sljit_u8 *bytes, *bytes_end, byte;+PCRE2_SPTR alternative, cc_save, oc;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+PCRE2_UCHAR othercase[4];+#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16+PCRE2_UCHAR othercase[2];+#else+PCRE2_UCHAR othercase[1];+#endif++repeat = 1;+while (TRUE)+  {+  if (*rec_count == 0)+    return 0;+  (*rec_count)--;++  last = TRUE;+  any = FALSE;+  class = FALSE;+  caseless = FALSE;++  switch (*cc)+    {+    case OP_CHARI:+    caseless = TRUE;+    /* Fall through */+    case OP_CHAR:+    last = FALSE;+    cc++;+    break;++    case OP_SOD:+    case OP_SOM:+    case OP_SET_SOM:+    case OP_NOT_WORD_BOUNDARY:+    case OP_WORD_BOUNDARY:+    case OP_EODN:+    case OP_EOD:+    case OP_CIRC:+    case OP_CIRCM:+    case OP_DOLL:+    case OP_DOLLM:+    /* Zero width assertions. */+    cc++;+    continue;++    case OP_ASSERT:+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    cc = bracketend(cc);+    continue;++    case OP_PLUSI:+    case OP_MINPLUSI:+    case OP_POSPLUSI:+    caseless = TRUE;+    /* Fall through */+    case OP_PLUS:+    case OP_MINPLUS:+    case OP_POSPLUS:+    cc++;+    break;++    case OP_EXACTI:+    caseless = TRUE;+    /* Fall through */+    case OP_EXACT:+    repeat = GET2(cc, 1);+    last = FALSE;+    cc += 1 + IMM2_SIZE;+    break;++    case OP_QUERYI:+    case OP_MINQUERYI:+    case OP_POSQUERYI:+    caseless = TRUE;+    /* Fall through */+    case OP_QUERY:+    case OP_MINQUERY:+    case OP_POSQUERY:+    len = 1;+    cc++;+#ifdef SUPPORT_UNICODE+    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);+#endif+    max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count);+    if (max_chars == 0)+      return consumed;+    last = FALSE;+    break;++    case OP_KET:+    cc += 1 + LINK_SIZE;+    continue;++    case OP_ALT:+    cc += GET(cc, 1);+    continue;++    case OP_ONCE:+    case OP_BRA:+    case OP_BRAPOS:+    case OP_CBRA:+    case OP_CBRAPOS:+    alternative = cc + GET(cc, 1);+    while (*alternative == OP_ALT)+      {+      max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count);+      if (max_chars == 0)+        return consumed;+      alternative += GET(alternative, 1);+      }++    if (*cc == OP_CBRA || *cc == OP_CBRAPOS)+      cc += IMM2_SIZE;+    cc += 1 + LINK_SIZE;+    continue;++    case OP_CLASS:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+    if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE))+      return consumed;+#endif+    class = TRUE;+    break;++    case OP_NCLASS:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf) return consumed;+#endif+    class = TRUE;+    break;++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+    case OP_XCLASS:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf) return consumed;+#endif+    any = TRUE;+    cc += GET(cc, 1);+    break;+#endif++    case OP_DIGIT:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+    if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))+      return consumed;+#endif+    any = TRUE;+    cc++;+    break;++    case OP_WHITESPACE:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+    if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))+      return consumed;+#endif+    any = TRUE;+    cc++;+    break;++    case OP_WORDCHAR:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+    if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))+      return consumed;+#endif+    any = TRUE;+    cc++;+    break;++    case OP_NOT:+    case OP_NOTI:+    cc++;+    /* Fall through. */+    case OP_NOT_DIGIT:+    case OP_NOT_WHITESPACE:+    case OP_NOT_WORDCHAR:+    case OP_ANY:+    case OP_ALLANY:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf) return consumed;+#endif+    any = TRUE;+    cc++;+    break;++#ifdef SUPPORT_UNICODE+    case OP_NOTPROP:+    case OP_PROP:+#if PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf) return consumed;+#endif+    any = TRUE;+    cc += 1 + 2;+    break;+#endif++    case OP_TYPEEXACT:+    repeat = GET2(cc, 1);+    cc += 1 + IMM2_SIZE;+    continue;++    case OP_NOTEXACT:+    case OP_NOTEXACTI:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf) return consumed;+#endif+    any = TRUE;+    repeat = GET2(cc, 1);+    cc += 1 + IMM2_SIZE + 1;+    break;++    default:+    return consumed;+    }++  if (any)+    {+    do+      {+      chars->count = 255;++      consumed++;+      if (--max_chars == 0)+        return consumed;+      chars++;+      }+    while (--repeat > 0);++    repeat = 1;+    continue;+    }++  if (class)+    {+    bytes = (sljit_u8*) (cc + 1);+    cc += 1 + 32 / sizeof(PCRE2_UCHAR);++    switch (*cc)+      {+      case OP_CRSTAR:+      case OP_CRMINSTAR:+      case OP_CRPOSSTAR:+      case OP_CRQUERY:+      case OP_CRMINQUERY:+      case OP_CRPOSQUERY:+      max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count);+      if (max_chars == 0)+        return consumed;+      break;++      default:+      case OP_CRPLUS:+      case OP_CRMINPLUS:+      case OP_CRPOSPLUS:+      break;++      case OP_CRRANGE:+      case OP_CRMINRANGE:+      case OP_CRPOSRANGE:+      repeat = GET2(cc, 1);+      if (repeat <= 0)+        return consumed;+      break;+      }++    do+      {+      if (bytes[31] & 0x80)+        chars->count = 255;+      else if (chars->count != 255)+        {+        bytes_end = bytes + 32;+        chr = 0;+        do+          {+          byte = *bytes++;+          SLJIT_ASSERT((chr & 0x7) == 0);+          if (byte == 0)+            chr += 8;+          else+            {+            do+              {+              if ((byte & 0x1) != 0)+                add_prefix_char(chr, chars, TRUE);+              byte >>= 1;+              chr++;+              }+            while (byte != 0);+            chr = (chr + 7) & ~7;+            }+          }+        while (chars->count != 255 && bytes < bytes_end);+        bytes = bytes_end - 32;+        }++      consumed++;+      if (--max_chars == 0)+        return consumed;+      chars++;+      }+    while (--repeat > 0);++    switch (*cc)+      {+      case OP_CRSTAR:+      case OP_CRMINSTAR:+      case OP_CRPOSSTAR:+      return consumed;++      case OP_CRQUERY:+      case OP_CRMINQUERY:+      case OP_CRPOSQUERY:+      cc++;+      break;++      case OP_CRRANGE:+      case OP_CRMINRANGE:+      case OP_CRPOSRANGE:+      if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE))+        return consumed;+      cc += 1 + 2 * IMM2_SIZE;+      break;+      }++    repeat = 1;+    continue;+    }++  len = 1;+#ifdef SUPPORT_UNICODE+  if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);+#endif++  if (caseless && char_has_othercase(common, cc))+    {+#ifdef SUPPORT_UNICODE+    if (common->utf)+      {+      GETCHAR(chr, cc);+      if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)+        return consumed;+      }+    else+#endif+      {+      chr = *cc;+#ifdef SUPPORT_UNICODE+      if (common->ucp && chr > 127)+        othercase[0] = UCD_OTHERCASE(chr);+      else+#endif+        othercase[0] = TABLE_GET(chr, common->fcc, chr);+      }+    }+  else+    {+    caseless = FALSE;+    othercase[0] = 0; /* Stops compiler warning - PH */+    }++  len_save = len;+  cc_save = cc;+  while (TRUE)+    {+    oc = othercase;+    do+      {+      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++;+      cc++;+      oc++;+      }+    while (len > 0);++    if (--repeat == 0)+      break;++    len = len_save;+    cc = cc_save;+    }++  repeat = 1;+  if (last)+    return consumed;+  }+}++#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++#include "pcre2_jit_simd_inc.h"++#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD++static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forward_char_data *chars, int max)+{+  sljit_s32 i, j, max_i = 0, max_j = 0;+  sljit_u32 max_pri = 0;+  PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri;++  for (i = max - 1; i >= 1; i--)+    {+    if (chars[i].last_count > 2)+      {+      a1 = chars[i].chars[0];+      a2 = chars[i].chars[1];+      a_pri = chars[i].last_count;++      j = i - max_fast_forward_char_pair_offset();+      if (j < 0)+        j = 0;++      while (j < i)+        {+        b_pri = chars[j].last_count;+        if (b_pri > 2 && a_pri + b_pri >= max_pri)+          {+          b1 = chars[j].chars[0];+          b2 = chars[j].chars[1];++          if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)+            {+            max_pri = a_pri + b_pri;+            max_i = i;+            max_j = j;+            }+          }+        j++;+        }+      }+    }++if (max_pri == 0)+  return FALSE;++fast_forward_char_pair_simd(common, max_i, chars[max_i].chars[0], chars[max_i].chars[1], max_j, chars[max_j].chars[0], chars[max_j].chars[1]);+return TRUE;+}++#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */++static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)+{+DEFINE_COMPILER;+struct sljit_label *start;+struct sljit_jump *match;+struct sljit_jump *partial_quit;+PCRE2_UCHAR mask;+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));++if (has_match_end)+  {+  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);++  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);+  }++#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD++if (JIT_HAS_FAST_FORWARD_CHAR_SIMD)+  {+  fast_forward_char_simd(common, char1, char2, offset);++  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);+  return;+  }++#endif++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)+  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);+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start);+    }+  else+    {+    match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start);+    JUMPHERE(match);+    }+  }++#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 + 1)));+  jumpto_if_not_utf_char_start(compiler, TMP1, start);+  }+#endif++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)+  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);+}++static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_label *start;+struct sljit_jump *match;+fast_forward_char_data chars[MAX_N_CHARS];+sljit_s32 offset;+PCRE2_UCHAR mask;+PCRE2_UCHAR *char_set, *char_set_end;+int i, max, from;+int range_right = -1, range_len;+sljit_u8 *update_table = NULL;+BOOL in_range;+sljit_u32 rec_count;++for (i = 0; i < MAX_N_CHARS; i++)+  {+  chars[i].count = 0;+  chars[i].last_count = 0;+  }++rec_count = 10000;+max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);++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;+  }++#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD+if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && check_fast_forward_char_pair_simd(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].count < 255))+    {+    range_len = i - from;+    range_right = i - 1;+    }++  if (i < max && chars[i].count < 255)+    {+    SLJIT_ASSERT(chars[i].count > 0);+    if (!in_range)+      {+      in_range = TRUE;+      from = i;+      }+    }+  else+    in_range = FALSE;+  }++if (range_right >= 0)+  {+  update_table = (sljit_u8 *)allocate_read_only_data(common, 256);+  if (update_table == NULL)+    return TRUE;+  memset(update_table, IN_UCHARS(range_len), 256);++  for (i = 0; i < range_len; i++)+    {+    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);+    }+  }++offset = -1;+/* Scan forward. */+for (i = 0; i < max; i++)+  {+  if (range_right == i)+    continue;++  if (offset == -1)+    {+    if (chars[i].last_count >= 2)+      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;+  /* Works regardless the value is 1 or 2. */+  fast_forward_first_char2(common, chars[offset].chars[0], chars[offset].chars[1], offset);+  return TRUE;+  }++SLJIT_ASSERT(range_right != offset);++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 | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));+  add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));+  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 | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));+  add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));+  }++SLJIT_ASSERT(range_right >= 0);++if (!HAS_VIRTUAL_REGISTERS)+  OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);++start = LABEL();+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));+#else+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);+#endif++if (!HAS_VIRTUAL_REGISTERS)+  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);+else+  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);++if (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 (chars[offset].count == 1)+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0], start);+  else+    {+    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].chars[0] | mask, start);+      }+    else+      {+      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);+      }+    }+  }++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+if (common->utf && offset != 0)+  {+  if (offset < 0)+    {+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    }+  else+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));++  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));+  }+#endif++if (offset >= 0)+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++if (common->match_end_ptr != 0)+  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);+else+  OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));+return TRUE;+}++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 ((common->re->flags & PCRE2_FIRSTCASELESS) != 0)+  {+  oc = TABLE_GET(first_char, common->fcc, first_char);+#if defined SUPPORT_UNICODE+  if (first_char > 127 && (common->utf || common->ucp))+    oc = UCD_OTHERCASE(first_char);+#endif+  }++fast_forward_first_char2(common, first_char, oc, 0);+}++static SLJIT_INLINE void fast_forward_newline(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_label *loop;+struct sljit_jump *lastchar = NULL;+struct sljit_jump *firstchar;+struct sljit_jump *quit = NULL;+struct sljit_jump *foundcr = NULL;+struct sljit_jump *notfoundnl;+jump_list *newline = NULL;++if (common->match_end_ptr != 0)+  {+  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);+  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);+  }++if (common->nltype == NLTYPE_FIXED && common->newline > 255)+  {+#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD+  if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && common->mode == PCRE2_JIT_COMPLETE)+    {+    if (HAS_VIRTUAL_REGISTERS)+      {+      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));+      }+    else+      {+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));+      }+    firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);++    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);+    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL);+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32+    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);+#endif+    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);++    fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+    }+  else+#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */+    {+    lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+    if (HAS_VIRTUAL_REGISTERS)+      {+      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));+      }+    else+      {+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));+      }+    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_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+    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);++    loop = LABEL();+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);+    CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);++    JUMPHERE(quit);+    JUMPHERE(lastchar);+    }++  JUMPHERE(firstchar);++  if (common->match_end_ptr != 0)+    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);+  return;+  }++if (HAS_VIRTUAL_REGISTERS)+  {+  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));+  }+else+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));++/* Example: match /^/ to \r\n from offset 1. */+firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);++if (common->nltype == NLTYPE_ANY)+  move_back(common, NULL, FALSE);+else+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++loop = LABEL();+common->ff_newline_shortcut = loop;++#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD+if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common->nltype == NLTYPE_ANYCRLF))+  {+  if (common->nltype == NLTYPE_ANYCRLF)+    {+    fast_forward_char_simd(common, CHAR_CR, CHAR_LF, 0);+    if (common->mode != PCRE2_JIT_COMPLETE)+      lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);++    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);+    }+   else+    {+    fast_forward_char_simd(common, common->newline, common->newline, 0);++    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    if (common->mode != PCRE2_JIT_COMPLETE)+      {+      OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);+      CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);+      }+    }+  }+else+#endif /* JIT_HAS_FAST_FORWARD_CHAR_SIMD */+  {+  read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);+  lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)+    foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);+  check_newlinechar(common, common->nltype, &newline, FALSE);+  set_jumps(newline, loop);+  }++if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)+  {+  if (quit == NULL)+    {+    quit = JUMP(SLJIT_JUMP);+    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_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+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+  JUMPHERE(notfoundnl);+  JUMPHERE(quit);+  }++if (lastchar)+  JUMPHERE(lastchar);+JUMPHERE(firstchar);++if (common->match_end_ptr != 0)+  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);+}++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)+{+DEFINE_COMPILER;+const sljit_u8 *start_bits = common->re->start_bitmap;+struct sljit_label *start;+struct sljit_jump *partial_quit;+#if PCRE2_CODE_UNIT_WIDTH != 8+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);+  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();++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+  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);+  if (!HAS_VIRTUAL_REGISTERS)+    {+    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);++#if PCRE2_CODE_UNIT_WIDTH != 8+if (found != NULL)+  JUMPHERE(found);+#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);+}++static SLJIT_INLINE jump_list *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)+{+DEFINE_COMPILER;+struct sljit_label *loop;+struct sljit_jump *toolong;+struct sljit_jump *already_found;+struct sljit_jump *found;+struct sljit_jump *found_oc = NULL;+jump_list *not_found = NULL;+sljit_u32 oc, bit;++SLJIT_ASSERT(common->req_char_ptr != 0);+OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(REQ_CU_MAX) * 100);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);+toolong = CMP(SLJIT_LESS, TMP2, 0, STR_END, 0);+already_found = CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0);++if (has_firstchar)+  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+else+  OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);++oc = req_char;+if (caseless)+  {+  oc = TABLE_GET(req_char, common->fcc, req_char);+#if defined SUPPORT_UNICODE+  if (req_char > 127 && (common->utf || common->ucp))+    oc = UCD_OTHERCASE(req_char);+#endif+  }++#ifdef JIT_HAS_FAST_REQUESTED_CHAR_SIMD+if (JIT_HAS_FAST_REQUESTED_CHAR_SIMD)+  {+  not_found = fast_requested_char_simd(common, req_char, oc);+  }+else+#endif+  {+  loop = LABEL();+  add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));++  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);++  if (req_char == oc)+    found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);+  else+    {+    bit = req_char ^ oc;+    if (is_powerof2(bit))+      {+       OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);+      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);+      }+    else+      {+      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);+      found_oc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);+      }+    }+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));+  JUMPTO(SLJIT_JUMP, loop);++  JUMPHERE(found);+  if (found_oc)+    JUMPHERE(found_oc);+  }++OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);++JUMPHERE(already_found);+JUMPHERE(toolong);+return not_found;+}++static void do_revertframes(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_jump *jump;+struct sljit_label *mainloop;++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);+GET_LOCAL_BASE(TMP1, 0, 0);++/* Drop frames until we reach STACK_TOP. */+mainloop = LABEL();+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, TMP1, 0);+if (HAS_VIRTUAL_REGISTERS)+  {+  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 = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0);+/* End of reverting values. */+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);++JUMPHERE(jump);+OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);+if (HAS_VIRTUAL_REGISTERS)+  {+  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);+}++static void check_wordboundary(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_jump *skipread;+jump_list *skipread_list = NULL;+#ifdef SUPPORT_UNICODE+struct sljit_label *valid_utf;+jump_list *invalid_utf1 = NULL;+#endif /* SUPPORT_UNICODE */+jump_list *invalid_utf2 = NULL;+#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE+struct sljit_jump *jump;+#endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */++SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);++sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);+/* Get type of the previous char, and put it to TMP3. */+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);+skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);++#ifdef SUPPORT_UNICODE+if (common->invalid_utf)+  {+  peek_char_back(common, READ_CHAR_MAX, &invalid_utf1);++  if (common->mode != PCRE2_JIT_COMPLETE)+    {+    OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);+    move_back(common, NULL, TRUE);+    check_start_used_ptr(common);+    OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);+    }+  }+else+#endif /* SUPPORT_UNICODE */+  {+  if (common->mode == PCRE2_JIT_COMPLETE)+    peek_char_back(common, READ_CHAR_MAX, NULL);+  else+    {+    move_back(common, NULL, TRUE);+    check_start_used_ptr(common);+    read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR);+    }+  }++/* Testing char type. */+#ifdef SUPPORT_UNICODE+if (common->ucp)+  {+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);+  jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);+  add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);+  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_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, TMP3, 0, TMP2, 0);+  }+else+#endif /* SUPPORT_UNICODE */+  {+#if PCRE2_CODE_UNIT_WIDTH != 8+  jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);+#elif defined SUPPORT_UNICODE+  /* Here TMP3 has already been zeroed. */+  jump = NULL;+  if (common->utf)+    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);+  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);+  OP2(SLJIT_AND, TMP3, 0, TMP1, 0, SLJIT_IMM, 1);+#if PCRE2_CODE_UNIT_WIDTH != 8+  JUMPHERE(jump);+#elif defined SUPPORT_UNICODE+  if (jump != NULL)+    JUMPHERE(jump);+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+  }+JUMPHERE(skipread);++OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);+check_str_end(common, &skipread_list);+peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2);++/* Testing char type. This is a code duplication. */+#ifdef SUPPORT_UNICODE++valid_utf = LABEL();++if (common->ucp)+  {+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);+  jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);+  add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);+  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_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+#endif /* SUPPORT_UNICODE */+  {+#if PCRE2_CODE_UNIT_WIDTH != 8+  /* TMP2 may be destroyed by peek_char. */+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);+  jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);+#elif defined SUPPORT_UNICODE+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);+  jump = NULL;+  if (common->utf)+    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);+#endif+  OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);+  OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);+  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);+#if PCRE2_CODE_UNIT_WIDTH != 8+  JUMPHERE(jump);+#elif defined SUPPORT_UNICODE+  if (jump != NULL)+    JUMPHERE(jump);+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+  }+set_jumps(skipread_list, LABEL());++OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);+OP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0);+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);++#ifdef SUPPORT_UNICODE+if (common->invalid_utf)+  {+  set_jumps(invalid_utf1, LABEL());++  peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, NULL);+  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf);++  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1);+  OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);++  set_jumps(invalid_utf2, LABEL());+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);+  OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);+  OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);+  }+#endif /* SUPPORT_UNICODE */+}++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_CLASS_RANGE_SIZE];+sljit_u8 bit, cbit, all;+int i, byte, length = 0;++bit = bits[0] & 0x1;+/* All bits will be zero or one (since bit is zero or one). */+all = -bit;++for (i = 0; i < 256; )+  {+  byte = i >> 3;+  if ((i & 0x7) == 0 && bits[byte] == all)+    i += 8;+  else+    {+    cbit = (bits[byte] >> (i & 0x7)) & 0x1;+    if (cbit != bit)+      {+      if (length >= MAX_CLASS_RANGE_SIZE)+        return FALSE;+      ranges[length] = i;+      length++;+      bit = cbit;+      all = -cbit;+      }+    i++;+    }+  }++if (((bit == 0) && nclass) || ((bit == 1) && !nclass))+  {+  if (length >= MAX_CLASS_RANGE_SIZE)+    return FALSE;+  ranges[length] = 256;+  length++;+  }++if (length < 0 || length > 4)+  return FALSE;++bit = bits[0] & 0x1;+if (invert) bit ^= 0x1;++/* No character is accepted. */+if (length == 0 && bit == 0)+  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));++switch(length)+  {+  case 0:+  /* When bit != 0, all characters are accepted. */+  return TRUE;++  case 1:+  add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));+  return TRUE;++  case 2:+  if (ranges[0] + 1 != ranges[1])+    {+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);+    add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));+    }+  else+    add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));+  return TRUE;++  case 3:+  if (bit != 0)+    {+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));+    if (ranges[0] + 1 != ranges[1])+      {+      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);+      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));+      }+    else+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));+    return TRUE;+    }++  add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));+  if (ranges[1] + 1 != ranges[2])+    {+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));+    }+  else+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));+  return TRUE;++  case 4:+  if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])+      && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]+      && (ranges[1] & (ranges[2] - ranges[0])) == 0+      && is_powerof2(ranges[2] - ranges[0]))+    {+    SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);+    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);+    if (ranges[2] + 1 != ranges[3])+      {+      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);+      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));+      }+    else+      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));+    return TRUE;+    }++  if (bit != 0)+    {+    i = 0;+    if (ranges[0] + 1 != ranges[1])+      {+      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);+      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));+      i = ranges[0];+      }+    else+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));++    if (ranges[2] + 1 != ranges[3])+      {+      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);+      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));+      }+    else+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));+    return TRUE;+    }++  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));+  if (ranges[1] + 1 != ranges[2])+    {+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));+    }+  else+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));+  return TRUE;++  default:+  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;++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++;+    }+  }++if (len == 0) return FALSE;  /* Should never occur, but stops analyzers complaining. */++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);+      }+  }++if (invert)+  nclass = !nclass;++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. */+DEFINE_COMPILER;++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 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, SLJIT_EQUAL);+  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);+  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_Z, TMP2, 0, SLJIT_EQUAL);+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void check_hspace(compiler_common *common)+{+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */+DEFINE_COMPILER;++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++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, 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_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_Z, TMP2, 0, SLJIT_EQUAL);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void check_vspace(compiler_common *common)+{+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */+DEFINE_COMPILER;++sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);++OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 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, SLJIT_EQUAL);+  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);+  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_Z, TMP2, 0, SLJIT_EQUAL);++OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);+}++static void do_casefulcmp(compiler_common *common)+{+DEFINE_COMPILER;+struct sljit_jump *jump;+struct sljit_label *label;+int char1_reg;+int char2_reg;++if (HAS_VIRTUAL_REGISTERS)+  {+  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);++if (char1_reg == STR_END)+  {+  OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);+  OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 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);+  }++OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);+}++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;++if (HAS_VIRTUAL_REGISTERS)+  {+  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, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);++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_reg, 0, SLJIT_IMM, 255);+#endif+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_reg, 0, SLJIT_IMM, 255);+#endif+OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);+#if PCRE2_CODE_UNIT_WIDTH != 8+JUMPHERE(jump);+#endif++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);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);++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);+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);+}++static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc,+    compare_context *context, jump_list **backtracks)+{+DEFINE_COMPILER;+unsigned int othercasebit = 0;+PCRE2_SPTR othercasechar = NULL;+#ifdef SUPPORT_UNICODE+int utflength;+#endif++if (caseless && char_has_othercase(common, cc))+  {+  othercasebit = char_get_othercase_bit(common, cc);+  SLJIT_ASSERT(othercasebit);+  /* Extracting bit difference info. */+#if PCRE2_CODE_UNIT_WIDTH == 8+  othercasechar = cc + (othercasebit >> 8);+  othercasebit &= 0xff;+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32+  /* Note that this code only handles characters in the BMP. If there+  ever are characters outside the BMP whose othercase differs in only one+  bit from itself (there currently are none), this code will need to be+  revised for PCRE2_CODE_UNIT_WIDTH == 32. */+  othercasechar = cc + (othercasebit >> 9);+  if ((othercasebit & 0x100) != 0)+    othercasebit = (othercasebit & 0xff) << 8;+  else+    othercasebit &= 0xff;+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+  }++if (context->sourcereg == -1)+  {+#if PCRE2_CODE_UNIT_WIDTH == 8+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED+  if (context->length >= 4)+    OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);+  else if (context->length >= 2)+    OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);+  else+#endif+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);+#elif PCRE2_CODE_UNIT_WIDTH == 16+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED+  if (context->length >= 4)+    OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);+  else+#endif+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);+#elif PCRE2_CODE_UNIT_WIDTH == 32+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */+  context->sourcereg = TMP2;+  }++#ifdef SUPPORT_UNICODE+utflength = 1;+if (common->utf && HAS_EXTRALEN(*cc))+  utflength += GET_EXTRALEN(*cc);++do+  {+#endif++  context->length -= IN_UCHARS(1);+#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)++  /* Unaligned read is supported. */+  if (othercasebit != 0 && othercasechar == cc)+    {+    context->c.asuchars[context->ucharptr] = *cc | othercasebit;+    context->oc.asuchars[context->ucharptr] = othercasebit;+    }+  else+    {+    context->c.asuchars[context->ucharptr] = *cc;+    context->oc.asuchars[context->ucharptr] = 0;+    }+  context->ucharptr++;++#if PCRE2_CODE_UNIT_WIDTH == 8+  if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))+#else+  if (context->ucharptr >= 2 || context->length == 0)+#endif+    {+    if (context->length >= 4)+      OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);+    else if (context->length >= 2)+      OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);+#if PCRE2_CODE_UNIT_WIDTH == 8+    else if (context->length >= 1)+      OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;++    switch(context->ucharptr)+      {+      case 4 / sizeof(PCRE2_UCHAR):+      if (context->oc.asint != 0)+        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));+      break;++      case 2 / sizeof(PCRE2_UCHAR):+      if (context->oc.asushort != 0)+        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));+      break;++#if PCRE2_CODE_UNIT_WIDTH == 8+      case 1:+      if (context->oc.asbyte != 0)+        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));+      break;+#endif++      default:+      SLJIT_UNREACHABLE();+      break;+      }+    context->ucharptr = 0;+    }++#else++  /* Unaligned read is unsupported or in 32 bit mode. */+  if (context->length >= 1)+    OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);++  context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;++  if (othercasebit != 0 && othercasechar == cc)+    {+    OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));+    }+  else+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));++#endif++  cc++;+#ifdef SUPPORT_UNICODE+  utflength--;+  }+while (utflength > 0);+#endif++return cc;+}++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8++#define SET_TYPE_OFFSET(value) \+  if ((value) != typeoffset) \+    { \+    if ((value) < typeoffset) \+      OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \+    else \+      OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \+    } \+  typeoffset = (value);++#define SET_CHAR_OFFSET(value) \+  if ((value) != charoffset) \+    { \+    if ((value) < charoffset) \+      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \+    else \+      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \+    } \+  charoffset = (value);++static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr);++static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)+{+DEFINE_COMPILER;+jump_list *found = NULL;+jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;+sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;+struct sljit_jump *jump = NULL;+PCRE2_SPTR ccbegin;+int compares, invertcmp, numberofcmps;+#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)+BOOL utf = common->utf;+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */++#ifdef SUPPORT_UNICODE+BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;+BOOL charsaved = FALSE;+int typereg = TMP1;+const sljit_u32 *other_cases;+sljit_uw typeoffset;+#endif /* SUPPORT_UNICODE */++/* Scanning the necessary info. */+cc++;+ccbegin = cc;+compares = 0;++if (cc[-1] & XCL_MAP)+  {+  min = 0;+  cc += 32 / sizeof(PCRE2_UCHAR);+  }++while (*cc != XCL_END)+  {+  compares++;+  if (*cc == XCL_SINGLE)+    {+    cc ++;+    GETCHARINCTEST(c, cc);+    if (c > max) max = c;+    if (c < min) min = c;+#ifdef SUPPORT_UNICODE+    needschar = TRUE;+#endif /* SUPPORT_UNICODE */+    }+  else if (*cc == XCL_RANGE)+    {+    cc ++;+    GETCHARINCTEST(c, cc);+    if (c < min) min = c;+    GETCHARINCTEST(c, cc);+    if (c > max) max = c;+#ifdef SUPPORT_UNICODE+    needschar = TRUE;+#endif /* SUPPORT_UNICODE */+    }+#ifdef SUPPORT_UNICODE+  else+    {+    SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);+    cc++;+    if (*cc == PT_CLIST)+      {+      other_cases = PRIV(ucd_caseless_sets) + cc[1];+      while (*other_cases != NOTACHAR)+        {+        if (*other_cases > max) max = *other_cases;+        if (*other_cases < min) min = *other_cases;+        other_cases++;+        }+      }+    else+      {+      max = READ_CHAR_MAX;+      min = 0;+      }++    switch(*cc)+      {+      case PT_ANY:+      /* Any either accepts everything or ignored. */+      if (cc[-1] == XCL_PROP)+        {+        compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE);+        if (list == backtracks)+          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));+        return;+        }+      break;++      case PT_LAMP:+      case PT_GC:+      case PT_PC:+      case PT_ALNUM:+      needstype = TRUE;+      break;++      case PT_SC:+      needsscript = TRUE;+      break;++      case PT_SPACE:+      case PT_PXSPACE:+      case PT_WORD:+      case PT_PXGRAPH:+      case PT_PXPRINT:+      case PT_PXPUNCT:+      needstype = TRUE;+      needschar = TRUE;+      break;++      case PT_CLIST:+      case PT_UCNC:+      needschar = TRUE;+      break;++      default:+      SLJIT_UNREACHABLE();+      break;+      }+    cc += 2;+    }+#endif /* SUPPORT_UNICODE */+  }+SLJIT_ASSERT(compares > 0);++/* We are not necessary in utf mode even in 8 bit mode. */+cc = ccbegin;+if ((cc[-1] & XCL_NOT) != 0)+  read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR);+else+  {+#ifdef SUPPORT_UNICODE+  read_char(common, min, max, (needstype || needsscript) ? backtracks : NULL, 0);+#else /* !SUPPORT_UNICODE */+  read_char(common, min, max, NULL, 0);+#endif /* SUPPORT_UNICODE */+  }++if ((cc[-1] & XCL_HASPROP) == 0)+  {+  if ((cc[-1] & XCL_MAP) != 0)+    {+    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);+    if (!optimize_class(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found))+      {+      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);+      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);+      OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);+      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);+      OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);+      add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));+      }++    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));+    JUMPHERE(jump);++    cc += 32 / sizeof(PCRE2_UCHAR);+    }+  else+    {+    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);+    add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));+    }+  }+else if ((cc[-1] & XCL_MAP) != 0)+  {+  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);+#ifdef SUPPORT_UNICODE+  charsaved = TRUE;+#endif /* SUPPORT_UNICODE */+  if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list))+    {+#if PCRE2_CODE_UNIT_WIDTH == 8+    jump = NULL;+    if (common->utf)+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+      jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);++    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);+    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);+    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);+    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);+    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+    if (common->utf)+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+      JUMPHERE(jump);+    }++  OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);+  cc += 32 / sizeof(PCRE2_UCHAR);+  }++#ifdef SUPPORT_UNICODE+if (needstype || needsscript)+  {+  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, UNASSIGNED_UTF_CHAR);+    JUMPHERE(jump);+    }+#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */++  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);+  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);+  OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));+  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);+  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));+  OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);++  /* Before anything else, we deal with scripts. */+  if (needsscript)+    {+    OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);+    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);++    OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));++    ccbegin = cc;++    while (*cc != XCL_END)+      {+      if (*cc == XCL_SINGLE)+        {+        cc ++;+        GETCHARINCTEST(c, cc);+        }+      else if (*cc == XCL_RANGE)+        {+        cc ++;+        GETCHARINCTEST(c, cc);+        GETCHARINCTEST(c, cc);+        }+      else+        {+        SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);+        cc++;+        if (*cc == PT_SC)+          {+          compares--;+          invertcmp = (compares == 0 && list != backtracks);+          if (cc[-1] == XCL_NOTPROP)+            invertcmp ^= 0x1;+          jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]);+          add_jump(compiler, compares > 0 ? list : backtracks, jump);+          }+        cc += 2;+        }+      }++    cc = ccbegin;++    if (needstype)+      {+      /* TMP2 has already been shifted by 2 */+      if (!needschar)+        {+        OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0);+        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);++        OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));+        }+      else+        {+        OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0);+        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);++        OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);+        OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));+        typereg = RETURN_ADDR;+        }+      }+    else if (needschar)+      OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);+    }+  else if (needstype)+    {+    OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);+    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);++    if (!needschar)+      {+      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);++      OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));+      }+    else+      {+      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);++      OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);+      OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));+      typereg = RETURN_ADDR;+      }+    }+  else if (needschar)+    OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);+  }+#endif /* SUPPORT_UNICODE */++/* Generating code. */+charoffset = 0;+numberofcmps = 0;+#ifdef SUPPORT_UNICODE+typeoffset = 0;+#endif /* SUPPORT_UNICODE */++while (*cc != XCL_END)+  {+  compares--;+  invertcmp = (compares == 0 && list != backtracks);+  jump = NULL;++  if (*cc == XCL_SINGLE)+    {+    cc ++;+    GETCHARINCTEST(c, cc);++    if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))+      {+      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_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;+      }+    else+      {+      jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));+      numberofcmps = 0;+      }+    }+  else if (*cc == XCL_RANGE)+    {+    cc ++;+    GETCHARINCTEST(c, cc);+    SET_CHAR_OFFSET(c);+    GETCHARINCTEST(c, cc);++    if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))+      {+      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_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;+      }+    else+      {+      jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));+      numberofcmps = 0;+      }+    }+#ifdef SUPPORT_UNICODE+  else+    {+    SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);+    if (*cc == XCL_NOTPROP)+      invertcmp ^= 0x1;+    cc++;+    switch(*cc)+      {+      case PT_ANY:+      if (!invertcmp)+        jump = JUMP(SLJIT_JUMP);+      break;++      case PT_LAMP:+      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;++      case PT_GC:+      c = PRIV(ucp_typerange)[(int)cc[1] * 2];+      SET_TYPE_OFFSET(c);+      jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);+      break;++      case PT_PC:+      jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);+      break;++      case PT_SC:+      compares++;+      /* Do nothing. */+      break;++      case PT_SPACE:+      case PT_PXSPACE:+      SET_CHAR_OFFSET(9);+      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_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);+      OP_FLAGS(SLJIT_OR, 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_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_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_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_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;++      case PT_CLIST:+      other_cases = PRIV(ucd_caseless_sets) + cc[1];++      /* At least three characters are required.+         Otherwise this case would be handled by the normal code path. */+      SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);+      SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);++      /* Optimizing character pairs, if their difference is power of 2. */+      if (is_powerof2(other_cases[1] ^ other_cases[0]))+        {+        if (charoffset == 0)+          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);+        else+          {+          OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);+          OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);+          }+        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]))+        {+        if (charoffset == 0)+          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);+        else+          {+          OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);+          OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);+          }+        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_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_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_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_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_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_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_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_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_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);+      OP_FLAGS(SLJIT_OR, 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);+      break;++      case PT_PXPRINT:+      /* C and Z groups are the farthest two groups. */+      SET_TYPE_OFFSET(ucp_Ll);+      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_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_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_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);+      break;++      case PT_PXPUNCT:+      SET_TYPE_OFFSET(ucp_Sc);+      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_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_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_UNREACHABLE();+      break;+      }+    cc += 2;+    }+#endif /* SUPPORT_UNICODE */++  if (jump != NULL)+    add_jump(compiler, compares > 0 ? list : backtracks, jump);+  }++if (found != NULL)+  set_jumps(found, LABEL());+}++#undef SET_TYPE_OFFSET+#undef SET_CHAR_OFFSET++#endif++static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks)+{+DEFINE_COMPILER;+int length;+struct sljit_jump *jump[4];+#ifdef SUPPORT_UNICODE+struct sljit_label *label;+#endif /* SUPPORT_UNICODE */++switch(type)+  {+  case OP_SOD:+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));+    }+  else+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));+  add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));+  return cc;++  case OP_SOM:+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));+    }+  else+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));+  add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));+  return cc;++  case OP_NOT_WORD_BOUNDARY:+  case OP_WORD_BOUNDARY:+  add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));+#ifdef SUPPORT_UNICODE+  if (common->invalid_utf)+    {+    add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0));+    return cc;+    }+#endif /* SUPPORT_UNICODE */+  sljit_set_current_flags(compiler, SLJIT_SET_Z);+  add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));+  return cc;++  case OP_EODN:+  /* Requires rather complex checks. */+  jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);+  if (common->nltype == NLTYPE_FIXED && common->newline > 255)+    {+    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    if (common->mode == PCRE2_JIT_COMPLETE)+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));+    else+      {+      jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);+      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));+      JUMPHERE(jump[1]);+      }+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));+    }+  else if (common->nltype == NLTYPE_FIXED)+    {+    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));+    }+  else+    {+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);+    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+    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_NOT_EQUAL) /* LESS */);+    /* Equal. */+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+    jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);+    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));++    JUMPHERE(jump[1]);+    if (common->nltype == NLTYPE_ANYCRLF)+      {+      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));+      }+    else+      {+      OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);+      read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));+      add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));+      sljit_set_current_flags(compiler, SLJIT_SET_Z);+      add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));+      OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);+      }+    JUMPHERE(jump[2]);+    JUMPHERE(jump[3]);+    }+  JUMPHERE(jump[0]);+  if (common->mode != PCRE2_JIT_COMPLETE)+    check_partial(common, TRUE);+  return cc;++  case OP_EOD:+  add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));+  if (common->mode != PCRE2_JIT_COMPLETE)+    check_partial(common, TRUE);+  return cc;++  case OP_DOLL:+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);+    }+  else+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), 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);+  else+    {+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));+    check_partial(common, FALSE);+    }+  return cc;++  case OP_DOLLM:+  jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);+    }+  else+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), 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]);++  if (common->nltype == NLTYPE_FIXED && common->newline > 255)+    {+    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    if (common->mode == PCRE2_JIT_COMPLETE)+      add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));+    else+      {+      jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);+      /* STR_PTR = STR_END - IN_UCHARS(1) */+      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));+      check_partial(common, TRUE);+      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));+      JUMPHERE(jump[1]);+      }++    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));+    }+  else+    {+    peek_char(common, common->nlmax, TMP3, 0, NULL);+    check_newlinechar(common, common->nltype, backtracks, FALSE);+    }+  JUMPHERE(jump[0]);+  return cc;++  case OP_CIRC:+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));+    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));+    }+  else+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);+    add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));+    }+  return cc;++  case OP_CIRCM:+  /* TMP2 might be used by peek_char_back. */+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));+    jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);+    }+  else+    {+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));+    jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);+    OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), 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]);++  if (!common->alt_circumflex)+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));++  if (common->nltype == NLTYPE_FIXED && common->newline > 255)+    {+    OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0));+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));+    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));+    }+  else+    {+    peek_char_back(common, common->nlmax, backtracks);+    check_newlinechar(common, common->nltype, backtracks, FALSE);+    }+  JUMPHERE(jump[0]);+  return cc;++  case OP_REVERSE:+  length = GET(cc, 0);+  if (length == 0)+    return cc + LINK_SIZE;+  if (HAS_VIRTUAL_REGISTERS)+    {+    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));+    }+  else+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));+#ifdef SUPPORT_UNICODE+  if (common->utf)+    {+    OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length);+    label = LABEL();+    add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0));+    move_back(common, backtracks, FALSE);+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1);+    JUMPTO(SLJIT_NOT_ZERO, label);+    }+  else+#endif+    {+    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));+    add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0));+    }+  check_start_used_ptr(common);+  return cc + LINK_SIZE;+  }+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, ricount;+PCRE2_SPTR prevcc, endcc, bptr;+BOOL first = TRUE;+uint32_t c;++prevcc = cc;+endcc = NULL;+do+  {+  GETCHARINC(c, cc);+  rgb = UCD_GRAPHBREAK(c);++  if (first)+    {+    lgb = rgb;+    endcc = cc;+    first = FALSE;+    continue;+    }++  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)+    break;++  /* 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 or ZWJ follows Extended_Pictographic, do not update lgb; this+  allows any number of them before a following Extended_Pictographic. */++  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||+       lgb != ucp_gbExtended_Pictographic)+    lgb = rgb;++  prevcc = endcc;+  endcc = cc;+  }+while (cc < end_subject);++return endcc;+}++#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */++static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc)+{+PCRE2_SPTR start_subject = args->begin;+PCRE2_SPTR end_subject = args->end;+int lgb, rgb, ricount;+PCRE2_SPTR prevcc, endcc, bptr;+BOOL first = TRUE;+uint32_t c;++prevcc = cc;+endcc = NULL;+do+  {+  GETCHARINC_INVALID(c, cc, end_subject, break);+  rgb = UCD_GRAPHBREAK(c);++  if (first)+    {+    lgb = rgb;+    endcc = cc;+    first = FALSE;+    continue;+    }++  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)+    break;++  /* 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)+      {+      GETCHARBACK_INVALID(c, bptr, start_subject, break);++      if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator)+        break;++      ricount++;+      }++    if ((ricount & 1) != 0)+      break;  /* Grapheme break required */+    }++  /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this+  allows any number of them before a following Extended_Pictographic. */++  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||+       lgb != ucp_gbExtended_Pictographic)+    lgb = rgb;++  prevcc = endcc;+  endcc = cc;+  }+while (cc < end_subject);++return endcc;+}++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;++/* Patch by PH */+/* GETCHARINC(c, cc); */+c = *cc++;++#if PCRE2_CODE_UNIT_WIDTH == 32+if (c >= 0x110000)+  return NULL;+#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */+lgb = UCD_GRAPHBREAK(c);++while (cc < end_subject)+  {+  c = *cc;+#if PCRE2_CODE_UNIT_WIDTH == 32+  if (c >= 0x110000)+    break;+#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */+  rgb = UCD_GRAPHBREAK(c);++  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)+    break;++  /* 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 PCRE2_CODE_UNIT_WIDTH == 32+      if (c >= 0x110000)+        break;+#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */++      if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break;++      ricount++;+      }++    if ((ricount & 1) != 0)+      break;  /* Grapheme break required */+    }++  /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this+  allows any number of them before a following Extended_Pictographic. */++  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||+       lgb != ucp_gbExtended_Pictographic)+    lgb = rgb;++  cc++;+  }++return cc;+}++#endif /* SUPPORT_UNICODE */++static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr)+{+DEFINE_COMPILER;+int length;+unsigned int c, oc, bit;+compare_context context;+struct sljit_jump *jump[3];+jump_list *end_list;+#ifdef SUPPORT_UNICODE+PCRE2_UCHAR propdata[5];+#endif /* SUPPORT_UNICODE */++switch(type)+  {+  case OP_NOT_DIGIT:+  case OP_DIGIT:+  /* Digits are usually 0-9, so it is worth to optimize them. */+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+  if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE))+    read_char7_type(common, backtracks, type == OP_NOT_DIGIT);+  else+#endif+    read_char8_type(common, backtracks, type == OP_NOT_DIGIT);+    /* Flip the starting bit in the negative case. */+  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;++  case OP_NOT_WHITESPACE:+  case OP_WHITESPACE:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+  if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE))+    read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE);+  else+#endif+    read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE);+  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;++  case OP_NOT_WORDCHAR:+  case OP_WORDCHAR:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+  if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE))+    read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR);+  else+#endif+    read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR);+  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;++  case OP_ANY:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+  read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);+  if (common->nltype == NLTYPE_FIXED && common->newline > 255)+    {+    jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);+    end_list = NULL;+    if (common->mode != PCRE2_JIT_PARTIAL_HARD)+      add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));+    else+      check_str_end(common, &end_list);++    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));+    set_jumps(end_list, LABEL());+    JUMPHERE(jump[0]);+    }+  else+    check_newlinechar(common, common->nltype, backtracks, TRUE);+  return cc;++  case OP_ALLANY:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+#ifdef SUPPORT_UNICODE+  if (common->utf)+    {+    if (common->invalid_utf)+      {+      read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR);+      return cc;+      }++#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16+    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 PCRE2_CODE_UNIT_WIDTH == 8+    jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);+    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+    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_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 /* PCRE2_CODE_UNIT_WIDTH == 8 */+    JUMPHERE(jump[0]);+    return cc;+#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */+    }+#endif /* SUPPORT_UNICODE */+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  return cc;++  case OP_ANYBYTE:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  return cc;++#ifdef SUPPORT_UNICODE+  case OP_NOTPROP:+  case OP_PROP:+  propdata[0] = XCL_HASPROP;+  propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;+  propdata[2] = cc[0];+  propdata[3] = cc[1];+  propdata[4] = XCL_END;+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+  compile_xclass_matchingpath(common, propdata, backtracks);+  return cc + 2;+#endif++  case OP_ANYNL:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+  read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0);+  jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);+  /* We don't need to handle soft partial matching case. */+  end_list = NULL;+  if (common->mode != PCRE2_JIT_PARTIAL_HARD)+    add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));+  else+    check_str_end(common, &end_list);+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+  jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  jump[2] = JUMP(SLJIT_JUMP);+  JUMPHERE(jump[0]);+  check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);+  set_jumps(end_list, LABEL());+  JUMPHERE(jump[1]);+  JUMPHERE(jump[2]);+  return cc;++  case OP_NOT_HSPACE:+  case OP_HSPACE:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);++  if (type == OP_NOT_HSPACE)+    read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR);+  else+    read_char(common, 0x9, 0x3000, NULL, 0);++  add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));+  sljit_set_current_flags(compiler, SLJIT_SET_Z);+  add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));+  return cc;++  case OP_NOT_VSPACE:+  case OP_VSPACE:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);++  if (type == OP_NOT_VSPACE)+    read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR);+  else+    read_char(common, 0xa, 0x2029, NULL, 0);++  add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));+  sljit_set_current_flags(compiler, SLJIT_SET_Z);+  add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));+  return cc;++#ifdef SUPPORT_UNICODE+  case OP_EXTUNI:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);++  SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);+  OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);++#if PCRE2_CODE_UNIT_WIDTH != 32+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,+    common->utf ? (common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_utf)) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));+  if (common->invalid_utf)+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));+#else+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,+    common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));+  if (!common->utf || common->invalid_utf)+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));+#endif++  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);++  if (common->mode == PCRE2_JIT_PARTIAL_HARD)+    {+    jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0);+    /* Since we successfully read a char above, partial matching must occure. */+    check_partial(common, TRUE);+    JUMPHERE(jump[0]);+    }+  return cc;+#endif++  case OP_CHAR:+  case OP_CHARI:+  length = 1;+#ifdef SUPPORT_UNICODE+  if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);+#endif++  if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE)+    detect_partial_match(common, backtracks);++  if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)+    {+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));+    if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE))+      add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));++    context.length = IN_UCHARS(length);+    context.sourcereg = -1;+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED+    context.ucharptr = 0;+#endif+    return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);+    }++#ifdef SUPPORT_UNICODE+  if (common->utf)+    {+    GETCHAR(c, cc);+    }+  else+#endif+    c = *cc;++  SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc));++  if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)+    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));++  oc = char_othercase(common, c);+  read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0);++  SLJIT_ASSERT(!is_powerof2(c ^ oc));++  if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))+    {+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);+    CMOV(SLJIT_EQUAL, TMP1, SLJIT_IMM, c);+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));+    }+  else+    {+    jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));+    JUMPHERE(jump[0]);+    }+  return cc + length;++  case OP_NOT:+  case OP_NOTI:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);++  length = 1;+#ifdef SUPPORT_UNICODE+  if (common->utf)+    {+#if PCRE2_CODE_UNIT_WIDTH == 8+    c = *cc;+    if (c < 128 && !common->invalid_utf)+      {+      OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);+      if (type == OP_NOT || !char_has_othercase(common, cc))+        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));+      else+        {+        /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */+        OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);+        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));+        }+      /* Skip the variable-length character. */+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+      jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);+      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);+      JUMPHERE(jump[0]);+      return cc + 1;+      }+    else+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+      {+      GETCHARLEN(c, cc, length);+      }+    }+  else+#endif /* SUPPORT_UNICODE */+    c = *cc;++  if (type == OP_NOT || !char_has_othercase(common, cc))+    {+    read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR);+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));+    }+  else+    {+    oc = char_othercase(common, c);+    read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR);+    bit = c ^ oc;+    if (is_powerof2(bit))+      {+      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));+      }+    else+      {+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));+      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));+      }+    }+  return cc + length;++  case OP_CLASS:+  case OP_NCLASS:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+  bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255;+  if (type == OP_NCLASS)+    read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR);+  else+    read_char(common, 0, bit, NULL, 0);+#else+  if (type == OP_NCLASS)+    read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR);+  else+    read_char(common, 0, 255, NULL, 0);+#endif++  if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))+    return cc + 32 / sizeof(PCRE2_UCHAR);++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+  jump[0] = NULL;+  if (common->utf)+    {+    jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);+    if (type == OP_CLASS)+      {+      add_jump(compiler, backtracks, jump[0]);+      jump[0] = NULL;+      }+    }+#elif PCRE2_CODE_UNIT_WIDTH != 8+  jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);+  if (type == OP_CLASS)+    {+    add_jump(compiler, backtracks, jump[0]);+    jump[0] = NULL;+    }+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */++  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);+  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);+  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);+  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);+  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+  if (jump[0] != NULL)+    JUMPHERE(jump[0]);+#endif+  return cc + 32 / sizeof(PCRE2_UCHAR);++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32+  case OP_XCLASS:+  if (check_str_ptr)+    detect_partial_match(common, backtracks);+  compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);+  return cc + GET(cc, 0) - 1;+#endif+  }+SLJIT_UNREACHABLE();+return cc;+}++static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks)+{+/* This function consumes at least one input character. */+/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */+DEFINE_COMPILER;+PCRE2_SPTR ccbegin = cc;+compare_context context;+int size;++context.length = 0;+do+  {+  if (cc >= ccend)+    break;++  if (*cc == OP_CHAR)+    {+    size = 1;+#ifdef SUPPORT_UNICODE+    if (common->utf && HAS_EXTRALEN(cc[1]))+      size += GET_EXTRALEN(cc[1]);+#endif+    }+  else if (*cc == OP_CHARI)+    {+    size = 1;+#ifdef SUPPORT_UNICODE+    if (common->utf)+      {+      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)+        size = 0;+      else if (HAS_EXTRALEN(cc[1]))+        size += GET_EXTRALEN(cc[1]);+      }+    else+#endif+    if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)+      size = 0;+    }+  else+    size = 0;++  cc += 1 + size;+  context.length += IN_UCHARS(size);+  }+while (size > 0 && context.length <= 128);++cc = ccbegin;+if (context.length > 0)+  {+  /* We have a fixed-length byte sequence. */+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);+  add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));++  context.sourcereg = -1;+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED+  context.ucharptr = 0;+#endif+  do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);+  return cc;+  }++/* A non-fixed length character will be checked if length == 0. */+return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);+}++/* Forward definitions. */+static void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *);+static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);++#define PUSH_BACKTRACK(size, ccstart, error) \+  do \+    { \+    backtrack = sljit_alloc_memory(compiler, (size)); \+    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \+      return error; \+    memset(backtrack, 0, size); \+    backtrack->prev = parent->top; \+    backtrack->cc = (ccstart); \+    parent->top = backtrack; \+    } \+  while (0)++#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \+  do \+    { \+    backtrack = sljit_alloc_memory(compiler, (size)); \+    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \+      return; \+    memset(backtrack, 0, size); \+    backtrack->prev = parent->top; \+    backtrack->cc = (ccstart); \+    parent->top = backtrack; \+    } \+  while (0)++#define BACKTRACK_AS(type) ((type *)backtrack)++static void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)+{+/* The OVECTOR offset goes to TMP2. */+DEFINE_COMPILER;+int count = GET2(cc, 1 + IMM2_SIZE);+PCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size;+unsigned int offset;+jump_list *found = NULL;++SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));++count--;+while (count-- > 0)+  {+  offset = GET2(slot, 0) << 1;+  GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));+  add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));+  slot += common->name_entry_size;+  }++offset = GET2(slot, 0) << 1;+GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));+if (backtracks != NULL && !common->unset_backref)+  add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));++set_jumps(found, LABEL());+}++static void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)+{+DEFINE_COMPILER;+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);+int offset = 0;+struct sljit_jump *jump = NULL;+struct sljit_jump *partial;+struct sljit_jump *nopartial;+#if defined SUPPORT_UNICODE+struct sljit_label *loop;+struct sljit_label *caseless_loop;+jump_list *no_match = NULL;+int source_reg = COUNT_MATCH;+int source_end_reg = ARGUMENTS;+int char1_reg = STACK_LIMIT;+#endif /* SUPPORT_UNICODE */++if (ref)+  {+  offset = GET2(cc, 1) << 1;+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));+  /* OVECTOR(1) contains the "string begin - 1" constant. */+  if (withchecks && !common->unset_backref)+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));+  }+else+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);++#if defined SUPPORT_UNICODE+if (common->utf && *cc == OP_REFI)+  {+  SLJIT_ASSERT(common->iref_ptr != 0);++  if (ref)+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));+  else+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));++  if (withchecks && emptyfail)+    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0));++  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr, source_reg, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw), source_end_reg, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2, char1_reg, 0);++  OP1(SLJIT_MOV, source_reg, 0, TMP1, 0);+  OP1(SLJIT_MOV, source_end_reg, 0, TMP2, 0);++  loop = LABEL();+  jump = CMP(SLJIT_GREATER_EQUAL, source_reg, 0, source_end_reg, 0);+  partial = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);++  /* Read original character. It must be a valid UTF character. */+  OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);+  OP1(SLJIT_MOV, STR_PTR, 0, source_reg, 0);++  read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR | READ_CHAR_VALID_UTF);++  OP1(SLJIT_MOV, source_reg, 0, STR_PTR, 0);+  OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);+  OP1(SLJIT_MOV, char1_reg, 0, TMP1, 0);++  /* Read second character. */+  read_char(common, 0, READ_CHAR_MAX, &no_match, READ_CHAR_UPDATE_STR_PTR);++  CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);++  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);++  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));++  OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);+  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);+  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);++  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records));++  OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, other_case));+  OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, caseset));+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);+  CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);++  add_jump(compiler, &no_match, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0));+  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);+  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_caseless_sets));++  caseless_loop = LABEL();+  OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0);+  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t));+  OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, char1_reg, 0);+  JUMPTO(SLJIT_EQUAL, loop);+  JUMPTO(SLJIT_LESS, caseless_loop);++  set_jumps(no_match, LABEL());+  if (common->mode == PCRE2_JIT_COMPLETE)+    JUMPHERE(partial);++  OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr);+  OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw));+  OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2);+  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));++  if (common->mode != PCRE2_JIT_COMPLETE)+    {+    JUMPHERE(partial);+    OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr);+    OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw));+    OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2);++    check_partial(common, FALSE);+    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));+    }++  JUMPHERE(jump);+  OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr);+  OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw));+  OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2);+  return;+  }+else+#endif /* SUPPORT_UNICODE */+  {+  if (ref)+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);+  else+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);++  if (withchecks)+    jump = JUMP(SLJIT_ZERO);++  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);+  partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);+  if (common->mode == PCRE2_JIT_COMPLETE)+    add_jump(compiler, backtracks, partial);++  add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));+  add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));++  if (common->mode != PCRE2_JIT_COMPLETE)+    {+    nopartial = JUMP(SLJIT_JUMP);+    JUMPHERE(partial);+    /* TMP2 -= STR_END - STR_PTR */+    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);+    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);+    partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);+    OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);+    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));+    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));+    JUMPHERE(partial);+    check_partial(common, FALSE);+    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));+    JUMPHERE(nopartial);+    }+  }++if (jump != NULL)+  {+  if (emptyfail)+    add_jump(compiler, backtracks, jump);+  else+    JUMPHERE(jump);+  }+}++static SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);+backtrack_common *backtrack;+PCRE2_UCHAR type;+int offset = 0;+struct sljit_label *label;+struct sljit_jump *zerolength;+struct sljit_jump *jump = NULL;+PCRE2_SPTR ccbegin = cc;+int min = 0, max = 0;+BOOL minimize;++PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL);++if (ref)+  offset = GET2(cc, 1) << 1;+else+  cc += IMM2_SIZE;+type = cc[1 + IMM2_SIZE];++SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);+minimize = (type & 0x1) != 0;+switch(type)+  {+  case OP_CRSTAR:+  case OP_CRMINSTAR:+  min = 0;+  max = 0;+  cc += 1 + IMM2_SIZE + 1;+  break;+  case OP_CRPLUS:+  case OP_CRMINPLUS:+  min = 1;+  max = 0;+  cc += 1 + IMM2_SIZE + 1;+  break;+  case OP_CRQUERY:+  case OP_CRMINQUERY:+  min = 0;+  max = 1;+  cc += 1 + IMM2_SIZE + 1;+  break;+  case OP_CRRANGE:+  case OP_CRMINRANGE:+  min = GET2(cc, 1 + IMM2_SIZE + 1);+  max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);+  cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;+  break;+  default:+  SLJIT_UNREACHABLE();+  break;+  }++if (!minimize)+  {+  if (min == 0)+    {+    allocate_stack(common, 2);+    if (ref)+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));+    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_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)+      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));+    else+      {+      compile_dnref_search(common, ccbegin, NULL);+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);+      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));+      }+    /* Restore if not zero length. */+    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));+    }+  else+    {+    allocate_stack(common, 1);+    if (ref)+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+    if (ref)+      {+      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));+      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));+      }+    else+      {+      compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);+      zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));+      }+    }++  if (min > 1 || max > 1)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);++  label = LABEL();+  if (!ref)+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);+  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);++  if (min > 1 || max > 1)+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);+    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);+    if (min > 1)+      CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);+    if (max > 1)+      {+      jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);+      allocate_stack(common, 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+      JUMPTO(SLJIT_JUMP, label);+      JUMPHERE(jump);+      }+    }++  if (max == 0)+    {+    /* Includes min > 1 case as well. */+    allocate_stack(common, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+    JUMPTO(SLJIT_JUMP, label);+    }++  JUMPHERE(zerolength);+  BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();++  count_match(common);+  return cc;+  }++allocate_stack(common, ref ? 2 : 3);+if (ref)+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+if (type != OP_CRMINSTAR)+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);++if (min == 0)+  {+  /* 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)+    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));+  else+    {+    compile_dnref_search(common, ccbegin, NULL);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);+    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));+    }+  /* Length is non-zero, we can match real repeats. */+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+  jump = JUMP(SLJIT_JUMP);+  }+else+  {+  if (ref)+    {+    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));+    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));+    }+  else+    {+    compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);+    zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));+    }+  }++BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();+if (max > 0)+  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));++if (!ref)+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));+compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);++if (min > 1)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);+  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath);+  }+else if (max > 0)+  OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);++if (jump != NULL)+  JUMPHERE(jump);+JUMPHERE(zerolength);++count_match(common);+return cc;+}++static SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+recurse_entry *entry = common->entries;+recurse_entry *prev = NULL;+sljit_sw start = GET(cc, 1);+PCRE2_SPTR start_cc;+BOOL needs_control_head;++PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);++/* Inlining simple patterns. */+if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)+  {+  start_cc = common->start + start;+  compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);+  BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;+  return cc + 1 + LINK_SIZE;+  }++while (entry != NULL)+  {+  if (entry->start == start)+    break;+  prev = entry;+  entry = entry->next;+  }++if (entry == NULL)+  {+  entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    return NULL;+  entry->next = NULL;+  entry->entry_label = NULL;+  entry->backtrack_label = NULL;+  entry->entry_calls = NULL;+  entry->backtrack_calls = NULL;+  entry->start = start;++  if (prev != NULL)+    prev->next = entry;+  else+    common->entries = entry;+  }++BACKTRACK_AS(recurse_backtrack)->entry = entry;++if (entry->entry_label == NULL)+  add_jump(compiler, &entry->entry_calls, JUMP(SLJIT_FAST_CALL));+else+  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 sljit_s32 SLJIT_FUNC do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)+{+PCRE2_SPTR begin;+PCRE2_SIZE *ovector;+sljit_u32 oveccount, capture_top;++if (arguments->callout == NULL)+  return 0;++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 = 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 = 1;+callout_block->offset_vector = ovector;++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);+}++#define CALLOUT_ARG_OFFSET(arg) \+    SLJIT_OFFSETOF(pcre2_callout_block, arg)++static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+sljit_s32 mov_opcode;+unsigned int callout_length = (*cc == OP_CALLOUT)+    ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE);+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);++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);+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+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, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);++if (common->mark_ptr != 0)+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));+mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1));+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE));++if (*cc == OP_CALLOUT)+  {+  value1 = 0;+  value2 = 0;+  value3 = 0;+  }+else+  {+  value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1);+  value2 = (callout_length - (1 + 4*LINK_SIZE + 2));+  value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE));+  }++OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1);+OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2);+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, STR_PTR, 0);+/* SLJIT_R0 = arguments */+OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);+GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_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_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_NOT_EQUAL32 /* SIG_LESS */, common->abort_label);+return cc + callout_length;+}++#undef CALLOUT_ARG_SIZE+#undef CALLOUT_ARG_OFFSET++static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc)+{+while (TRUE)+  {+  switch (*cc)+    {+    case OP_CALLOUT_STR:+    cc += GET(cc, 1 + 2*LINK_SIZE);+    break;++    case OP_NOT_WORD_BOUNDARY:+    case OP_WORD_BOUNDARY:+    case OP_CIRC:+    case OP_CIRCM:+    case OP_DOLL:+    case OP_DOLLM:+    case OP_CALLOUT:+    case OP_ALT:+    cc += PRIV(OP_lengths)[*cc];+    break;++    case OP_KET:+    return FALSE;++    default:+    return TRUE;+    }+  }+}++static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional)+{+DEFINE_COMPILER;+int framesize;+int extrasize;+BOOL local_quit_available = FALSE;+BOOL needs_control_head;+int private_data_ptr;+backtrack_common altbacktrack;+PCRE2_SPTR ccbegin;+PCRE2_UCHAR opcode;+PCRE2_UCHAR bra = OP_BRA;+jump_list *tmp = NULL;+jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;+jump_list **found;+/* Saving previous accept variables. */+BOOL save_local_quit_available = common->local_quit_available;+BOOL save_in_positive_assertion = common->in_positive_assertion;+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_assertion_quit = common->positive_assertion_quit;+jump_list *save_accept = common->accept;+struct sljit_jump *jump;+struct sljit_jump *brajump = NULL;++/* Assert captures then. */+common->then_trap = NULL;++if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)+  {+  SLJIT_ASSERT(!conditional);+  bra = *cc;+  cc++;+  }+private_data_ptr = PRIVATE_DATA(cc);+SLJIT_ASSERT(private_data_ptr != 0);+framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);+backtrack->framesize = framesize;+backtrack->private_data_ptr = private_data_ptr;+opcode = *cc;+SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);+found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;+ccbegin = cc;+cc += GET(cc, 1);++if (bra == OP_BRAMINZERO)+  {+  /* This is a braminzero backtrack path. */+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  free_stack(common, 1);+  brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);+  }++if (framesize < 0)+  {+  extrasize = 1;+  if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))+    extrasize = 0;++  if (needs_control_head)+    extrasize++;++  if (framesize == no_frame)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);++  if (extrasize > 0)+    allocate_stack(common, extrasize);++  if (needs_control_head)+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);++  if (extrasize > 0)+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);++  if (needs_control_head)+    {+    SLJIT_ASSERT(extrasize == 2);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);+    }+  }+else+  {+  extrasize = needs_control_head ? 3 : 2;+  allocate_stack(common, framesize + extrasize);++  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+  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);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);++  if (needs_control_head)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);+    }+  else+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);++  init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize);+  }++memset(&altbacktrack, 0, sizeof(backtrack_common));+if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT))+  {+  /* Control verbs cannot escape from these asserts. */+  local_quit_available = TRUE;+  common->local_quit_available = TRUE;+  common->quit_label = NULL;+  common->quit = NULL;+  }++common->in_positive_assertion = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK);+common->positive_assertion_quit = NULL;++while (1)+  {+  common->accept_label = NULL;+  common->accept = NULL;+  altbacktrack.top = NULL;+  altbacktrack.topbacktracks = NULL;++  if (*ccbegin == OP_ALT && extrasize > 0)+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));++  altbacktrack.cc = ccbegin;+  compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    {+    if (local_quit_available)+      {+      common->local_quit_available = save_local_quit_available;+      common->quit_label = save_quit_label;+      common->quit = save_quit;+      }+    common->in_positive_assertion = save_in_positive_assertion;+    common->then_trap = save_then_trap;+    common->accept_label = save_accept_label;+    common->positive_assertion_quit = save_positive_assertion_quit;+    common->accept = save_accept;+    return NULL;+    }+  common->accept_label = LABEL();+  if (common->accept != NULL)+    set_jumps(common->accept, common->accept_label);++  /* Reset stack. */+  if (framesize < 0)+    {+    if (framesize == no_frame)+      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+    else if (extrasize > 0)+      free_stack(common, extrasize);++    if (needs_control_head)+      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_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), 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), 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));+      }+    }++  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)+    {+    /* We know that STR_PTR was stored on the top of the stack. */+    if (conditional)+      {+      if (extrasize > 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), STACK(-extrasize));+      else+        {+        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_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), STACK(-framesize - 1));+      }+    }+  add_jump(compiler, found, JUMP(SLJIT_JUMP));++  compile_backtrackingpath(common, altbacktrack.top);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    {+    if (local_quit_available)+      {+      common->local_quit_available = save_local_quit_available;+      common->quit_label = save_quit_label;+      common->quit = save_quit;+      }+    common->in_positive_assertion = save_in_positive_assertion;+    common->then_trap = save_then_trap;+    common->accept_label = save_accept_label;+    common->positive_assertion_quit = save_positive_assertion_quit;+    common->accept = save_accept;+    return NULL;+    }+  set_jumps(altbacktrack.topbacktracks, LABEL());++  if (*cc != OP_ALT)+    break;++  ccbegin = cc;+  cc += GET(cc, 1);+  }++if (local_quit_available)+  {+  SLJIT_ASSERT(common->positive_assertion_quit == NULL);+  /* Makes the check less complicated below. */+  common->positive_assertion_quit = common->quit;+  }++/* None of them matched. */+if (common->positive_assertion_quit != NULL)+  {+  jump = JUMP(SLJIT_JUMP);+  set_jumps(common->positive_assertion_quit, LABEL());+  SLJIT_ASSERT(framesize != no_stack);+  if (framesize < 0)+    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_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (extrasize + 1) * sizeof(sljit_sw));+    }+  JUMPHERE(jump);+  }++if (needs_control_head)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));++if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)+  {+  /* Assert is failed. */+  if ((conditional && extrasize > 0) || bra == OP_BRAZERO)+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));++  if (framesize < 0)+    {+    /* The topmost item should be 0. */+    if (bra == OP_BRAZERO)+      {+      if (extrasize == 2)+        free_stack(common, 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+      }+    else if (extrasize > 0)+      free_stack(common, extrasize);+    }+  else+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));+    /* The topmost item should be 0. */+    if (bra == OP_BRAZERO)+      {+      free_stack(common, framesize + extrasize - 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+      }+    else+      free_stack(common, framesize + extrasize);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);+    }+  jump = JUMP(SLJIT_JUMP);+  if (bra != OP_BRAZERO)+    add_jump(compiler, target, jump);++  /* Assert is successful. */+  set_jumps(tmp, LABEL());+  if (framesize < 0)+    {+    /* 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), STACK(-extrasize));++    /* Keep the STR_PTR on the top of the stack. */+    if (bra == OP_BRAZERO)+      {+      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_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 (bra == OP_BRA)+      {+      /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */+      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_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));+        if (bra == OP_BRAMINZERO)+          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+        }+      else+        {+        SLJIT_ASSERT(extrasize == 3);+        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));+        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);+        }+      }+    }++  if (bra == OP_BRAZERO)+    {+    backtrack->matchingpath = LABEL();+    SET_LABEL(jump, backtrack->matchingpath);+    }+  else if (bra == OP_BRAMINZERO)+    {+    JUMPTO(SLJIT_JUMP, backtrack->matchingpath);+    JUMPHERE(brajump);+    if (framesize >= 0)+      {+      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));+      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());+    }+  }+else+  {+  /* AssertNot is successful. */+  if (framesize < 0)+    {+    if (extrasize > 0)+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));++    if (bra != OP_BRA)+      {+      if (extrasize == 2)+        free_stack(common, 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+      }+    else if (extrasize > 0)+      free_stack(common, extrasize);+    }+  else+    {+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));+    /* The topmost item should be 0. */+    if (bra != OP_BRA)+      {+      free_stack(common, framesize + extrasize - 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+      }+    else+      free_stack(common, framesize + extrasize);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);+    }++  if (bra == OP_BRAZERO)+    backtrack->matchingpath = LABEL();+  else if (bra == OP_BRAMINZERO)+    {+    JUMPTO(SLJIT_JUMP, backtrack->matchingpath);+    JUMPHERE(brajump);+    }++  if (bra != OP_BRA)+    {+    SLJIT_ASSERT(found == &backtrack->common.topbacktracks);+    set_jumps(backtrack->common.topbacktracks, LABEL());+    backtrack->common.topbacktracks = NULL;+    }+  }++if (local_quit_available)+  {+  common->local_quit_available = save_local_quit_available;+  common->quit_label = save_quit_label;+  common->quit = save_quit;+  }+common->in_positive_assertion = save_in_positive_assertion;+common->then_trap = save_then_trap;+common->accept_label = save_accept_label;+common->positive_assertion_quit = save_positive_assertion_quit;+common->accept = save_accept;+return cc + 1 + LINK_SIZE;+}++static SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)+{+DEFINE_COMPILER;+int stacksize;++if (framesize < 0)+  {+  if (framesize == no_frame)+    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+  else+    {+    stacksize = needs_control_head ? 1 : 0;+    if (ket != OP_KET || has_alternatives)+      stacksize++;++    if (stacksize > 0)+      free_stack(common, stacksize);+    }++  if (needs_control_head)+    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), 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), STACK(-1));+    }+  }+else+  {+  stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;+  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), STACK(-1));++  if (ket == OP_KETRMAX)+    {+    /* TMP2 which is set here used by OP_KETRMAX below. */+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    }+  }+if (needs_control_head)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);+}++static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)+{+DEFINE_COMPILER;++if (common->capture_last_ptr != 0)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);+  stacksize++;+  }+if (common->optimized_cbracket[offset >> 1] == 0)+  {+  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), STACK(stacksize), TMP1, 0);+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+  stacksize += 2;+  }+return stacksize;+}++static PCRE2_SPTR SLJIT_FUNC do_script_run(PCRE2_SPTR ptr, PCRE2_SPTR endptr)+{+  if (PRIV(script_run)(ptr, endptr, FALSE))+    return endptr;+  return NULL;+}++#ifdef SUPPORT_UNICODE++static PCRE2_SPTR SLJIT_FUNC do_script_run_utf(PCRE2_SPTR ptr, PCRE2_SPTR endptr)+{+  if (PRIV(script_run)(ptr, endptr, TRUE))+    return endptr;+  return NULL;+}++#endif /* SUPPORT_UNICODE */++static SLJIT_INLINE void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent)+{+DEFINE_COMPILER;++SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+#ifdef SUPPORT_UNICODE+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,+  common->utf ? SLJIT_FUNC_OFFSET(do_script_run_utf) : SLJIT_FUNC_OFFSET(do_script_run));+#else+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_script_run));+#endif++OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);+add_jump(compiler, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));+}++/*+  Handling bracketed expressions is probably the most complex part.++  Stack layout naming characters:+    S - Push the current STR_PTR+    0 - Push a 0 (NULL)+    A - Push the current STR_PTR. Needed for restoring the STR_PTR+        before the next alternative. Not pushed if there are no alternatives.+    M - Any values pushed by the current alternative. Can be empty, or anything.+    C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.+    L - Push the previous local (pointed by localptr) to the stack+   () - opional values stored on the stack+  ()* - optonal, can be stored multiple times++  The following list shows the regular expression templates, their PCRE byte codes+  and stack layout supported by pcre-sljit.++  (?:)                     OP_BRA     | OP_KET                A M+  ()                       OP_CBRA    | OP_KET                C M+  (?:)+                    OP_BRA     | OP_KETRMAX        0   A M S   ( A M S )*+                           OP_SBRA    | OP_KETRMAX        0   L M S   ( L M S )*+  (?:)+?                   OP_BRA     | OP_KETRMIN        0   A M S   ( A M S )*+                           OP_SBRA    | OP_KETRMIN        0   L M S   ( L M S )*+  ()+                      OP_CBRA    | OP_KETRMAX        0   C M S   ( C M S )*+                           OP_SCBRA   | OP_KETRMAX        0   C M S   ( C M S )*+  ()+?                     OP_CBRA    | OP_KETRMIN        0   C M S   ( C M S )*+                           OP_SCBRA   | OP_KETRMIN        0   C M S   ( C M S )*+  (?:)?    OP_BRAZERO    | OP_BRA     | OP_KET            S ( A M 0 )+  (?:)??   OP_BRAMINZERO | OP_BRA     | OP_KET            S ( A M 0 )+  ()?      OP_BRAZERO    | OP_CBRA    | OP_KET            S ( C M 0 )+  ()??     OP_BRAMINZERO | OP_CBRA    | OP_KET            S ( C M 0 )+  (?:)*    OP_BRAZERO    | OP_BRA     | OP_KETRMAX      S 0 ( A M S )*+           OP_BRAZERO    | OP_SBRA    | OP_KETRMAX      S 0 ( L M S )*+  (?:)*?   OP_BRAMINZERO | OP_BRA     | OP_KETRMIN      S 0 ( A M S )*+           OP_BRAMINZERO | OP_SBRA    | OP_KETRMIN      S 0 ( L M S )*+  ()*      OP_BRAZERO    | OP_CBRA    | OP_KETRMAX      S 0 ( C M S )*+           OP_BRAZERO    | OP_SCBRA   | OP_KETRMAX      S 0 ( C M S )*+  ()*?     OP_BRAMINZERO | OP_CBRA    | OP_KETRMIN      S 0 ( C M S )*+           OP_BRAMINZERO | OP_SCBRA   | OP_KETRMIN      S 0 ( C M S )*+++  Stack layout naming characters:+    A - Push the alternative index (starting from 0) on the stack.+        Not pushed if there is no alternatives.+    M - Any values pushed by the current alternative. Can be empty, or anything.++  The next list shows the possible content of a bracket:+  (|)     OP_*BRA    | OP_ALT ...         M A+  (?()|)  OP_*COND   | OP_ALT             M A+  (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A+                                          Or nothing, if trace is unnecessary+*/++static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+PCRE2_UCHAR opcode;+int private_data_ptr = 0;+int offset = 0;+int i, stacksize;+int repeat_ptr = 0, repeat_length = 0;+int repeat_type = 0, repeat_count = 0;+PCRE2_SPTR ccbegin;+PCRE2_SPTR matchingpath;+PCRE2_SPTR slot;+PCRE2_UCHAR bra = OP_BRA;+PCRE2_UCHAR ket;+assert_backtrack *assert;+BOOL has_alternatives;+BOOL needs_control_head = FALSE;+struct sljit_jump *jump;+struct sljit_jump *skip;+struct sljit_label *rmax_label = NULL;+struct sljit_jump *braminzero = NULL;++PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);++if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)+  {+  bra = *cc;+  cc++;+  opcode = *cc;+  }++opcode = *cc;+ccbegin = cc;+matchingpath = bracketend(cc) - 1 - LINK_SIZE;+ket = *matchingpath;+if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)+  {+  repeat_ptr = PRIVATE_DATA(matchingpath);+  repeat_length = PRIVATE_DATA(matchingpath + 1);+  repeat_type = PRIVATE_DATA(matchingpath + 2);+  repeat_count = PRIVATE_DATA(matchingpath + 3);+  SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);+  if (repeat_type == OP_UPTO)+    ket = OP_KETRMAX;+  if (repeat_type == OP_MINUPTO)+    ket = OP_KETRMIN;+  }++matchingpath = ccbegin + 1 + LINK_SIZE;+SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);+SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));+cc += GET(cc, 1);++has_alternatives = *cc == OP_ALT;+if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))+  {+  SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3,+    compile_time_checks_must_be_grouped_together);+  has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE;+  }++if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))+  opcode = OP_SCOND;++if (opcode == OP_CBRA || opcode == OP_SCBRA)+  {+  /* Capturing brackets has a pre-allocated space. */+  offset = GET2(ccbegin, 1 + LINK_SIZE);+  if (common->optimized_cbracket[offset] == 0)+    {+    private_data_ptr = OVECTOR_PRIV(offset);+    offset <<= 1;+    }+  else+    {+    offset <<= 1;+    private_data_ptr = OVECTOR(offset);+    }+  BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;+  matchingpath += IMM2_SIZE;+  }+else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)+  {+  /* Other brackets simply allocate the next entry. */+  private_data_ptr = PRIVATE_DATA(ccbegin);+  SLJIT_ASSERT(private_data_ptr != 0);+  BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;+  if (opcode == OP_ONCE)+    BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);+  }++/* Instructions before the first alternative. */+stacksize = 0;+if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))+  stacksize++;+if (bra == OP_BRAZERO)+  stacksize++;++if (stacksize > 0)+  allocate_stack(common, stacksize);++stacksize = 0;+if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))+  {+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);+  stacksize++;+  }++if (bra == OP_BRAZERO)+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);++if (bra == OP_BRAMINZERO)+  {+  /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  if (ket != OP_KETRMIN)+    {+    free_stack(common, 1);+    braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);+    }+  else if (opcode == OP_ONCE || opcode >= OP_SBRA)+    {+    jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    /* Nothing stored during the first run. */+    skip = JUMP(SLJIT_JUMP);+    JUMPHERE(jump);+    /* Checking zero-length iteration. */+    if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)+      {+      /* When we come from outside, private_data_ptr contains the previous STR_PTR. */+      braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+      }+    else+      {+      /* 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), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2));+      }+    JUMPHERE(skip);+    }+  else+    {+    jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    JUMPHERE(jump);+    }+  }++if (repeat_type != 0)+  {+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);+  if (repeat_type == OP_EXACT)+    rmax_label = LABEL();+  }++if (ket == OP_KETRMIN)+  BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();++if (ket == OP_KETRMAX)+  {+  rmax_label = LABEL();+  if (has_alternatives && opcode >= OP_BRA && opcode < OP_SBRA && repeat_type == 0)+    BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;+  }++/* Handling capturing brackets and alternatives. */+if (opcode == OP_ONCE)+  {+  stacksize = 0;+  if (needs_control_head)+    {+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);+    stacksize++;+    }++  if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)+    {+    /* Neither capturing brackets nor recursions are found in the block. */+    if (ket == OP_KETRMIN)+      {+      stacksize += 2;+      if (!needs_control_head)+        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+      }+    else+      {+      if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);+      if (ket == OP_KETRMAX || has_alternatives)+        stacksize++;+      }++    if (stacksize > 0)+      allocate_stack(common, stacksize);++    stacksize = 0;+    if (needs_control_head)+      {+      stacksize++;+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);+      }++    if (ket == OP_KETRMIN)+      {+      if (needs_control_head)+        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_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)+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);+    }+  else+    {+    if (ket != OP_KET || has_alternatives)+      stacksize++;++    stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;+    allocate_stack(common, stacksize);++    if (needs_control_head)+      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_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));++    stacksize = needs_control_head ? 1 : 0;+    if (ket != OP_KET || has_alternatives)+      {+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);+      stacksize++;+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);+      }+    else+      {+      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);+    }+  }+else if (opcode == OP_CBRA || opcode == OP_SCBRA)+  {+  /* Saving the previous values. */+  if (common->optimized_cbracket[offset >> 1] != 0)+    {+    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));+    allocate_stack(common, 2);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);+    }+  else+    {+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+    allocate_stack(common, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);+    }+  }+else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)+  {+  /* Saving the previous value. */+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+  allocate_stack(common, 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);+  }+else if (has_alternatives)+  {+  /* Pushing the starting string pointer. */+  allocate_stack(common, 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+  }++/* Generating code for the first alternative. */+if (opcode == OP_COND || opcode == OP_SCOND)+  {+  if (*matchingpath == OP_CREF)+    {+    SLJIT_ASSERT(has_alternatives);+    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),+      CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));+    matchingpath += 1 + IMM2_SIZE;+    }+  else if (*matchingpath == OP_DNCREF)+    {+    SLJIT_ASSERT(has_alternatives);++    i = GET2(matchingpath, 1 + IMM2_SIZE);+    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_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_Z, TMP2, 0, TMP2, 0, STR_PTR, 0);+      slot += common->name_entry_size;+      }+    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);+    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));+    matchingpath += 1 + 2 * IMM2_SIZE;+    }+  else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL)+    {+    /* Never has other case. */+    BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;+    SLJIT_ASSERT(!has_alternatives);++    if (*matchingpath == OP_TRUE)+      {+      stacksize = 1;+      matchingpath++;+      }+    else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL)+      stacksize = 0;+    else if (*matchingpath == OP_RREF)+      {+      stacksize = GET2(matchingpath, 1);+      if (common->currententry == NULL)+        stacksize = 0;+      else if (stacksize == RREF_ANY)+        stacksize = 1;+      else if (common->currententry->start == 0)+        stacksize = stacksize == 0;+      else+        stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);++      if (stacksize != 0)+        matchingpath += 1 + IMM2_SIZE;+      }+    else+      {+      if (common->currententry == NULL || common->currententry->start == 0)+        stacksize = 0;+      else+        {+        stacksize = GET2(matchingpath, 1 + IMM2_SIZE);+        slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;+        i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);+        while (stacksize > 0)+          {+          if ((int)GET2(slot, 0) == i)+            break;+          slot += common->name_entry_size;+          stacksize--;+          }+        }++      if (stacksize != 0)+        matchingpath += 1 + 2 * IMM2_SIZE;+      }++      /* The stacksize == 0 is a common "else" case. */+      if (stacksize == 0)+        {+        if (*cc == OP_ALT)+          {+          matchingpath = cc + 1 + LINK_SIZE;+          cc += GET(cc, 1);+          }+        else+          matchingpath = cc;+        }+    }+  else+    {+    SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);+    /* Similar code as PUSH_BACKTRACK macro. */+    assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));+    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+      return NULL;+    memset(assert, 0, sizeof(assert_backtrack));+    assert->common.cc = matchingpath;+    BACKTRACK_AS(bracket_backtrack)->u.assert = assert;+    matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);+    }+  }++compile_matchingpath(common, matchingpath, cc, backtrack);+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+  return NULL;++if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA)+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);++if (opcode == OP_ONCE)+  match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);++if (opcode == OP_SCRIPT_RUN)+  match_script_run_common(common, private_data_ptr, backtrack);++stacksize = 0;+if (repeat_type == OP_MINUPTO)+  {+  /* We need to preserve the counter. TMP2 will be used below. */+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);+  stacksize++;+  }+if (ket != OP_KET || bra != OP_BRA)+  stacksize++;+if (offset != 0)+  {+  if (common->capture_last_ptr != 0)+    stacksize++;+  if (common->optimized_cbracket[offset >> 1] == 0)+    stacksize += 2;+  }+if (has_alternatives && opcode != OP_ONCE)+  stacksize++;++if (stacksize > 0)+  allocate_stack(common, stacksize);++stacksize = 0;+if (repeat_type == OP_MINUPTO)+  {+  /* TMP2 was set above. */+  OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);+  stacksize++;+  }++if (ket != OP_KET || bra != OP_BRA)+  {+  if (ket != OP_KET)+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);+  else+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);+  stacksize++;+  }++if (offset != 0)+  stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);++/* Skip and count the other alternatives. */+i = 1;+while (*cc == OP_ALT)+  {+  cc += GET(cc, 1);+  i++;+  }++if (has_alternatives)+  {+  if (opcode != OP_ONCE)+    {+    if (i <= 3)+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);+    else+      BACKTRACK_AS(bracket_backtrack)->u.matching_put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));+    }+  if (ket != OP_KETRMAX)+    BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();+  }++/* Must be after the matchingpath label. */+if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)+  {+  SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);+  }++if (ket == OP_KETRMAX)+  {+  if (repeat_type != 0)+    {+    if (has_alternatives)+      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();+    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)+      free_stack(common, 1);+    }+  else if (opcode < OP_BRA || opcode >= OP_SBRA)+    {+    if (has_alternatives)+      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();++    /* Checking zero-length iteration. */+    if (opcode != OP_ONCE)+      {+      /* This case includes opcodes such as OP_SCRIPT_RUN. */+      CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);+      /* Drop STR_PTR for greedy plus quantifier. */+      if (bra != OP_BRAZERO)+        free_stack(common, 1);+      }+    else+      /* TMP2 must contain the starting STR_PTR. */+      CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);+    }+  else+    JUMPTO(SLJIT_JUMP, rmax_label);+  BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();+  }++if (repeat_type == OP_EXACT)+  {+  count_match(common);+  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)+  {+  /* We need to preserve the counter. */+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);+  allocate_stack(common, 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);+  }++if (bra == OP_BRAZERO)+  BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();++if (bra == OP_BRAMINZERO)+  {+  /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */+  JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);+  if (braminzero != NULL)+    {+    JUMPHERE(braminzero);+    /* We need to release the end pointer to perform the+    backtrack for the zero-length iteration. When+    framesize is < 0, OP_ONCE will do the release itself. */+    if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)+      {+      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);+    }+  /* Continue to the normal backtrack. */+  }++if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)+  count_match(common);++cc += 1 + LINK_SIZE;++if (opcode == OP_ONCE)+  {+  /* We temporarily encode the needs_control_head in the lowest bit.+     Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns+     the same value for small signed numbers (including negative numbers). */+  BACKTRACK_AS(bracket_backtrack)->u.framesize = (int)((unsigned)BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);+  }+return cc + repeat_length;+}++static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+PCRE2_UCHAR opcode;+int private_data_ptr;+int cbraprivptr = 0;+BOOL needs_control_head;+int framesize;+int stacksize;+int offset = 0;+BOOL zero = FALSE;+PCRE2_SPTR ccbegin = NULL;+int stack; /* Also contains the offset of control head. */+struct sljit_label *loop = NULL;+struct jump_list *emptymatch = NULL;++PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);+if (*cc == OP_BRAPOSZERO)+  {+  zero = TRUE;+  cc++;+  }++opcode = *cc;+private_data_ptr = PRIVATE_DATA(cc);+SLJIT_ASSERT(private_data_ptr != 0);+BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;+switch(opcode)+  {+  case OP_BRAPOS:+  case OP_SBRAPOS:+  ccbegin = cc + 1 + LINK_SIZE;+  break;++  case OP_CBRAPOS:+  case OP_SCBRAPOS:+  offset = GET2(cc, 1 + LINK_SIZE);+  /* This case cannot be optimized in the same was as+  normal capturing brackets. */+  SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);+  cbraprivptr = OVECTOR_PRIV(offset);+  offset <<= 1;+  ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;+  break;++  default:+  SLJIT_UNREACHABLE();+  break;+  }++framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);+BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;+if (framesize < 0)+  {+  if (offset != 0)+    {+    stacksize = 2;+    if (common->capture_last_ptr != 0)+      stacksize++;+    }+  else+    stacksize = 1;++  if (needs_control_head)+    stacksize++;+  if (!zero)+    stacksize++;++  BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;+  allocate_stack(common, stacksize);+  if (framesize == no_frame)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);++  stack = 0;+  if (offset != 0)+    {+    stack = 2;+    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), STACK(0), TMP1, 0);+    if (common->capture_last_ptr != 0)+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);+    if (needs_control_head)+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);+    if (common->capture_last_ptr != 0)+      {+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);+      stack = 3;+      }+    }+  else+    {+    if (needs_control_head)+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+    stack = 1;+    }++  if (needs_control_head)+    stack++;+  if (!zero)+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);+  if (needs_control_head)+    {+    stack--;+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);+    }+  }+else+  {+  stacksize = framesize + 1;+  if (!zero)+    stacksize++;+  if (needs_control_head)+    stacksize++;+  if (offset == 0)+    stacksize++;+  BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;++  allocate_stack(common, stacksize);+  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_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));++  stack = 0;+  if (!zero)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);+    stack = 1;+    }+  if (needs_control_head)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);+    stack++;+    }+  if (offset == 0)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);+    stack++;+    }+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);+  init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize);+  stack -= 1 + (offset == 0);+  }++if (offset != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);++loop = LABEL();+while (*cc != OP_KETRPOS)+  {+  backtrack->top = NULL;+  backtrack->topbacktracks = NULL;+  cc += GET(cc, 1);++  compile_matchingpath(common, ccbegin, cc, backtrack);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    return NULL;++  if (framesize < 0)+    {+    if (framesize == no_frame)+      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);++    if (offset != 0)+      {+      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);+      if (common->capture_last_ptr != 0)+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+      }+    else+      {+      if (opcode == OP_SBRAPOS)+        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+      }++    /* Even if the match is empty, we need to reset the control head. */+    if (needs_control_head)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));++    if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)+      add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));++    if (!zero)+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);+    }+  else+    {+    if (offset != 0)+      {+      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);+      if (common->capture_last_ptr != 0)+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+      }+    else+      {+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+      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), 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. */+    if (needs_control_head)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));++    if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)+      add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));++    if (!zero)+      {+      if (framesize < 0)+        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);+      else+        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+      }+    }++  JUMPTO(SLJIT_JUMP, loop);+  flush_stubs(common);++  compile_backtrackingpath(common, backtrack->top);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    return NULL;+  set_jumps(backtrack->topbacktracks, LABEL());++  if (framesize < 0)+    {+    if (offset != 0)+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);+    else+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    }+  else+    {+    if (offset != 0)+      {+      /* Last alternative. */+      if (*cc == OP_KETRPOS)+        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);+      }+    else+      {+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));+      }+    }++  if (*cc == OP_KETRPOS)+    break;+  ccbegin = cc + 1 + LINK_SIZE;+  }++/* We don't have to restore the control head in case of a failed match. */++backtrack->topbacktracks = NULL;+if (!zero)+  {+  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), STACK(-stacksize), SLJIT_IMM, 0));+  }++/* None of them matched. */+set_jumps(emptymatch, LABEL());+count_match(common);+return cc + 1 + LINK_SIZE;+}++static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_u32 *max, sljit_u32 *exact, PCRE2_SPTR *end)+{+int class_len;++*opcode = *cc;+*exact = 0;++if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)+  {+  cc++;+  *type = OP_CHAR;+  }+else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)+  {+  cc++;+  *type = OP_CHARI;+  *opcode -= OP_STARI - OP_STAR;+  }+else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)+  {+  cc++;+  *type = OP_NOT;+  *opcode -= OP_NOTSTAR - OP_STAR;+  }+else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)+  {+  cc++;+  *type = OP_NOTI;+  *opcode -= OP_NOTSTARI - OP_STAR;+  }+else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)+  {+  cc++;+  *opcode -= OP_TYPESTAR - OP_STAR;+  *type = OP_END;+  }+else+  {+  SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);+  *type = *opcode;+  cc++;+  class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0);+  *opcode = cc[class_len - 1];++  if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)+    {+    *opcode -= OP_CRSTAR - OP_STAR;+    *end = cc + class_len;++    if (*opcode == OP_PLUS || *opcode == OP_MINPLUS)+      {+      *exact = 1;+      *opcode -= OP_PLUS - OP_STAR;+      }+    }+  else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)+    {+    *opcode -= OP_CRPOSSTAR - OP_POSSTAR;+    *end = cc + class_len;++    if (*opcode == OP_POSPLUS)+      {+      *exact = 1;+      *opcode = OP_POSSTAR;+      }+    }+  else+    {+    SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);+    *max = GET2(cc, (class_len + IMM2_SIZE));+    *exact = GET2(cc, class_len);++    if (*max == 0)+      {+      if (*opcode == OP_CRPOSRANGE)+        *opcode = OP_POSSTAR;+      else+        *opcode -= OP_CRRANGE - OP_STAR;+      }+    else+      {+      *max -= *exact;+      if (*max == 0)+        *opcode = OP_EXACT;+      else if (*max == 1)+        {+        if (*opcode == OP_CRPOSRANGE)+          *opcode = OP_POSQUERY;+        else+          *opcode -= OP_CRRANGE - OP_QUERY;+        }+      else+        {+        if (*opcode == OP_CRPOSRANGE)+          *opcode = OP_POSUPTO;+        else+          *opcode -= OP_CRRANGE - OP_UPTO;+        }+      }+    *end = cc + class_len + 2 * IMM2_SIZE;+    }+  return cc;+  }++switch(*opcode)+  {+  case OP_EXACT:+  *exact = GET2(cc, 0);+  cc += IMM2_SIZE;+  break;++  case OP_PLUS:+  case OP_MINPLUS:+  *exact = 1;+  *opcode -= OP_PLUS - OP_STAR;+  break;++  case OP_POSPLUS:+  *exact = 1;+  *opcode = OP_POSSTAR;+  break;++  case OP_UPTO:+  case OP_MINUPTO:+  case OP_POSUPTO:+  *max = GET2(cc, 0);+  cc += IMM2_SIZE;+  break;+  }++if (*type == OP_END)+  {+  *type = *cc;+  *end = next_opcode(common, cc);+  cc++;+  return cc;+  }++*end = cc + 1;+#ifdef SUPPORT_UNICODE+if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);+#endif+return cc;+}++static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+PCRE2_UCHAR opcode;+PCRE2_UCHAR type;+sljit_u32 max = 0, exact;+sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1);+sljit_s32 early_fail_type;+BOOL charpos_enabled;+PCRE2_UCHAR charpos_char;+unsigned int charpos_othercasebit;+PCRE2_SPTR end;+jump_list *no_match = NULL;+jump_list *no_char1_match = NULL;+struct sljit_jump *jump = NULL;+struct sljit_label *label;+int private_data_ptr = PRIVATE_DATA(cc);+int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);+int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;+int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);+int tmp_base, tmp_offset;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+BOOL use_tmp;+#endif++PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL);++early_fail_type = (early_fail_ptr & 0x7);+early_fail_ptr >>= 3;++/* During recursion, these optimizations are disabled. */+if (common->early_fail_start_ptr == 0)+  {+  early_fail_ptr = 0;+  early_fail_type = type_skip;+  }++SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0+  || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr));++if (early_fail_type == type_fail)+  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr));++cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);++if (type != OP_EXTUNI)+  {+  tmp_base = TMP3;+  tmp_offset = 0;+  }+else+  {+  tmp_base = SLJIT_MEM1(SLJIT_SP);+  tmp_offset = POSSESSIVE0;+  }++/* Handle fixed part first. */+if (exact > 1)+  {+  SLJIT_ASSERT(early_fail_ptr == 0);++  if (common->mode == PCRE2_JIT_COMPLETE+#ifdef SUPPORT_UNICODE+      && !common->utf+#endif+      && type != OP_ANYNL && type != OP_EXTUNI)+    {+    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));+    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0));+    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);+    label = LABEL();+    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);+    OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+    JUMPTO(SLJIT_NOT_ZERO, label);+    }+  else+    {+    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_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+    JUMPTO(SLJIT_NOT_ZERO, label);+    }+  }+else if (exact == 1)+  {+  compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);++  if (early_fail_type == type_fail_range)+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw));+    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);+    OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);+    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0));++    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw), STR_PTR, 0);+    }+  }++switch(opcode)+  {+  case OP_STAR:+  case OP_UPTO:+  SLJIT_ASSERT(early_fail_ptr == 0 || opcode == OP_STAR);++  if (type == OP_ANYNL || type == OP_EXTUNI)+    {+    SLJIT_ASSERT(private_data_ptr == 0);+    SLJIT_ASSERT(early_fail_ptr == 0);++    allocate_stack(common, 2);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);++    if (opcode == OP_UPTO)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max);++    label = LABEL();+    compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);+    if (opcode == OP_UPTO)+      {+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);+      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);+      }++    /* We cannot use TMP3 because of allocate_stack. */+    allocate_stack(common, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+    JUMPTO(SLJIT_JUMP, label);+    if (jump != NULL)+      JUMPHERE(jump);+    BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+    break;+    }+#ifdef SUPPORT_UNICODE+  else if (type == OP_ALLANY && !common->invalid_utf)+#else+  else if (type == OP_ALLANY)+#endif+    {+    if (opcode == OP_STAR)+      {+      if (private_data_ptr == 0)+        allocate_stack(common, 2);++      OP1(SLJIT_MOV, base, offset0, STR_END, 0);+      OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);++      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);+      process_partial_match(common);++      if (early_fail_ptr != 0)+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);+      BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+      break;+      }+#ifdef SUPPORT_UNICODE+    else if (!common->utf)+#else+    else+#endif+      {+      if (private_data_ptr == 0)+        allocate_stack(common, 2);++      OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);+      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));++      if (common->mode == PCRE2_JIT_COMPLETE)+        {+        OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);+        CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);+        }+      else+        {+        jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);+        process_partial_match(common);+        JUMPHERE(jump);+        }++      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);++      if (early_fail_ptr != 0)+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+      BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+      break;+      }+    }++  charpos_enabled = FALSE;+  charpos_char = 0;+  charpos_othercasebit = 0;++  if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))+    {+#ifdef SUPPORT_UNICODE+    charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);+#else+    charpos_enabled = TRUE;+#endif+    if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))+      {+      charpos_othercasebit = char_get_othercase_bit(common, end + 1);+      if (charpos_othercasebit == 0)+        charpos_enabled = FALSE;+      }++    if (charpos_enabled)+      {+      charpos_char = end[1];+      /* Consume the OP_CHAR opcode. */+      end += 2;+#if PCRE2_CODE_UNIT_WIDTH == 8+      SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32+      SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);+      if ((charpos_othercasebit & 0x100) != 0)+        charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;+#endif+      if (charpos_othercasebit != 0)+        charpos_char |= charpos_othercasebit;++      BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;+      BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;+      BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;+      }+    }++  if (charpos_enabled)+    {+    if (opcode == OP_UPTO)+      OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);++    /* Search the first instance of charpos_char. */+    jump = JUMP(SLJIT_JUMP);+    label = LABEL();+    if (opcode == OP_UPTO)+      {+      OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));+      }+    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);+    if (early_fail_ptr != 0)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+    JUMPHERE(jump);++    detect_partial_match(common, &backtrack->topbacktracks);+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    if (charpos_othercasebit != 0)+      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);++    if (private_data_ptr == 0)+      allocate_stack(common, 2);+    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+    OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);++    if (opcode == OP_UPTO)+      {+      OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+      add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));+      }++    /* Search the last instance of charpos_char. */+    label = LABEL();+    compile_char1_matchingpath(common, type, cc, &no_match, FALSE);+    if (early_fail_ptr != 0)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+    detect_partial_match(common, &no_match);+    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));+    if (charpos_othercasebit != 0)+      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);++    if (opcode == OP_STAR)+      {+      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);+      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+      JUMPTO(SLJIT_JUMP, label);+      }+    else+      {+      jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);+      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+      JUMPHERE(jump);+      OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+      JUMPTO(SLJIT_NOT_ZERO, label);+      }++    set_jumps(no_match, LABEL());+    OP2(SLJIT_ADD, STR_PTR, 0, base, offset0, SLJIT_IMM, IN_UCHARS(1));+    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+    }+  else+    {+    if (private_data_ptr == 0)+      allocate_stack(common, 2);++    OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR);+    SLJIT_ASSERT(!use_tmp || tmp_base == TMP3);++    if (common->utf)+      OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);+#endif+    if (opcode == OP_UPTO)+      OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);++    detect_partial_match(common, &no_match);+    label = LABEL();+    compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf)+      OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);+#endif++    if (opcode == OP_UPTO)+      {+      OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+      add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));+      }++    detect_partial_match_to(common, label);+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++    set_jumps(no_char1_match, LABEL());+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf)+      {+      set_jumps(no_match, LABEL());+      if (use_tmp)+        {+        OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);+        OP1(SLJIT_MOV, base, offset0, TMP3, 0);+        }+      else+        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+      }+    else+#endif+      {+      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+      set_jumps(no_match, LABEL());+      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+      }++    if (early_fail_ptr != 0)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+    }++  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+  break;++  case OP_MINSTAR:+  if (private_data_ptr == 0)+    allocate_stack(common, 1);+  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+  if (early_fail_ptr != 0)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+  break;++  case OP_MINUPTO:+  SLJIT_ASSERT(early_fail_ptr == 0);+  if (private_data_ptr == 0)+    allocate_stack(common, 2);+  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+  OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1);+  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+  break;++  case OP_QUERY:+  case OP_MINQUERY:+  SLJIT_ASSERT(early_fail_ptr == 0);+  if (private_data_ptr == 0)+    allocate_stack(common, 1);+  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+  if (opcode == OP_QUERY)+    compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);+  BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();+  break;++  case OP_EXACT:+  break;++  case OP_POSSTAR:+#if defined SUPPORT_UNICODE+  if (type == OP_ALLANY && !common->invalid_utf)+#else+  if (type == OP_ALLANY)+#endif+    {+    OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);+    process_partial_match(common);+    if (early_fail_ptr != 0)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);+    break;+    }++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+  if (common->utf)+    {+    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);+    detect_partial_match(common, &no_match);+    label = LABEL();+    compile_char1_matchingpath(common, type, cc, &no_match, FALSE);+    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);+    detect_partial_match_to(common, label);++    set_jumps(no_match, LABEL());+    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);+    if (early_fail_ptr != 0)+      {+      if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3)+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, TMP3, 0);+      else+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+      }+    break;+    }+#endif++  detect_partial_match(common, &no_match);+  label = LABEL();+  compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);+  detect_partial_match_to(common, label);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++  set_jumps(no_char1_match, LABEL());+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  set_jumps(no_match, LABEL());+  if (early_fail_ptr != 0)+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);+  break;++  case OP_POSUPTO:+  SLJIT_ASSERT(early_fail_ptr == 0);+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+  if (common->utf)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);+    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);++    detect_partial_match(common, &no_match);+    label = LABEL();+    compile_char1_matchingpath(common, type, cc, &no_match, FALSE);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);+    OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+    add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));+    detect_partial_match_to(common, label);++    set_jumps(no_match, LABEL());+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);+    break;+    }+#endif++  if (type == OP_ALLANY)+    {+    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));++    if (common->mode == PCRE2_JIT_COMPLETE)+      {+      OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);+      CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);+      }+    else+      {+      jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);+      process_partial_match(common);+      JUMPHERE(jump);+      }+    break;+    }++  OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);++  detect_partial_match(common, &no_match);+  label = LABEL();+  compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);+  OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);+  add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));+  detect_partial_match_to(common, label);+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++  set_jumps(no_char1_match, LABEL());+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));+  set_jumps(no_match, LABEL());+  break;++  case OP_POSQUERY:+  SLJIT_ASSERT(early_fail_ptr == 0);+  OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);+  compile_char1_matchingpath(common, type, cc, &no_match, TRUE);+  OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);+  set_jumps(no_match, LABEL());+  OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);+  break;++  default:+  SLJIT_UNREACHABLE();+  break;+  }++count_match(common);+return end;+}++static SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;++PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);++if (*cc == OP_FAIL)+  {+  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));+  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. */+  if (common->accept_label == NULL)+    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));+  else+    JUMPTO(SLJIT_JUMP, common->accept_label);+  return cc + 1;+  }++if (common->accept_label == NULL)+  add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));+else+  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);++if (HAS_VIRTUAL_REGISTERS)+  {+  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+  OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));+  }+else+  OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options));++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_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+  JUMPTO(SLJIT_ZERO, common->accept_label);++OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));+if (common->accept_label == NULL)+  add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));+else+  CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));+return cc + 1;+}++static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc)+{+DEFINE_COMPILER;+int offset = GET2(cc, 1);+BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;++/* Data will be discarded anyway... */+if (common->currententry != NULL)+  return cc + 1 + IMM2_SIZE;++if (!optimized_cbracket)+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));+offset <<= 1;+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);+if (!optimized_cbracket)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+return cc + 1 + IMM2_SIZE;+}++static SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+PCRE2_UCHAR opcode = *cc;+PCRE2_SPTR ccend = cc + 1;++if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG ||+    opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)+  ccend += 2 + cc[1];++PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);++if (opcode == OP_SKIP)+  {+  allocate_stack(common, 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+  return ccend;+  }++if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)+  {+  if (HAS_VIRTUAL_REGISTERS)+    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);+  OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);+  }++return ccend;+}++static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP };++static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+BOOL needs_control_head;+int size;++PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);+common->then_trap = BACKTRACK_AS(then_trap_backtrack);+BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;+BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);+BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);++size = BACKTRACK_AS(then_trap_backtrack)->framesize;+size = 3 + (size < 0 ? 0 : size);++OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);+allocate_stack(common, size);+if (size > 3)+  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);+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);++size = BACKTRACK_AS(then_trap_backtrack)->framesize;+if (size >= 0)+  init_frame(common, cc, ccend, size - 1, 0);+}++static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)+{+DEFINE_COMPILER;+backtrack_common *backtrack;+BOOL has_then_trap = FALSE;+then_trap_backtrack *save_then_trap = NULL;++SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));++if (common->has_then && common->then_offsets[cc - common->start] != 0)+  {+  SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);+  has_then_trap = TRUE;+  save_then_trap = common->then_trap;+  /* Tail item on backtrack. */+  compile_then_trap_matchingpath(common, cc, ccend, parent);+  }++while (cc < ccend)+  {+  switch(*cc)+    {+    case OP_SOD:+    case OP_SOM:+    case OP_NOT_WORD_BOUNDARY:+    case OP_WORD_BOUNDARY:+    case OP_EODN:+    case OP_EOD:+    case OP_DOLL:+    case OP_DOLLM:+    case OP_CIRC:+    case OP_CIRCM:+    case OP_REVERSE:+    cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);+    break;++    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:+    case OP_ANYBYTE:+    case OP_NOTPROP:+    case OP_PROP:+    case OP_ANYNL:+    case OP_NOT_HSPACE:+    case OP_HSPACE:+    case OP_NOT_VSPACE:+    case OP_VSPACE:+    case OP_EXTUNI:+    case OP_NOT:+    case OP_NOTI:+    cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);+    break;++    case OP_SET_SOM:+    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));+    allocate_stack(common, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);+    cc++;+    break;++    case OP_CHAR:+    case OP_CHARI:+    if (common->mode == PCRE2_JIT_COMPLETE)+      cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);+    else+      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);+    break;++    case OP_STAR:+    case OP_MINSTAR:+    case OP_PLUS:+    case OP_MINPLUS:+    case OP_QUERY:+    case OP_MINQUERY:+    case OP_UPTO:+    case OP_MINUPTO:+    case OP_EXACT:+    case OP_POSSTAR:+    case OP_POSPLUS:+    case OP_POSQUERY:+    case OP_POSUPTO:+    case OP_STARI:+    case OP_MINSTARI:+    case OP_PLUSI:+    case OP_MINPLUSI:+    case OP_QUERYI:+    case OP_MINQUERYI:+    case OP_UPTOI:+    case OP_MINUPTOI:+    case OP_EXACTI:+    case OP_POSSTARI:+    case OP_POSPLUSI:+    case OP_POSQUERYI:+    case OP_POSUPTOI:+    case OP_NOTSTAR:+    case OP_NOTMINSTAR:+    case OP_NOTPLUS:+    case OP_NOTMINPLUS:+    case OP_NOTQUERY:+    case OP_NOTMINQUERY:+    case OP_NOTUPTO:+    case OP_NOTMINUPTO:+    case OP_NOTEXACT:+    case OP_NOTPOSSTAR:+    case OP_NOTPOSPLUS:+    case OP_NOTPOSQUERY:+    case OP_NOTPOSUPTO:+    case OP_NOTSTARI:+    case OP_NOTMINSTARI:+    case OP_NOTPLUSI:+    case OP_NOTMINPLUSI:+    case OP_NOTQUERYI:+    case OP_NOTMINQUERYI:+    case OP_NOTUPTOI:+    case OP_NOTMINUPTOI:+    case OP_NOTEXACTI:+    case OP_NOTPOSSTARI:+    case OP_NOTPOSPLUSI:+    case OP_NOTPOSQUERYI:+    case OP_NOTPOSUPTOI:+    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    case OP_TYPEEXACT:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPOSPLUS:+    case OP_TYPEPOSQUERY:+    case OP_TYPEPOSUPTO:+    cc = compile_iterator_matchingpath(common, cc, parent);+    break;++    case OP_CLASS:+    case OP_NCLASS:+    if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE)+      cc = compile_iterator_matchingpath(common, cc, parent);+    else+      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);+    break;++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32+    case OP_XCLASS:+    if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)+      cc = compile_iterator_matchingpath(common, cc, parent);+    else+      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);+    break;+#endif++    case OP_REF:+    case OP_REFI:+    if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)+      cc = compile_ref_iterator_matchingpath(common, cc, parent);+    else+      {+      compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);+      cc += 1 + IMM2_SIZE;+      }+    break;++    case OP_DNREF:+    case OP_DNREFI:+    if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)+      cc = compile_ref_iterator_matchingpath(common, cc, parent);+    else+      {+      compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);+      compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);+      cc += 1 + 2 * IMM2_SIZE;+      }+    break;++    case OP_RECURSE:+    cc = compile_recurse_matchingpath(common, cc, parent);+    break;++    case OP_CALLOUT:+    case OP_CALLOUT_STR:+    cc = compile_callout_matchingpath(common, cc, parent);+    break;++    case OP_ASSERT:+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);+    cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);+    break;++    case OP_BRAMINZERO:+    PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);+    cc = bracketend(cc + 1);+    if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)+      {+      allocate_stack(common, 1);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);+      }+    else+      {+      allocate_stack(common, 2);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);+      }+    BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();+    count_match(common);+    break;++    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    case OP_ONCE:+    case OP_SCRIPT_RUN:+    case OP_BRA:+    case OP_CBRA:+    case OP_COND:+    case OP_SBRA:+    case OP_SCBRA:+    case OP_SCOND:+    cc = compile_bracket_matchingpath(common, cc, parent);+    break;++    case OP_BRAZERO:+    if (cc[1] > OP_ASSERTBACK_NOT)+      cc = compile_bracket_matchingpath(common, cc, parent);+    else+      {+      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);+      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);+      }+    break;++    case OP_BRAPOS:+    case OP_CBRAPOS:+    case OP_SBRAPOS:+    case OP_SCBRAPOS:+    case OP_BRAPOSZERO:+    cc = compile_bracketpos_matchingpath(common, cc, parent);+    break;++    case OP_MARK:+    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);+    SLJIT_ASSERT(common->mark_ptr != 0);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);+    allocate_stack(common, common->has_skip_arg ? 5 : 1);+    if (HAS_VIRTUAL_REGISTERS)+      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);+    if (common->has_skip_arg)+      {+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);+      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);+      }+    cc += 1 + 2 + cc[1];+    break;++    case OP_PRUNE:+    case OP_PRUNE_ARG:+    case OP_SKIP:+    case OP_SKIP_ARG:+    case OP_THEN:+    case OP_THEN_ARG:+    case OP_COMMIT:+    case OP_COMMIT_ARG:+    cc = compile_control_verb_matchingpath(common, cc, parent);+    break;++    case OP_FAIL:+    case OP_ACCEPT:+    case OP_ASSERT_ACCEPT:+    cc = compile_fail_accept_matchingpath(common, cc, parent);+    break;++    case OP_CLOSE:+    cc = compile_close_matchingpath(common, cc);+    break;++    case OP_SKIPZERO:+    cc = bracketend(cc + 1);+    break;++    default:+    SLJIT_UNREACHABLE();+    return;+    }+  if (cc == NULL)+    return;+  }++if (has_then_trap)+  {+  /* Head item on backtrack. */+  PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);+  BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;+  BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;+  common->then_trap = save_then_trap;+  }+SLJIT_ASSERT(cc == ccend);+}++#undef PUSH_BACKTRACK+#undef PUSH_BACKTRACK_NOVALUE+#undef BACKTRACK_AS++#define COMPILE_BACKTRACKINGPATH(current) \+  do \+    { \+    compile_backtrackingpath(common, (current)); \+    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \+      return; \+    } \+  while (0)++#define CURRENT_AS(type) ((type *)current)++static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+PCRE2_SPTR cc = current->cc;+PCRE2_UCHAR opcode;+PCRE2_UCHAR type;+sljit_u32 max = 0, exact;+struct sljit_label *label = NULL;+struct sljit_jump *jump = NULL;+jump_list *jumplist = NULL;+PCRE2_SPTR end;+int private_data_ptr = PRIVATE_DATA(cc);+int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);+int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;+int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);++cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);++switch(opcode)+  {+  case OP_STAR:+  case OP_UPTO:+  if (type == OP_ANYNL || type == OP_EXTUNI)+    {+    SLJIT_ASSERT(private_data_ptr == 0);+    set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    free_stack(common, 1);+    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);+    }+  else+    {+    if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled)+      {+      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+      OP1(SLJIT_MOV, TMP2, 0, base, offset1);+      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));++      jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);+      label = LABEL();+      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));+      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+      if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0)+        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit);+      CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);+      move_back(common, NULL, TRUE);+      CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label);+      }+    else+      {+      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+      jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);+      move_back(common, NULL, TRUE);+      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+      JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);+      }+    JUMPHERE(jump);+    if (private_data_ptr == 0)+      free_stack(common, 2);+    }+  break;++  case OP_MINSTAR:+  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+  compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);+  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+  JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);+  set_jumps(jumplist, LABEL());+  if (private_data_ptr == 0)+    free_stack(common, 1);+  break;++  case OP_MINUPTO:+  OP1(SLJIT_MOV, TMP1, 0, base, offset1);+  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+  OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);+  add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO));++  OP1(SLJIT_MOV, base, offset1, TMP1, 0);+  compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);+  OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);+  JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);++  set_jumps(jumplist, LABEL());+  if (private_data_ptr == 0)+    free_stack(common, 2);+  break;++  case OP_QUERY:+  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+  OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);+  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);+  jump = JUMP(SLJIT_JUMP);+  set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());+  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+  OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);+  JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);+  JUMPHERE(jump);+  if (private_data_ptr == 0)+    free_stack(common, 1);+  break;++  case OP_MINQUERY:+  OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);+  OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);+  jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);+  compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);+  JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);+  set_jumps(jumplist, LABEL());+  JUMPHERE(jump);+  if (private_data_ptr == 0)+    free_stack(common, 1);+  break;++  case OP_EXACT:+  case OP_POSSTAR:+  case OP_POSQUERY:+  case OP_POSUPTO:+  break;++  default:+  SLJIT_UNREACHABLE();+  break;+  }++set_jumps(current->topbacktracks, LABEL());+}++static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+PCRE2_SPTR cc = current->cc;+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);+PCRE2_UCHAR type;++type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];++if ((type & 0x1) == 0)+  {+  /* Maximize case. */+  set_jumps(current->topbacktracks, LABEL());+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  free_stack(common, 1);+  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);+  return;+  }++OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);+set_jumps(current->topbacktracks, LABEL());+free_stack(common, ref ? 2 : 3);+}++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)+  {+  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());+}++static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+PCRE2_SPTR cc = current->cc;+PCRE2_UCHAR bra = OP_BRA;+struct sljit_jump *brajump = NULL;++SLJIT_ASSERT(*cc != OP_BRAMINZERO);+if (*cc == OP_BRAZERO)+  {+  bra = *cc;+  cc++;+  }++if (bra == OP_BRAZERO)+  {+  SLJIT_ASSERT(current->topbacktracks == NULL);+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  }++if (CURRENT_AS(assert_backtrack)->framesize < 0)+  {+  set_jumps(current->topbacktracks, LABEL());++  if (bra == OP_BRAZERO)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);+    free_stack(common, 1);+    }+  return;+  }++if (bra == OP_BRAZERO)+  {+  if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)+    {+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);+    CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);+    free_stack(common, 1);+    return;+    }+  free_stack(common, 1);+  brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);+  }++if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)+  {+  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, 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());+  }+else+  set_jumps(current->topbacktracks, LABEL());++if (bra == OP_BRAZERO)+  {+  /* We know there is enough place on the stack. */+  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);+  }+}++static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+int opcode, stacksize, alt_count, alt_max;+int offset = 0;+int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;+int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;+PCRE2_SPTR cc = current->cc;+PCRE2_SPTR ccbegin;+PCRE2_SPTR ccprev;+PCRE2_UCHAR bra = OP_BRA;+PCRE2_UCHAR ket;+assert_backtrack *assert;+BOOL has_alternatives;+BOOL needs_control_head = FALSE;+struct sljit_jump *brazero = NULL;+struct sljit_jump *next_alt = NULL;+struct sljit_jump *once = NULL;+struct sljit_jump *cond = NULL;+struct sljit_label *rmin_label = NULL;+struct sljit_label *exact_label = NULL;+struct sljit_put_label *put_label = NULL;++if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)+  {+  bra = *cc;+  cc++;+  }++opcode = *cc;+ccbegin = bracketend(cc) - 1 - LINK_SIZE;+ket = *ccbegin;+if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)+  {+  repeat_ptr = PRIVATE_DATA(ccbegin);+  repeat_type = PRIVATE_DATA(ccbegin + 2);+  repeat_count = PRIVATE_DATA(ccbegin + 3);+  SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);+  if (repeat_type == OP_UPTO)+    ket = OP_KETRMAX;+  if (repeat_type == OP_MINUPTO)+    ket = OP_KETRMIN;+  }+ccbegin = cc;+cc += GET(cc, 1);+has_alternatives = *cc == OP_ALT;+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))+  has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;+if (opcode == OP_CBRA || opcode == OP_SCBRA)+  offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))+  opcode = OP_SCOND;++alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;++/* Decoding the needs_control_head in framesize. */+if (opcode == OP_ONCE)+  {+  needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;+  CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;+  }++if (ket != OP_KET && repeat_type != 0)+  {+  /* TMP1 is used in OP_KETRMIN below. */+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  free_stack(common, 1);+  if (repeat_type == OP_UPTO)+    OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);+  else+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);+  }++if (ket == OP_KETRMAX)+  {+  if (bra == OP_BRAZERO)+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    free_stack(common, 1);+    brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);+    }+  }+else if (ket == OP_KETRMIN)+  {+  if (bra != OP_BRAMINZERO)+    {+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    if (repeat_type != 0)+      {+      /* TMP1 was set a few lines above. */+      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);+      /* Drop STR_PTR for non-greedy plus quantifier. */+      if (opcode != OP_ONCE)+        free_stack(common, 1);+      }+    else if (opcode >= OP_SBRA || opcode == OP_ONCE)+      {+      /* Checking zero-length iteration. */+      if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)+        CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);+      else+        {+        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+        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)+        free_stack(common, 1);+      }+    else+      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);+    }+  rmin_label = LABEL();+  if (repeat_type != 0)+    OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);+  }+else if (bra == OP_BRAZERO)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  free_stack(common, 1);+  brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);+  }+else if (repeat_type == OP_EXACT)+  {+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);+  exact_label = LABEL();+  }++if (offset != 0)+  {+  if (common->capture_last_ptr != 0)+    {+    SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));+    free_stack(common, 3);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);+    }+  else if (common->optimized_cbracket[offset >> 1] == 0)+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    free_stack(common, 2);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);+    }+  }++if (SLJIT_UNLIKELY(opcode == OP_ONCE))+  {+  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)+    {+    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));+    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw));+    }+  once = JUMP(SLJIT_JUMP);+  }+else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))+  {+  if (has_alternatives)+    {+    /* Always exactly one alternative. */+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    free_stack(common, 1);++    alt_max = 2;+    next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);+    }+  }+else if (has_alternatives)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  free_stack(common, 1);++  if (alt_max > 3)+    {+    sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);++    SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label);+    sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL());+    sljit_emit_op0(compiler, SLJIT_ENDBR);+    }+  else+    next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);+  }++COMPILE_BACKTRACKINGPATH(current->top);+if (current->topbacktracks)+  set_jumps(current->topbacktracks, LABEL());++if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))+  {+  /* Conditional block always has at most one alternative. */+  if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)+    {+    SLJIT_ASSERT(has_alternatives);+    assert = CURRENT_AS(bracket_backtrack)->u.assert;+    if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))+      {+      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);+      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));+      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);+      }+    cond = JUMP(SLJIT_JUMP);+    set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());+    }+  else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)+    {+    SLJIT_ASSERT(has_alternatives);+    cond = JUMP(SLJIT_JUMP);+    set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());+    }+  else+    SLJIT_ASSERT(!has_alternatives);+  }++if (has_alternatives)+  {+  alt_count = 1;+  do+    {+    current->top = NULL;+    current->topbacktracks = NULL;+    current->nextbacktracks = NULL;+    /* Conditional blocks always have an additional alternative, even if it is empty. */+    if (*cc == OP_ALT)+      {+      ccprev = cc + 1 + LINK_SIZE;+      cc += GET(cc, 1);+      if (opcode != OP_COND && opcode != OP_SCOND)+        {+        if (opcode != OP_ONCE)+          {+          if (private_data_ptr != 0)+            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);+          else+            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+          }+        else+          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));+        }+      compile_matchingpath(common, ccprev, cc, current);+      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+        return;++      if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA)+        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);++      if (opcode == OP_SCRIPT_RUN)+        match_script_run_common(common, private_data_ptr, current);+      }++    /* Instructions after the current alternative is successfully matched. */+    /* There is a similar code in compile_bracket_matchingpath. */+    if (opcode == OP_ONCE)+      match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);++    stacksize = 0;+    if (repeat_type == OP_MINUPTO)+      {+      /* We need to preserve the counter. TMP2 will be used below. */+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);+      stacksize++;+      }+    if (ket != OP_KET || bra != OP_BRA)+      stacksize++;+    if (offset != 0)+      {+      if (common->capture_last_ptr != 0)+        stacksize++;+      if (common->optimized_cbracket[offset >> 1] == 0)+        stacksize += 2;+      }+    if (opcode != OP_ONCE)+      stacksize++;++    if (stacksize > 0)+      allocate_stack(common, stacksize);++    stacksize = 0;+    if (repeat_type == OP_MINUPTO)+      {+      /* TMP2 was set above. */+      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);+      stacksize++;+      }++    if (ket != OP_KET || bra != OP_BRA)+      {+      if (ket != OP_KET)+        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);+      else+        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);+      stacksize++;+      }++    if (offset != 0)+      stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);++    if (opcode != OP_ONCE)+      {+      if (alt_max <= 3)+        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);+      else+        put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));+      }++    if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)+      {+      /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */+      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);+      }++    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);++    if (opcode != OP_ONCE)+      {+      if (alt_max <= 3)+        {+        JUMPHERE(next_alt);+        alt_count++;+        if (alt_count < alt_max)+          {+          SLJIT_ASSERT(alt_count == 2 && alt_max == 3);+          next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);+          }+        }+      else+        {+        sljit_set_put_label(put_label, LABEL());+        sljit_emit_op0(compiler, SLJIT_ENDBR);+        }+      }++    COMPILE_BACKTRACKINGPATH(current->top);+    if (current->topbacktracks)+      set_jumps(current->topbacktracks, LABEL());+    SLJIT_ASSERT(!current->nextbacktracks);+    }+  while (*cc == OP_ALT);++  if (cond != NULL)+    {+    SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);+    assert = CURRENT_AS(bracket_backtrack)->u.assert;+    if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)+      {+      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);+      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));+      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);+      }+    JUMPHERE(cond);+    }++  /* Free the STR_PTR. */+  if (private_data_ptr == 0)+    free_stack(common, 1);+  }++if (offset != 0)+  {+  /* Using both tmp register is better for instruction scheduling. */+  if (common->optimized_cbracket[offset >> 1] != 0)+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    free_stack(common, 2);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);+    }+  else+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    free_stack(common, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);+    }+  }+else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)+  {+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));+  free_stack(common, 1);+  }+else if (opcode == OP_ONCE)+  {+  cc = ccbegin + GET(ccbegin, 1);+  stacksize = needs_control_head ? 1 : 0;++  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)+    {+    /* Reset head and drop saved frame. */+    stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);+    }+  else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))+    {+    /* The STR_PTR must be released. */+    stacksize++;+    }++  if (stacksize > 0)+    free_stack(common, stacksize);++  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), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 1));+  else if (ket == OP_KETRMIN)+    {+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    /* See the comment below. */+    free_stack(common, 2);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);+    }+  }++if (repeat_type == OP_EXACT)+  {+  OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);+  CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);+  }+else if (ket == OP_KETRMAX)+  {+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  if (bra != OP_BRAZERO)+    free_stack(common, 1);++  CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);+  if (bra == OP_BRAZERO)+    {+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);+    JUMPHERE(brazero);+    free_stack(common, 1);+    }+  }+else if (ket == OP_KETRMIN)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));++  /* OP_ONCE removes everything in case of a backtrack, so we don't+  need to explicitly release the STR_PTR. The extra release would+  affect badly the free_stack(2) above. */+  if (opcode != OP_ONCE)+    free_stack(common, 1);+  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);+  if (opcode == OP_ONCE)+    free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);+  else if (bra == OP_BRAMINZERO)+    free_stack(common, 1);+  }+else if (bra == OP_BRAZERO)+  {+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+  JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);+  JUMPHERE(brazero);+  }+}++static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+int offset;+struct sljit_jump *jump;++if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)+  {+  if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)+    {+    offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);+    if (common->capture_last_ptr != 0)+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);+    if (common->capture_last_ptr != 0)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);+    }+  set_jumps(current->topbacktracks, LABEL());+  free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);+  return;+  }++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)+  {+  jump = JUMP(SLJIT_JUMP);+  set_jumps(current->topbacktracks, LABEL());+  /* Drop the stack frame. */+  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), STACK(-CURRENT_AS(bracketpos_backtrack)->framesize - 1));+}++static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+assert_backtrack backtrack;++current->top = NULL;+current->topbacktracks = NULL;+current->nextbacktracks = NULL;+if (current->cc[1] > OP_ASSERTBACK_NOT)+  {+  /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */+  compile_bracket_matchingpath(common, current->cc, current);+  compile_bracket_backtrackingpath(common, current->top);+  }+else+  {+  memset(&backtrack, 0, sizeof(backtrack));+  backtrack.common.cc = current->cc;+  backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;+  /* Manual call of compile_assert_matchingpath. */+  compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);+  }+SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);+}++static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+PCRE2_UCHAR opcode = *current->cc;+struct sljit_label *loop;+struct sljit_jump *jump;++if (opcode == OP_THEN || opcode == OP_THEN_ARG)+  {+  if (common->then_trap != NULL)+    {+    SLJIT_ASSERT(common->control_head_ptr != 0);++    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);+    jump = JUMP(SLJIT_JUMP);++    loop = LABEL();+    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    JUMPHERE(jump);+    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->local_quit_available && common->in_positive_assertion)+    {+    add_jump(compiler, &common->positive_assertion_quit, JUMP(SLJIT_JUMP));+    return;+    }+  }++if (common->local_quit_available)+  {+  /* Abort match with a fail. */+  if (common->quit_label == NULL)+    add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));+  else+    JUMPTO(SLJIT_JUMP, common->quit_label);+  return;+  }++if (opcode == OP_SKIP_ARG)+  {+  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_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, SLJIT_R0, 0);+  add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0));+  return;+  }++if (opcode == OP_SKIP)+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+else+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);+add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));+}++static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+struct sljit_jump *jump;+int size;++if (CURRENT_AS(then_trap_backtrack)->then_trap)+  {+  common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;+  return;+  }++size = CURRENT_AS(then_trap_backtrack)->framesize;+size = 3 + (size < 0 ? 0 : size);++OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));+free_stack(common, size);+jump = JUMP(SLJIT_JUMP);++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);++JUMPHERE(jump);+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);+}++static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)+{+DEFINE_COMPILER;+then_trap_backtrack *save_then_trap = common->then_trap;++while (current)+  {+  if (current->nextbacktracks != NULL)+    set_jumps(current->nextbacktracks, LABEL());+  switch(*current->cc)+    {+    case OP_SET_SOM:+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    free_stack(common, 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);+    break;++    case OP_STAR:+    case OP_MINSTAR:+    case OP_PLUS:+    case OP_MINPLUS:+    case OP_QUERY:+    case OP_MINQUERY:+    case OP_UPTO:+    case OP_MINUPTO:+    case OP_EXACT:+    case OP_POSSTAR:+    case OP_POSPLUS:+    case OP_POSQUERY:+    case OP_POSUPTO:+    case OP_STARI:+    case OP_MINSTARI:+    case OP_PLUSI:+    case OP_MINPLUSI:+    case OP_QUERYI:+    case OP_MINQUERYI:+    case OP_UPTOI:+    case OP_MINUPTOI:+    case OP_EXACTI:+    case OP_POSSTARI:+    case OP_POSPLUSI:+    case OP_POSQUERYI:+    case OP_POSUPTOI:+    case OP_NOTSTAR:+    case OP_NOTMINSTAR:+    case OP_NOTPLUS:+    case OP_NOTMINPLUS:+    case OP_NOTQUERY:+    case OP_NOTMINQUERY:+    case OP_NOTUPTO:+    case OP_NOTMINUPTO:+    case OP_NOTEXACT:+    case OP_NOTPOSSTAR:+    case OP_NOTPOSPLUS:+    case OP_NOTPOSQUERY:+    case OP_NOTPOSUPTO:+    case OP_NOTSTARI:+    case OP_NOTMINSTARI:+    case OP_NOTPLUSI:+    case OP_NOTMINPLUSI:+    case OP_NOTQUERYI:+    case OP_NOTMINQUERYI:+    case OP_NOTUPTOI:+    case OP_NOTMINUPTOI:+    case OP_NOTEXACTI:+    case OP_NOTPOSSTARI:+    case OP_NOTPOSPLUSI:+    case OP_NOTPOSQUERYI:+    case OP_NOTPOSUPTOI:+    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    case OP_TYPEEXACT:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPOSPLUS:+    case OP_TYPEPOSQUERY:+    case OP_TYPEPOSUPTO:+    case OP_CLASS:+    case OP_NCLASS:+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+    case OP_XCLASS:+#endif+    compile_iterator_backtrackingpath(common, current);+    break;++    case OP_REF:+    case OP_REFI:+    case OP_DNREF:+    case OP_DNREFI:+    compile_ref_iterator_backtrackingpath(common, current);+    break;++    case OP_RECURSE:+    compile_recurse_backtrackingpath(common, current);+    break;++    case OP_ASSERT:+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    compile_assert_backtrackingpath(common, current);+    break;++    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    case OP_ONCE:+    case OP_SCRIPT_RUN:+    case OP_BRA:+    case OP_CBRA:+    case OP_COND:+    case OP_SBRA:+    case OP_SCBRA:+    case OP_SCOND:+    compile_bracket_backtrackingpath(common, current);+    break;++    case OP_BRAZERO:+    if (current->cc[1] > OP_ASSERTBACK_NOT)+      compile_bracket_backtrackingpath(common, current);+    else+      compile_assert_backtrackingpath(common, current);+    break;++    case OP_BRAPOS:+    case OP_CBRAPOS:+    case OP_SBRAPOS:+    case OP_SCBRAPOS:+    case OP_BRAPOSZERO:+    compile_bracketpos_backtrackingpath(common, current);+    break;++    case OP_BRAMINZERO:+    compile_braminzero_backtrackingpath(common, current);+    break;++    case OP_MARK:+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));+    if (common->has_skip_arg)+      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));+    free_stack(common, common->has_skip_arg ? 5 : 1);+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);+    if (common->has_skip_arg)+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);+    break;++    case OP_THEN:+    case OP_THEN_ARG:+    case OP_PRUNE:+    case OP_PRUNE_ARG:+    case OP_SKIP:+    case OP_SKIP_ARG:+    compile_control_verb_backtrackingpath(common, current);+    break;++    case OP_COMMIT:+    case OP_COMMIT_ARG:+    if (!common->local_quit_available)+      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);+    if (common->quit_label == NULL)+      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));+    else+      JUMPTO(SLJIT_JUMP, common->quit_label);+    break;++    case OP_CALLOUT:+    case OP_CALLOUT_STR:+    case OP_FAIL:+    case OP_ACCEPT:+    case OP_ASSERT_ACCEPT:+    set_jumps(current->topbacktracks, LABEL());+    break;++    case OP_THEN_TRAP:+    /* A virtual opcode for then traps. */+    compile_then_trap_backtrackingpath(common, current);+    break;++    default:+    SLJIT_UNREACHABLE();+    break;+    }+  current = current->prev;+  }+common->then_trap = save_then_trap;+}++static SLJIT_INLINE void compile_recurse(compiler_common *common)+{+DEFINE_COMPILER;+PCRE2_SPTR cc = common->start + common->currententry->start;+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;+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;+jump_list *match = NULL;+struct sljit_jump *next_alt = NULL;+struct sljit_jump *accept_exit = NULL;+struct sljit_label *quit;+struct sljit_put_label *put_label = NULL;++/* Recurse captures then. */+common->then_trap = NULL;++SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);++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);++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);++if (alt_max > 1)+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);++memset(&altbacktrack, 0, sizeof(backtrack_common));+common->quit_label = NULL;+common->accept_label = NULL;+common->quit = NULL;+common->accept = NULL;+altbacktrack.cc = ccbegin;+cc += GET(cc, 1);+while (1)+  {+  altbacktrack.top = NULL;+  altbacktrack.topbacktracks = NULL;++  if (altbacktrack.cc != ccbegin)+    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));++  compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    return;++  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)+    {+    if (alt_max > 3)+      put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(1));+    else+      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, -1);++    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 > 3)+        {+        sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);+        sljit_set_put_label(put_label, LABEL());+        sljit_emit_op0(compiler, SLJIT_ENDBR);+        }+      else+        next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);+      }+    else+      free_stack(common, has_accept ? 2 : 1);+    }+  else if (alt_max > 3)+    {+    sljit_set_put_label(put_label, LABEL());+    sljit_emit_op0(compiler, SLJIT_ENDBR);+    }+  else+    {+    JUMPHERE(next_alt);+    if (alt_count + 1 < alt_max)+      {+      SLJIT_ASSERT(alt_count == 1 && alt_max == 3);+      next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);+      }+    }++  alt_count++;++  compile_backtrackingpath(common, altbacktrack.top);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    return;+  set_jumps(altbacktrack.topbacktracks, LABEL());++  if (*cc != OP_ALT)+    break;++  altbacktrack.cc = cc + 1 + LINK_SIZE;+  cc += GET(cc, 1);+  }++/* 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);+OP_SRC(SLJIT_FAST_RETURN, 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);+  copy_recurse_data(common, ccbegin, ccend, recurse_copy_shared_to_global, local_size, private_data_size + local_size, has_quit);+  JUMPTO(SLJIT_JUMP, quit);+  }++if (has_accept)+  {+  JUMPHERE(accept_exit);+  free_stack(common, 2);++  /* 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);+  OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);+  }++if (common->accept != NULL)+  {+  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, -1);+  }++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);+OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);+}++#undef COMPILE_BACKTRACKINGPATH+#undef CURRENT_AS++#define PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS \+  (PCRE2_JIT_INVALID_UTF)++static int jit_compile(pcre2_code *code, sljit_u32 mode)+{+pcre2_real_code *re = (pcre2_real_code *)code;+struct sljit_compiler *compiler;+backtrack_common rootbacktrack;+compiler_common common_data;+compiler_common *common = &common_data;+const sljit_u8 *tables = re->tables;+void *allocator_data = &re->memctl;+int private_data_size;+PCRE2_SPTR ccend;+executable_functions *functions;+void *executable_func;+sljit_uw executable_size;+sljit_uw total_length;+struct sljit_label *mainloop_label = NULL;+struct sljit_label *continue_match_label;+struct sljit_label *empty_match_found_label = NULL;+struct sljit_label *empty_match_backtrack_label = NULL;+struct sljit_label *reset_match_label;+struct sljit_label *quit_label;+struct sljit_jump *jump;+struct sljit_jump *minlength_check_failed = NULL;+struct sljit_jump *empty_match = NULL;+struct sljit_jump *end_anchor_failed = NULL;+jump_list *reqcu_not_found = NULL;++SLJIT_ASSERT(tables);++#if HAS_VIRTUAL_REGISTERS == 1+SLJIT_ASSERT(sljit_get_register_index(TMP3) < 0 && sljit_get_register_index(ARGUMENTS) < 0 && sljit_get_register_index(RETURN_ADDR) < 0);+#elif HAS_VIRTUAL_REGISTERS == 0+SLJIT_ASSERT(sljit_get_register_index(TMP3) >= 0 && sljit_get_register_index(ARGUMENTS) >= 0 && sljit_get_register_index(RETURN_ADDR) >= 0);+#else+#error "Invalid value for HAS_VIRTUAL_REGISTERS"+#endif++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;++#ifdef SUPPORT_UNICODE+common->invalid_utf = (mode & PCRE2_JIT_INVALID_UTF) != 0;+#endif /* SUPPORT_UNICODE */+mode &= ~PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS;++common->start = rootbacktrack.cc;+common->read_only_data_head = NULL;+common->fcc = tables + fcc_offset;+common->lcc = (sljit_sw)(tables + lcc_offset);+common->mode = mode;+common->might_be_empty = (re->minlength == 0) || (re->flags & PCRE2_MATCH_EMPTY);+common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY);+common->nltype = NLTYPE_FIXED;+switch(re->newline_convention)+  {+  case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break;+  case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break;+  case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;+  case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;+  case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;+  case PCRE2_NEWLINE_NUL: common->newline = CHAR_NUL; break;+  default: return PCRE2_ERROR_INTERNAL;+  }+common->nlmax = READ_CHAR_MAX;+common->nlmin = 0;+if (re->bsr_convention == PCRE2_BSR_UNICODE)+  common->bsr_nltype = NLTYPE_ANY;+else if (re->bsr_convention == PCRE2_BSR_ANYCRLF)+  common->bsr_nltype = NLTYPE_ANYCRLF;+else+  {+#ifdef BSR_ANYCRLF+  common->bsr_nltype = NLTYPE_ANYCRLF;+#else+  common->bsr_nltype = NLTYPE_ANY;+#endif+  }+common->bsr_nlmax = READ_CHAR_MAX;+common->bsr_nlmin = 0;+common->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0;+common->ctypes = (sljit_sw)(tables + ctypes_offset);+common->name_count = re->name_count;+common->name_entry_size = re->name_entry_size;+common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0;+common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0;+#ifdef SUPPORT_UNICODE+/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */+common->utf = (re->overall_options & PCRE2_UTF) != 0;+common->ucp = (re->overall_options & PCRE2_UCP) != 0;+if (common->utf)+  {+  if (common->nltype == NLTYPE_ANY)+    common->nlmax = 0x2029;+  else if (common->nltype == NLTYPE_ANYCRLF)+    common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;+  else+    {+    /* We only care about the first newline character. */+    common->nlmax = common->newline & 0xff;+    }++  if (common->nltype == NLTYPE_FIXED)+    common->nlmin = common->newline & 0xff;+  else+    common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;++  if (common->bsr_nltype == NLTYPE_ANY)+    common->bsr_nlmax = 0x2029;+  else+    common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;+  common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;+  }+else+  common->invalid_utf = FALSE;+#endif /* SUPPORT_UNICODE */+ccend = bracketend(common->start);++/* Calculate the local space size on the stack. */+common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);+common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data);+if (!common->optimized_cbracket)+  return PCRE2_ERROR_NOMEMORY;+#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1+memset(common->optimized_cbracket, 0, re->top_bracket + 1);+#else+memset(common->optimized_cbracket, 1, re->top_bracket + 1);+#endif++SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);+#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2+common->capture_last_ptr = common->ovector_start;+common->ovector_start += sizeof(sljit_sw);+#endif+if (!check_opcode_types(common, common->start, ccend))+  {+  SLJIT_FREE(common->optimized_cbracket, allocator_data);+  return PCRE2_ERROR_NOMEMORY;+  }++/* Checking flags and updating ovector_start. */+if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)+  {+  common->req_char_ptr = common->ovector_start;+  common->ovector_start += sizeof(sljit_sw);+  }+if (mode != PCRE2_JIT_COMPLETE)+  {+  common->start_used_ptr = common->ovector_start;+  common->ovector_start += sizeof(sljit_sw);+  if (mode == PCRE2_JIT_PARTIAL_SOFT)+    {+    common->hit_start = common->ovector_start;+    common->ovector_start += sizeof(sljit_sw);+    }+  }+if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0)+  {+  common->match_end_ptr = common->ovector_start;+  common->ovector_start += sizeof(sljit_sw);+  }+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD+common->control_head_ptr = 1;+#endif+if (common->control_head_ptr != 0)+  {+  common->control_head_ptr = common->ovector_start;+  common->ovector_start += sizeof(sljit_sw);+  }+if (common->has_set_som)+  {+  /* Saving the real start pointer is necessary. */+  common->start_ptr = common->ovector_start;+  common->ovector_start += sizeof(sljit_sw);+  }++/* Aligning ovector to even number of sljit words. */+if ((common->ovector_start & sizeof(sljit_sw)) != 0)+  common->ovector_start += sizeof(sljit_sw);++if (common->start_ptr == 0)+  common->start_ptr = OVECTOR(0);++/* Capturing brackets cannot be optimized if callouts are allowed. */+if (common->capture_last_ptr != 0)+  memset(common->optimized_cbracket, 0, re->top_bracket + 1);++SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));+common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);++total_length = ccend - common->start;+common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);+if (!common->private_data_ptrs)+  {+  SLJIT_FREE(common->optimized_cbracket, allocator_data);+  return PCRE2_ERROR_NOMEMORY;+  }+memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));++private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);+set_private_data_ptrs(common, &private_data_size, ccend);+if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back)+  detect_early_fail(common, common->start, &private_data_size, 0, 0);++SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr);++if (private_data_size > SLJIT_MAX_LOCAL_SIZE)+  {+  SLJIT_FREE(common->private_data_ptrs, allocator_data);+  SLJIT_FREE(common->optimized_cbracket, allocator_data);+  return PCRE2_ERROR_NOMEMORY;+  }++if (common->has_then)+  {+  common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length);+  memset(common->then_offsets, 0, total_length);+  set_then_offsets(common, common->start, NULL);+  }++compiler = sljit_create_compiler(allocator_data, NULL);+if (!compiler)+  {+  SLJIT_FREE(common->optimized_cbracket, allocator_data);+  SLJIT_FREE(common->private_data_ptrs, allocator_data);+  return PCRE2_ERROR_NOMEMORY;+  }+common->compiler = compiler;++/* Main pcre_jit_exec entry. */+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);+if (common->req_char_ptr != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);++OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);+OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));+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, 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);++if (common->early_fail_start_ptr < common->early_fail_end_ptr)+  reset_early_fail(common);++if (mode == PCRE2_JIT_PARTIAL_SOFT)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);+if (common->mark_ptr != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);+if (common->control_head_ptr != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);++/* Main part of the matching */+if ((re->overall_options & PCRE2_ANCHORED) == 0)+  {+  mainloop_label = mainloop_entry(common);+  continue_match_label = LABEL();+  /* Forward search if possible. */+  if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)+    {+    if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common))+      ;+    else if ((re->flags & PCRE2_FIRSTSET) != 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);+    }+  }+else+  continue_match_label = LABEL();++if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)+  {+  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);+  OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength));+  minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);+  }+if (common->req_char_ptr != 0)+  reqcu_not_found = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);++/* Store the current STR_PTR in OVECTOR(0). */+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);+/* Copy the limit of allowed recursions. */+OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);+if (common->capture_last_ptr != 0)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0);+if (common->fast_forward_bc_ptr != NULL)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3, STR_PTR, 0);++if (common->start_ptr != OVECTOR(0))+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);++/* Copy the beginning of the string. */+if (mode == PCRE2_JIT_PARTIAL_SOFT)+  {+  jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);+  JUMPHERE(jump);+  }+else if (mode == PCRE2_JIT_PARTIAL_HARD)+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);++compile_matchingpath(common, common->start, ccend, &rootbacktrack);+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+  {+  sljit_free_compiler(compiler);+  SLJIT_FREE(common->optimized_cbracket, allocator_data);+  SLJIT_FREE(common->private_data_ptrs, allocator_data);+  PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);+  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));+  empty_match_found_label = LABEL();+  }++common->accept_label = LABEL();+if (common->accept != NULL)+  set_jumps(common->accept, common->accept_label);++/* This means we have a match. Update the ovector. */+copy_ovector(common, re->top_bracket + 1);+common->quit_label = common->abort_label = LABEL();+if (common->quit != NULL)+  set_jumps(common->quit, common->quit_label);+if (common->abort != NULL)+  set_jumps(common->abort, common->abort_label);+if (minlength_check_failed != NULL)+  SET_LABEL(minlength_check_failed, common->abort_label);++sljit_emit_op0(compiler, SLJIT_SKIP_FRAMES_BEFORE_RETURN);+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();+  set_jumps(common->partialmatch, common->partialmatchlabel);+  return_with_partial_match(common, common->quit_label);+  }++if (common->might_be_empty)+  empty_match_backtrack_label = LABEL();+compile_backtrackingpath(common, rootbacktrack.top);+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+  {+  sljit_free_compiler(compiler);+  SLJIT_FREE(common->optimized_cbracket, allocator_data);+  SLJIT_FREE(common->private_data_ptrs, allocator_data);+  PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);+  return PCRE2_ERROR_NOMEMORY;+  }++SLJIT_ASSERT(rootbacktrack.prev == NULL);+reset_match_label = LABEL();++if (mode == PCRE2_JIT_PARTIAL_SOFT)+  {+  /* Update hit_start only in the first time. */+  jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);+  JUMPHERE(jump);+  }++/* Check we have remaining characters. */+if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);+  }++OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),+    (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3) : common->start_ptr);++if ((re->overall_options & PCRE2_ANCHORED) == 0)+  {+  if (common->ff_newline_shortcut != NULL)+    {+    /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */+    if ((re->overall_options & PCRE2_FIRSTLINE) == 0)+      {+      if (common->match_end_ptr != 0)+        {+        OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);+        OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);+        CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut);+        OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);+        }+      else+        CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);+      }+    }+  else+    CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label);+  }++/* No more remaining characters. */+if (reqcu_not_found != NULL)+  set_jumps(reqcu_not_found, LABEL());++if (mode == PCRE2_JIT_PARTIAL_SOFT)+  CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);++OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);+JUMPTO(SLJIT_JUMP, common->quit_label);++flush_stubs(common);++if (common->might_be_empty)+  {+  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_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);+  JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);+  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);+  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);+  }++common->fast_forward_bc_ptr = NULL;+common->early_fail_start_ptr = 0;+common->early_fail_end_ptr = 0;+common->currententry = common->entries;+common->local_quit_available = TRUE;+quit_label = common->quit_label;+while (common->currententry != NULL)+  {+  /* Might add new entries. */+  compile_recurse(common);+  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))+    {+    sljit_free_compiler(compiler);+    SLJIT_FREE(common->optimized_cbracket, allocator_data);+    SLJIT_FREE(common->private_data_ptrs, allocator_data);+    PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);+    return PCRE2_ERROR_NOMEMORY;+    }+  flush_stubs(common);+  common->currententry = common->currententry->next;+  }+common->local_quit_available = FALSE;+common->quit_label = quit_label;++/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */+/* This is a (really) rare case. */+set_jumps(common->stackalloc, LABEL());+/* RETURN_ADDR is not a saved register. */+sljit_emit_fast_enter(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);+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);++/* Allocation failed. */+JUMPHERE(jump);+/* We break the return address cache here, but this is a really rare case. */+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT);+JUMPTO(SLJIT_JUMP, common->quit_label);++/* Call limit reached. */+set_jumps(common->calllimit, LABEL());+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT);+JUMPTO(SLJIT_JUMP, common->quit_label);++if (common->revertframes != NULL)+  {+  set_jumps(common->revertframes, LABEL());+  do_revertframes(common);+  }+if (common->wordboundary != NULL)+  {+  set_jumps(common->wordboundary, LABEL());+  check_wordboundary(common);+  }+if (common->anynewline != NULL)+  {+  set_jumps(common->anynewline, LABEL());+  check_anynewline(common);+  }+if (common->hspace != NULL)+  {+  set_jumps(common->hspace, LABEL());+  check_hspace(common);+  }+if (common->vspace != NULL)+  {+  set_jumps(common->vspace, LABEL());+  check_vspace(common);+  }+if (common->casefulcmp != NULL)+  {+  set_jumps(common->casefulcmp, LABEL());+  do_casefulcmp(common);+  }+if (common->caselesscmp != NULL)+  {+  set_jumps(common->caselesscmp, LABEL());+  do_caselesscmp(common);+  }+if (common->reset_match != NULL)+  {+  set_jumps(common->reset_match, LABEL());+  do_reset_match(common, (re->top_bracket + 1) * 2);+  CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);+  OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);+  JUMPTO(SLJIT_JUMP, reset_match_label);+  }+#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+if (common->utfreadchar != NULL)+  {+  set_jumps(common->utfreadchar, LABEL());+  do_utfreadchar(common);+  }+if (common->utfreadtype8 != NULL)+  {+  set_jumps(common->utfreadtype8, LABEL());+  do_utfreadtype8(common);+  }+if (common->utfpeakcharback != NULL)+  {+  set_jumps(common->utfpeakcharback, LABEL());+  do_utfpeakcharback(common);+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */+#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16+if (common->utfreadchar_invalid != NULL)+  {+  set_jumps(common->utfreadchar_invalid, LABEL());+  do_utfreadchar_invalid(common);+  }+if (common->utfreadnewline_invalid != NULL)+  {+  set_jumps(common->utfreadnewline_invalid, LABEL());+  do_utfreadnewline_invalid(common);+  }+if (common->utfmoveback_invalid)+  {+  set_jumps(common->utfmoveback_invalid, LABEL());+  do_utfmoveback_invalid(common);+  }+if (common->utfpeakcharback_invalid)+  {+  set_jumps(common->utfpeakcharback_invalid, LABEL());+  do_utfpeakcharback_invalid(common);+  }+#endif /* PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 */+if (common->getucd != NULL)+  {+  set_jumps(common->getucd, LABEL());+  do_getucd(common);+  }+if (common->getucdtype != NULL)+  {+  set_jumps(common->getucdtype, LABEL());+  do_getucdtype(common);+  }+#endif /* SUPPORT_UNICODE */++SLJIT_FREE(common->optimized_cbracket, allocator_data);+SLJIT_FREE(common->private_data_ptrs, allocator_data);++executable_func = sljit_generate_code(compiler);+executable_size = sljit_get_generated_code_size(compiler);+sljit_free_compiler(compiler);++if (executable_func == NULL)+  {+  PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);+  return PCRE2_ERROR_NOMEMORY;+  }++/* Reuse the function descriptor if possible. */+if (re->executable_jit != NULL)+  functions = (executable_functions *)re->executable_jit;+else+  {+  functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data);+  if (functions == NULL)+    {+    /* This case is highly unlikely since we just recently+    freed a lot of memory. Not impossible though. */+    sljit_free_code(executable_func, NULL);+    PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);+    return PCRE2_ERROR_NOMEMORY;+    }+  memset(functions, 0, sizeof(executable_functions));+  functions->top_bracket = re->top_bracket + 1;+  functions->limit_match = re->limit_match;+  re->executable_jit = functions;+  }++/* Turn mode into an index. */+if (mode == PCRE2_JIT_COMPLETE)+  mode = 0;+else+  mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2;++SLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES);+functions->executable_funcs[mode] = executable_func;+functions->read_only_data_heads[mode] = common->read_only_data_head;+functions->executable_sizes[mode] = executable_size;+return 0;+}++#endif++/*************************************************+*        JIT compile a Regular Expression        *+*************************************************/++/* This function used JIT to convert a previously-compiled pattern into machine+code.++Arguments:+  code          a compiled pattern+  options       JIT option bits++Returns:        0: success or (*NOJIT) was used+               <0: an error code+*/++#define PUBLIC_JIT_COMPILE_OPTIONS \+  (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD|PCRE2_JIT_INVALID_UTF)++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_jit_compile(pcre2_code *code, uint32_t options)+{+pcre2_real_code *re = (pcre2_real_code *)code;++if (code == NULL)+  return PCRE2_ERROR_NULL;++if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0)+  return PCRE2_ERROR_JIT_BADOPTION;++/* Support for invalid UTF was first introduced in JIT, with the option+PCRE2_JIT_INVALID_UTF. Later, support was added to the interpreter, and the+compile-time option PCRE2_MATCH_INVALID_UTF was created. This is now the+preferred feature, with the earlier option deprecated. However, for backward+compatibility, if the earlier option is set, it forces the new option so that+if JIT matching falls back to the interpreter, there is still support for+invalid UTF. However, if this function has already been successfully called+without PCRE2_JIT_INVALID_UTF and without PCRE2_MATCH_INVALID_UTF (meaning that+non-invalid-supporting JIT code was compiled), give an error.++If in the future support for PCRE2_JIT_INVALID_UTF is withdrawn, the following+actions are needed:++  1. Remove the definition from pcre2.h.in and from the list in+     PUBLIC_JIT_COMPILE_OPTIONS above.++  2. Replace PCRE2_JIT_INVALID_UTF with a local flag in this module.++  3. Replace PCRE2_JIT_INVALID_UTF in pcre2_jit_test.c.++  4. Delete the following short block of code. The setting of "re" and+     "functions" can be moved into the JIT-only block below, but if that is+     done, (void)re and (void)functions will be needed in the non-JIT case, to+     avoid compiler warnings.+*/++#ifdef SUPPORT_JIT+executable_functions *functions = (executable_functions *)re->executable_jit;+static int executable_allocator_is_working = 0;+#endif++if ((options & PCRE2_JIT_INVALID_UTF) != 0)+  {+  if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0)+    {+#ifdef SUPPORT_JIT+    if (functions != NULL) return PCRE2_ERROR_JIT_BADOPTION;+#endif+    re->overall_options |= PCRE2_MATCH_INVALID_UTF;+    }+  }++/* The above tests are run with and without JIT support. This means that+PCRE2_JIT_INVALID_UTF propagates back into the regex options (ensuring+interpreter support) even in the absence of JIT. But now, if there is no JIT+support, give an error return. */++#ifndef SUPPORT_JIT+return PCRE2_ERROR_JIT_BADOPTION;+#else  /* SUPPORT_JIT */++/* There is JIT support. Do the necessary. */++if ((re->flags & PCRE2_NOJIT) != 0) return 0;++if (executable_allocator_is_working == 0)+  {+  /* Checks whether the executable allocator is working. This check+     might run multiple times in multi-threaded environments, but the+     result should not be affected by it. */+  void *ptr = SLJIT_MALLOC_EXEC(32, NULL);++  executable_allocator_is_working = -1;++  if (ptr != NULL)+    {+    SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL);+    executable_allocator_is_working = 1;+    }+  }++if (executable_allocator_is_working < 0)+  return PCRE2_ERROR_NOMEMORY;++if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)+  options |= PCRE2_JIT_INVALID_UTF;++if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL+    || functions->executable_funcs[0] == NULL)) {+  uint32_t excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);+  int result = jit_compile(code, options & ~excluded_options);+  if (result != 0)+    return result;+  }++if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL+    || functions->executable_funcs[1] == NULL)) {+  uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD);+  int result = jit_compile(code, options & ~excluded_options);+  if (result != 0)+    return result;+  }++if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL+    || functions->executable_funcs[2] == NULL)) {+  uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);+  int result = jit_compile(code, options & ~excluded_options);+  if (result != 0)+    return result;+  }++return 0;++#endif  /* SUPPORT_JIT */+}++/* JIT compiler uses an all-in-one approach. This improves security,+   since the code generator functions are not exported. */++#define INCLUDED_FROM_PCRE2_JIT_COMPILE++#include "pcre2_jit_match.c"+#include "pcre2_jit_misc.c"++/* End of pcre2_jit_compile.c */
+ src/c/pcre2/src/pcre2_jit_match.c view
@@ -0,0 +1,186 @@+/*************************************************+*      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.+-----------------------------------------------------------------------------+*/++#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE+#error This file must be included from pcre2_jit_compile.c.+#endif++#ifdef SUPPORT_JIT++static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func)+{+sljit_u8 local_space[MACHINE_STACK_SIZE];+struct sljit_stack local_stack;++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);+}++#endif+++/*************************************************+*              Do a JIT pattern match            *+*************************************************/++/* This function runs a JIT pattern match.++Arguments:+  code            points to the compiled expression+  subject         points to the subject string+  length          length of subject string (may contain binary zeros)+  start_offset    where to start in the subject string+  options         option bits+  match_data      points to a match_data block+  mcontext        points to a match context++Returns:          > 0 => success; value is the number of ovector pairs filled+                  = 0 => success, but ovector is not big enough+                   -1 => failed to match (PCRE_ERROR_NOMATCH)+                 < -1 => some kind of unexpected problem+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_jit_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)+{+#ifndef SUPPORT_JIT++(void)code;+(void)subject;+(void)length;+(void)start_offset;+(void)options;+(void)match_data;+(void)mcontext;+return PCRE2_ERROR_JIT_BADOPTION;++#else  /* SUPPORT_JIT */++pcre2_real_code *re = (pcre2_real_code *)code;+executable_functions *functions = (executable_functions *)re->executable_jit;+pcre2_jit_stack *jit_stack;+uint32_t oveccount = match_data->oveccount;+uint32_t max_oveccount;+union {+   void *executable_func;+   jit_function call_executable_func;+} convert_executable_func;+jit_arguments arguments;+int rc;+int index = 0;++if ((options & PCRE2_PARTIAL_HARD) != 0)+  index = 2;+else if ((options & PCRE2_PARTIAL_SOFT) != 0)+  index = 1;++if (functions == NULL || functions->executable_funcs[index] == NULL)+  return PCRE2_ERROR_JIT_BADOPTION;++/* Sanity checks should be handled by pcre_exec. */+arguments.str = subject + start_offset;+arguments.begin = subject;+arguments.end = subject + length;+arguments.match_data = match_data;+arguments.startchar_ptr = subject;+arguments.mark_ptr = NULL;+arguments.options = options;++if (mcontext != NULL)+  {+  arguments.callout = mcontext->callout;+  arguments.callout_data = mcontext->callout_data;+  arguments.offset_limit = mcontext->offset_limit;+  arguments.limit_match = (mcontext->match_limit < re->limit_match)?+    mcontext->match_limit : re->limit_match;+  if (mcontext->jit_callback != NULL)+    jit_stack = mcontext->jit_callback(mcontext->jit_callback_data);+  else+    jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data;+  }+else+  {+  arguments.callout = NULL;+  arguments.callout_data = NULL;+  arguments.offset_limit = PCRE2_UNSET;+  arguments.limit_match = (MATCH_LIMIT < re->limit_match)?+    MATCH_LIMIT : re->limit_match;+  jit_stack = NULL;+  }+++max_oveccount = functions->top_bracket;+if (oveccount > max_oveccount)+  oveccount = max_oveccount;+arguments.oveccount = oveccount << 1;+++convert_executable_func.executable_func = functions->executable_funcs[index];+if (jit_stack != NULL)+  {+  arguments.stack = (struct sljit_stack *)(jit_stack->stack);+  rc = convert_executable_func.call_executable_func(&arguments);+  }+else+  rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func);++if (rc > (int)oveccount)+  rc = 0;+match_data->code = re;+match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;+match_data->rc = rc;+match_data->startchar = arguments.startchar_ptr - subject;+match_data->leftchar = 0;+match_data->rightchar = 0;+match_data->mark = arguments.mark_ptr;+match_data->matchedby = PCRE2_MATCHEDBY_JIT;++return match_data->rc;++#endif  /* SUPPORT_JIT */+}++/* End of pcre2_jit_match.c */
+ src/c/pcre2/src/pcre2_jit_misc.c view
@@ -0,0 +1,232 @@+/*************************************************+*      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 University of Cambridge++-----------------------------------------------------------------------------+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright notice,+      this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above copyright+      notice, this list of conditions and the following disclaimer in the+      documentation and/or other materials provided with the distribution.++    * Neither the name of the University of Cambridge nor the names of its+      contributors may be used to endorse or promote products derived from+      this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.+-----------------------------------------------------------------------------+*/+++#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE+#error This file must be included from pcre2_jit_compile.c.+#endif++++/*************************************************+*           Free JIT read-only data              *+*************************************************/++void+PRIV(jit_free_rodata)(void *current, void *allocator_data)+{+#ifndef SUPPORT_JIT+(void)current;+(void)allocator_data;+#else  /* SUPPORT_JIT */+void *next;++SLJIT_UNUSED_ARG(allocator_data);++while (current != NULL)+  {+  next = *(void**)current;+  SLJIT_FREE(current, allocator_data);+  current = next;+  }++#endif /* SUPPORT_JIT */+}++/*************************************************+*           Free JIT compiled code               *+*************************************************/++void+PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl)+{+#ifndef SUPPORT_JIT+(void)executable_jit;+(void)memctl;+#else  /* SUPPORT_JIT */++executable_functions *functions = (executable_functions *)executable_jit;+void *allocator_data = memctl;+int i;++for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)+  {+  if (functions->executable_funcs[i] != NULL)+    sljit_free_code(functions->executable_funcs[i], NULL);+  PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);+  }++SLJIT_FREE(functions, allocator_data);++#endif /* SUPPORT_JIT */+}+++/*************************************************+*            Free unused JIT memory              *+*************************************************/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_jit_free_unused_memory(pcre2_general_context *gcontext)+{+#ifndef SUPPORT_JIT+(void)gcontext;     /* Suppress warning */+#else  /* SUPPORT_JIT */+SLJIT_UNUSED_ARG(gcontext);+sljit_free_unused_memory_exec();+#endif  /* SUPPORT_JIT */+}++++/*************************************************+*            Allocate a JIT stack                *+*************************************************/++PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION+pcre2_jit_stack_create(size_t startsize, size_t maxsize,+  pcre2_general_context *gcontext)+{+#ifndef SUPPORT_JIT++(void)gcontext;+(void)startsize;+(void)maxsize;+return NULL;++#else  /* SUPPORT_JIT */++pcre2_jit_stack *jit_stack;++if (startsize < 1 || maxsize < 1)+  return NULL;+if (startsize > maxsize)+  startsize = maxsize;+startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);+maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);++jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);+if (jit_stack == NULL) return NULL;+jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);+if (jit_stack->stack == NULL)+  {+  jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);+  return NULL;+  }+return jit_stack;++#endif+}+++/*************************************************+*         Assign a JIT stack to a pattern        *+*************************************************/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback,+  void *callback_data)+{+#ifndef SUPPORT_JIT+(void)mcontext;+(void)callback;+(void)callback_data;+#else  /* SUPPORT_JIT */++if (mcontext == NULL) return;+mcontext->jit_callback = callback;+mcontext->jit_callback_data = callback_data;++#endif  /* SUPPORT_JIT */+}+++/*************************************************+*               Free a JIT stack                 *+*************************************************/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_jit_stack_free(pcre2_jit_stack *jit_stack)+{+#ifndef SUPPORT_JIT+(void)jit_stack;+#else  /* SUPPORT_JIT */+if (jit_stack != NULL)+  {+  sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl);+  jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);+  }+#endif  /* SUPPORT_JIT */+}+++/*************************************************+*               Get target CPU type              *+*************************************************/++const char*+PRIV(jit_get_target)(void)+{+#ifndef SUPPORT_JIT+return "JIT is not supported";+#else  /* SUPPORT_JIT */+return sljit_get_platform_name();+#endif  /* SUPPORT_JIT */+}+++/*************************************************+*              Get size of JIT code              *+*************************************************/++size_t+PRIV(jit_get_size)(void *executable_jit)+{+#ifndef SUPPORT_JIT+(void)executable_jit;+return 0;+#else  /* SUPPORT_JIT */+sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes;+SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed);+return executable_sizes[0] + executable_sizes[1] + executable_sizes[2];+#endif+}++/* End of pcre2_jit_misc.c */
+ src/c/pcre2/src/pcre2_jit_neon_inc.h view
@@ -0,0 +1,343 @@+/*************************************************+*      Perl-Compatible Regular Expressions       *+*************************************************/++/* PCRE is a library of functions to support regular expressions whose syntax+and semantics are as close as possible to those of the Perl 5 language.++                       Written by Philip Hazel+            This module by Zoltan Herczeg and Sebastian Pop+     Original API code Copyright (c) 1997-2012 University of Cambridge+          New API code Copyright (c) 2016-2019 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.+-----------------------------------------------------------------------------+*/++# if defined(FFCS)+#  if defined(FF_UTF)+#   define FF_FUN ffcs_utf+#  else+#   define FF_FUN ffcs+#  endif++# elif defined(FFCS_2)+#  if defined(FF_UTF)+#   define FF_FUN ffcs_2_utf+#  else+#   define FF_FUN ffcs_2+#  endif++# elif defined(FFCS_MASK)+#  if defined(FF_UTF)+#   define FF_FUN ffcs_mask_utf+#  else+#   define FF_FUN ffcs_mask+#  endif++# elif defined(FFCPS_0)+#  if defined (FF_UTF)+#   define FF_FUN ffcps_0_utf+#  else+#   define FF_FUN ffcps_0+#  endif++# elif defined (FFCPS_1)+#  if defined (FF_UTF)+#   define FF_FUN ffcps_1_utf+#  else+#   define FF_FUN ffcps_1+#  endif++# elif defined (FFCPS_DEFAULT)+#  if defined (FF_UTF)+#   define FF_FUN ffcps_default_utf+#  else+#   define FF_FUN ffcps_default+#  endif+# endif++static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)+#undef FF_FUN+{+quad_word qw;+int_char ic;+ic.x = chars;++#if defined(FFCS)+sljit_u8 c1 = ic.c.c1;+vect_t vc1 = VDUPQ(c1);++#elif defined(FFCS_2)+sljit_u8 c1 = ic.c.c1;+vect_t vc1 = VDUPQ(c1);+sljit_u8 c2 = ic.c.c2;+vect_t vc2 = VDUPQ(c2);++#elif defined(FFCS_MASK)+sljit_u8 c1 = ic.c.c1;+vect_t vc1 = VDUPQ(c1);+sljit_u8 mask = ic.c.c2;+vect_t vmask = VDUPQ(mask);+#endif++#if defined(FFCPS)+compare_type compare1_type = compare_match1;+compare_type compare2_type = compare_match1;+vect_t cmp1a, cmp1b, cmp2a, cmp2b;+const sljit_u32 diff = IN_UCHARS(offs1 - offs2);+PCRE2_UCHAR char1a = ic.c.c1;+PCRE2_UCHAR char2a = ic.c.c3;++# ifdef FFCPS_CHAR1A2A+cmp1a = VDUPQ(char1a);+cmp2a = VDUPQ(char2a);+cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */+cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */+# else+PCRE2_UCHAR char1b = ic.c.c2;+PCRE2_UCHAR char2b = ic.c.c4;+if (char1a == char1b)+  {+  cmp1a = VDUPQ(char1a);+  cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */+  }+else+  {+  sljit_u32 bit1 = char1a ^ char1b;+  if (is_powerof2(bit1))+    {+    compare1_type = compare_match1i;+    cmp1a = VDUPQ(char1a | bit1);+    cmp1b = VDUPQ(bit1);+    }+  else+    {+    compare1_type = compare_match2;+    cmp1a = VDUPQ(char1a);+    cmp1b = VDUPQ(char1b);+    }+  }++if (char2a == char2b)+  {+  cmp2a = VDUPQ(char2a);+  cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */+  }+else+  {+  sljit_u32 bit2 = char2a ^ char2b;+  if (is_powerof2(bit2))+    {+    compare2_type = compare_match1i;+    cmp2a = VDUPQ(char2a | bit2);+    cmp2b = VDUPQ(bit2);+    }+  else+    {+    compare2_type = compare_match2;+    cmp2a = VDUPQ(char2a);+    cmp2b = VDUPQ(char2b);+    }+  }+# endif++str_ptr += IN_UCHARS(offs1);+#endif++#if PCRE2_CODE_UNIT_WIDTH != 8+vect_t char_mask = VDUPQ(0xff);+#endif++#if defined(FF_UTF)+restart:;+#endif++#if defined(FFCPS)+sljit_u8 *p1 = str_ptr - diff;+#endif+sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf);+str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf);+vect_t data = VLD1Q(str_ptr);+#if PCRE2_CODE_UNIT_WIDTH != 8+data = VANDQ(data, char_mask);+#endif+ +#if defined(FFCS)+vect_t eq = VCEQQ(data, vc1);++#elif defined(FFCS_2)+vect_t eq1 = VCEQQ(data, vc1);+vect_t eq2 = VCEQQ(data, vc2);+vect_t eq = VORRQ(eq1, eq2);    ++#elif defined(FFCS_MASK)+vect_t eq = VORRQ(data, vmask);+eq = VCEQQ(eq, vc1);++#elif defined(FFCPS)+# if defined(FFCPS_DIFF1)+vect_t prev_data = data;+# endif++vect_t data2;+if (p1 < str_ptr)+  {+  data2 = VLD1Q(str_ptr - diff);+#if PCRE2_CODE_UNIT_WIDTH != 8+  data2 = VANDQ(data2, char_mask);+#endif+  }+else+  data2 = shift_left_n_lanes(data, offs1 - offs2);+ +if (compare1_type == compare_match1)+  data = VCEQQ(data, cmp1a);+else+  data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);++if (compare2_type == compare_match1)+  data2 = VCEQQ(data2, cmp2a);+else+  data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);++vect_t eq = VANDQ(data, data2);+#endif++VST1Q(qw.mem, eq);+/* Ignore matches before the first STR_PTR. */+if (align_offset < 8)+  {+  qw.dw[0] >>= align_offset * 8;+  if (qw.dw[0])+    {+    str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;+    goto match;+    }+  if (qw.dw[1])+    {+    str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;+    goto match;+    }+  }+else+  {+  qw.dw[1] >>= (align_offset - 8) * 8;+  if (qw.dw[1])+    {+    str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;+    goto match;+    }+  }+str_ptr += 16;++while (str_ptr < str_end)+  {+  vect_t orig_data = VLD1Q(str_ptr);+#if PCRE2_CODE_UNIT_WIDTH != 8+  orig_data = VANDQ(orig_data, char_mask);+#endif+  data = orig_data;++#if defined(FFCS)+  eq = VCEQQ(data, vc1);++#elif defined(FFCS_2)+  eq1 = VCEQQ(data, vc1);+  eq2 = VCEQQ(data, vc2);+  eq = VORRQ(eq1, eq2);    ++#elif defined(FFCS_MASK)+  eq = VORRQ(data, vmask);+  eq = VCEQQ(eq, vc1);+#endif++#if defined(FFCPS)+# if defined (FFCPS_DIFF1)+  data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1);+# else+  data2 = VLD1Q(str_ptr - diff);+#  if PCRE2_CODE_UNIT_WIDTH != 8+  data2 = VANDQ(data2, char_mask);+#  endif+# endif++# ifdef FFCPS_CHAR1A2A+  data = VCEQQ(data, cmp1a);+  data2 = VCEQQ(data2, cmp2a);+# else+  if (compare1_type == compare_match1)+    data = VCEQQ(data, cmp1a);+  else+    data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);+  if (compare2_type == compare_match1)+    data2 = VCEQQ(data2, cmp2a);+  else+    data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);+# endif++  eq = VANDQ(data, data2);+#endif++  VST1Q(qw.mem, eq);+  if (qw.dw[0])+    str_ptr += __builtin_ctzll(qw.dw[0]) / 8;+  else if (qw.dw[1])+    str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;+  else {+    str_ptr += 16;+#if defined (FFCPS_DIFF1)+    prev_data = orig_data;+#endif+    continue;+  }++match:;+  if (str_ptr >= str_end)+    /* Failed match. */+    return NULL;++#if defined(FF_UTF)+  if (utf_continue(str_ptr + IN_UCHARS(-offs1)))+    {+    /* Not a match. */+    str_ptr += IN_UCHARS(1);+    goto restart;+    }+#endif++  /* Match. */+#if defined (FFCPS)+  str_ptr -= IN_UCHARS(offs1);+#endif+  return str_ptr;+  }++/* Failed match. */+return NULL;+}
+ src/c/pcre2/src/pcre2_jit_simd_inc.h view
@@ -0,0 +1,1123 @@+/*************************************************+*      Perl-Compatible Regular Expressions       *+*************************************************/++/* PCRE is a library of functions to support regular expressions whose syntax+and semantics are as close as possible to those of the Perl 5 language.++                       Written by Philip Hazel+                    This module by Zoltan Herczeg+     Original API code Copyright (c) 1997-2012 University of Cambridge+          New API code Copyright (c) 2016-2019 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.+-----------------------------------------------------------------------------+*/++#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)+{+sljit_u32 value = chr;+#if PCRE2_CODE_UNIT_WIDTH == 8+#define SSE2_COMPARE_TYPE_INDEX 0+return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value);+#elif PCRE2_CODE_UNIT_WIDTH == 16+#define SSE2_COMPARE_TYPE_INDEX 1+return (sljit_s32)((value << 16) | value);+#elif PCRE2_CODE_UNIT_WIDTH == 32+#define SSE2_COMPARE_TYPE_INDEX 2+return (sljit_s32)(value);+#else+#error "Unsupported unit width"+#endif+}++static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg, sljit_s8 offset)+{+sljit_u8 instruction[5];++SLJIT_ASSERT(dst_xmm_reg < 8);+SLJIT_ASSERT(src_general_reg < 8);++/* MOVDQA xmm1, xmm2/m128 */+instruction[0] = ((sljit_u8)offset & 0xf) == 0 ? 0x66 : 0xf3;+instruction[1] = 0x0f;+instruction[2] = 0x6f;++if (offset == 0)+  {+  instruction[3] = (dst_xmm_reg << 3) | src_general_reg;+  sljit_emit_op_custom(compiler, instruction, 4);+  return;+  }++instruction[3] = 0x40 | (dst_xmm_reg << 3) | src_general_reg;+instruction[4] = (sljit_u8)offset;+sljit_emit_op_custom(compiler, instruction, 5);+}++typedef enum {+    sse2_compare_match1,+    sse2_compare_match1i,+    sse2_compare_match2,+} sse2_compare_type;++static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, sse2_compare_type compare_type,+  int step, 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;++SLJIT_ASSERT(step >= 0 && step <= 3);++if (compare_type != sse2_compare_match2)+  {+  if (step == 0)+    {+    if (compare_type == sse2_compare_match1i)+      {+      /* 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);+      }+    return;+    }++  if (step != 2)+    return;++  /* 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);+  return;+  }++switch (step)+  {+  case 0:+  /* 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);+  return;++  case 1:+  /* 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);+  return;++  case 2:+  /* PCMPEQB/W/D xmm1, xmm2/m128 */+  /* instruction[0] = 0x66; */+  /* instruction[1] = 0x0f; */+  instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;+  instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;+  sljit_emit_op_custom(compiler, instruction, 4);+  return;++  case 3:+  /* 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);+  return;+  }+}++#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))++static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)+{+DEFINE_COMPILER;+struct sljit_label *start;+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+struct sljit_label *restart;+#endif+struct sljit_jump *quit;+struct sljit_jump *partial_quit[2];+sse2_compare_type compare_type = sse2_compare_match1;+sljit_u8 instruction[8];+sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);+sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);+sljit_s32 data_ind = 0;+sljit_s32 tmp_ind = 1;+sljit_s32 cmp1_ind = 2;+sljit_s32 cmp2_ind = 3;+sljit_u32 bit = 0;+int i;++SLJIT_UNUSED_ARG(offset);++if (char1 != char2)+  {+  bit = char1 ^ char2;+  compare_type = sse2_compare_match1i;++  if (!is_powerof2(bit))+    {+    bit = 0;+    compare_type = sse2_compare_match2;+    }+  }++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_reg_ind < 8);++/* MOVD xmm, r/m32 */+instruction[0] = 0x66;+instruction[1] = 0x0f;+instruction[2] = 0x6e;+instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;+sljit_emit_op_custom(compiler, instruction, 4);++if (char1 != char2)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));++  /* MOVD xmm, r/m32 */+  instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_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 | (cmp1_ind << 3) | cmp1_ind;+instruction[4] = 0;+sljit_emit_op_custom(compiler, instruction, 5);++if (char1 != char2)+  {+  /* PSHUFD xmm1, xmm2/m128, imm8 */+  instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;+  sljit_emit_op_custom(compiler, instruction, 5);+  }++#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);++load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);+for (i = 0; i < 4; i++)+  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);++/* PMOVMSKB reg, xmm */+/* instruction[0] = 0x66; */+/* instruction[1] = 0x0f; */+instruction[2] = 0xd7;+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;+sljit_emit_op_custom(compiler, instruction, 4);++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);++quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);++OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);++/* Second part (aligned) */+start = LABEL();++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);++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]);++load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);+for (i = 0; i < 4; i++)+  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);++/* PMOVMSKB reg, xmm */+/* instruction[0] = 0x66; */+/* instruction[1] = 0x0f; */+instruction[2] = 0xd7;+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;+sljit_emit_op_custom(compiler, instruction, 4);++CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);++JUMPHERE(quit);++/* BSF r32, r/m32 */+instruction[0] = 0x0f;+instruction[1] = 0xbc;+instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;+sljit_emit_op_custom(compiler, instruction, 3);++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);++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+}++#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))++static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)+{+DEFINE_COMPILER;+struct sljit_label *start;+struct sljit_jump *quit;+jump_list *not_found = NULL;+sse2_compare_type compare_type = sse2_compare_match1;+sljit_u8 instruction[8];+sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);+sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);+sljit_s32 data_ind = 0;+sljit_s32 tmp_ind = 1;+sljit_s32 cmp1_ind = 2;+sljit_s32 cmp2_ind = 3;+sljit_u32 bit = 0;+int i;++if (char1 != char2)+  {+  bit = char1 ^ char2;+  compare_type = sse2_compare_match1i;++  if (!is_powerof2(bit))+    {+    bit = 0;+    compare_type = sse2_compare_match2;+    }+  }++add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));+OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);+OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);++/* First part (unaligned start) */++OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));++SLJIT_ASSERT(tmp1_reg_ind < 8);++/* MOVD xmm, r/m32 */+instruction[0] = 0x66;+instruction[1] = 0x0f;+instruction[2] = 0x6e;+instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;+sljit_emit_op_custom(compiler, instruction, 4);++if (char1 != char2)+  {+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));++  /* MOVD xmm, r/m32 */+  instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind;+  sljit_emit_op_custom(compiler, instruction, 4);+  }++OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);++/* PSHUFD xmm1, xmm2/m128, imm8 */+/* instruction[0] = 0x66; */+/* instruction[1] = 0x0f; */+instruction[2] = 0x70;+instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind;+instruction[4] = 0;+sljit_emit_op_custom(compiler, instruction, 5);++if (char1 != char2)+  {+  /* PSHUFD xmm1, xmm2/m128, imm8 */+  instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;+  sljit_emit_op_custom(compiler, instruction, 5);+  }++OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);++load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);+for (i = 0; i < 4; i++)+  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);++/* PMOVMSKB reg, xmm */+/* instruction[0] = 0x66; */+/* instruction[1] = 0x0f; */+instruction[2] = 0xd7;+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;+sljit_emit_op_custom(compiler, instruction, 4);++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);++quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);++OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);++/* Second part (aligned) */+start = LABEL();++OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);++add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));++load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);+for (i = 0; i < 4; i++)+  fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);++/* PMOVMSKB reg, xmm */+/* instruction[0] = 0x66; */+/* instruction[1] = 0x0f; */+instruction[2] = 0xd7;+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;+sljit_emit_op_custom(compiler, instruction, 4);++CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);++JUMPHERE(quit);++/* BSF r32, r/m32 */+instruction[0] = 0x0f;+instruction[1] = 0xbc;+instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;+sljit_emit_op_custom(compiler, instruction, 3);++OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0);+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));++OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);+return not_found;+}++#ifndef _WIN64++static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_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+}++#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))++static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,+  PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)+{+DEFINE_COMPILER;+sse2_compare_type compare1_type = sse2_compare_match1;+sse2_compare_type compare2_type = sse2_compare_match1;+sljit_u32 bit1 = 0;+sljit_u32 bit2 = 0;+sljit_u32 diff = IN_UCHARS(offs1 - offs2);+sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);+sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2);+sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);+sljit_s32 data1_ind = 0;+sljit_s32 data2_ind = 1;+sljit_s32 tmp1_ind = 2;+sljit_s32 tmp2_ind = 3;+sljit_s32 cmp1a_ind = 4;+sljit_s32 cmp1b_ind = 5;+sljit_s32 cmp2a_ind = 6;+sljit_s32 cmp2b_ind = 7;+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];+int i;++SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);+SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));+SLJIT_ASSERT(tmp1_reg_ind < 8 && tmp2_reg_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))+    {+    compare1_type = sse2_compare_match1i;+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));+    }+  else+    {+    compare1_type = sse2_compare_match2;+    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_reg_ind;+sljit_emit_op_custom(compiler, instruction, 4);++if (char1a != char1b)+  {+  instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_reg_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))+    {+    compare2_type = sse2_compare_match1i;+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));+    }+  else+    {+    compare2_type = sse2_compare_match2;+    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_reg_ind;+sljit_emit_op_custom(compiler, instruction, 4);++if (char2a != char2b)+  {+  instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_reg_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, diff);+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);++load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0);++jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);++load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff);+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, 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);++for (i = 0; i < 4; i++)+  {+  fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);+  fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_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_reg_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);++jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);++OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);++/* Main loop. */+start = LABEL();++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_reg_ind, 0);+load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff);++for (i = 0; i < 4; i++)+  {+  fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind);+  fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_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_reg_ind << 3) | 0;+sljit_emit_op_custom(compiler, instruction, 4);++CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);++JUMPHERE(jump[0]);++/* BSF r32, r/m32 */+instruction[0] = 0x0f;+instruction[1] = 0xbc;+instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;+sljit_emit_op_custom(compiler, instruction, 3);++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);+}++#endif /* !_WIN64 */++#undef SSE2_COMPARE_TYPE_INDEX++#endif /* SLJIT_CONFIG_X86 && !SUPPORT_VALGRIND */++#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 && (defined __ARM_NEON || defined __ARM_NEON__))++#include <arm_neon.h>++typedef union {+  unsigned int x;+  struct { unsigned char c1, c2, c3, c4; } c;+} int_char;++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+static SLJIT_INLINE int utf_continue(sljit_u8 *s)+{+#if PCRE2_CODE_UNIT_WIDTH == 8+return (*s & 0xc0) == 0x80;+#elif PCRE2_CODE_UNIT_WIDTH == 16+return (*s & 0xfc00) == 0xdc00;+#else+#error "Unknown code width"+#endif+}+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */++#if PCRE2_CODE_UNIT_WIDTH == 8+# define VECTOR_FACTOR 16+# define vect_t uint8x16_t+# define VLD1Q(X) vld1q_u8((sljit_u8 *)(X))+# define VCEQQ vceqq_u8+# define VORRQ vorrq_u8+# define VST1Q vst1q_u8+# define VDUPQ vdupq_n_u8+# define VEXTQ vextq_u8+# define VANDQ vandq_u8+typedef union {+       uint8_t mem[16];+       uint64_t dw[2];+} quad_word;+#elif PCRE2_CODE_UNIT_WIDTH == 16+# define VECTOR_FACTOR 8+# define vect_t uint16x8_t+# define VLD1Q(X) vld1q_u16((sljit_u16 *)(X))+# define VCEQQ vceqq_u16+# define VORRQ vorrq_u16+# define VST1Q vst1q_u16+# define VDUPQ vdupq_n_u16+# define VEXTQ vextq_u16+# define VANDQ vandq_u16+typedef union {+       uint16_t mem[8];+       uint64_t dw[2];+} quad_word;+#else+# define VECTOR_FACTOR 4+# define vect_t uint32x4_t+# define VLD1Q(X) vld1q_u32((sljit_u32 *)(X))+# define VCEQQ vceqq_u32+# define VORRQ vorrq_u32+# define VST1Q vst1q_u32+# define VDUPQ vdupq_n_u32+# define VEXTQ vextq_u32+# define VANDQ vandq_u32+typedef union {+       uint32_t mem[4];+       uint64_t dw[2];+} quad_word;+#endif++#define FFCS+#include "pcre2_jit_neon_inc.h"+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+# define FF_UTF+# include "pcre2_jit_neon_inc.h"+# undef FF_UTF+#endif+#undef FFCS++#define FFCS_2+#include "pcre2_jit_neon_inc.h"+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+# define FF_UTF+# include "pcre2_jit_neon_inc.h"+# undef FF_UTF+#endif+#undef FFCS_2++#define FFCS_MASK+#include "pcre2_jit_neon_inc.h"+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+# define FF_UTF+# include "pcre2_jit_neon_inc.h"+# undef FF_UTF+#endif+#undef FFCS_MASK++#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1++static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)+{+DEFINE_COMPILER;+int_char ic;+struct sljit_jump *partial_quit;+/* Save temporary registers. */+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0);++/* Prepare function arguments */+OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);+OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);+OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset);++if (char1 == char2)+  {+    ic.c.c1 = char1;+    ic.c.c2 = char2;+    OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+  if (common->utf && offset > 0)+    sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                     SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_utf));+  else+    sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                     SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs));+#else+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                   SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs));+#endif+  }+else+  {+  PCRE2_UCHAR mask = char1 ^ char2;+  if (is_powerof2(mask))+    {+    ic.c.c1 = char1 | mask;+    ic.c.c2 = mask;+    OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf && offset > 0)+      sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                       SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask_utf));+    else+      sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                       SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask));+#else+    sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                     SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask));+#endif+    }+  else+    {+      ic.c.c1 = char1;+      ic.c.c2 = char2;+      OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf && offset > 0)+      sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                       SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2_utf));+    else+      sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                       SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2));+#else+    sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),+                     SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2));+#endif+    }+  }+/* Restore registers. */+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);+OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);++/* Check return value. */+partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);+if (common->mode == PCRE2_JIT_COMPLETE)+  add_jump(compiler, &common->failed_match, partial_quit);++/* Fast forward STR_PTR to the result of memchr. */+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);++if (common->mode != PCRE2_JIT_COMPLETE)+  JUMPHERE(partial_quit);+}++typedef enum {+  compare_match1,+  compare_match1i,+  compare_match2,+} compare_type;++static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2)+{+if (ctype == compare_match2)+  {+  vect_t tmp = dst;+  dst = VCEQQ(dst, cmp1);+  tmp = VCEQQ(tmp, cmp2);+  dst = VORRQ(dst, tmp);+  return dst;+  }++if (ctype == compare_match1i)+  dst = VORRQ(dst, cmp2);+dst = VCEQQ(dst, cmp1);+return dst;+}++static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_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+}++/* ARM doesn't have a shift left across lanes. */+static SLJIT_INLINE vect_t shift_left_n_lanes(vect_t a, sljit_u8 n)+{+vect_t zero = VDUPQ(0);+SLJIT_ASSERT(0 < n && n < VECTOR_FACTOR);+/* VEXTQ takes an immediate as last argument. */+#define C(X) case X: return VEXTQ(zero, a, VECTOR_FACTOR - X);+switch (n)+  {+  C(1); C(2); C(3);+#if PCRE2_CODE_UNIT_WIDTH != 32+  C(4); C(5); C(6); C(7);+# if PCRE2_CODE_UNIT_WIDTH != 16+  C(8); C(9); C(10); C(11); C(12); C(13); C(14); C(15);+# endif+#endif+  default:+    /* Based on the ASSERT(0 < n && n < VECTOR_FACTOR) above, this won't+       happen. The return is still here for compilers to not warn. */+    return a;+  }+}++#define FFCPS+#define FFCPS_DIFF1+#define FFCPS_CHAR1A2A++#define FFCPS_0+#include "pcre2_jit_neon_inc.h"+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+# define FF_UTF+# include "pcre2_jit_neon_inc.h"+# undef FF_UTF+#endif+#undef FFCPS_0++#undef FFCPS_CHAR1A2A++#define FFCPS_1+#include "pcre2_jit_neon_inc.h"+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+# define FF_UTF+# include "pcre2_jit_neon_inc.h"+# undef FF_UTF+#endif+#undef FFCPS_1++#undef FFCPS_DIFF1++#define FFCPS_DEFAULT+#include "pcre2_jit_neon_inc.h"+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+# define FF_UTF+# include "pcre2_jit_neon_inc.h"+# undef FF_UTF+#endif+#undef FFCPS++#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1++static void fast_forward_char_pair_simd(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 diff = IN_UCHARS(offs1 - offs2);+struct sljit_jump *partial_quit;+int_char ic;+SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);+SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));+SLJIT_ASSERT(compiler->scratches == 5);++/* Save temporary register STR_PTR. */+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);++/* Prepare arguments for the function call. */+if (common->match_end_ptr == 0)+   OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);+else+  {+  OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);+  OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));++  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, STR_END, 0, SLJIT_R0, 0);+  CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0);+  }++OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1);+OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2);+ic.c.c1 = char1a;+ic.c.c2 = char1b;+ic.c.c3 = char2a;+ic.c.c4 = char2b;+OP1(SLJIT_MOV_U32, SLJIT_R4, 0, SLJIT_IMM, ic.x);++if (diff == 1) {+  if (char1a == char1b && char2a == char2b) {+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf)+      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(ffcps_0_utf));+    else+#endif+      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(ffcps_0));+  } else {+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+    if (common->utf)+      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(ffcps_1_utf));+    else+#endif+      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(ffcps_1));+  }+} else {+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32+  if (common->utf)+    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(ffcps_default_utf));+  else+#endif+    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(ffcps_default));+}++/* Restore STR_PTR register. */+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);++/* Check return value. */+partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);+add_jump(compiler, &common->failed_match, partial_quit);++/* Fast forward STR_PTR to the result of memchr. */+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);++JUMPHERE(partial_quit);+}++#endif /* SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 */
+ src/c/pcre2/src/pcre2_jit_test.c view
@@ -0,0 +1,2501 @@+/*************************************************+*      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 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 <stdio.h>+#include <string.h>++#define PCRE2_CODE_UNIT_WIDTH 0+#include "pcre2.h"++/*+ Letter characters:+   \xe6\x92\xad = 0x64ad = 25773 (kanji)+ Non-letter characters:+   \xc2\xa1 = 0xa1 =  (Inverted Exclamation Mark)+   \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888+   \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character)+   \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character)+ Newlines:+   \xc2\x85 = 0x85 = 133 (NExt Line = NEL)+   \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator)+ Othercase pairs:+   \xc3\xa9 = 0xe9 = 233 (e')+      \xc3\x89 = 0xc9 = 201 (E')+   \xc3\xa1 = 0xe1 = 225 (a')+      \xc3\x81 = 0xc1 = 193 (A')+   \x53 = 0x53 = S+     \x73 = 0x73 = s+     \xc5\xbf = 0x17f = 383 (long S)+   \xc8\xba = 0x23a = 570+      \xe2\xb1\xa5 = 0x2c65 = 11365+   \xe1\xbd\xb8 = 0x1f78 = 8056+      \xe1\xbf\xb8 = 0x1ff8 = 8184+   \xf0\x90\x90\x80 = 0x10400 = 66560+      \xf0\x90\x90\xa8 = 0x10428 = 66600+   \xc7\x84 = 0x1c4 = 452+     \xc7\x85 = 0x1c5 = 453+     \xc7\x86 = 0x1c6 = 454+ Caseless sets:+   ucp_Armenian - \x{531}-\x{556} -> \x{561}-\x{586}+   ucp_Coptic - \x{2c80}-\x{2ce3} -> caseless: XOR 0x1+   ucp_Latin - \x{ff21}-\x{ff3a} -> \x{ff41]-\x{ff5a}++ Mark property:+   \xcc\x8d = 0x30d = 781+ Special:+   \xc2\x80 = 0x80 = 128 (lowest 2 byte character)+   \xdf\xbf = 0x7ff = 2047 (highest 2 byte character)+   \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character)+   \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character)+   \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character)+   \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character)+*/++static int regression_tests(void);+static int invalid_utf8_regression_tests(void);+static int invalid_utf16_regression_tests(void);+static int invalid_utf32_regression_tests(void);++int main(void)+{+	int jit = 0;+#if defined SUPPORT_PCRE2_8+	pcre2_config_8(PCRE2_CONFIG_JIT, &jit);+#elif defined SUPPORT_PCRE2_16+	pcre2_config_16(PCRE2_CONFIG_JIT, &jit);+#elif defined SUPPORT_PCRE2_32+	pcre2_config_32(PCRE2_CONFIG_JIT, &jit);+#endif+	if (!jit) {+		printf("JIT must be enabled to run pcre_jit_test\n");+		return 1;+	}+	return regression_tests()+		| invalid_utf8_regression_tests()+		| invalid_utf16_regression_tests()+		| invalid_utf32_regression_tests();+}++/* --------------------------------------------------------------------------------------- */++#if !(defined SUPPORT_PCRE2_8) && !(defined SUPPORT_PCRE2_16) && !(defined SUPPORT_PCRE2_32)+#error SUPPORT_PCRE2_8 or SUPPORT_PCRE2_16 or SUPPORT_PCRE2_32 must be defined+#endif++#define MU	(PCRE2_MULTILINE | PCRE2_UTF)+#define MUP	(PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP)+#define CMU	(PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF)+#define CMUP	(PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP)+#define M	(PCRE2_MULTILINE)+#define MP	(PCRE2_MULTILINE | PCRE2_UCP)+#define U	(PCRE2_UTF)+#define CM	(PCRE2_CASELESS | PCRE2_MULTILINE)++#define BSR(x)	((x) << 16)+#define A	PCRE2_NEWLINE_ANYCRLF++#define GET_NEWLINE(x)	((x) & 0xffff)+#define GET_BSR(x)	((x) >> 16)++#define OFFSET_MASK	0x00ffff+#define F_NO8		0x010000+#define F_NO16		0x020000+#define F_NO32		0x020000+#define F_NOMATCH	0x040000+#define F_DIFF		0x080000+#define F_FORCECONV	0x100000+#define F_PROPERTY	0x200000++struct regression_test_case {+	int compile_options;+	int newline;+	int match_options;+	int start_offset;+	const char *pattern;+	const char *input;+};++static struct regression_test_case regression_test_cases[] = {+	/* Constant strings. */+	{ MU, A, 0, 0, "AbC", "AbAbC" },+	{ MU, A, 0, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" },+	{ CMU, A, 0, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" },+	{ M, A, 0, 0, "[^a]", "aAbB" },+	{ CM, A, 0, 0, "[^m]", "mMnN" },+	{ M, A, 0, 0, "a[^b][^#]", "abacd" },+	{ CM, A, 0, 0, "A[^B][^E]", "abacd" },+	{ CMU, A, 0, 0, "[^x][^#]", "XxBll" },+	{ MU, A, 0, 0, "[^a]", "aaa\xc3\xa1#Ab" },+	{ CMU, A, 0, 0, "[^A]", "aA\xe6\x92\xad" },+	{ MU, A, 0, 0, "\\W(\\W)?\\w", "\r\n+bc" },+	{ MU, A, 0, 0, "\\W(\\W)?\\w", "\n\r+bc" },+	{ MU, A, 0, 0, "\\W(\\W)?\\w", "\r\r+bc" },+	{ MU, A, 0, 0, "\\W(\\W)?\\w", "\n\n+bc" },+	{ MU, A, 0, 0, "[axd]", "sAXd" },+	{ CMU, A, 0, 0, "[axd]", "sAXd" },+	{ CMU, A, 0, 0 | F_NOMATCH, "[^axd]", "DxA" },+	{ MU, A, 0, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" },+	{ MU, A, 0, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" },+	{ CMU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." },+	{ MU, A, 0, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." },+	{ MU, A, 0, 0, "[^a]", "\xc2\x80[]" },+	{ CMU, A, 0, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" },+	{ CM, A, 0, 0, "1a2b3c4", "1a2B3c51A2B3C4" },+	{ 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 /* !NEVER_BACKSLASH_C */+	{ 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" },+	{ CMUP, A, 0, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },+	{ M, A, 0, 0, "[3-57-9]", "5" },+	{ PCRE2_AUTO_CALLOUT, A, 0, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890",+		"12345678901234567890123456789012345678901234567890123456789012345678901234567890" },++	/* Assertions. */+	{ MU, A, 0, 0, "\\b[^A]", "A_B#" },+	{ M, A, 0, 0 | F_NOMATCH, "\\b\\W", "\n*" },+	{ MU, A, 0, 0, "\\B[^,]\\b[^s]\\b", "#X" },+	{ MP, A, 0, 0, "\\B", "_\xa1" },+	{ MP, A, 0, 0 | F_PROPERTY, "\\b_\\b[,A]\\B", "_," },+	{ MUP, A, 0, 0, "\\b", "\xe6\x92\xad!" },+	{ MUP, A, 0, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" },+	{ MUP, A, 0, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" },+	{ MUP, A, 0, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" },+	{ MU, A, 0, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" },+	{ CMUP, A, 0, 0, "\\By", "\xf0\x90\x90\xa8y" },+	{ M, A, 0, 0 | F_NOMATCH, "\\R^", "\n" },+	{ M, A, 0, 1 | F_NOMATCH, "^", "\n" },+	{ 0, 0, 0, 0, "^ab", "ab" },+	{ 0, 0, 0, 0 | F_NOMATCH, "^ab", "aab" },+	{ M, PCRE2_NEWLINE_CRLF, 0, 0, "^a", "\r\raa\n\naa\r\naa" },+	{ MU, A, 0, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" },+	{ M, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--b--\x85--" },+	{ MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xe2\x80\xa8--" },+	{ MU, PCRE2_NEWLINE_ANY, 0, 0, "^-", "a--\xc2\x85--" },+	{ 0, 0, 0, 0, "ab$", "ab" },+	{ 0, 0, 0, 0 | F_NOMATCH, "ab$", "abab\n\n" },+	{ PCRE2_DOLLAR_ENDONLY, 0, 0, 0 | F_NOMATCH, "ab$", "abab\r\n" },+	{ M, PCRE2_NEWLINE_CRLF, 0, 0, "a$", "\r\raa\n\naa\r\naa" },+	{ M, PCRE2_NEWLINE_ANY, 0, 0, "a$", "aaa" },+	{ MU, PCRE2_NEWLINE_ANYCRLF, 0, 0, "#$", "#\xc2\x85###\r#" },+	{ MU, PCRE2_NEWLINE_ANY, 0, 0, "#$", "#\xe2\x80\xa9" },+	{ 0, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0 | F_NOMATCH, "^a", "aa\naa" },+	{ M, PCRE2_NEWLINE_ANY, PCRE2_NOTBOL, 0, "^a", "aa\naa" },+	{ 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\naa" },+	{ 0, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0 | F_NOMATCH, "a$", "aa\r\n" },+	{ U | PCRE2_DOLLAR_ENDONLY, PCRE2_NEWLINE_ANY, 0, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" },+	{ M, PCRE2_NEWLINE_ANY, PCRE2_NOTEOL, 0, "a$", "aa\naa" },+	{ 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa" },+	{ U, PCRE2_NEWLINE_CR, 0, 0, "a\\Z", "aaa\r" },+	{ 0, PCRE2_NEWLINE_CR, 0, 0, ".\\Z", "aaa\n" },+	{ 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r" },+	{ U, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\n" },+	{ 0, PCRE2_NEWLINE_CRLF, 0, 0, ".\\Z", "aaa\r\n" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\n" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".\\Z", "aaa\r\n" },+	{ U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xc2\x85" },+	{ U, PCRE2_NEWLINE_ANY, 0, 0, ".\\Z", "aaa\xe2\x80\xa8" },+	{ M, A, 0, 0, "\\Aa", "aaa" },+	{ M, A, 0, 1 | F_NOMATCH, "\\Aa", "aaa" },+	{ M, A, 0, 1, "\\Ga", "aaa" },+	{ M, A, 0, 1 | F_NOMATCH, "\\Ga", "aba" },+	{ M, A, 0, 0, "a\\z", "aaa" },+	{ M, A, 0, 0 | F_NOMATCH, "a\\z", "aab" },++	/* Brackets and alternatives. */+	{ MU, A, 0, 0, "(ab|bb|cd)", "bacde" },+	{ MU, A, 0, 0, "(?:ab|a)(bc|c)", "ababc" },+	{ MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" },+	{ CMU, A, 0, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" },+	{ MU, A, 0, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" },+	{ MU, A, 0, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" },+	{ MU, A, 0, 0, "\xc7\x82|\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" },+	{ 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#" },+	{ CM, A, 0, 0, "ab|cd", "CD" },+	{ CM, A, 0, 0, "a1277|a1377|bX487", "bx487" },+	{ CM, A, 0, 0, "a1277|a1377|bx487", "bX487" },++	/* Greedy and non-greedy ? operators. */+	{ MU, A, 0, 0, "(?:a)?a", "laab" },+	{ CMU, A, 0, 0, "(A)?A", "llaab" },+	{ MU, A, 0, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */+	{ MU, A, 0, 0, "(a)?a", "manm" },+	{ CMU, A, 0, 0, "(a|b)?\?d((?:e)?)", "ABABdx" },+	{ MU, A, 0, 0, "(a|b)?\?d((?:e)?)", "abcde" },+	{ MU, A, 0, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" },++	/* Greedy and non-greedy + operators */+	{ MU, A, 0, 0, "(aa)+aa", "aaaaaaa" },+	{ MU, A, 0, 0, "(aa)+?aa", "aaaaaaa" },+	{ MU, A, 0, 0, "(?:aba|ab|a)+l", "ababamababal" },+	{ MU, A, 0, 0, "(?:aba|ab|a)+?l", "ababamababal" },+	{ MU, A, 0, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },+	{ MU, A, 0, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },+	{ MU, A, 0, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" },++	/* Greedy and non-greedy * operators */+	{ CMU, A, 0, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" },+	{ MU, A, 0, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" },+	{ MU, A, 0, 0, "(aa|ab)*ab", "aaabaaab" },+	{ CMU, A, 0, 0, "(aa|Ab)*?aB", "aaabaaab" },+	{ MU, A, 0, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" },+	{ MU, A, 0, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" },+	{ M, A, 0, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" },+	{ M, A, 0, 0, "((?:a|)*){0}a", "a" },++	/* Combining ? + * operators */+	{ MU, A, 0, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" },+	{ MU, A, 0, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" },+	{ MU, A, 0, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" },+	{ MU, A, 0, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" },+	{ MU, A, 0, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" },++	/* Single character iterators. */+	{ MU, A, 0, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" },+	{ MU, A, 0, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" },+	{ MU, A, 0, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" },+	{ MU, A, 0, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" },+	{ MU, A, 0, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" },+	{ MU, A, 0, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" },+	{ MU, A, 0, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" },+	{ MU, A, 0, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" },+	{ MU, A, 0, 0, "(ba{2})+c", "baabaaabacbaabaac" },+	{ MU, A, 0, 0, "(a*+bc++)+", "aaabbcaaabcccab" },+	{ MU, A, 0, 0, "(a?+[^b])+", "babaacacb" },+	{ MU, A, 0, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" },+	{ CMU, A, 0, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" },+	{ CMU, A, 0, 0, "[c-f]+k", "DemmFke" },+	{ MU, A, 0, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" },+	{ MU, A, 0, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" },+	{ CMU, A, 0, 0, "[ace]{3,7}", "AcbDAcEEcEd" },+	{ CMU, A, 0, 0, "[ace]{3,7}?", "AcbDAcEEcEd" },+	{ CMU, A, 0, 0, "[ace]{3,}", "AcbDAcEEcEd" },+	{ CMU, A, 0, 0, "[ace]{3,}?", "AcbDAcEEcEd" },+	{ MU, A, 0, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" },+	{ CMU, A, 0, 0, "[ace]{5}?", "AcCebDAcEEcEd" },+	{ MU, A, 0, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" },+	{ MU, A, 0, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" },+	{ MU, A, 0, 0, "\\b\\w+\\B", "x,a_cd" },+	{ MUP, A, 0, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" },+	{ CMU, A, 0, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" },+	{ CMUP, A, 0, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" },+	{ CMU, A, 0, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" },+	{ CMU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" },+	{ MU, A, 0, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" },+	{ MU, A, 0, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" },+	{ MU, A, 0, 0, "\\d+123", "987654321,01234" },+	{ MU, A, 0, 0, "abcd*|\\w+xy", "aaaaa,abxyz" },+	{ MU, A, 0, 0, "(?:abc|((?:amc|\\b\\w*xy)))", "aaaaa,abxyz" },+	{ MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.abcd#."},+	{ MU, A, 0, 0, "a(?R)|([a-z]++)#", ".abcd.mbcd#."},+	{ MU, A, 0, 0, ".[ab]*.", "xx" },+	{ MU, A, 0, 0, ".[ab]*a", "xxa" },+	{ MU, A, 0, 0, ".[ab]?.", "xx" },+	{ MU, A, 0, 0, "_[ab]+_*a", "_aa" },++	/* Bracket repeats with limit. */+	{ MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" },+	{ MU, A, 0, 0, "(?:ab|abab){1,5}M", "abababababababababababM" },+	{ MU, A, 0, 0, "(?>ab|abab){1,5}M", "abababababababababababM" },+	{ MU, A, 0, 0, "(?:ab|abab){1,5}?M", "abababababababababababM" },+	{ MU, A, 0, 0, "(?>ab|abab){1,5}?M", "abababababababababababM" },+	{ MU, A, 0, 0, "(?:(ab){1,4}?){1,3}?M", "abababababababababababababM" },+	{ MU, A, 0, 0, "(?:(ab){1,4}){1,3}abababababababababababM", "ababababababababababababM" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?:(ab){1,4}){1,3}abababababababababababM", "abababababababababababM" },+	{ MU, A, 0, 0, "(ab){4,6}?M", "abababababababM" },++	/* Basic character sets. */+	{ MU, A, 0, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " },+	{ MU, A, 0, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" },+	{ MU, A, 0, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" },+	{ MU, A, 0, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" },+	{ MU, A, 0, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" },+	{ MU, A, 0, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" },+	{ MU, A, 0, 0, "x[bcef]+", "xaxdxecbfg" },+	{ MU, A, 0, 0, "x[bcdghij]+", "xaxexfxdgbjk" },+	{ MU, A, 0, 0, "x[^befg]+", "xbxexacdhg" },+	{ MU, A, 0, 0, "x[^bcdl]+", "xlxbxaekmd" },+	{ MU, A, 0, 0, "x[^bcdghi]+", "xbxdxgxaefji" },+	{ MU, A, 0, 0, "x[B-Fb-f]+", "xaxAxgxbfBFG" },+	{ CMU, A, 0, 0, "\\x{e9}+", "#\xf0\x90\x90\xa8\xc3\xa8\xc3\xa9\xc3\x89\xc3\x88" },+	{ CMU, A, 0, 0, "[^\\x{e9}]+", "\xc3\xa9#\xf0\x90\x90\xa8\xc3\xa8\xc3\x88\xc3\x89" },+	{ MU, A, 0, 0, "[\\x02\\x7e]+", "\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x02\x7e\x7f" },+	{ MU, A, 0, 0, "[^\\x02\\x7e]+", "\x02\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x7f\x7e" },+	{ MU, A, 0, 0, "[\\x{81}-\\x{7fe}]+", "#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xc2\x81\xdf\xbe\xdf\xbf" },+	{ MU, A, 0, 0, "[^\\x{81}-\\x{7fe}]+", "\xc2\x81#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xdf\xbf\xdf\xbe" },+	{ MU, A, 0, 0, "[\\x{801}-\\x{fffe}]+", "#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xe0\xa0\x81\xef\xbf\xbe\xef\xbf\xbf" },+	{ MU, A, 0, 0, "[^\\x{801}-\\x{fffe}]+", "\xe0\xa0\x81#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xef\xbf\xbf\xef\xbf\xbe" },+	{ MU, A, 0, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" },+	{ MU, A, 0, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" },+	{ CMU, A, 0, 0 | F_NOMATCH, "^[\\x{0100}-\\x{017f}]", " " },++	/* Unicode properties. */+	{ MUP, A, 0, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" },+	{ MUP, A, 0, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" },+	{ MUP, A, 0, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" },+	{ MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" },+	{ MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" },+	{ MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" },+	{ MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" },+	{ MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" },+	{ MUP, A, 0, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" },+	{ MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" },+	{ MUP, A, 0, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" },+	{ MUP, A, 0, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" },+	{ CMUP, A, 0, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" },+	{ MUP, A, 0, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" },+	{ MUP, A, 0, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" },+	{ MU, A, 0, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" },+	{ CMUP, A, 0, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" },+	{ MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" },+	{ MUP, A, 0, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" },+	{ PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "[a-b\\s]{2,5}[^a]", "AB  baaa" },+	{ MUP, 0, 0, 0 | F_NOMATCH, "[^\\p{Hangul}\\p{Z}]", " " },++	/* Possible empty brackets. */+	{ MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" },+	{ MU, A, 0, 0, "(|ab||bc|a)+d", "abcxabcabd" },+	{ MU, A, 0, 0, "(?:|ab||bc|a)*d", "abcxabcabd" },+	{ MU, A, 0, 0, "(|ab||bc|a)*d", "abcxabcabd" },+	{ MU, A, 0, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" },+	{ MU, A, 0, 0, "(|ab||bc|a)+?d", "abcxabcabd" },+	{ MU, A, 0, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" },+	{ MU, A, 0, 0, "(|ab||bc|a)*?d", "abcxabcabd" },+	{ MU, A, 0, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" },+	{ MU, A, 0, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" },++	/* Start offset. */+	{ MU, A, 0, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" },+	{ MU, A, 0, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" },+	{ MU, A, 0, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" },+	{ MU, A, 0, 1, "(\\w\\W\\w)+", "ab#d" },++	/* Newline. */+	{ M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },+	{ M, PCRE2_NEWLINE_CR, 0, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },+	{ M, PCRE2_NEWLINE_CRLF, 0, 0, "\\W{1,3}[^#]", "\r\n##...." },+	{ MU, A, PCRE2_NO_UTF_CHECK, 1, "^.a", "\n\x80\nxa" },+	{ MU, A, 0, 1, "^", "\r\n" },+	{ M, PCRE2_NEWLINE_CRLF, 0, 1 | F_NOMATCH, "^", "\r\n" },+	{ M, PCRE2_NEWLINE_CRLF, 0, 1, "^", "\r\na" },++	/* Any character except newline or any newline. */+	{ 0, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" },+	{ U, PCRE2_NEWLINE_CRLF, 0, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" },+	{ 0, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" },+	{ U, PCRE2_NEWLINE_ANY, 0, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" },+	{ U, PCRE2_NEWLINE_ANYCRLF, 0, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" },+	{ 0, PCRE2_NEWLINE_ANY, 0, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" },+	{ U, PCRE2_NEWLINE_ANY, 0, 0, "(.+)#", "#\rMn\xc2\x85#\n###" },+	{ 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\r" },+	{ 0, BSR(PCRE2_BSR_ANYCRLF), 0, 0, "\\R", "\x85#\r\n#" },+	{ U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\xe2\x80\xa8#c" },+	{ U, BSR(PCRE2_BSR_UNICODE), 0, 0, "\\R", "ab\r\nc" },+	{ U, PCRE2_NEWLINE_CRLF | BSR(PCRE2_BSR_UNICODE), 0, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" },+	{ MU, A, 0, 0 | F_NOMATCH, "\\R+", "ab" },+	{ MU, A, 0, 0, "\\R+", "ab\r\n\r" },+	{ MU, A, 0, 0, "\\R*", "ab\r\n\r" },+	{ MU, A, 0, 0, "\\R*", "\r\n\r" },+	{ MU, A, 0, 0, "\\R{2,4}", "\r\nab\r\r" },+	{ MU, A, 0, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" },+	{ MU, A, 0, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" },+	{ MU, A, 0, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" },+	{ MU, A, 0, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" },+	{ MU, A, 0, 0, "\\R+\\R\\R", "\r\r\r" },+	{ MU, A, 0, 0, "\\R*\\R\\R", "\n\r" },+	{ MU, A, 0, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" },+	{ MU, A, 0, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" },++	/* Atomic groups (no fallback from "next" direction). */+	{ MU, A, 0, 0 | F_NOMATCH, "(?>ab)ab", "bab" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?>(ab))ab", "bab" },+	{ MU, A, 0, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op",+			"bababcdedefgheijijklmlmnop" },+	{ MU, A, 0, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" },+	{ MU, A, 0, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" },+	{ MU, A, 0, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" },+	{ MU, A, 0, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" },+	{ MU, A, 0, 0, "((?>a|)+?)b", "aaacaaab" },+	{ MU, A, 0, 0, "(?>x|)*$", "aaa" },+	{ MU, A, 0, 0, "(?>(x)|)*$", "aaa" },+	{ MU, A, 0, 0, "(?>x|())*$", "aaa" },+	{ MU, A, 0, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" },+	{ MU, A, 0, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" },+	{ MU, A, 0, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" },+	{ MU, A, 0, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" },+	{ MU, A, 0, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" },+	{ MU, A, 0, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" },+	{ MU, A, 0, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" },+	{ MU, A, 0, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" },+	{ MU, A, 0, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" },+	{ MU, A, 0, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" },+	{ MU, A, 0, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" },+	{ MU, A, 0, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" },+	{ MU, A, 0, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" },+	{ MU, A, 0, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" },+	{ CM, A, 0, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" },+	{ MU, A, 0, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" },+	{ MU, A, 0, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" },+	{ MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" },+	{ MU, A, 0, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" },+	{ MU, A, 0, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" },+	{ MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" },+	{ MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" },+	{ MU, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" },+	{ MU, A, 0, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" },+	{ MU, A, 0, 0, "(c(ab)?+ab)+", "cabcababcab" },+	{ MU, A, 0, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" },++	/* Possessive quantifiers. */+	{ MU, A, 0, 0, "(?:a|b)++m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "(?:a|b)*+m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "(?:a|b)*+m", "ababbaaxababbaam" },+	{ MU, A, 0, 0, "(a|b)++m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "(a|b)*+m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "(a|b)*+m", "ababbaaxababbaam" },+	{ MU, A, 0, 0, "(a|b(*ACCEPT))++m", "maaxab" },+	{ MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "(?:b*)++m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "(?:b*)*+m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "(b*)++m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "(b*)++m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "(b*)*+m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "(?:a|(b))++m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" },+	{ MU, A, 0, 0, "(a|(b))++m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "((a)|b)*+m", "mababbaaxababbaam" },+	{ MU, A, 0, 0, "((a)|(b))*+m", "ababbaaxababbaam" },+	{ MU, A, 0, 0, "(a|(b)(*ACCEPT))++m", "maaxab" },+	{ MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "(?:(b*))++m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "((b*))++m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "((b*))++m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxm" },+	{ MU, A, 0, 0, "((b*))*+m", "bxbbxbbbxbbm" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" },+	{ MU, A, 0, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" },+	{ MU, A, 0, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" },+	{ MU, A, 0, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" },+	{ MU, A, 0, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" },++	/* Back references. */+	{ MU, A, 0, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" },+	{ CMU, A, 0, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" },+	{ CM, A, 0, 0, "(a{2,4})\\1", "AaAaaAaA" },+	{ MU, A, 0, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" },+	{ MU, A, 0, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" },+	{ MU, A, 0, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" },+	{ MU, A, 0, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" },+	{ MU, A, 0, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" },+	{ MU, A, 0, 0, "(?:(aa)|b)\\1?b", "bb" },+	{ CMU, A, 0, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" },+	{ MU, A, 0, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" },+	{ CMU, A, 0, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" },+	{ MU, A, 0, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" },+	{ CM, A, 0, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" },+	{ MU, A, 0, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" },+	{ MU, A, 0, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" },+	{ M, A, 0, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" },+	{ MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." },+	{ MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." },+	{ MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" },+	{ MUP, A, 0, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" },+	{ PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." },+	{ CMUP, A, 0, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k<A>{1,3}(?<A>aa)(?<A>bb)", "aabb" },+	{ MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k<A>{1,3}(?<A>aa)(?<A>bb)", "aabb" },+	{ MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k<A>*(?<A>aa)(?<A>bb)", "aabb" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "(?<A>aa)(?<A>bb)\\k<A>{0,3}aaaaaa", "aabbaaaaaa" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "(?<A>aa)(?<A>bb)\\k<A>{2,5}bb", "aabbaaaabb" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>{0,3}m", "aaaaaaaabbbbaabbbbm" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0 | F_NOMATCH, "\\k<A>{1,3}?(?<A>aa)(?<A>bb)", "aabb" },+	{ MU | PCRE2_DUPNAMES | PCRE2_MATCH_UNSET_BACKREF, A, 0, 0, "\\k<A>{1,3}?(?<A>aa)(?<A>bb)", "aabb" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "\\k<A>*?(?<A>aa)(?<A>bb)", "aabb" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>{0,3}?m", "aaaaaabbbbbbaabbbbbbbbbbm" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>*?m", "aaaaaabbbbbbaabbbbbbbbbbm" },+	{ MU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>aa)|(?<A>bb))\\k<A>{2,3}?", "aaaabbbbaaaabbbbbbbbbb" },+	{ CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{0,3}M", "aaaaaaaabbbbaabbbbm" },+	{ CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{1,3}M", "aaaaaaaabbbbaabbbbm" },+	{ CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{0,3}?M", "aaaaaabbbbbbaabbbbbbbbbbm" },+	{ CMU | PCRE2_DUPNAMES, A, 0, 0, "(?:(?<A>AA)|(?<A>BB))\\k<A>{2,3}?", "aaaabbbbaaaabbbbbbbbbb" },++	/* Assertions. */+	{ MU, A, 0, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" },+	{ MU, A, 0, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" },+	{ MU, A, 0, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" },+	{ MU, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" },+	{ MU, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" },+	{ M, A, 0, 0, "(?<=aaa|aa|a)a", "aaa" },+	{ M, A, 0, 2, "(?<=aaa|aa|a)a", "aaa" },+	{ MU, A, 0, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" },+	{ MU, A, 0, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" },+	{ MU, A, 0, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" },+	{ MU, A, 0, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" },+	{ MU, A, 0, 0, "((?(?=(a))a)+k)", "bbak" },+	{ MU, A, 0, 0, "((?(?=a)a)+k)", "bbak" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" },+	{ MU, A, 0, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" },+	{ MU, A, 0, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" },+	{ MU, A, 0, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" },+	{ MU, A, 0, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" },+	{ MU, A, 0, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" },+	{ MU, A, 0, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" },+	{ MU, A, 0, 0, "((?!a)?(?!([^a]))?)+$", "acbab" },+	{ MU, A, 0, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" },+	{ MU, A, 0, 0, "a(?=(?C)\\B(?C`x`))b", "ab" },+	{ MU, A, 0, 0, "a(?!(?C)\\B(?C`x`))bb|ab", "abb" },+	{ MU, A, 0, 0, "a(?=\\b|(?C)\\B(?C`x`))b", "ab" },+	{ MU, A, 0, 0, "a(?!\\b|(?C)\\B(?C`x`))bb|ab", "abb" },+	{ MU, A, 0, 0, "c(?(?=(?C)\\B(?C`x`))ab|a)", "cab" },+	{ MU, A, 0, 0, "c(?(?!(?C)\\B(?C`x`))ab|a)", "cab" },+	{ MU, A, 0, 0, "c(?(?=\\b|(?C)\\B(?C`x`))ab|a)", "cab" },+	{ MU, A, 0, 0, "c(?(?!\\b|(?C)\\B(?C`x`))ab|a)", "cab" },+	{ MU, A, 0, 0, "a(?=)b", "ab" },+	{ MU, A, 0, 0 | F_NOMATCH, "a(?!)b", "ab" },++	/* Not empty, ACCEPT, FAIL */+	{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "a*", "bcaad" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "a*?", "bcaad" },+	{ MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*", "bcaad" },+	{ MU, A, 0, 0, "a(*ACCEPT)b", "ab" },+	{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" },+	{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" },+	{ MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" },+	{ MU, A, PCRE2_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" },+	{ MU, A, 0, 0, "((a(*ACCEPT)b))", "ab" },+	{ MU, A, 0, 0, "(a(*FAIL)a|a)", "aaa" },+	{ MU, A, 0, 0, "(?=ab(*ACCEPT)b)a", "ab" },+	{ MU, A, 0, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" },+	{ MU, A, 0, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" },+	{ MU, A, PCRE2_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" },+	{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "(?=A)", "AB" },++	/* Conditional blocks. */+	{ MU, A, 0, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" },+	{ MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" },+	{ MU, A, 0, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" },+	{ MU, A, 0, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" },+	{ MU, A, 0, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" },+	{ MU, A, 0, 0, "(?(?=a)ab)", "a" },+	{ MU, A, 0, 0, "(?(?<!b)c)", "b" },+	{ MU, A, 0, 0, "(?(DEFINE)a(b))", "a" },+	{ MU, A, 0, 0, "a(?(DEFINE)(?:b|(?:c?)+)*)", "a" },+	{ MU, A, 0, 0, "(?(?=.[a-c])[k-l]|[A-D])", "kdB" },+	{ MU, A, 0, 0, "(?(?!.{0,4}[cd])(aa|bb)|(cc|dd))+", "aabbccddaa" },+	{ MU, A, 0, 0, "(?(?=[^#@]*@)(aaab|aa|aba)|(aba|aab)){3,}", "aaabaaaba#aaabaaaba#aaabaaaba@" },+	{ MU, A, 0, 0, "((?=\\w{5})\\w(?(?=\\w*k)\\d|[a-f_])*\\w\\s)+", "mol m10kk m088k _f_a_ mbkkl" },+	{ MU, A, 0, 0, "(c)?\?(?(1)a|b)", "cdcaa" },+	{ MU, A, 0, 0, "(c)?\?(?(1)a|b)", "cbb" },+	{ MU, A, 0, 0 | F_DIFF, "(?(?=(a))(aaaa|a?))+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?=a)(aaaa|a?))+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?!(b))(aaaa|a?))+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?!b)(aaaa|a?))+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0 | F_DIFF, "(?(?=(a))a*)+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?=a)a*)+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?!(b))a*)+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?!b)a*)+aak", "aaaaab aaaaak" },+	{ MU, A, 0, 0, "(?(?=(?=(?!(x))a)aa)aaa|(?(?=(?!y)bb)bbb))*k", "abaabbaaabbbaaabbb abaabbaaabbbaaabbbk" },+	{ MU, A, 0, 0, "(?P<Name>a)?(?P<Name2>b)?(?(Name)c|d)*l", "bc ddd abccabccl" },+	{ MU, A, 0, 0, "(?P<Name>a)?(?P<Name2>b)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" },+	{ MU, A, 0, 0, "(?P<Name>a)?(?P<Name2>b)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" },+	{ MU, A, 0, 0, "((?:a|aa)(?(1)aaa))x", "aax" },+	{ MU, A, 0, 0, "(?(?!)a|b)", "ab" },+	{ MU, A, 0, 0, "(?(?!)a)", "ab" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?(?!)a|b)", "ac" },++	/* Set start of match. */+	{ MU, A, 0, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" },+	{ MU, A, 0, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" },+	{ MU, A, 0, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" },+	{ MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" },+	{ MU, A, PCRE2_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" },++	/* First line. */+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0, "(?<=a)", "a" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[^a][^b]", "ab" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "a", "\na" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "[abc]", "\na" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^a", "\na" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0 | F_NOMATCH, "^(?<=\n)", "\na" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0, "\xf0\x90\x90\x80", "\xf0\x90\x90\x80" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\xc2\x85#" },+	{ M | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "#", "\x85#" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_ANY, 0, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_PROPERTY, "\\p{Any}", "\r\na" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, ".", "\r" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0, "a", "\ra" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH, "ba", "bbb\r\nba" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" },+	{ MU | PCRE2_FIRSTLINE, PCRE2_NEWLINE_CRLF, 0, 1, ".", "\r\n" },+	{ PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_LF, 0, 0 | F_NOMATCH, "ab.", "ab" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" },+	{ PCRE2_FIRSTLINE | PCRE2_DOTALL, PCRE2_NEWLINE_ANY, 0, 0, "....a", "012\n0a" },+	{ MU | PCRE2_FIRSTLINE, A, 0, 0, "[aC]", "a" },++	/* Recurse. */+	{ MU, A, 0, 0, "(a)(?1)", "aa" },+	{ MU, A, 0, 0, "((a))(?1)", "aa" },+	{ MU, A, 0, 0, "(b|a)(?1)", "aa" },+	{ MU, A, 0, 0, "(b|(a))(?1)", "aa" },+	{ MU, A, 0, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" },+	{ MU, A, 0, 0, "((a)(b)(?:a*))(?1)", "abab" },+	{ MU, A, 0, 0, "((a+)c(?2))b(?1)", "aacaabaca" },+	{ MU, A, 0, 0, "((?2)b|(a)){2}(?1)", "aabab" },+	{ MU, A, 0, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" },+	{ 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, "(?(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" },+	{ MU, A, 0, 0, "b|<(?R)*>", "<<b>" },+	{ MU, A, 0, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" },+	{ MU, A, 0, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" },+	{ MU, A, 0, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" },+	{ MU, A, 0, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" },+	{ MU, A, 0, 0, "(a)((?(R1)a|b))(?2)", "ababba" },+	{ MU, A, 0, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" },+	{ MU, A, 0, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" },+	{ MU, A, 0, 0, "(?P<Name>a(?(R&Name)a|b))(?1)", "aab abb abaa" },+	{ MU, A, 0, 0, "((?(R)a|(?1)){3})", "XaaaaaaaaaX" },+	{ 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" },+	{ CM, A, 0, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" },+	{ CM, A, 0, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" },+	{ CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" },+	{ CM, A, 0, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" },+	{ CM, A, 0, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" },+	{ CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" },+	{ CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" },+	{ CM, A, 0, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" },+	{ CM, A, 0, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" },+	{ M, A, 0, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" },+	{ M, A, 0, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" },+	{ CM, A, 0, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" },+	{ CM, A, 0, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" },+	{ CM, A, 0, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" },+	{ CM, A, 0, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" },+	{ CM | PCRE2_EXTENDED, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" },+	{ CM, A, 0, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" },+	{ CM, A, 0, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" },+	{ M, PCRE2_NEWLINE_ANY, 0, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" },+	{ 0, BSR(PCRE2_BSR_UNICODE), 0, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" },+	{ 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" },+	{ 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" },+	{ 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" },+	{ 0, 0, 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" },++	/* Partial matching. */+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "ab", "a" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "ab|a", "a" },+	{ MU, A, PCRE2_PARTIAL_HARD, 0, "ab|a", "a" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "\\b#", "a" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "(?<=a)b", "a" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "a\\B", "a" },+	{ MU, A, PCRE2_PARTIAL_HARD, 0, "a\\b", "a" },++	/* (*MARK) verb. */+	{ MU, A, 0, 0, "a(*MARK:aa)a", "ababaa" },+	{ MU, A, 0, 0 | F_NOMATCH, "a(*:aa)a", "abab" },+	{ MU, A, 0, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" },+	{ MU, A, 0, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" },+	{ MU, A, 0, 0, "(?>a(*:aa))b|ac", "ac" },+	{ MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" },+	{ MU, A, 0, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" },+	{ MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" },+	{ MU, A, 0, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" },+	{ MU, A, 0, 0 | F_NOMATCH, "(a(*:aa)){0}(?:b(?1)b)+", "ba" },+	{ MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" },+	{ MU, A, 0, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" },+	{ MU, A, 0, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*:mark)m", "a" },++	/* (*COMMIT) verb. */+	{ MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" },+	{ MU, A, 0, 0, "aa(*COMMIT)b", "xaxaab" },+	{ MU, A, 0, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" },+	{ MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b)++", "abac" },+	{ MU, A, 0, 0 | F_NOMATCH, "((a)(*COMMIT)b)++", "abac" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?=a(*COMMIT)b)ab|ad", "ad" },++	/* (*PRUNE) verb. */+	{ MU, A, 0, 0, "aa\\K(*PRUNE)b", "aaab" },+	{ MU, A, 0, 0, "aa(*PRUNE:bb)b|a", "aa" },+	{ MU, A, 0, 0, "(a)(a)(*PRUNE)b|(a)", "aa" },+	{ MU, A, 0, 0, "(a)(a)(a)(a)(a)(a)(a)(a)(*PRUNE)b|(a)", "aaaaaaaa" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|", "a" },+	{ MU, A, PCRE2_PARTIAL_SOFT, 0, "a(*PRUNE)a|m", "a" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?=a(*PRUNE)b)ab|ad", "ad" },+	{ MU, A, 0, 0, "a(*COMMIT)(*PRUNE)d|bc", "abc" },+	{ MU, A, 0, 0, "(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=a(*COMMIT)b)a(*PRUNE)c|bc", "abc" },+	{ MU, A, 0, 0, "(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?=(a)(*COMMIT)b)a(*PRUNE)c|bc", "abc" },+	{ MU, A, 0, 0, "(a(*COMMIT)b){0}a(?1)(*PRUNE)c|bc", "abc" },+	{ MU, A, 0, 0 | F_NOMATCH, "(a(*COMMIT)b){0}a(*COMMIT)(?1)(*PRUNE)c|bc", "abc" },+	{ MU, A, 0, 0, "(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(a(*COMMIT)b)++(*PRUNE)d|c", "ababc" },+	{ MU, A, 0, 0, "((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)((a)(*COMMIT)b)++(*PRUNE)d|c", "ababc" },+	{ MU, A, 0, 0, "(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*abab(*PRUNE)d|ba", "ababab" },+	{ MU, A, 0, 0, "(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+abab(*PRUNE)d|ba", "ababab" },+	{ MU, A, 0, 0, "(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)?ab(*PRUNE)d|ba", "aba" },+	{ MU, A, 0, 0, "(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)*?n(*PRUNE)d|ba", "abababn" },+	{ MU, A, 0, 0, "(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)+?n(*PRUNE)d|ba", "abababn" },+	{ MU, A, 0, 0, "(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" },+	{ MU, A, 0, 0 | F_NOMATCH, "(*COMMIT)(?>a(*COMMIT)b)??n(*PRUNE)d|bn", "abn" },++	/* (*SKIP) verb. */+	{ MU, A, 0, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" },+	{ MU, A, 0, 0, "(\\w+(*SKIP)#)", "abcd,xyz#," },+	{ MU, A, 0, 0, "\\w+(*SKIP)#|mm", "abcd,xyz#," },+	{ MU, A, 0, 0 | F_NOMATCH, "b+(?<=(*SKIP)#c)|b+", "#bbb" },++	/* (*THEN) verb. */+	{ MU, A, 0, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" },+	{ MU, A, 0, 0 | F_NOMATCH, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcm" },+	{ MU, A, 0, 0, "((?:a(*THEN)|aab)c|a+)+m", "aabcaabcnmaabcaabcm" },+	{ MU, A, 0, 0, "((?:a|aab)(*THEN)c|a+)+m", "aam" },+	{ MU, A, 0, 0, "((?:a(*COMMIT)|aab)(*THEN)c|a+)+m", "aam" },+	{ MU, A, 0, 0, "(?(?=a(*THEN)b)ab|ad)", "ad" },+	{ MU, A, 0, 0, "(?(?!a(*THEN)b)ad|add)", "add" },+	{ MU, A, 0, 0 | F_NOMATCH, "(?(?=a)a(*THEN)b|ad)", "ad" },+	{ MU, A, 0, 0, "(?!(?(?=a)ab|b(*THEN)d))bn|bnn", "bnn" },+	{ MU, A, 0, 0, "(?=(*THEN: ))* ", " " },+	{ MU, A, 0, 0, "a(*THEN)(?R) |", "a" },++	/* 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_" },++#ifdef SUPPORT_UNICODE+	/* Script runs and iterations. */+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)*#", "!abcdefghijklmno!abcdefghijklmno!abcdef#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)+#", "!abcdefghijklmno!abcdefghijklmno!abcdef#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)*?#", "!abcdefghijklmno!abcdefghijklmno!abcdef#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)+?#", "!abcdefghijklmno!abcdefghijklmno!abcdef#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)*+#", "!abcdefghijklmno!abcdefghijklmno!abcdef#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)++#", "!abcdefghijklmno!abcdefghijklmno!abcdef#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)?#", "!ab!abc!ab!ab#" },+	{ MU, A, 0, 0, "!(*sr:\\w\\w|\\w\\w\\w)??#", "!ab!abc!ab!ab#" },+#endif++	/* 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?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" },+	{ M, A, 0, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },++	{ 0, 0, 0, 0, NULL, NULL }+};++#ifdef SUPPORT_PCRE2_8+static pcre2_jit_stack_8* callback8(void *arg)+{+	return (pcre2_jit_stack_8 *)arg;+}+#endif++#ifdef SUPPORT_PCRE2_16+static pcre2_jit_stack_16* callback16(void *arg)+{+	return (pcre2_jit_stack_16 *)arg;+}+#endif++#ifdef SUPPORT_PCRE2_32+static pcre2_jit_stack_32* callback32(void *arg)+{+	return (pcre2_jit_stack_32 *)arg;+}+#endif++#ifdef SUPPORT_PCRE2_8+static pcre2_jit_stack_8 *stack8;++static pcre2_jit_stack_8 *getstack8(void)+{+	if (!stack8)+		stack8 = pcre2_jit_stack_create_8(1, 1024 * 1024, NULL);+	return stack8;+}++static void setstack8(pcre2_match_context_8 *mcontext)+{+	if (!mcontext) {+		if (stack8)+			pcre2_jit_stack_free_8(stack8);+		stack8 = NULL;+		return;+	}++	pcre2_jit_stack_assign_8(mcontext, callback8, getstack8());+}+#endif /* SUPPORT_PCRE2_8 */++#ifdef SUPPORT_PCRE2_16+static pcre2_jit_stack_16 *stack16;++static pcre2_jit_stack_16 *getstack16(void)+{+	if (!stack16)+		stack16 = pcre2_jit_stack_create_16(1, 1024 * 1024, NULL);+	return stack16;+}++static void setstack16(pcre2_match_context_16 *mcontext)+{+	if (!mcontext) {+		if (stack16)+			pcre2_jit_stack_free_16(stack16);+		stack16 = NULL;+		return;+	}++	pcre2_jit_stack_assign_16(mcontext, callback16, getstack16());+}+#endif /* SUPPORT_PCRE2_16 */++#ifdef SUPPORT_PCRE2_32+static pcre2_jit_stack_32 *stack32;++static pcre2_jit_stack_32 *getstack32(void)+{+	if (!stack32)+		stack32 = pcre2_jit_stack_create_32(1, 1024 * 1024, NULL);+	return stack32;+}++static void setstack32(pcre2_match_context_32 *mcontext)+{+	if (!mcontext) {+		if (stack32)+			pcre2_jit_stack_free_32(stack32);+		stack32 = NULL;+		return;+	}++	pcre2_jit_stack_assign_32(mcontext, callback32, getstack32());+}+#endif /* SUPPORT_PCRE2_32 */++#ifdef SUPPORT_PCRE2_16++static int convert_utf8_to_utf16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int *offsetmap, int max_length)+{+	PCRE2_SPTR8 iptr = input;+	PCRE2_UCHAR16 *optr = output;+	unsigned int c;++	if (max_length == 0)+		return 0;++	while (*iptr && max_length > 1) {+		c = 0;+		if (offsetmap)+			*offsetmap++ = (int)(iptr - (unsigned char*)input);++		if (*iptr < 0xc0)+			c = *iptr++;+		else if (!(*iptr & 0x20)) {+			c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);+			iptr += 2;+		} else if (!(*iptr & 0x10)) {+			c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f);+			iptr += 3;+		} else if (!(*iptr & 0x08)) {+			c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f);+			iptr += 4;+		}++		if (c < 65536) {+			*optr++ = c;+			max_length--;+		} else if (max_length <= 2) {+			*optr = '\0';+			return (int)(optr - output);+		} else {+			c -= 0x10000;+			*optr++ = 0xd800 | ((c >> 10) & 0x3ff);+			*optr++ = 0xdc00 | (c & 0x3ff);+			max_length -= 2;+			if (offsetmap)+				offsetmap++;+		}+	}+	if (offsetmap)+		*offsetmap = (int)(iptr - (unsigned char*)input);+	*optr = '\0';+	return (int)(optr - output);+}++static int copy_char8_to_char16(PCRE2_SPTR8 input, PCRE2_UCHAR16 *output, int max_length)+{+	PCRE2_SPTR8 iptr = input;+	PCRE2_UCHAR16 *optr = output;++	if (max_length == 0)+		return 0;++	while (*iptr && max_length > 1) {+		*optr++ = *iptr++;+		max_length--;+	}+	*optr = '\0';+	return (int)(optr - output);+}++#define REGTEST_MAX_LENGTH16 4096+static PCRE2_UCHAR16 regtest_buf16[REGTEST_MAX_LENGTH16];+static int regtest_offsetmap16[REGTEST_MAX_LENGTH16];++#endif /* SUPPORT_PCRE2_16 */++#ifdef SUPPORT_PCRE2_32++static int convert_utf8_to_utf32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int *offsetmap, int max_length)+{+	PCRE2_SPTR8 iptr = input;+	PCRE2_UCHAR32 *optr = output;+	unsigned int c;++	if (max_length == 0)+		return 0;++	while (*iptr && max_length > 1) {+		c = 0;+		if (offsetmap)+			*offsetmap++ = (int)(iptr - (unsigned char*)input);++		if (*iptr < 0xc0)+			c = *iptr++;+		else if (!(*iptr & 0x20)) {+			c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);+			iptr += 2;+		} else if (!(*iptr & 0x10)) {+			c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f);+			iptr += 3;+		} else if (!(*iptr & 0x08)) {+			c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f);+			iptr += 4;+		}++		*optr++ = c;+		max_length--;+	}+	if (offsetmap)+		*offsetmap = (int)(iptr - (unsigned char*)input);+	*optr = 0;+	return (int)(optr - output);+}++static int copy_char8_to_char32(PCRE2_SPTR8 input, PCRE2_UCHAR32 *output, int max_length)+{+	PCRE2_SPTR8 iptr = input;+	PCRE2_UCHAR32 *optr = output;++	if (max_length == 0)+		return 0;++	while (*iptr && max_length > 1) {+		*optr++ = *iptr++;+		max_length--;+	}+	*optr = '\0';+	return (int)(optr - output);+}++#define REGTEST_MAX_LENGTH32 4096+static PCRE2_UCHAR32 regtest_buf32[REGTEST_MAX_LENGTH32];+static int regtest_offsetmap32[REGTEST_MAX_LENGTH32];++#endif /* SUPPORT_PCRE2_32 */++static int check_ascii(const char *input)+{+	const unsigned char *ptr = (unsigned char *)input;+	while (*ptr) {+		if (*ptr > 127)+			return 0;+		ptr++;+	}+	return 1;+}++#define OVECTOR_SIZE 15++static int regression_tests(void)+{+	struct regression_test_case *current = regression_test_cases;+	int error;+	PCRE2_SIZE err_offs;+	int is_successful;+	int is_ascii;+	int total = 0;+	int successful = 0;+	int successful_row = 0;+	int counter = 0;+	int jit_compile_mode;+	int utf = 0;+	int disabled_options = 0;+	int i;+#ifdef SUPPORT_PCRE2_8+	pcre2_code_8 *re8;+	pcre2_compile_context_8 *ccontext8;+	pcre2_match_data_8 *mdata8_1;+	pcre2_match_data_8 *mdata8_2;+	pcre2_match_context_8 *mcontext8;+	PCRE2_SIZE *ovector8_1 = NULL;+	PCRE2_SIZE *ovector8_2 = NULL;+	int return_value8[2];+#endif+#ifdef SUPPORT_PCRE2_16+	pcre2_code_16 *re16;+	pcre2_compile_context_16 *ccontext16;+	pcre2_match_data_16 *mdata16_1;+	pcre2_match_data_16 *mdata16_2;+	pcre2_match_context_16 *mcontext16;+	PCRE2_SIZE *ovector16_1 = NULL;+	PCRE2_SIZE *ovector16_2 = NULL;+	int return_value16[2];+	int length16;+#endif+#ifdef SUPPORT_PCRE2_32+	pcre2_code_32 *re32;+	pcre2_compile_context_32 *ccontext32;+	pcre2_match_data_32 *mdata32_1;+	pcre2_match_data_32 *mdata32_2;+	pcre2_match_context_32 *mcontext32;+	PCRE2_SIZE *ovector32_1 = NULL;+	PCRE2_SIZE *ovector32_2 = NULL;+	int return_value32[2];+	int length32;+#endif++#if defined SUPPORT_PCRE2_8+	PCRE2_UCHAR8 cpu_info[128];+#elif defined SUPPORT_PCRE2_16+	PCRE2_UCHAR16 cpu_info[128];+#elif defined SUPPORT_PCRE2_32+	PCRE2_UCHAR32 cpu_info[128];+#endif+#if defined SUPPORT_UNICODE && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2)+	int return_value;+#endif++	/* This test compares the behaviour of interpreter and JIT. Although disabling+	utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is+	still considered successful from pcre_jit_test point of view. */++#if defined SUPPORT_PCRE2_8+	pcre2_config_8(PCRE2_CONFIG_JITTARGET, &cpu_info);+#elif defined SUPPORT_PCRE2_16+	pcre2_config_16(PCRE2_CONFIG_JITTARGET, &cpu_info);+#elif defined SUPPORT_PCRE2_32+	pcre2_config_32(PCRE2_CONFIG_JITTARGET, &cpu_info);+#endif++	printf("Running JIT regression tests\n");+	printf("  target CPU of SLJIT compiler: ");+	for (i = 0; cpu_info[i]; i++)+		printf("%c", (char)(cpu_info[i]));+	printf("\n");++#if defined SUPPORT_PCRE2_8+	pcre2_config_8(PCRE2_CONFIG_UNICODE, &utf);+#elif defined SUPPORT_PCRE2_16+	pcre2_config_16(PCRE2_CONFIG_UNICODE, &utf);+#elif defined SUPPORT_PCRE2_32+	pcre2_config_32(PCRE2_CONFIG_UNICODE, &utf);+#endif++	if (!utf)+		disabled_options |= PCRE2_UTF;+#ifdef SUPPORT_PCRE2_8+	printf("  in  8 bit mode with UTF-8  %s:\n", utf ? "enabled" : "disabled");+#endif+#ifdef SUPPORT_PCRE2_16+	printf("  in 16 bit mode with UTF-16 %s:\n", utf ? "enabled" : "disabled");+#endif+#ifdef SUPPORT_PCRE2_32+	printf("  in 32 bit mode with UTF-32 %s:\n", utf ? "enabled" : "disabled");+#endif++	while (current->pattern) {+		/* printf("\nPattern: %s :\n", current->pattern); */+		total++;+		is_ascii = 0;+		if (!(current->start_offset & F_PROPERTY))+			is_ascii = check_ascii(current->pattern) && check_ascii(current->input);++		if (current->match_options & PCRE2_PARTIAL_SOFT)+			jit_compile_mode = PCRE2_JIT_PARTIAL_SOFT;+		else if (current->match_options & PCRE2_PARTIAL_HARD)+			jit_compile_mode = PCRE2_JIT_PARTIAL_HARD;+		else+			jit_compile_mode = PCRE2_JIT_COMPLETE;+		error = 0;+#ifdef SUPPORT_PCRE2_8+		re8 = NULL;+		ccontext8 = pcre2_compile_context_create_8(NULL);+		if (ccontext8) {+			if (GET_NEWLINE(current->newline))+				pcre2_set_newline_8(ccontext8, GET_NEWLINE(current->newline));+			if (GET_BSR(current->newline))+				pcre2_set_bsr_8(ccontext8, GET_BSR(current->newline));++			if (!(current->start_offset & F_NO8)) {+				re8 = pcre2_compile_8((PCRE2_SPTR8)current->pattern, PCRE2_ZERO_TERMINATED,+					current->compile_options & ~disabled_options,+					&error, &err_offs, ccontext8);++				if (!re8 && (utf || is_ascii))+					printf("\n8 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error);+			}+			pcre2_compile_context_free_8(ccontext8);+		}+		else+			printf("\n8 bit: Cannot allocate compile context\n");+#endif+#ifdef SUPPORT_PCRE2_16+		if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))+			convert_utf8_to_utf16((PCRE2_SPTR8)current->pattern, regtest_buf16, NULL, REGTEST_MAX_LENGTH16);+		else+			copy_char8_to_char16((PCRE2_SPTR8)current->pattern, regtest_buf16, REGTEST_MAX_LENGTH16);++		re16 = NULL;+		ccontext16 = pcre2_compile_context_create_16(NULL);+		if (ccontext16) {+			if (GET_NEWLINE(current->newline))+				pcre2_set_newline_16(ccontext16, GET_NEWLINE(current->newline));+			if (GET_BSR(current->newline))+				pcre2_set_bsr_16(ccontext16, GET_BSR(current->newline));++			if (!(current->start_offset & F_NO16)) {+				re16 = pcre2_compile_16(regtest_buf16, PCRE2_ZERO_TERMINATED,+					current->compile_options & ~disabled_options,+					&error, &err_offs, ccontext16);++				if (!re16 && (utf || is_ascii))+					printf("\n16 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error);+			}+			pcre2_compile_context_free_16(ccontext16);+		}+		else+			printf("\n16 bit: Cannot allocate compile context\n");+#endif+#ifdef SUPPORT_PCRE2_32+		if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))+			convert_utf8_to_utf32((PCRE2_SPTR8)current->pattern, regtest_buf32, NULL, REGTEST_MAX_LENGTH32);+		else+			copy_char8_to_char32((PCRE2_SPTR8)current->pattern, regtest_buf32, REGTEST_MAX_LENGTH32);++		re32 = NULL;+		ccontext32 = pcre2_compile_context_create_32(NULL);+		if (ccontext32) {+			if (GET_NEWLINE(current->newline))+				pcre2_set_newline_32(ccontext32, GET_NEWLINE(current->newline));+			if (GET_BSR(current->newline))+				pcre2_set_bsr_32(ccontext32, GET_BSR(current->newline));++			if (!(current->start_offset & F_NO32)) {+				re32 = pcre2_compile_32(regtest_buf32, PCRE2_ZERO_TERMINATED,+					current->compile_options & ~disabled_options,+					&error, &err_offs, ccontext32);++				if (!re32 && (utf || is_ascii))+					printf("\n32 bit: Cannot compile pattern \"%s\": %d\n", current->pattern, error);+			}+			pcre2_compile_context_free_32(ccontext32);+		}+		else+			printf("\n32 bit: Cannot allocate compile context\n");+#endif++		counter++;+		if ((counter & 0x3) != 0) {+#ifdef SUPPORT_PCRE2_8+			setstack8(NULL);+#endif+#ifdef SUPPORT_PCRE2_16+			setstack16(NULL);+#endif+#ifdef SUPPORT_PCRE2_32+			setstack32(NULL);+#endif+		}++#ifdef SUPPORT_PCRE2_8+		return_value8[0] = -1000;+		return_value8[1] = -1000;+		mdata8_1 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL);+		mdata8_2 = pcre2_match_data_create_8(OVECTOR_SIZE, NULL);+		mcontext8 = pcre2_match_context_create_8(NULL);+		if (!mdata8_1 || !mdata8_2 || !mcontext8) {+			printf("\n8 bit: Cannot allocate match data\n");+			pcre2_match_data_free_8(mdata8_1);+			pcre2_match_data_free_8(mdata8_2);+			pcre2_match_context_free_8(mcontext8);+			pcre2_code_free_8(re8);+			re8 = NULL;+		} 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 * 2; ++i)+				ovector8_1[i] = -2;+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)+				ovector8_2[i] = -2;+			pcre2_set_match_limit_8(mcontext8, 10000000);+		}+		if (re8) {+			return_value8[1] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input),+				current->start_offset & OFFSET_MASK, current->match_options, mdata8_2, mcontext8);++			if (pcre2_jit_compile_8(re8, jit_compile_mode)) {+				printf("\n8 bit: JIT compiler does not support \"%s\"\n", current->pattern);+			} else if ((counter & 0x1) != 0) {+				setstack8(mcontext8);+				return_value8[0] = pcre2_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input),+					current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8);+			} else {+				pcre2_jit_stack_assign_8(mcontext8, NULL, getstack8());+				return_value8[0] = pcre2_jit_match_8(re8, (PCRE2_SPTR8)current->input, strlen(current->input),+					current->start_offset & OFFSET_MASK, current->match_options, mdata8_1, mcontext8);+			}+		}+#endif++#ifdef SUPPORT_PCRE2_16+		return_value16[0] = -1000;+		return_value16[1] = -1000;+		mdata16_1 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL);+		mdata16_2 = pcre2_match_data_create_16(OVECTOR_SIZE, NULL);+		mcontext16 = pcre2_match_context_create_16(NULL);+		if (!mdata16_1 || !mdata16_2 || !mcontext16) {+			printf("\n16 bit: Cannot allocate match data\n");+			pcre2_match_data_free_16(mdata16_1);+			pcre2_match_data_free_16(mdata16_2);+			pcre2_match_context_free_16(mcontext16);+			pcre2_code_free_16(re16);+			re16 = NULL;+		} 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 * 2; ++i)+				ovector16_1[i] = -2;+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)+				ovector16_2[i] = -2;+			pcre2_set_match_limit_16(mcontext16, 10000000);+		}+		if (re16) {+			if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))+				length16 = convert_utf8_to_utf16((PCRE2_SPTR8)current->input, regtest_buf16, regtest_offsetmap16, REGTEST_MAX_LENGTH16);+			else+				length16 = copy_char8_to_char16((PCRE2_SPTR8)current->input, regtest_buf16, REGTEST_MAX_LENGTH16);++			return_value16[1] = pcre2_match_16(re16, regtest_buf16, length16,+				current->start_offset & OFFSET_MASK, current->match_options, mdata16_2, mcontext16);++			if (pcre2_jit_compile_16(re16, jit_compile_mode)) {+				printf("\n16 bit: JIT compiler does not support \"%s\"\n", current->pattern);+			} else if ((counter & 0x1) != 0) {+				setstack16(mcontext16);+				return_value16[0] = pcre2_match_16(re16, regtest_buf16, length16,+					current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16);+			} else {+				pcre2_jit_stack_assign_16(mcontext16, NULL, getstack16());+				return_value16[0] = pcre2_jit_match_16(re16, regtest_buf16, length16,+					current->start_offset & OFFSET_MASK, current->match_options, mdata16_1, mcontext16);+			}+		}+#endif++#ifdef SUPPORT_PCRE2_32+		return_value32[0] = -1000;+		return_value32[1] = -1000;+		mdata32_1 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL);+		mdata32_2 = pcre2_match_data_create_32(OVECTOR_SIZE, NULL);+		mcontext32 = pcre2_match_context_create_32(NULL);+		if (!mdata32_1 || !mdata32_2 || !mcontext32) {+			printf("\n32 bit: Cannot allocate match data\n");+			pcre2_match_data_free_32(mdata32_1);+			pcre2_match_data_free_32(mdata32_2);+			pcre2_match_context_free_32(mcontext32);+			pcre2_code_free_32(re32);+			re32 = NULL;+		} 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 * 2; ++i)+				ovector32_1[i] = -2;+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)+				ovector32_2[i] = -2;+			pcre2_set_match_limit_32(mcontext32, 10000000);+		}+		if (re32) {+			if ((current->compile_options & PCRE2_UTF) || (current->start_offset & F_FORCECONV))+				length32 = convert_utf8_to_utf32((PCRE2_SPTR8)current->input, regtest_buf32, regtest_offsetmap32, REGTEST_MAX_LENGTH32);+			else+				length32 = copy_char8_to_char32((PCRE2_SPTR8)current->input, regtest_buf32, REGTEST_MAX_LENGTH32);++			return_value32[1] = pcre2_match_32(re32, regtest_buf32, length32,+				current->start_offset & OFFSET_MASK, current->match_options, mdata32_2, mcontext32);++			if (pcre2_jit_compile_32(re32, jit_compile_mode)) {+				printf("\n32 bit: JIT compiler does not support \"%s\"\n", current->pattern);+			} else if ((counter & 0x1) != 0) {+				setstack32(mcontext32);+				return_value32[0] = pcre2_match_32(re32, regtest_buf32, length32,+					current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32);+			} else {+				pcre2_jit_stack_assign_32(mcontext32, NULL, getstack32());+				return_value32[0] = pcre2_jit_match_32(re32, regtest_buf32, length32,+					current->start_offset & OFFSET_MASK, current->match_options, mdata32_1, mcontext32);+			}+		}+#endif++		/* printf("[%d-%d-%d|%d-%d|%d-%d|%d-%d]%s",+			return_value8[0], return_value16[0], return_value32[0],+			(int)ovector8_1[0], (int)ovector8_1[1],+			(int)ovector16_1[0], (int)ovector16_1[1],+			(int)ovector32_1[0], (int)ovector32_1[1],+			(current->compile_options & PCRE2_CASELESS) ? "C" : ""); */++		/* If F_DIFF is set, just run the test, but do not compare the results.+		Segfaults can still be captured. */++		is_successful = 1;+		if (!(current->start_offset & F_DIFF)) {+#if defined SUPPORT_UNICODE && ((defined(SUPPORT_PCRE2_8) + defined(SUPPORT_PCRE2_16) + defined(SUPPORT_PCRE2_32)) >= 2)+			if (!(current->start_offset & F_FORCECONV)) {++				/* All results must be the same. */+#ifdef SUPPORT_PCRE2_8+				if ((return_value = return_value8[0]) != return_value8[1]) {+					printf("\n8 bit: Return value differs(J8:%d,I8:%d): [%d] '%s' @ '%s'\n",+						return_value8[0], return_value8[1], total, current->pattern, current->input);+					is_successful = 0;+				} else+#endif+#ifdef SUPPORT_PCRE2_16+				if ((return_value = return_value16[0]) != return_value16[1]) {+					printf("\n16 bit: Return value differs(J16:%d,I16:%d): [%d] '%s' @ '%s'\n",+						return_value16[0], return_value16[1], total, current->pattern, current->input);+					is_successful = 0;+				} else+#endif+#ifdef SUPPORT_PCRE2_32+				if ((return_value = return_value32[0]) != return_value32[1]) {+					printf("\n32 bit: Return value differs(J32:%d,I32:%d): [%d] '%s' @ '%s'\n",+						return_value32[0], return_value32[1], total, current->pattern, current->input);+					is_successful = 0;+				} else+#endif+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16+				if (return_value8[0] != return_value16[0]) {+					printf("\n8 and 16 bit: Return value differs(J8:%d,J16:%d): [%d] '%s' @ '%s'\n",+						return_value8[0], return_value16[0],+						total, current->pattern, current->input);+					is_successful = 0;+				} else+#endif+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32+				if (return_value8[0] != return_value32[0]) {+					printf("\n8 and 32 bit: Return value differs(J8:%d,J32:%d): [%d] '%s' @ '%s'\n",+						return_value8[0], return_value32[0],+						total, current->pattern, current->input);+					is_successful = 0;+				} else+#endif+#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32+				if (return_value16[0] != return_value32[0]) {+					printf("\n16 and 32 bit: Return value differs(J16:%d,J32:%d): [%d] '%s' @ '%s'\n",+						return_value16[0], return_value32[0],+						total, current->pattern, current->input);+					is_successful = 0;+				} else+#endif+				if (return_value >= 0 || return_value == PCRE2_ERROR_PARTIAL) {+					if (return_value == PCRE2_ERROR_PARTIAL) {+						return_value = 2;+					} else {+						return_value *= 2;+					}+#ifdef SUPPORT_PCRE2_8+					return_value8[0] = return_value;+#endif+#ifdef SUPPORT_PCRE2_16+					return_value16[0] = return_value;+#endif+#ifdef SUPPORT_PCRE2_32+					return_value32[0] = return_value;+#endif+					/* Transform back the results. */+					if (current->compile_options & PCRE2_UTF) {+#ifdef SUPPORT_PCRE2_16+						for (i = 0; i < return_value; ++i) {+							if (ovector16_1[i] != PCRE2_UNSET)+								ovector16_1[i] = regtest_offsetmap16[ovector16_1[i]];+							if (ovector16_2[i] != PCRE2_UNSET)+								ovector16_2[i] = regtest_offsetmap16[ovector16_2[i]];+						}+#endif+#ifdef SUPPORT_PCRE2_32+						for (i = 0; i < return_value; ++i) {+							if (ovector32_1[i] != PCRE2_UNSET)+								ovector32_1[i] = regtest_offsetmap32[ovector32_1[i]];+							if (ovector32_2[i] != PCRE2_UNSET)+								ovector32_2[i] = regtest_offsetmap32[ovector32_2[i]];+						}+#endif+					}++					for (i = 0; i < return_value; ++i) {+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_16+						if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) {+							printf("\n8 and 16 bit: Ovector[%d] value differs(J8:%d,I8:%d,J16:%d,I16:%d): [%d] '%s' @ '%s' \n",+								i, (int)ovector8_1[i], (int)ovector8_2[i], (int)ovector16_1[i], (int)ovector16_2[i],+								total, current->pattern, current->input);+							is_successful = 0;+						}+#endif+#if defined SUPPORT_PCRE2_8 && defined SUPPORT_PCRE2_32+						if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector32_1[i] || ovector8_1[i] != ovector32_2[i]) {+							printf("\n8 and 32 bit: Ovector[%d] value differs(J8:%d,I8:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n",+								i, (int)ovector8_1[i], (int)ovector8_2[i], (int)ovector32_1[i], (int)ovector32_2[i],+								total, current->pattern, current->input);+							is_successful = 0;+						}+#endif+#if defined SUPPORT_PCRE2_16 && defined SUPPORT_PCRE2_32+						if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector32_1[i] || ovector16_1[i] != ovector32_2[i]) {+							printf("\n16 and 32 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n",+								i, (int)ovector16_1[i], (int)ovector16_2[i], (int)ovector32_1[i], (int)ovector32_2[i],+								total, current->pattern, current->input);+							is_successful = 0;+						}+#endif+					}+				}+			} else+#endif /* more than one of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16 and SUPPORT_PCRE2_32 */+			{+#ifdef SUPPORT_PCRE2_8+				if (return_value8[0] != return_value8[1]) {+					printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",+						return_value8[0], return_value8[1], total, current->pattern, current->input);+					is_successful = 0;+				} else if (return_value8[0] >= 0 || return_value8[0] == PCRE2_ERROR_PARTIAL) {+					if (return_value8[0] == PCRE2_ERROR_PARTIAL)+						return_value8[0] = 2;+					else+						return_value8[0] *= 2;++					for (i = 0; i < return_value8[0]; ++i)+						if (ovector8_1[i] != ovector8_2[i]) {+							printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",+								i, (int)ovector8_1[i], (int)ovector8_2[i], total, current->pattern, current->input);+							is_successful = 0;+						}+				}+#endif++#ifdef SUPPORT_PCRE2_16+				if (return_value16[0] != return_value16[1]) {+					printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",+						return_value16[0], return_value16[1], total, current->pattern, current->input);+					is_successful = 0;+				} else if (return_value16[0] >= 0 || return_value16[0] == PCRE2_ERROR_PARTIAL) {+					if (return_value16[0] == PCRE2_ERROR_PARTIAL)+						return_value16[0] = 2;+					else+						return_value16[0] *= 2;++					for (i = 0; i < return_value16[0]; ++i)+						if (ovector16_1[i] != ovector16_2[i]) {+							printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",+								i, (int)ovector16_1[i], (int)ovector16_2[i], total, current->pattern, current->input);+							is_successful = 0;+						}+				}+#endif++#ifdef SUPPORT_PCRE2_32+				if (return_value32[0] != return_value32[1]) {+					printf("\n32 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",+						return_value32[0], return_value32[1], total, current->pattern, current->input);+					is_successful = 0;+				} else if (return_value32[0] >= 0 || return_value32[0] == PCRE2_ERROR_PARTIAL) {+					if (return_value32[0] == PCRE2_ERROR_PARTIAL)+						return_value32[0] = 2;+					else+						return_value32[0] *= 2;++					for (i = 0; i < return_value32[0]; ++i)+						if (ovector32_1[i] != ovector32_2[i]) {+							printf("\n32 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",+								i, (int)ovector32_1[i], (int)ovector32_2[i], total, current->pattern, current->input);+							is_successful = 0;+						}+				}+#endif+			}+		}++		if (is_successful) {+#ifdef SUPPORT_PCRE2_8+			if (!(current->start_offset & F_NO8) && (utf || is_ascii)) {+				if (return_value8[0] < 0 && !(current->start_offset & F_NOMATCH)) {+					printf("8 bit: Test should match: [%d] '%s' @ '%s'\n",+						total, current->pattern, current->input);+					is_successful = 0;+				}++				if (return_value8[0] >= 0 && (current->start_offset & F_NOMATCH)) {+					printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n",+						total, current->pattern, current->input);+					is_successful = 0;+				}+			}+#endif+#ifdef SUPPORT_PCRE2_16+			if (!(current->start_offset & F_NO16) && (utf || is_ascii)) {+				if (return_value16[0] < 0 && !(current->start_offset & F_NOMATCH)) {+					printf("16 bit: Test should match: [%d] '%s' @ '%s'\n",+						total, current->pattern, current->input);+					is_successful = 0;+				}++				if (return_value16[0] >= 0 && (current->start_offset & F_NOMATCH)) {+					printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n",+						total, current->pattern, current->input);+					is_successful = 0;+				}+			}+#endif+#ifdef SUPPORT_PCRE2_32+			if (!(current->start_offset & F_NO32) && (utf || is_ascii)) {+				if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) {+					printf("32 bit: Test should match: [%d] '%s' @ '%s'\n",+						total, current->pattern, current->input);+					is_successful = 0;+				}++				if (return_value32[0] >= 0 && (current->start_offset & F_NOMATCH)) {+					printf("32 bit: Test should not match: [%d] '%s' @ '%s'\n",+						total, current->pattern, current->input);+					is_successful = 0;+				}+			}+#endif+		}++		if (is_successful) {+#ifdef SUPPORT_PCRE2_8+			if (re8 && !(current->start_offset & F_NO8) && pcre2_get_mark_8(mdata8_1) != pcre2_get_mark_8(mdata8_2)) {+				printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",+					total, current->pattern, current->input);+				is_successful = 0;+			}+#endif+#ifdef SUPPORT_PCRE2_16+			if (re16 && !(current->start_offset & F_NO16) && pcre2_get_mark_16(mdata16_1) != pcre2_get_mark_16(mdata16_2)) {+				printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",+					total, current->pattern, current->input);+				is_successful = 0;+			}+#endif+#ifdef SUPPORT_PCRE2_32+			if (re32 && !(current->start_offset & F_NO32) && pcre2_get_mark_32(mdata32_1) != pcre2_get_mark_32(mdata32_2)) {+				printf("32 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",+					total, current->pattern, current->input);+				is_successful = 0;+			}+#endif+		}++#ifdef SUPPORT_PCRE2_8+		pcre2_code_free_8(re8);+		pcre2_match_data_free_8(mdata8_1);+		pcre2_match_data_free_8(mdata8_2);+		pcre2_match_context_free_8(mcontext8);+#endif+#ifdef SUPPORT_PCRE2_16+		pcre2_code_free_16(re16);+		pcre2_match_data_free_16(mdata16_1);+		pcre2_match_data_free_16(mdata16_2);+		pcre2_match_context_free_16(mcontext16);+#endif+#ifdef SUPPORT_PCRE2_32+		pcre2_code_free_32(re32);+		pcre2_match_data_free_32(mdata32_1);+		pcre2_match_data_free_32(mdata32_2);+		pcre2_match_context_free_32(mcontext32);+#endif++		if (is_successful) {+			successful++;+			successful_row++;+			printf(".");+			if (successful_row >= 60) {+				successful_row = 0;+				printf("\n");+			}+		} else+			successful_row = 0;++		fflush(stdout);+		current++;+	}+#ifdef SUPPORT_PCRE2_8+	setstack8(NULL);+#endif+#ifdef SUPPORT_PCRE2_16+	setstack16(NULL);+#endif+#ifdef SUPPORT_PCRE2_32+	setstack32(NULL);+#endif++	if (total == successful) {+		printf("\nAll JIT regression tests are successfully passed.\n");+		return 0;+	} else {+		printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);+		return 1;+	}+}++#if defined SUPPORT_UNICODE++static int check_invalid_utf_result(int pattern_index, const char *type, int result,+	int match_start, int match_end, PCRE2_SIZE *ovector)+{+	if (match_start < 0) {+		if (result != -1) {+			printf("Pattern[%d] %s result is not -1.\n", pattern_index, type);+			return 1;+		}+		return 0;+	}++	if (result <= 0) {+		printf("Pattern[%d] %s result (%d) is not greater than 0.\n", pattern_index, type, result);+		return 1;+	}++	if (ovector[0] != (PCRE2_SIZE)match_start) {+		printf("Pattern[%d] %s ovector[0] is unexpected (%d instead of %d)\n",+			pattern_index, type, (int)ovector[0], match_start);+		return 1;+	}++	if (ovector[1] != (PCRE2_SIZE)match_end) {+		printf("Pattern[%d] %s ovector[1] is unexpected (%d instead of %d)\n",+			pattern_index, type, (int)ovector[1], match_end);+		return 1;+	}++	return 0;+}++#endif /* SUPPORT_UNICODE */++#if defined SUPPORT_UNICODE && defined SUPPORT_PCRE2_8++#define UDA (PCRE2_UTF | PCRE2_DOTALL | PCRE2_ANCHORED)+#define CI (PCRE2_JIT_COMPLETE | PCRE2_JIT_INVALID_UTF)+#define CPI (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_INVALID_UTF)++struct invalid_utf8_regression_test_case {+	int compile_options;+	int jit_compile_options;+	int start_offset;+	int skip_left;+	int skip_right;+	int match_start;+	int match_end;+	const char *pattern[2];+	const char *input;+};++static const char invalid_utf8_newline_cr;++static const struct invalid_utf8_regression_test_case invalid_utf8_regression_test_cases[] = {+	{ UDA, CI, 0, 0, 0, 0, 4, { ".", NULL }, "\xf4\x8f\xbf\xbf" },+	{ UDA, CI, 0, 0, 0, 0, 4, { ".", NULL }, "\xf0\x90\x80\x80" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf4\x90\x80\x80" },+	{ UDA, CI, 0, 0, 1, -1, -1, { ".", NULL }, "\xf4\x8f\xbf\xbf" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf0\x90\x80\x7f" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf0\x90\x80\xc0" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf0\x8f\xbf\xbf" },+	{ UDA, CI, 0, 0, 0, 0, 3, { ".", NULL }, "\xef\xbf\xbf#" },+	{ UDA, CI, 0, 0, 0, 0, 3, { ".", NULL }, "\xef\xbf\xbf" },+	{ UDA, CI, 0, 0, 0, 0, 3, { ".", NULL }, "\xe0\xa0\x80#" },+	{ UDA, CI, 0, 0, 0, 0, 3, { ".", NULL }, "\xe0\xa0\x80" },+	{ UDA, CI, 0, 0, 2, -1, -1, { ".", NULL }, "\xef\xbf\xbf#" },+	{ UDA, CI, 0, 0, 1, -1, -1, { ".", NULL }, "\xef\xbf\xbf" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xef\xbf\x7f#" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xef\xbf\xc0" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xe0\x9f\xbf#" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xe0\x9f\xbf" },+	{ UDA, CI, 0, 0, 0, 0, 3, { ".", NULL }, "\xed\x9f\xbf#" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xed\xa0\x80#" },+	{ UDA, CI, 0, 0, 0, 0, 3, { ".", NULL }, "\xee\x80\x80#" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xed\xbf\xbf#" },+	{ UDA, CI, 0, 0, 0, 0, 2, { ".", NULL }, "\xdf\xbf##" },+	{ UDA, CI, 0, 0, 0, 0, 2, { ".", NULL }, "\xdf\xbf#" },+	{ UDA, CI, 0, 0, 0, 0, 2, { ".", NULL }, "\xdf\xbf" },+	{ UDA, CI, 0, 0, 0, 0, 2, { ".", NULL }, "\xc2\x80##" },+	{ UDA, CI, 0, 0, 0, 0, 2, { ".", NULL }, "\xc2\x80#" },+	{ UDA, CI, 0, 0, 0, 0, 2, { ".", NULL }, "\xc2\x80" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xe0\x80##" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xdf\xc0##" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xe0\x80" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xdf\xc0" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xc1\xbf##" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xc1\xbf" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\x80###" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\x80" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf8###" },+	{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf8" },+	{ UDA, CI, 0, 0, 0, 0, 1, { ".", NULL }, "\x7f" },++	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "\xf4\x8f\xbf\xbf#" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\xf4\xa0\x80\x80\xf4\xa0\x80\x80" },+	{ UDA, CPI, 4, 1, 1, -1, -1, { "\\B", "\\b" }, "\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbf" },+	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "#\xef\xbf\xbf#" },+	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "#\xe0\xa0\x80#" },+	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "\xf0\x90\x80\x80#" },+	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "\xf3\xbf\xbf\xbf#" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\xf0\x8f\xbf\xbf\xf0\x8f\xbf\xbf" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\xf5\x80\x80\x80\xf5\x80\x80\x80" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\xf4\x90\x80\x80\xf4\x90\x80\x80" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\xf4\x8f\xbf\xff\xf4\x8f\xbf\xff" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\xf4\x8f\xff\xbf\xf4\x8f\xff\xbf" },+	{ UDA, CPI, 4, 0, 1, -1, -1, { "\\B", "\\b" }, "\xef\x80\x80\x80\xef\x80\x80" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "\x80\x80\x80\x80\x80\x80\x80\x80" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "#\xe0\x9f\xbf\xe0\x9f\xbf#" },+	{ UDA, CPI, 4, 2, 2, -1, -1, { "\\B", "\\b" }, "#\xe0\xa0\x80\xe0\xa0\x80#" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "#\xf0\x80\x80\xf0\x80\x80#" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "#\xed\xa0\x80\xed\xa0\x80#" },+	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "##\xdf\xbf#" },+	{ UDA, CPI, 4, 2, 0, 2, 2, { "\\B", NULL }, "##\xdf\xbf#" },+	{ UDA, CPI, 4, 0, 0, 4, 4, { "\\B", NULL }, "##\xc2\x80#" },+	{ UDA, CPI, 4, 2, 0, 2, 2, { "\\B", NULL }, "##\xc2\x80#" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "##\xc1\xbf\xc1\xbf##" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "##\xdf\xc0\xdf\xc0##" },+	{ UDA, CPI, 4, 0, 0, -1, -1, { "\\B", "\\b" }, "##\xe0\x80\xe0\x80##" },++	{ UDA, CPI, 3, 0, 0, 3, 3, { "\\B", NULL }, "\xef\xbf\xbf#" },+	{ UDA, CPI, 3, 0, 0, 3, 3, { "\\B", NULL }, "\xe0\xa0\x80#" },+	{ UDA, CPI, 3, 0, 0, -1, -1, { "\\B", "\\b" }, "\xe0\x9f\xbf\xe0\x9f\xbf" },+	{ UDA, CPI, 3, 1, 1, -1, -1, { "\\B", "\\b" }, "\xef\xbf\xbf\xef\xbf\xbf" },+	{ UDA, CPI, 3, 0, 1, -1, -1, { "\\B", "\\b" }, "\xdf\x80\x80\xdf\x80" },+	{ UDA, CPI, 3, 0, 0, -1, -1, { "\\B", "\\b" }, "\xef\xbf\xff\xef\xbf\xff" },+	{ UDA, CPI, 3, 0, 0, -1, -1, { "\\B", "\\b" }, "\xef\xff\xbf\xef\xff\xbf" },+	{ UDA, CPI, 3, 0, 0, -1, -1, { "\\B", "\\b" }, "\xed\xbf\xbf\xed\xbf\xbf" },++	{ UDA, CPI, 2, 0, 0, 2, 2, { "\\B", NULL }, "\xdf\xbf#" },+	{ UDA, CPI, 2, 0, 0, 2, 2, { "\\B", NULL }, "\xc2\x80#" },+	{ UDA, CPI, 2, 1, 1, -1, -1, { "\\B", "\\b" }, "\xdf\xbf\xdf\xbf" },+	{ UDA, CPI, 2, 0, 0, -1, -1, { "\\B", "\\b" }, "\xc1\xbf\xc1\xbf" },+	{ UDA, CPI, 2, 0, 0, -1, -1, { "\\B", "\\b" }, "\xe0\x80\xe0\x80" },+	{ UDA, CPI, 2, 0, 0, -1, -1, { "\\B", "\\b" }, "\xdf\xff\xdf\xff" },+	{ UDA, CPI, 2, 0, 0, -1, -1, { "\\B", "\\b" }, "\xff\xbf\xff\xbf" },++	{ UDA, CPI, 1, 0, 0, 1, 1, { "\\B", NULL }, "\x7f#" },+	{ UDA, CPI, 1, 0, 0, 1, 1, { "\\B", NULL }, "\x01#" },+	{ UDA, CPI, 1, 0, 0, -1, -1, { "\\B", "\\b" }, "\x80\x80" },+	{ UDA, CPI, 1, 0, 0, -1, -1, { "\\B", "\\b" }, "\xb0\xb0" },++	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 2, { "(.)\\1", NULL }, "aA" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, -1, -1, { "(.)\\1", NULL }, "a\xff" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 4, { "(.)\\1", NULL }, "\xc3\xa1\xc3\x81" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 1, -1, -1, { "(.)\\1", NULL }, "\xc3\xa1\xc3\x81" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, -1, -1, { "(.)\\1", NULL }, "\xc2\x80\x80" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 6, { "(.)\\1", NULL }, "\xe1\xbd\xb8\xe1\xbf\xb8" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 1, -1, -1, { "(.)\\1", NULL }, "\xe1\xbd\xb8\xe1\xbf\xb8" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 8, { "(.)\\1", NULL }, "\xf0\x90\x90\x80\xf0\x90\x90\xa8" },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 1, -1, -1, { "(.)\\1", NULL }, "\xf0\x90\x90\x80\xf0\x90\x90\xa8" },++	{ UDA, CPI, 0, 0, 0, 0, 1, { "\\X", NULL }, "A" },+	{ UDA, CPI, 0, 0, 0, -1, -1, { "\\X", NULL }, "\xff" },+	{ UDA, CPI, 0, 0, 0, 0, 2, { "\\X", NULL }, "\xc3\xa1" },+	{ UDA, CPI, 0, 0, 1, -1, -1, { "\\X", NULL }, "\xc3\xa1" },+	{ UDA, CPI, 0, 0, 0, -1, -1, { "\\X", NULL }, "\xc3\x7f" },+	{ UDA, CPI, 0, 0, 0, 0, 3, { "\\X", NULL }, "\xe1\xbd\xb8" },+	{ UDA, CPI, 0, 0, 1, -1, -1, { "\\X", NULL }, "\xe1\xbd\xb8" },+	{ UDA, CPI, 0, 0, 0, 0, 4, { "\\X", NULL }, "\xf0\x90\x90\x80" },+	{ UDA, CPI, 0, 0, 1, -1, -1, { "\\X", NULL }, "\xf0\x90\x90\x80" },++	{ UDA, CPI, 0, 0, 0, -1, -1, { "[^#]", NULL }, "#" },+	{ UDA, CPI, 0, 0, 0, 0, 4, { "[^#]", NULL }, "\xf4\x8f\xbf\xbf" },+	{ UDA, CPI, 0, 0, 0, -1, -1, { "[^#]", NULL }, "\xf4\x90\x80\x80" },+	{ UDA, CPI, 0, 0, 0, -1, -1, { "[^#]", NULL }, "\xc1\x80" },++	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 2, 3, { "^\\W", NULL }, " \x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 14, 15, { "^\\W", NULL }, " \xc0\x8a#\xe0\x80\x8a#\xf0\x80\x80\x8a#\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 3, 4, { "^\\W", NULL }, " \xf8\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 3, 4, { "^\\W", NULL }, " \xc3\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 3, 4, { "^\\W", NULL }, " \xf1\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 4, 5, { "^\\W", NULL }, " \xf2\xbf\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 5, 6, { "^\\W", NULL }, " \xf2\xbf\xbf\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 3, 4, { "^\\W", NULL }, " \xef\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 4, 5, { "^\\W", NULL }, " \xef\xbf\x0a#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 5, 6, { "^\\W", NULL }, " \x85#\xc2\x85#"},+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 7, 8, { "^\\W", NULL }, " \xe2\x80\xf8\xe2\x80\xa8#"},++	{ PCRE2_UTF | PCRE2_FIRSTLINE, CI, 0, 0, 0, -1, -1, { "#", NULL }, "\xe2\x80\xf8\xe2\x80\xa8#"},+	{ PCRE2_UTF | PCRE2_FIRSTLINE, CI, 0, 0, 0, 3, 4, { "#", NULL }, "\xe2\x80\xf8#\xe2\x80\xa8#"},+	{ PCRE2_UTF | PCRE2_FIRSTLINE, CI, 0, 0, 0, -1, -1, { "#", NULL }, "abcd\xc2\x85#"},+	{ PCRE2_UTF | PCRE2_FIRSTLINE, CI, 0, 0, 0, 1, 2, { "#", NULL }, "\x85#\xc2\x85#"},+	{ PCRE2_UTF | PCRE2_FIRSTLINE, CI, 0, 0, 0, 5, 6, { "#", NULL }, "\xef,\x80,\xf8#\x0a"},+	{ PCRE2_UTF | PCRE2_FIRSTLINE, CI, 0, 0, 0, -1, -1, { "#", NULL }, "\xef,\x80,\xf8\x0a#"},++	{ PCRE2_UTF | PCRE2_NO_START_OPTIMIZE, CI, 0, 0, 0, 4, 8, { "#\xc7\x85#", NULL }, "\x80\x80#\xc7#\xc7\x85#" },+	{ PCRE2_UTF | PCRE2_NO_START_OPTIMIZE, CI, 0, 0, 0, 7, 11, { "#\xc7\x85#", NULL }, "\x80\x80#\xc7\x80\x80\x80#\xc7\x85#" },+	{ PCRE2_UTF, CI, 0, 0, 0, 4, 8, { "#\xc7\x85#", NULL }, "\x80\x80#\xc7#\xc7\x85#" },+	{ PCRE2_UTF, CI, 0, 0, 0, 7, 11, { "#\xc7\x85#", NULL }, "\x80\x80#\xc7\x80\x80\x80#\xc7\x85#" },++	{ PCRE2_UTF | PCRE2_UCP, CI, 0, 0, 0, -1, -1, { "[\\s]", NULL }, "\xed\xa0\x80" },++	/* These two are not invalid UTF tests, but this infrastructure fits better for them. */+	{ 0, PCRE2_JIT_COMPLETE, 0, 0, 1, -1, -1, { "\\X{2}", NULL }, "\r\n\n" },+	{ 0, PCRE2_JIT_COMPLETE, 0, 0, 1, -1, -1, { "\\R{2}", NULL }, "\r\n\n" },++	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 0, 0, 0, -1, -1, { "^.a", &invalid_utf8_newline_cr }, "\xc3\xa7#a" },++	{ 0, 0, 0, 0, 0, 0, 0, { NULL, NULL }, NULL }+};++#undef UDA+#undef CI+#undef CPI++static int run_invalid_utf8_test(const struct invalid_utf8_regression_test_case *current,+	int pattern_index, int i, pcre2_compile_context_8 *ccontext, pcre2_match_data_8 *mdata)+{+	pcre2_code_8 *code;+	int result, errorcode;+	PCRE2_SIZE length, erroroffset;+	PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_8(mdata);++	if (current->pattern[i] == NULL)+		return 1;++	code = pcre2_compile_8((PCRE2_UCHAR8*)current->pattern[i], PCRE2_ZERO_TERMINATED,+		current->compile_options, &errorcode, &erroroffset, ccontext);++	if (!code) {+		printf("Pattern[%d:0] cannot be compiled. Error offset: %d\n", pattern_index, (int)erroroffset);+		return 0;+	}++	if (pcre2_jit_compile_8(code, current->jit_compile_options) != 0) {+		printf("Pattern[%d:0] cannot be compiled by the JIT compiler.\n", pattern_index);+		pcre2_code_free_8(code);+		return 0;+	}++	length = (PCRE2_SIZE)(strlen(current->input) - current->skip_left - current->skip_right);++	if (current->jit_compile_options & PCRE2_JIT_COMPLETE) {+		result = pcre2_jit_match_8(code, (PCRE2_UCHAR8*)(current->input + current->skip_left),+			length, current->start_offset - current->skip_left, 0, mdata, NULL);++		if (check_invalid_utf_result(pattern_index, "match", result, current->match_start, current->match_end, ovector)) {+			pcre2_code_free_8(code);+			return 0;+		}+	}++	if (current->jit_compile_options & PCRE2_JIT_PARTIAL_SOFT) {+		result = pcre2_jit_match_8(code, (PCRE2_UCHAR8*)(current->input + current->skip_left),+			length, current->start_offset - current->skip_left, PCRE2_PARTIAL_SOFT, mdata, NULL);++		if (check_invalid_utf_result(pattern_index, "partial match", result, current->match_start, current->match_end, ovector)) {+			pcre2_code_free_8(code);+			return 0;+		}+	}++	pcre2_code_free_8(code);+	return 1;+}++static int invalid_utf8_regression_tests(void)+{+	const struct invalid_utf8_regression_test_case *current;+	pcre2_compile_context_8 *ccontext;+	pcre2_match_data_8 *mdata;+	int total = 0, successful = 0;+	int result;++	printf("\nRunning invalid-utf8 JIT regression tests\n");++	ccontext = pcre2_compile_context_create_8(NULL);+	pcre2_set_newline_8(ccontext, PCRE2_NEWLINE_ANY);+	mdata = pcre2_match_data_create_8(4, NULL);++	for (current = invalid_utf8_regression_test_cases; current->pattern[0]; current++) {+		/* printf("\nPattern: %s :\n", current->pattern); */+		total++;++		result = 1;+		if (current->pattern[1] != &invalid_utf8_newline_cr)+		{+			if (!run_invalid_utf8_test(current, total - 1, 0, ccontext, mdata))+				result = 0;+			if (!run_invalid_utf8_test(current, total - 1, 1, ccontext, mdata))+				result = 0;+		} else {+			pcre2_set_newline_8(ccontext, PCRE2_NEWLINE_CR);+			if (!run_invalid_utf8_test(current, total - 1, 0, ccontext, mdata))+				result = 0;+			pcre2_set_newline_8(ccontext, PCRE2_NEWLINE_ANY);+		}++		if (result) {+			successful++;+		}++		printf(".");+		if ((total % 60) == 0)+			printf("\n");+	}++	if ((total % 60) != 0)+		printf("\n");++	pcre2_match_data_free_8(mdata);+	pcre2_compile_context_free_8(ccontext);++	if (total == successful) {+		printf("\nAll invalid UTF8 JIT regression tests are successfully passed.\n");+		return 0;+	} else {+		printf("\nInvalid UTF8 successful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);+		return 1;+	}+}++#else /* !SUPPORT_UNICODE || !SUPPORT_PCRE2_8 */++static int invalid_utf8_regression_tests(void)+{+	return 0;+}++#endif /* SUPPORT_UNICODE && SUPPORT_PCRE2_8 */++#if defined SUPPORT_UNICODE && defined SUPPORT_PCRE2_16++#define UDA (PCRE2_UTF | PCRE2_DOTALL | PCRE2_ANCHORED)+#define CI (PCRE2_JIT_COMPLETE | PCRE2_JIT_INVALID_UTF)+#define CPI (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_INVALID_UTF)++struct invalid_utf16_regression_test_case {+	int compile_options;+	int jit_compile_options;+	int start_offset;+	int skip_left;+	int skip_right;+	int match_start;+	int match_end;+	const PCRE2_UCHAR16 *pattern[2];+	const PCRE2_UCHAR16 *input;+};++static PCRE2_UCHAR16 allany16[] = { '.', 0 };+static PCRE2_UCHAR16 non_word_boundary16[] = { '\\', 'B', 0 };+static PCRE2_UCHAR16 word_boundary16[] = { '\\', 'b', 0 };+static PCRE2_UCHAR16 backreference16[] = { '(', '.', ')', '\\', '1', 0 };+static PCRE2_UCHAR16 grapheme16[] = { '\\', 'X', 0 };+static PCRE2_UCHAR16 nothashmark16[] = { '[', '^', '#', ']', 0 };+static PCRE2_UCHAR16 afternl16[] = { '^', '\\', 'W', 0 };+static PCRE2_UCHAR16 generic16[] = { '#', 0xd800, 0xdc00, '#', 0 };+static PCRE2_UCHAR16 test16_1[] = { 0xd7ff, 0xe000, 0xffff, 0x01, '#', 0 };+static PCRE2_UCHAR16 test16_2[] = { 0xd800, 0xdc00, 0xd800, 0xdc00, 0 };+static PCRE2_UCHAR16 test16_3[] = { 0xdbff, 0xdfff, 0xdbff, 0xdfff, 0 };+static PCRE2_UCHAR16 test16_4[] = { 0xd800, 0xdbff, 0xd800, 0xdbff, 0 };+static PCRE2_UCHAR16 test16_5[] = { '#', 0xd800, 0xdc00, '#', 0 };+static PCRE2_UCHAR16 test16_6[] = { 'a', 'A', 0xdc28, 0 };+static PCRE2_UCHAR16 test16_7[] = { 0xd801, 0xdc00, 0xd801, 0xdc28, 0 };+static PCRE2_UCHAR16 test16_8[] = { '#', 0xd800, 0xdc00, 0 };+static PCRE2_UCHAR16 test16_9[] = { ' ', 0x2028, '#', 0 };+static PCRE2_UCHAR16 test16_10[] = { ' ', 0xdc00, 0xd800, 0x2028, '#', 0 };+static PCRE2_UCHAR16 test16_11[] = { 0xdc00, 0xdc00, 0xd800, 0xdc00, 0xdc00, '#', 0xd800, 0xdc00, '#', 0 };+static PCRE2_UCHAR16 test16_12[] = { '#', 0xd800, 0xdc00, 0xd800, '#', 0xd800, 0xdc00, 0xdc00, 0xdc00, '#', 0xd800, 0xdc00, '#', 0 };++static const struct invalid_utf16_regression_test_case invalid_utf16_regression_test_cases[] = {+	{ UDA, CI, 0, 0, 0, 0, 1, { allany16, NULL }, test16_1 },+	{ UDA, CI, 1, 0, 0, 1, 2, { allany16, NULL }, test16_1 },+	{ UDA, CI, 2, 0, 0, 2, 3, { allany16, NULL }, test16_1 },+	{ UDA, CI, 3, 0, 0, 3, 4, { allany16, NULL }, test16_1 },+	{ UDA, CI, 0, 0, 0, 0, 2, { allany16, NULL }, test16_2 },+	{ UDA, CI, 0, 0, 3, -1, -1, { allany16, NULL }, test16_2 },+	{ UDA, CI, 1, 0, 0, -1, -1, { allany16, NULL }, test16_2 },+	{ UDA, CI, 0, 0, 0, 0, 2, { allany16, NULL }, test16_3 },+	{ UDA, CI, 0, 0, 3, -1, -1, { allany16, NULL }, test16_3 },+	{ UDA, CI, 1, 0, 0, -1, -1, { allany16, NULL }, test16_3 },++	{ UDA, CPI, 1, 0, 0, 1, 1, { non_word_boundary16, NULL }, test16_1 },+	{ UDA, CPI, 2, 0, 0, 2, 2, { non_word_boundary16, NULL }, test16_1 },+	{ UDA, CPI, 3, 0, 0, 3, 3, { non_word_boundary16, NULL }, test16_1 },+	{ UDA, CPI, 4, 0, 0, 4, 4, { non_word_boundary16, NULL }, test16_1 },+	{ UDA, CPI, 2, 0, 0, 2, 2, { non_word_boundary16, NULL }, test16_2 },+	{ UDA, CPI, 2, 0, 0, 2, 2, { non_word_boundary16, NULL }, test16_3 },+	{ UDA, CPI, 2, 1, 1, -1, -1, { non_word_boundary16, word_boundary16 }, test16_2 },+	{ UDA, CPI, 2, 1, 1, -1, -1, { non_word_boundary16, word_boundary16 }, test16_3 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { non_word_boundary16, word_boundary16 }, test16_4 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { non_word_boundary16, word_boundary16 }, test16_5 },++	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 2, { backreference16, NULL }, test16_6 },+	{ UDA | PCRE2_CASELESS, CPI, 1, 0, 0, -1, -1, { backreference16, NULL }, test16_6 },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 4, { backreference16, NULL }, test16_7 },+	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 1, -1, -1, { backreference16, NULL }, test16_7 },++	{ UDA, CPI, 0, 0, 0, 0, 1, { grapheme16, NULL }, test16_6 },+	{ UDA, CPI, 1, 0, 0, 1, 2, { grapheme16, NULL }, test16_6 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { grapheme16, NULL }, test16_6 },+	{ UDA, CPI, 0, 0, 0, 0, 2, { grapheme16, NULL }, test16_7 },+	{ UDA, CPI, 2, 0, 0, 2, 4, { grapheme16, NULL }, test16_7 },+	{ UDA, CPI, 1, 0, 0, -1, -1, { grapheme16, NULL }, test16_7 },++	{ UDA, CPI, 0, 0, 0, -1, -1, { nothashmark16, NULL }, test16_8 },+	{ UDA, CPI, 1, 0, 0, 1, 3, { nothashmark16, NULL }, test16_8 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { nothashmark16, NULL }, test16_8 },++	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 2, 3, { afternl16, NULL }, test16_9 },+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 4, 5, { afternl16, NULL }, test16_10 },++	{ PCRE2_UTF | PCRE2_NO_START_OPTIMIZE, CI, 0, 0, 0, 5, 9, { generic16, NULL }, test16_11 },+	{ PCRE2_UTF | PCRE2_NO_START_OPTIMIZE, CI, 0, 0, 0, 9, 13, { generic16, NULL }, test16_12 },+	{ PCRE2_UTF, CI, 0, 0, 0, 5, 9, { generic16, NULL }, test16_11 },+	{ PCRE2_UTF, CI, 0, 0, 0, 9, 13, { generic16, NULL }, test16_12 },++	{ 0, 0, 0, 0, 0, 0, 0, { NULL, NULL }, NULL }+};++#undef UDA+#undef CI+#undef CPI++static int run_invalid_utf16_test(const struct invalid_utf16_regression_test_case *current,+	int pattern_index, int i, pcre2_compile_context_16 *ccontext, pcre2_match_data_16 *mdata)+{+	pcre2_code_16 *code;+	int result, errorcode;+	PCRE2_SIZE length, erroroffset;+	const PCRE2_UCHAR16 *input;+	PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_16(mdata);++	if (current->pattern[i] == NULL)+		return 1;++	code = pcre2_compile_16(current->pattern[i], PCRE2_ZERO_TERMINATED,+		current->compile_options, &errorcode, &erroroffset, ccontext);++	if (!code) {+		printf("Pattern[%d:0] cannot be compiled. Error offset: %d\n", pattern_index, (int)erroroffset);+		return 0;+	}++	if (pcre2_jit_compile_16(code, current->jit_compile_options) != 0) {+		printf("Pattern[%d:0] cannot be compiled by the JIT compiler.\n", pattern_index);+		pcre2_code_free_16(code);+		return 0;+	}++	input = current->input;+	length = 0;++	while (*input++ != 0)+		length++;++	length -= current->skip_left + current->skip_right;++	if (current->jit_compile_options & PCRE2_JIT_COMPLETE) {+		result = pcre2_jit_match_16(code, (current->input + current->skip_left),+			length, current->start_offset - current->skip_left, 0, mdata, NULL);++		if (check_invalid_utf_result(pattern_index, "match", result, current->match_start, current->match_end, ovector)) {+			pcre2_code_free_16(code);+			return 0;+		}+	}++	if (current->jit_compile_options & PCRE2_JIT_PARTIAL_SOFT) {+		result = pcre2_jit_match_16(code, (current->input + current->skip_left),+			length, current->start_offset - current->skip_left, PCRE2_PARTIAL_SOFT, mdata, NULL);++		if (check_invalid_utf_result(pattern_index, "partial match", result, current->match_start, current->match_end, ovector)) {+			pcre2_code_free_16(code);+			return 0;+		}+	}++	pcre2_code_free_16(code);+	return 1;+}++static int invalid_utf16_regression_tests(void)+{+	const struct invalid_utf16_regression_test_case *current;+	pcre2_compile_context_16 *ccontext;+	pcre2_match_data_16 *mdata;+	int total = 0, successful = 0;+	int result;++	printf("\nRunning invalid-utf16 JIT regression tests\n");++	ccontext = pcre2_compile_context_create_16(NULL);+	pcre2_set_newline_16(ccontext, PCRE2_NEWLINE_ANY);+	mdata = pcre2_match_data_create_16(4, NULL);++	for (current = invalid_utf16_regression_test_cases; current->pattern[0]; current++) {+		/* printf("\nPattern: %s :\n", current->pattern); */+		total++;++		result = 1;+		if (!run_invalid_utf16_test(current, total - 1, 0, ccontext, mdata))+			result = 0;+		if (!run_invalid_utf16_test(current, total - 1, 1, ccontext, mdata))+			result = 0;++		if (result) {+			successful++;+		}++		printf(".");+		if ((total % 60) == 0)+			printf("\n");+	}++	if ((total % 60) != 0)+		printf("\n");++	pcre2_match_data_free_16(mdata);+	pcre2_compile_context_free_16(ccontext);++	if (total == successful) {+		printf("\nAll invalid UTF16 JIT regression tests are successfully passed.\n");+		return 0;+	} else {+		printf("\nInvalid UTF16 successful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);+		return 1;+	}+}++#else /* !SUPPORT_UNICODE || !SUPPORT_PCRE2_16 */++static int invalid_utf16_regression_tests(void)+{+	return 0;+}++#endif /* SUPPORT_UNICODE && SUPPORT_PCRE2_16 */++#if defined SUPPORT_UNICODE && defined SUPPORT_PCRE2_32++#define UDA (PCRE2_UTF | PCRE2_DOTALL | PCRE2_ANCHORED)+#define CI (PCRE2_JIT_COMPLETE | PCRE2_JIT_INVALID_UTF)+#define CPI (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_INVALID_UTF)++struct invalid_utf32_regression_test_case {+	int compile_options;+	int jit_compile_options;+	int start_offset;+	int skip_left;+	int skip_right;+	int match_start;+	int match_end;+	const PCRE2_UCHAR32 *pattern[2];+	const PCRE2_UCHAR32 *input;+};++static PCRE2_UCHAR32 allany32[] = { '.', 0 };+static PCRE2_UCHAR32 non_word_boundary32[] = { '\\', 'B', 0 };+static PCRE2_UCHAR32 word_boundary32[] = { '\\', 'b', 0 };+static PCRE2_UCHAR32 backreference32[] = { '(', '.', ')', '\\', '1', 0 };+static PCRE2_UCHAR32 grapheme32[] = { '\\', 'X', 0 };+static PCRE2_UCHAR32 nothashmark32[] = { '[', '^', '#', ']', 0 };+static PCRE2_UCHAR32 afternl32[] = { '^', '\\', 'W', 0 };+static PCRE2_UCHAR32 test32_1[] = { 0x10ffff, 0x10ffff, 0x110000, 0x110000, 0x10ffff, 0 };+static PCRE2_UCHAR32 test32_2[] = { 0xd7ff, 0xe000, 0xd800, 0xdfff, 0xe000, 0xdfff, 0xd800, 0 };+static PCRE2_UCHAR32 test32_3[] = { 'a', 'A', 0x110000, 0 };+static PCRE2_UCHAR32 test32_4[] = { '#', 0x10ffff, 0x110000, 0 };+static PCRE2_UCHAR32 test32_5[] = { ' ', 0x2028, '#', 0 };+static PCRE2_UCHAR32 test32_6[] = { ' ', 0x110000, 0x2028, '#', 0 };++static const struct invalid_utf32_regression_test_case invalid_utf32_regression_test_cases[] = {+	{ UDA, CI, 0, 0, 0, 0, 1, { allany32, NULL }, test32_1 },+	{ UDA, CI, 2, 0, 0, -1, -1, { allany32, NULL }, test32_1 },+	{ UDA, CI, 0, 0, 0, 0, 1, { allany32, NULL }, test32_2 },+	{ UDA, CI, 1, 0, 0, 1, 2, { allany32, NULL }, test32_2 },+	{ UDA, CI, 2, 0, 0, -1, -1, { allany32, NULL }, test32_2 },+	{ UDA, CI, 3, 0, 0, -1, -1, { allany32, NULL }, test32_2 },++	{ UDA, CPI, 1, 0, 0, 1, 1, { non_word_boundary32, NULL }, test32_1 },+	{ UDA, CPI, 3, 0, 0, -1, -1, { non_word_boundary32, word_boundary32 }, test32_1 },+	{ UDA, CPI, 1, 0, 0, 1, 1, { non_word_boundary32, NULL }, test32_2 },+	{ UDA, CPI, 3, 0, 0, -1, -1, { non_word_boundary32, word_boundary32 }, test32_2 },+	{ UDA, CPI, 6, 0, 0, -1, -1, { non_word_boundary32, word_boundary32 }, test32_2 },++	{ UDA | PCRE2_CASELESS, CPI, 0, 0, 0, 0, 2, { backreference32, NULL }, test32_3 },+	{ UDA | PCRE2_CASELESS, CPI, 1, 0, 0, -1, -1, { backreference32, NULL }, test32_3 },++	{ UDA, CPI, 0, 0, 0, 0, 1, { grapheme32, NULL }, test32_1 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { grapheme32, NULL }, test32_1 },+	{ UDA, CPI, 1, 0, 0, 1, 2, { grapheme32, NULL }, test32_2 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { grapheme32, NULL }, test32_2 },+	{ UDA, CPI, 3, 0, 0, -1, -1, { grapheme32, NULL }, test32_2 },+	{ UDA, CPI, 4, 0, 0, 4, 5, { grapheme32, NULL }, test32_2 },++	{ UDA, CPI, 0, 0, 0, -1, -1, { nothashmark32, NULL }, test32_4 },+	{ UDA, CPI, 1, 0, 0, 1, 2, { nothashmark32, NULL }, test32_4 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { nothashmark32, NULL }, test32_4 },+	{ UDA, CPI, 1, 0, 0, 1, 2, { nothashmark32, NULL }, test32_2 },+	{ UDA, CPI, 2, 0, 0, -1, -1, { nothashmark32, NULL }, test32_2 },++	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 2, 3, { afternl32, NULL }, test32_5 },+	{ PCRE2_UTF | PCRE2_MULTILINE, CI, 1, 0, 0, 3, 4, { afternl32, NULL }, test32_6 },++	{ 0, 0, 0, 0, 0, 0, 0, { NULL, NULL }, NULL }+};++#undef UDA+#undef CI+#undef CPI++static int run_invalid_utf32_test(const struct invalid_utf32_regression_test_case *current,+	int pattern_index, int i, pcre2_compile_context_32 *ccontext, pcre2_match_data_32 *mdata)+{+	pcre2_code_32 *code;+	int result, errorcode;+	PCRE2_SIZE length, erroroffset;+	const PCRE2_UCHAR32 *input;+	PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_32(mdata);++	if (current->pattern[i] == NULL)+		return 1;++	code = pcre2_compile_32(current->pattern[i], PCRE2_ZERO_TERMINATED,+		current->compile_options, &errorcode, &erroroffset, ccontext);++	if (!code) {+		printf("Pattern[%d:0] cannot be compiled. Error offset: %d\n", pattern_index, (int)erroroffset);+		return 0;+	}++	if (pcre2_jit_compile_32(code, current->jit_compile_options) != 0) {+		printf("Pattern[%d:0] cannot be compiled by the JIT compiler.\n", pattern_index);+		pcre2_code_free_32(code);+		return 0;+	}++	input = current->input;+	length = 0;++	while (*input++ != 0)+		length++;++	length -= current->skip_left + current->skip_right;++	if (current->jit_compile_options & PCRE2_JIT_COMPLETE) {+		result = pcre2_jit_match_32(code, (current->input + current->skip_left),+			length, current->start_offset - current->skip_left, 0, mdata, NULL);++		if (check_invalid_utf_result(pattern_index, "match", result, current->match_start, current->match_end, ovector)) {+			pcre2_code_free_32(code);+			return 0;+		}+	}++	if (current->jit_compile_options & PCRE2_JIT_PARTIAL_SOFT) {+		result = pcre2_jit_match_32(code, (current->input + current->skip_left),+			length, current->start_offset - current->skip_left, PCRE2_PARTIAL_SOFT, mdata, NULL);++		if (check_invalid_utf_result(pattern_index, "partial match", result, current->match_start, current->match_end, ovector)) {+			pcre2_code_free_32(code);+			return 0;+		}+	}++	pcre2_code_free_32(code);+	return 1;+}++static int invalid_utf32_regression_tests(void)+{+	const struct invalid_utf32_regression_test_case *current;+	pcre2_compile_context_32 *ccontext;+	pcre2_match_data_32 *mdata;+	int total = 0, successful = 0;+	int result;++	printf("\nRunning invalid-utf32 JIT regression tests\n");++	ccontext = pcre2_compile_context_create_32(NULL);+	pcre2_set_newline_32(ccontext, PCRE2_NEWLINE_ANY);+	mdata = pcre2_match_data_create_32(4, NULL);++	for (current = invalid_utf32_regression_test_cases; current->pattern[0]; current++) {+		/* printf("\nPattern: %s :\n", current->pattern); */+		total++;++		result = 1;+		if (!run_invalid_utf32_test(current, total - 1, 0, ccontext, mdata))+			result = 0;+		if (!run_invalid_utf32_test(current, total - 1, 1, ccontext, mdata))+			result = 0;++		if (result) {+			successful++;+		}++		printf(".");+		if ((total % 60) == 0)+			printf("\n");+	}++	if ((total % 60) != 0)+		printf("\n");++	pcre2_match_data_free_32(mdata);+	pcre2_compile_context_free_32(ccontext);++	if (total == successful) {+		printf("\nAll invalid UTF32 JIT regression tests are successfully passed.\n");+		return 0;+	} else {+		printf("\nInvalid UTF32 successful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);+		return 1;+	}+}++#else /* !SUPPORT_UNICODE || !SUPPORT_PCRE2_32 */++static int invalid_utf32_regression_tests(void)+{+	return 0;+}++#endif /* SUPPORT_UNICODE && SUPPORT_PCRE2_32 */++/* End of pcre2_jit_test.c */
+ src/c/pcre2/src/pcre2_maketables.c view
@@ -0,0 +1,163 @@+/*************************************************+*      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-2020 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 the external function pcre2_maketables(), which builds+character tables for PCRE2 in the current locale. The file is compiled on its+own as part of the PCRE2 library. It is also included in the compilation of+pcre2_dftables.c as a freestanding program, in which case the macro+PCRE2_DFTABLES is defined. */++#ifndef PCRE2_DFTABLES    /* Compiling the library */+#  ifdef HAVE_CONFIG_H+#  include "config.h"+#  endif+#  include "pcre2_internal.h"+#endif++++/*************************************************+*           Create PCRE2 character tables        *+*************************************************/++/* This function builds a set of character tables for use by PCRE2 and returns+a pointer to them. They are build using the ctype functions, and consequently+their contents will depend upon the current locale setting. When compiled as+part of the library, the store is obtained via a general context malloc, if+supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables+freestanding auxiliary program) malloc() is used, and the function has a+different name so as not to clash with the prototype in pcre2.h.++Arguments:   none when PCRE2_DFTABLES is defined+               else a PCRE2 general context or NULL+Returns:     pointer to the contiguous block of data+               else NULL if memory allocation failed+*/++#ifdef PCRE2_DFTABLES  /* Included in freestanding pcre2_dftables program */+static const uint8_t *maketables(void)+{+uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH);++#else  /* Not PCRE2_DFTABLES, that is, compiling the library */+PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION+pcre2_maketables(pcre2_general_context *gcontext)+{+uint8_t *yield = (uint8_t *)((gcontext != NULL)?+  gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) :+  malloc(TABLES_LENGTH));+#endif  /* PCRE2_DFTABLES */++int i;+uint8_t *p;++if (yield == NULL) return NULL;+p = yield;++/* First comes the lower casing table */++for (i = 0; i < 256; i++) *p++ = tolower(i);++/* Next the case-flipping table */++for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);++/* Then the character class tables. Don't try to be clever and save effort on+exclusive ones - in some locales things may be different.++Note that the table for "space" includes everything "isspace" gives, including+VT in the default locale. This makes it work for the POSIX class [:space:].+From PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl+space, because Perl added VT at release 5.18.++Note also that it is possible for a character to be alnum or alpha without+being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the+fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must+test for alnum specially. */++memset(p, 0, cbit_length);+for (i = 0; i < 256; i++)+  {+  if (isdigit(i))  p[cbit_digit  + i/8] |= 1u << (i&7);+  if (isupper(i))  p[cbit_upper  + i/8] |= 1u << (i&7);+  if (islower(i))  p[cbit_lower  + i/8] |= 1u << (i&7);+  if (isalnum(i))  p[cbit_word   + i/8] |= 1u << (i&7);+  if (i == '_')    p[cbit_word   + i/8] |= 1u << (i&7);+  if (isspace(i))  p[cbit_space  + i/8] |= 1u << (i&7);+  if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7);+  if (isgraph(i))  p[cbit_graph  + i/8] |= 1u << (i&7);+  if (isprint(i))  p[cbit_print  + i/8] |= 1u << (i&7);+  if (ispunct(i))  p[cbit_punct  + i/8] |= 1u << (i&7);+  if (iscntrl(i))  p[cbit_cntrl  + i/8] |= 1u << (i&7);+  }+p += cbit_length;++/* Finally, the character type table. In this, we used to exclude VT from the+white space chars, because Perl didn't recognize it as such for \s and for+comments within regexes. However, Perl changed at release 5.18, so PCRE1+changed at release 8.34 and it's always been this way for PCRE2. */++for (i = 0; i < 256; i++)+  {+  int x = 0;+  if (isspace(i)) x += ctype_space;+  if (isalpha(i)) x += ctype_letter;+  if (islower(i)) x += ctype_lcletter;+  if (isdigit(i)) x += ctype_digit;+  if (isalnum(i) || i == '_') x += ctype_word;+  *p++ = x;+  }++return yield;+}++#ifndef PCRE2_DFTABLES   /* Compiling the library */+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)+{+  if (gcontext)+    gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data);+  else+    free((void *)tables);+}+#endif++/* End of pcre2_maketables.c */
+ src/c/pcre2/src/pcre2_match.c view
@@ -0,0 +1,7311 @@+/*************************************************+*      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) 2015-2020 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++/* These defines enable 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"++#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_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \+   PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \+   PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT)++#define PUBLIC_JIT_MATCH_OPTIONS \+   (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\+    PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD|\+    PCRE2_COPY_MATCHED_SUBJECT)++/* 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 used in the match() function. Make them+sufficiently negative to avoid the external error codes. */++#define MATCH_ACCEPT       (-999)+#define MATCH_KETRPOS      (-998)+/* 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       (-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++/* 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). */++#define GF_CAPTURE     0x00010000u+#define GF_NOCAPTURE   0x00020000u+#define GF_CONDASSERT  0x00030000u+#define GF_RECURSE     0x00040000u++/* Masks for the identity and data parts of the group frame type. */++#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, RM36 };++#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;+}++++/*************************************************+*          Match a back-reference                *+*************************************************/++/* This function is called only when it is known that the offset lies within+the offsets that have so far been used in the match. Note that in caseless+UTF-8 mode, the number of subject bytes matched may be different to the number+of reference bytes. (In theory this could also happen in UTF-16 mode, but it+seems unlikely.)++Arguments:+  offset      index into the offset vector+  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+              < 0 no match+              > 0 partial match+*/++static int+match_ref(PCRE2_SIZE offset, BOOL caseless, heapframe *F, match_block *mb,+  PCRE2_SIZE *lengthptr)+{+PCRE2_SPTR p;+PCRE2_SIZE length;+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 >= Foffset_top || Fovector[offset] == PCRE2_UNSET)+  {+  if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)+    {+    *lengthptr = 0;+    return 0;      /* Match */+    }+  else return -1;  /* No match */+  }++/* Separate the caseless and UTF cases for speed. */++eptr = eptr_start = Feptr;+p = mb->start_subject + Fovector[offset];+length = Fovector[offset+1] - Fovector[offset];++if (caseless)+  {+#if defined SUPPORT_UNICODE+  BOOL utf = (mb->poptions & PCRE2_UTF) != 0;++  if (utf || (mb->poptions & PCRE2_UCP) != 0)+    {+    PCRE2_SPTR endptr = p + length;++    /* 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 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). UCP without uses Unicode properties but without UTF encoding. */++    while (p < endptr)+      {+      uint32_t c, d;+      const ucd_record *ur;+      if (eptr >= mb->end_subject) return 1;   /* Partial match */++      if (utf)+        {+        GETCHARINC(c, eptr);+        GETCHARINC(d, p);+        }+      else+        {+        c = *eptr++;+        d = *p++;+        }++      ur = GET_UCD(d);+      if (c != d && c != (uint32_t)((int)d + ur->other_case))+        {+        const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset;+        for (;;)+          {+          if (c < *pp) return -1;  /* No match */+          if (c == *pp++) break;+          }+        }+      }+    }+  else+#endif++  /* Not in UTF or UCP mode */+    {+    for (; length > 0; length--)+      {+      uint32_t cc, cp;+      if (eptr >= mb->end_subject) return 1;   /* Partial match */+      cc = UCHAR21TEST(eptr);+      cp = UCHAR21TEST(p);+      if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc))+        return -1;  /* No match */+      p++;+      eptr++;+      }+    }+  }++/* In the caseful case, we can just compare the code units, whether or not we+are in UTF and/or UCP mode. When partial matching, we have to do this unit by+unit. */++else+  {+  if (mb->partial != 0)+    {+    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;+    }+  }++*lengthptr = eptr - eptr_start;+return 0;  /* Match */+}++++/******************************************************************************+*******************************************************************************+                   "Recursion" in the match() function++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.++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.++*******************************************************************************+******************************************************************************/+++++/*************************************************+*       Macros for the match() function          *+*************************************************/++/* These macros pack up tests that are used for partial matching several times+in the code. The second one is used when we already know we are past the end of+the subject. We set the "hit end" flag if the pointer is at the end of the+subject and either (a) the pointer is past the earliest inspected character+(i.e. something has been matched, even if not part of the actual matched+string), or (b) the pattern contains a lookbehind. These are the conditions for+which adding more characters may allow the current match to continue.++For hard partial matching, we immediately return a partial match. Otherwise,+carrying on means that a complete match on the current subject will be sought.+A partial match is returned only if no complete match can be found. */++#define CHECK_PARTIAL()\+  if (Feptr >= mb->end_subject) \+    { \+    SCHECK_PARTIAL(); \+    }++#define SCHECK_PARTIAL()\+  if (mb->partial != 0 && \+      (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \+    { \+    mb->hitend = TRUE; \+    if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \+    }+++/* These macros are used to implement backtracking. They simulate a recursive+call to the match() function by means of a local vector of frames which+remember the backtracking points. */++#define RMATCH(ra,rb)\+  {\+  start_ecode = ra;\+  Freturn_id = rb;\+  goto MATCH_RECURSE;\+  L_##rb:;\+  }++#define RRETURN(ra)\+  {\+  rrc = ra;\+  goto RETURN_SWITCH;\+  }++++/*************************************************+*         Match from current position            *+*************************************************/++/* This function is called to run one match attempt at a single starting point+in the subject.++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:+   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  )+                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(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)+{+/* Frame-handling variables */++heapframe *F;           /* Current frame pointer */+heapframe *N = NULL;    /* Temporary frame pointers */+heapframe *P = NULL;+heapframe *assert_accept_frame = NULL;  /* For passing back a frame with captures */+PCRE2_SIZE frame_copy_size;     /* Amount to copy when creating a new frame */++/* Local variables that do not need to be preserved over calls to RRMATCH(). */++PCRE2_SPTR bracode;     /* Temp pointer to start of group */+PCRE2_SIZE offset;      /* Used for group offsets */+PCRE2_SIZE length;      /* Used for various length calculations */++int rrc;                /* Return from functions & backtracking "recursions" */+#ifdef SUPPORT_UNICODE+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 */++BOOL condition;         /* Used in conditional groups */+BOOL cur_is_word;       /* Used in "word" tests */+BOOL prev_is_word;      /* Used in "word" tests */++/* UTF and UCP flags */++#ifdef SUPPORT_UNICODE+BOOL utf = (mb->poptions & PCRE2_UTF) != 0;+BOOL ucp = (mb->poptions & PCRE2_UCP) != 0;+#else+BOOL utf = FALSE;  /* Required for convenience even when no Unicode support */+#endif++/* This is the length of the last part of a backtracking frame that must be+copied when a new frame is created. */++frame_copy_size = frame_size - offsetof(heapframe, eptr);++/* Set up the first current frame at the start of the vector, and initialize+fields that are not reset for new frames. */++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 */++/* 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)+  {+  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;+  }++#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 (;;)+  {+#ifdef DEBUG_SHOW_OPS+fprintf(stderr, "++ op=%d\n", *Fecode);+#endif++  Fop = (uint8_t)(*Fecode);  /* Cast needed for 16-bit and 32-bit modes */+  switch(Fop)+    {+    /* ===================================================================== */+    /* 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:+    if (Fcurrent_recurse == RECURSE_UNSET)+      {+      number = GET2(Fecode, 1);+      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 (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;+      }+    Fecode += PRIV(OP_lengths)[*Fecode];+    break;+++    /* ===================================================================== */+    /* 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 and mark can be fished out of it. */++    case OP_ASSERT_ACCEPT:+    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:++    /* Handle end of a recursion. */++    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 &&+             Fstart_match == mb->start_subject + mb->start_offset)))+      RRETURN(MATCH_NOMATCH);++    /* 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. */++    if (Feptr < mb->end_subject &&+        ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)+      {+      if (Fop == OP_END) RRETURN(MATCH_NOMATCH);+      return MATCH_NOMATCH;+      }++    /* 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. */++    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;++    ovector[0] = Fstart_match - mb->start_subject;+    ovector[1] = Feptr - mb->start_subject;++    /* Set i to the smaller of the sizes of the external and frame ovectors. */++    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 */+++    /*===================================================================== */+    /* Match any single character type except newline; have to take care with+    CRLF newlines and partial matching. */++    case OP_ANY:+    if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);+    if (mb->partial != 0 &&+        Feptr == mb->end_subject - 1 &&+        NLBLOCK->nltype == NLTYPE_FIXED &&+        NLBLOCK->nllen == 2 &&+        UCHAR21TEST(Feptr) == NLBLOCK->nl[0])+      {+      mb->hitend = TRUE;+      if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+      }+    /* Fall through */++    /* Match any single character whatsoever. */++    case OP_ALLANY:+    if (Feptr >= mb->end_subject)  /* DO NOT merge the Feptr++ here; it must */+      {                            /* not be updated before SCHECK_PARTIAL. */+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    Feptr++;+#ifdef SUPPORT_UNICODE+    if (utf) ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+#endif+    Fecode++;+    break;+++    /* ===================================================================== */+    /* 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 (Feptr >= mb->end_subject)   /* DO NOT merge the Feptr++ here; it must */+      {                             /* not be updated before SCHECK_PARTIAL. */+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    Feptr++;+    Fecode++;+    break;+++    /* ===================================================================== */+    /* 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);+      }++#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);+        }+      }++    /* If UCP is set without UTF we must do the same as above, but with one+    character per code unit. */++    else if (ucp)+      {+      uint32_t cc = UCHAR21(Feptr);+      fc = Fecode[1];+      if (fc < 128)+        {+        if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);+        }+      else+        {+        if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);+        }+      Feptr++;+      Fecode += 2;+      }++    else+#endif   /* SUPPORT_UNICODE */++    /* Not UTF or UCP 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);+      }++#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 = (mb->fcc)[ch];+        if (ch == fc) RRETURN(MATCH_NOMATCH);+        }+      }++    /* UCP without UTF is as above, but with one character per code unit. */++    else if (ucp)+      {+      uint32_t ch;+      fc = UCHAR21INC(Feptr);+      ch = Fecode[1];+      Fecode += 2;++      if (ch == fc)+        {+        RRETURN(MATCH_NOMATCH);  /* Caseful match */+        }+      else if (Fop == OP_NOTI)   /* If caseless */+        {+        if (ch > 127)+          ch = UCD_OTHERCASE(ch);+        else+          ch = (mb->fcc)[ch];+        if (ch == fc) RRETURN(MATCH_NOMATCH);+        }+      }++    else+#endif  /* SUPPORT_UNICODE */++    /* Neither UTF nor UCP is set */++      {+      uint32_t ch = Fecode[1];+      fc = UCHAR21INC(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, using Unicode casing if either UTF or UCP is set. */++    Lc = *Fecode++;++    /* Caseless comparison */++    if (Fop >= OP_STARI)+      {+#if PCRE2_CODE_UNIT_WIDTH == 8+#ifdef SUPPORT_UNICODE+      if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);+      else+#endif  /* SUPPORT_UNICODE */+      /* Lc will be < 128 in UTF-8 mode. */+      Loc = mb->fcc[Lc];+#else /* 16-bit & 32-bit */+#ifdef SUPPORT_UNICODE+      if ((utf || ucp) && 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 || ucp) && 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 opcodes+    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] & (1u << (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] & (1u << (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] & (1u << (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] & (1u << (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] & (1u << (fc&7))) == 0) break;+            Feptr += len;+            }++          if (reptype == REPTYPE_POS) continue;    /* No backtracking */++          /* After \C in UTF mode, Lstart_eptr might be in the middle of a+          Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't+          go too far. */++          for (;;)+            {+            RMATCH(Fecode, 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] & (1u << (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 */++        /* After \C in UTF mode, Lstart_eptr might be in the middle of a+        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't+        go too far. */++        for(;;)+          {+          RMATCH(Fecode, 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 (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_NOT_WHITESPACE:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)+      RRETURN(MATCH_NOMATCH);+    Fecode++;+    break;++    case OP_WHITESPACE:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)+      RRETURN(MATCH_NOMATCH);+    Fecode++;+    break;++    case OP_NOT_WORDCHAR:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)+      RRETURN(MATCH_NOMATCH);+    Fecode++;+    break;++    case OP_WORDCHAR:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)+      RRETURN(MATCH_NOMATCH);+    Fecode++;+    break;++    case OP_ANYNL:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    switch(fc)+      {+      default: RRETURN(MATCH_NOMATCH);++      case CHAR_CR:+      if (Feptr >= mb->end_subject)+        {+        SCHECK_PARTIAL();+        }+      else if (UCHAR21TEST(Feptr) == CHAR_LF) Feptr++;+      break;++      case CHAR_LF:+      break;++      case CHAR_VT:+      case CHAR_FF:+      case CHAR_NEL:+#ifndef EBCDIC+      case 0x2028:+      case 0x2029:+#endif  /* Not EBCDIC */+      if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);+      break;+      }+    Fecode++;+    break;++    case OP_NOT_HSPACE:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    switch(fc)+      {+      HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */+      default: break;+      }+    Fecode++;+    break;++    case OP_HSPACE:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    switch(fc)+      {+      HSPACE_CASES: break;  /* Byte and multibyte cases */+      default: RRETURN(MATCH_NOMATCH);+      }+    Fecode++;+    break;++    case OP_NOT_VSPACE:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    switch(fc)+      {+      VSPACE_CASES: RRETURN(MATCH_NOMATCH);+      default: break;+      }+    Fecode++;+    break;++    case OP_VSPACE:+    if (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+    switch(fc)+      {+      VSPACE_CASES: break;+      default: RRETURN(MATCH_NOMATCH);+      }+    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 (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    GETCHARINCTEST(fc, Feptr);+      {+      const uint32_t *cp;+      const ucd_record *prop = GET_UCD(fc);++      switch(Fecode[1])+        {+        case PT_ANY:+        if (Fop == OP_NOTPROP) RRETURN(MATCH_NOMATCH);+        break;++        case PT_LAMP:+        if ((prop->chartype == ucp_Lu ||+             prop->chartype == ucp_Ll ||+             prop->chartype == ucp_Lt) == (Fop == OP_NOTPROP))+          RRETURN(MATCH_NOMATCH);+        break;++        case PT_GC:+        if ((Fecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (Fop == OP_PROP))+          RRETURN(MATCH_NOMATCH);+        break;++        case PT_PC:+        if ((Fecode[2] != prop->chartype) == (Fop == OP_PROP))+          RRETURN(MATCH_NOMATCH);+        break;++        case PT_SC:+        if ((Fecode[2] != prop->script) == (Fop == OP_PROP))+          RRETURN(MATCH_NOMATCH);+        break;++        /* These are specials */++        case PT_ALNUM:+        if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+             PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (Fop == OP_NOTPROP))+          RRETURN(MATCH_NOMATCH);+        break;++        /* Perl space used to exclude VT, but from Perl 5.18 it is included,+        which means that Perl space and POSIX space are now identical. PCRE+        was changed at release 8.34. */++        case PT_SPACE:    /* Perl space */+        case PT_PXSPACE:  /* POSIX space */+        switch(fc)+          {+          HSPACE_CASES:+          VSPACE_CASES:+          if (Fop == OP_NOTPROP) RRETURN(MATCH_NOMATCH);+          break;++          default:+          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) ==+            (Fop == OP_NOTPROP)) RRETURN(MATCH_NOMATCH);+          break;+          }+        break;++        case PT_WORD:+        if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+             PRIV(ucp_gentype)[prop->chartype] == ucp_N ||+             fc == CHAR_UNDERSCORE) == (Fop == OP_NOTPROP))+          RRETURN(MATCH_NOMATCH);+        break;++        case PT_CLIST:+        cp = PRIV(ucd_caseless_sets) + Fecode[2];+        for (;;)+          {+          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 ((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:+        return PCRE2_ERROR_INTERNAL;+        }++      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 (Feptr >= mb->end_subject)+      {+      SCHECK_PARTIAL();+      RRETURN(MATCH_NOMATCH);+      }+    else+      {+      GETCHARINCTEST(fc, Feptr);+      Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,+        NULL);+      }+    CHECK_PARTIAL();+    Fecode++;+    break;++#endif  /* SUPPORT_UNICODE */+++    /* ===================================================================== */+    /* Match a single character type repeatedly. Note that the property type+    does not need to be in a stack frame as it is not used within an RMATCH()+    loop. */++#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:+    Lmin = Lmax = GET2(Fecode, 1);+    Fecode += 1 + IMM2_SIZE;+    goto REPEATTYPE;++    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    Lmin = 0;+    Lmax = GET2(Fecode, 1);+    reptype = (*Fecode == OP_TYPEMINUPTO)? REPTYPE_MIN : REPTYPE_MAX;+    Fecode += 1 + IMM2_SIZE;+    goto REPEATTYPE;++    case OP_TYPEPOSSTAR:+    reptype = REPTYPE_POS;+    Lmin = 0;+    Lmax = UINT32_MAX;+    Fecode++;+    goto REPEATTYPE;++    case OP_TYPEPOSPLUS:+    reptype = REPTYPE_POS;+    Lmin = 1;+    Lmax = UINT32_MAX;+    Fecode++;+    goto REPEATTYPE;++    case OP_TYPEPOSQUERY:+    reptype = REPTYPE_POS;+    Lmin = 0;+    Lmax = 1;+    Fecode++;+    goto REPEATTYPE;++    case OP_TYPEPOSUPTO:+    reptype = REPTYPE_POS;+    Lmin = 0;+    Lmax = GET2(Fecode, 1);+    Fecode += 1 + IMM2_SIZE;+    goto REPEATTYPE;++    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    fc = *Fecode++ - OP_TYPESTAR;+    Lmin = rep_min[fc];+    Lmax = rep_max[fc];+    reptype = rep_typ[fc];++    /* Common code for all repeated character type matches. */++    REPEATTYPE:+    Lctype = *Fecode++;      /* Code for the character type */++#ifdef SUPPORT_UNICODE+    if (Lctype == OP_PROP || Lctype == OP_NOTPROP)+      {+      proptype = *Fecode++;+      Lpropvalue = *Fecode++;+      }+    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). The code for UTF mode is separated out for+    tidiness, except for Unicode property tests. */++    if (Lmin > 0)+      {+#ifdef SUPPORT_UNICODE+      if (proptype >= 0)  /* Property tests in all modes */+        {+        switch(proptype)+          {+          case PT_ANY:+          if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);+          for (i = 1; i <= Lmin; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            }+          break;++          case PT_LAMP:+          for (i = 1; i <= Lmin; i++)+            {+            int chartype;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            chartype = UCD_CHARTYPE(fc);+            if ((chartype == ucp_Lu ||+                 chartype == ucp_Ll ||+                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          break;++          case PT_GC:+          for (i = 1; i <= Lmin; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          break;++          case PT_PC:+          for (i = 1; i <= Lmin; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          break;++          case PT_SC:+          for (i = 1; i <= Lmin; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          break;++          case PT_ALNUM:+          for (i = 1; i <= Lmin; i++)+            {+            int category;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            category = UCD_CATEGORY(fc);+            if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          break;++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          for (i = 1; i <= Lmin; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            switch(fc)+              {+              HSPACE_CASES:+              VSPACE_CASES:+              if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);+              break;++              default:+              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))+                RRETURN(MATCH_NOMATCH);+              break;+              }+            }+          break;++          case PT_WORD:+          for (i = 1; i <= Lmin; i++)+            {+            int category;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            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 <= Lmin; i++)+            {+            const uint32_t *cp;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            cp = PRIV(ucd_caseless_sets) + Lpropvalue;+            for (;;)+              {+              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 <= Lmin; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            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;++          /* This should not occur */++          default:+          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 (Lctype == OP_EXTUNI)+        {+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          else+            {+            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 in UTF mode */++#ifdef SUPPORT_UNICODE+      if (utf) switch(Lctype)+        {+        case OP_ANY:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);+          if (mb->partial != 0 &&+              Feptr + 1 >= mb->end_subject &&+              NLBLOCK->nltype == NLTYPE_FIXED &&+              NLBLOCK->nllen == 2 &&+              UCHAR21(Feptr) == NLBLOCK->nl[0])+            {+            mb->hitend = TRUE;+            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+            }+          Feptr++;+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+          }+        break;++        case OP_ALLANY:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          Feptr++;+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+          }+        break;++        case OP_ANYBYTE:+        if (Feptr > mb->end_subject - Lmin) RRETURN(MATCH_NOMATCH);+        Feptr += Lmin;+        break;++        case OP_ANYNL:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          GETCHARINC(fc, Feptr);+          switch(fc)+            {+            default: RRETURN(MATCH_NOMATCH);++            case CHAR_CR:+            if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;+            break;++            case CHAR_LF:+            break;++            case CHAR_VT:+            case CHAR_FF:+            case CHAR_NEL:+#ifndef EBCDIC+            case 0x2028:+            case 0x2029:+#endif  /* Not EBCDIC */+            if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);+            break;+            }+          }+        break;++        case OP_NOT_HSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          GETCHARINC(fc, Feptr);+          switch(fc)+            {+            HSPACE_CASES: RRETURN(MATCH_NOMATCH);+            default: break;+            }+          }+        break;++        case OP_HSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          GETCHARINC(fc, Feptr);+          switch(fc)+            {+            HSPACE_CASES: break;+            default: RRETURN(MATCH_NOMATCH);+            }+          }+        break;++        case OP_NOT_VSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          GETCHARINC(fc, Feptr);+          switch(fc)+            {+            VSPACE_CASES: RRETURN(MATCH_NOMATCH);+            default: break;+            }+          }+        break;++        case OP_VSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          GETCHARINC(fc, Feptr);+          switch(fc)+            {+            VSPACE_CASES: break;+            default: RRETURN(MATCH_NOMATCH);+            }+          }+        break;++        case OP_NOT_DIGIT:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          GETCHARINC(fc, Feptr);+          if (fc < 128 && (mb->ctypes[fc] & ctype_digit) != 0)+            RRETURN(MATCH_NOMATCH);+          }+        break;++        case OP_DIGIT:+        for (i = 1; i <= Lmin; i++)+          {+          uint32_t cc;+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          cc = UCHAR21(Feptr);+          if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          /* No need to skip more code units - we know it has only one. */+          }+        break;++        case OP_NOT_WHITESPACE:+        for (i = 1; i <= Lmin; i++)+          {+          uint32_t cc;+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          cc = UCHAR21(Feptr);+          if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+          }+        break;++        case OP_WHITESPACE:+        for (i = 1; i <= Lmin; i++)+          {+          uint32_t cc;+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          cc = UCHAR21(Feptr);+          if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          /* No need to skip more code units - we know it has only one. */+          }+        break;++        case OP_NOT_WORDCHAR:+        for (i = 1; i <= Lmin; i++)+          {+          uint32_t cc;+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          cc = UCHAR21(Feptr);+          if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+          }+        break;++        case OP_WORDCHAR:+        for (i = 1; i <= Lmin; i++)+          {+          uint32_t cc;+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          cc = UCHAR21(Feptr);+          if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          /* No need to skip more code units - we know it has only one. */+          }+        break;++        default:+        return PCRE2_ERROR_INTERNAL;+        }  /* End switch(Lctype) */++      else+#endif     /* SUPPORT_UNICODE */++      /* Code for the non-UTF case for minimum matching of operators other+      than OP_PROP and OP_NOTPROP. */++      switch(Lctype)+        {+        case OP_ANY:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);+          if (mb->partial != 0 &&+              Feptr + 1 >= mb->end_subject &&+              NLBLOCK->nltype == NLTYPE_FIXED &&+              NLBLOCK->nllen == 2 &&+              *Feptr == NLBLOCK->nl[0])+            {+            mb->hitend = TRUE;+            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+            }+          Feptr++;+          }+        break;++        case OP_ALLANY:+        if (Feptr > mb->end_subject - Lmin)+          {+          SCHECK_PARTIAL();+          RRETURN(MATCH_NOMATCH);+          }+        Feptr += Lmin;+        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 <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          switch(*Feptr++)+            {+            default: RRETURN(MATCH_NOMATCH);++            case CHAR_CR:+            if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;+            break;++            case CHAR_LF:+            break;++            case CHAR_VT:+            case CHAR_FF:+            case CHAR_NEL:+#if PCRE2_CODE_UNIT_WIDTH != 8+            case 0x2028:+            case 0x2029:+#endif+            if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);+            break;+            }+          }+        break;++        case OP_NOT_HSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          switch(*Feptr++)+            {+            default: break;+            HSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+            HSPACE_MULTIBYTE_CASES:+#endif+            RRETURN(MATCH_NOMATCH);+            }+          }+        break;++        case OP_HSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          switch(*Feptr++)+            {+            default: RRETURN(MATCH_NOMATCH);+            HSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+            HSPACE_MULTIBYTE_CASES:+#endif+            break;+            }+          }+        break;++        case OP_NOT_VSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          switch(*Feptr++)+            {+            VSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+            VSPACE_MULTIBYTE_CASES:+#endif+            RRETURN(MATCH_NOMATCH);+            default: break;+            }+          }+        break;++        case OP_VSPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          switch(*Feptr++)+            {+            default: RRETURN(MATCH_NOMATCH);+            VSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+            VSPACE_MULTIBYTE_CASES:+#endif+            break;+            }+          }+        break;++        case OP_NOT_DIGIT:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          }+        break;++        case OP_DIGIT:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          }+        break;++        case OP_NOT_WHITESPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          }+        break;++        case OP_WHITESPACE:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          }+        break;++        case OP_NOT_WORDCHAR:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          }+        break;++        case OP_WORDCHAR:+        for (i = 1; i <= Lmin; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)+            RRETURN(MATCH_NOMATCH);+          Feptr++;+          }+        break;++        default:+        return PCRE2_ERROR_INTERNAL;+        }+      }++    /* If Lmin = Lmax we are done. Continue with the main loop. */++    if (Lmin == Lmax) continue;++    /* If minimizing, we have to test the rest of the pattern before each+    subsequent match. */++    if (reptype == REPTYPE_MIN)+      {+#ifdef SUPPORT_UNICODE+      if (proptype >= 0)+        {+        switch(proptype)+          {+          case PT_ANY:+          for (;;)+            {+            RMATCH(Fecode, RM208);+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              RRETURN(MATCH_NOMATCH);+              }+            GETCHARINCTEST(fc, Feptr);+            if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          case PT_LAMP:+          for (;;)+            {+            int chartype;+            RMATCH(Fecode, RM209);+            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);+            chartype = UCD_CHARTYPE(fc);+            if ((chartype == ucp_Lu ||+                 chartype == ucp_Ll ||+                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          case PT_GC:+          for (;;)+            {+            RMATCH(Fecode, RM210);+            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 ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          case PT_PC:+          for (;;)+            {+            RMATCH(Fecode, RM211);+            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 ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          case PT_SC:+          for (;;)+            {+            RMATCH(Fecode, RM212);+            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 ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          case PT_ALNUM:+          for (;;)+            {+            int category;+            RMATCH(Fecode, RM213);+            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);+            category = UCD_CATEGORY(fc);+            if ((category == ucp_L || category == ucp_N) ==+                (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          for (;;)+            {+            RMATCH(Fecode, RM214);+            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);+            switch(fc)+              {+              HSPACE_CASES:+              VSPACE_CASES:+              if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);+              break;++              default:+              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))+                RRETURN(MATCH_NOMATCH);+              break;+              }+            }+          /* Control never gets here */++          case PT_WORD:+          for (;;)+            {+            int category;+            RMATCH(Fecode, RM215);+            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);+            category = UCD_CATEGORY(fc);+            if ((category == ucp_L ||+                 category == ucp_N ||+                 fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))+              RRETURN(MATCH_NOMATCH);+            }+          /* Control never gets here */++          case PT_CLIST:+          for (;;)+            {+            const uint32_t *cp;+            RMATCH(Fecode, RM216);+            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);+            cp = PRIV(ucd_caseless_sets) + Lpropvalue;+            for (;;)+              {+              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 (;;)+            {+            RMATCH(Fecode, RM217);+            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 ((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:+          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 (Lctype == OP_EXTUNI)+        {+        for (;;)+          {+          RMATCH(Fecode, RM218);+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          else+            {+            GETCHARINCTEST(fc, Feptr);+            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,+              utf, NULL);+            }+          CHECK_PARTIAL();+          }+        }+      else+#endif     /* SUPPORT_UNICODE */++      /* UTF mode for non-property testing character types. */++#ifdef SUPPORT_UNICODE+      if (utf)+        {+        for (;;)+          {+          RMATCH(Fecode, RM219);+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          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 */+                Feptr >= mb->end_subject &&+                NLBLOCK->nltype == NLTYPE_FIXED &&+                NLBLOCK->nllen == 2 &&+                fc == NLBLOCK->nl[0])+              {+              mb->hitend = TRUE;+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+              }+            break;++            case OP_ALLANY:+            case OP_ANYBYTE:+            break;++            case OP_ANYNL:+            switch(fc)+              {+              default: RRETURN(MATCH_NOMATCH);++              case CHAR_CR:+              if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;+              break;++              case CHAR_LF:+              break;++              case CHAR_VT:+              case CHAR_FF:+              case CHAR_NEL:+#ifndef EBCDIC+              case 0x2028:+              case 0x2029:+#endif  /* Not EBCDIC */+              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)+                RRETURN(MATCH_NOMATCH);+              break;+              }+            break;++            case OP_NOT_HSPACE:+            switch(fc)+              {+              HSPACE_CASES: RRETURN(MATCH_NOMATCH);+              default: break;+              }+            break;++            case OP_HSPACE:+            switch(fc)+              {+              HSPACE_CASES: break;+              default: RRETURN(MATCH_NOMATCH);+              }+            break;++            case OP_NOT_VSPACE:+            switch(fc)+              {+              VSPACE_CASES: RRETURN(MATCH_NOMATCH);+              default: break;+              }+            break;++            case OP_VSPACE:+            switch(fc)+              {+              VSPACE_CASES: break;+              default: RRETURN(MATCH_NOMATCH);+              }+            break;++            case OP_NOT_DIGIT:+            if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_DIGIT:+            if (fc >= 256 || (mb->ctypes[fc] & ctype_digit) == 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_NOT_WHITESPACE:+            if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_WHITESPACE:+            if (fc >= 256 || (mb->ctypes[fc] & ctype_space) == 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_NOT_WORDCHAR:+            if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_WORDCHAR:+            if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0)+              RRETURN(MATCH_NOMATCH);+            break;++            default:+            return PCRE2_ERROR_INTERNAL;+            }+          }+        }+      else+#endif  /* SUPPORT_UNICODE */++      /* Not UTF mode */+        {+        for (;;)+          {+          RMATCH(Fecode, RM33);+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            RRETURN(MATCH_NOMATCH);+            }+          if (Lctype == OP_ANY && IS_NEWLINE(Feptr))+            RRETURN(MATCH_NOMATCH);+          fc = *Feptr++;+          switch(Lctype)+            {+            case OP_ANY:               /* This is the non-NL case */+            if (mb->partial != 0 &&    /* Take care with CRLF partial */+                Feptr >= mb->end_subject &&+                NLBLOCK->nltype == NLTYPE_FIXED &&+                NLBLOCK->nllen == 2 &&+                fc == NLBLOCK->nl[0])+              {+              mb->hitend = TRUE;+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+              }+            break;++            case OP_ALLANY:+            case OP_ANYBYTE:+            break;++            case OP_ANYNL:+            switch(fc)+              {+              default: RRETURN(MATCH_NOMATCH);++              case CHAR_CR:+              if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;+              break;++              case CHAR_LF:+              break;++              case CHAR_VT:+              case CHAR_FF:+              case CHAR_NEL:+#if PCRE2_CODE_UNIT_WIDTH != 8+              case 0x2028:+              case 0x2029:+#endif+              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)+                RRETURN(MATCH_NOMATCH);+              break;+              }+            break;++            case OP_NOT_HSPACE:+            switch(fc)+              {+              default: break;+              HSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              HSPACE_MULTIBYTE_CASES:+#endif+              RRETURN(MATCH_NOMATCH);+              }+            break;++            case OP_HSPACE:+            switch(fc)+              {+              default: RRETURN(MATCH_NOMATCH);+              HSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              HSPACE_MULTIBYTE_CASES:+#endif+              break;+              }+            break;++            case OP_NOT_VSPACE:+            switch(fc)+              {+              default: break;+              VSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              VSPACE_MULTIBYTE_CASES:+#endif+              RRETURN(MATCH_NOMATCH);+              }+            break;++            case OP_VSPACE:+            switch(fc)+              {+              default: RRETURN(MATCH_NOMATCH);+              VSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              VSPACE_MULTIBYTE_CASES:+#endif+              break;+              }+            break;++            case OP_NOT_DIGIT:+            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_DIGIT:+            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_NOT_WHITESPACE:+            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_WHITESPACE:+            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_NOT_WORDCHAR:+            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)+              RRETURN(MATCH_NOMATCH);+            break;++            case OP_WORDCHAR:+            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)+              RRETURN(MATCH_NOMATCH);+            break;++            default:+            return PCRE2_ERROR_INTERNAL;+            }+          }+        }+      /* Control never gets here */+      }++    /* 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). */++    else+      {+      Lstart_eptr = Feptr;  /* Remember where we started */++#ifdef SUPPORT_UNICODE+      if (proptype >= 0)+        {+        switch(proptype)+          {+          case PT_ANY:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            if (Lctype == OP_NOTPROP) break;+            Feptr+= len;+            }+          break;++          case PT_LAMP:+          for (i = Lmin; i < Lmax; i++)+            {+            int chartype;+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            chartype = UCD_CHARTYPE(fc);+            if ((chartype == ucp_Lu ||+                 chartype == ucp_Ll ||+                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))+              break;+            Feptr+= len;+            }+          break;++          case PT_GC:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              break;+            Feptr+= len;+            }+          break;++          case PT_PC:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              break;+            Feptr+= len;+            }+          break;++          case PT_SC:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))+              break;+            Feptr+= len;+            }+          break;++          case PT_ALNUM:+          for (i = Lmin; i < Lmax; i++)+            {+            int category;+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            category = UCD_CATEGORY(fc);+            if ((category == ucp_L || category == ucp_N) ==+                (Lctype == OP_NOTPROP))+              break;+            Feptr+= len;+            }+          break;++          /* Perl space used to exclude VT, but from Perl 5.18 it is included,+          which means that Perl space and POSIX space are now identical. PCRE+          was changed at release 8.34. */++          case PT_SPACE:    /* Perl space */+          case PT_PXSPACE:  /* POSIX space */+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            switch(fc)+              {+              HSPACE_CASES:+              VSPACE_CASES:+              if (Lctype == OP_NOTPROP) goto ENDLOOP99;  /* Break the loop */+              break;++              default:+              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))+                goto ENDLOOP99;   /* Break the loop */+              break;+              }+            Feptr+= len;+            }+          ENDLOOP99:+          break;++          case PT_WORD:+          for (i = Lmin; i < Lmax; i++)+            {+            int category;+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            category = UCD_CATEGORY(fc);+            if ((category == ucp_L || category == ucp_N ||+                 fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))+              break;+            Feptr+= len;+            }+          break;++          case PT_CLIST:+          for (i = Lmin; i < Lmax; i++)+            {+            const uint32_t *cp;+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLENTEST(fc, Feptr, len);+            cp = PRIV(ucd_caseless_sets) + Lpropvalue;+            for (;;)+              {+              if (fc < *cp)+                { if (Lctype == OP_NOTPROP) break; else goto GOT_MAX; }+              if (fc == *cp++)+                { if (Lctype == OP_NOTPROP) goto GOT_MAX; else break; }+              }+            Feptr += len;+            }+          GOT_MAX:+          break;++          case PT_UCNC:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            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;+            Feptr += len;+            }+          break;++          default:+          return PCRE2_ERROR_INTERNAL;+          }++        /* Feptr is now past the end of the maximum run */++        if (reptype == REPTYPE_POS) continue;    /* No backtracking */++        /* After \C in UTF mode, Lstart_eptr might be in the middle of a+        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't+        go too far. */++        for(;;)+          {+          if (Feptr <= Lstart_eptr) break;+          RMATCH(Fecode, RM222);+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);+          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 (Lctype == OP_EXTUNI)+        {+        for (i = Lmin; i < Lmax; i++)+          {+          if (Feptr >= mb->end_subject)+            {+            SCHECK_PARTIAL();+            break;+            }+          else+            {+            GETCHARINCTEST(fc, Feptr);+            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,+              utf, NULL);+            }+          CHECK_PARTIAL();+          }++        /* Feptr is now past the end of the maximum run */++        if (reptype == REPTYPE_POS) continue;    /* No backtracking */++        /* 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 (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. */++          Feptr--;+          if (!utf) fc = *Feptr; else+            {+            BACKCHAR(Feptr);+            GETCHAR(fc, Feptr);+            }+          rgb = UCD_GRAPHBREAK(fc);++          for (;;)+            {+            if (Feptr <= Lstart_eptr) break;   /* At start of char run */+            fptr = Feptr - 1;+            if (!utf) fc = *fptr; else+              {+              BACKCHAR(fptr);+              GETCHAR(fc, fptr);+              }+            lgb = UCD_GRAPHBREAK(fc);+            if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;+            Feptr = fptr;+            rgb = lgb;+            }+          }+        }++      else+#endif   /* SUPPORT_UNICODE */++#ifdef SUPPORT_UNICODE+      if (utf)+        {+        switch(Lctype)+          {+          case OP_ANY:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (IS_NEWLINE(Feptr)) break;+            if (mb->partial != 0 &&    /* Take care with CRLF partial */+                Feptr + 1 >= mb->end_subject &&+                NLBLOCK->nltype == NLTYPE_FIXED &&+                NLBLOCK->nllen == 2 &&+                UCHAR21(Feptr) == NLBLOCK->nl[0])+              {+              mb->hitend = TRUE;+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+              }+            Feptr++;+            ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+            }+          break;++          case OP_ALLANY:+          if (Lmax < UINT32_MAX)+            {+            for (i = Lmin; i < Lmax; i++)+              {+              if (Feptr >= mb->end_subject)+                {+                SCHECK_PARTIAL();+                break;+                }+              Feptr++;+              ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);+              }+            }+          else+            {+            Feptr = mb->end_subject;   /* Unlimited UTF-8 repeat */+            SCHECK_PARTIAL();+            }+          break;++          /* The "byte" (i.e. "code unit") case is the same as non-UTF */++          case OP_ANYBYTE:+          fc = Lmax - Lmin;+          if (fc > (uint32_t)(mb->end_subject - Feptr))+            {+            Feptr = mb->end_subject;+            SCHECK_PARTIAL();+            }+          else Feptr += fc;+          break;++          case OP_ANYNL:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc == CHAR_CR)+              {+              if (++Feptr >= mb->end_subject) break;+              if (UCHAR21(Feptr) == CHAR_LF) Feptr++;+              }+            else+              {+              if (fc != CHAR_LF &&+                  (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||+                   (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL+#ifndef EBCDIC+                    && fc != 0x2028 && fc != 0x2029+#endif  /* Not EBCDIC */+                    )))+                break;+              Feptr += len;+              }+            }+          break;++          case OP_NOT_HSPACE:+          case OP_HSPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            BOOL gotspace;+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            switch(fc)+              {+              HSPACE_CASES: gotspace = TRUE; break;+              default: gotspace = FALSE; break;+              }+            if (gotspace == (Lctype == OP_NOT_HSPACE)) break;+            Feptr += len;+            }+          break;++          case OP_NOT_VSPACE:+          case OP_VSPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            BOOL gotspace;+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            switch(fc)+              {+              VSPACE_CASES: gotspace = TRUE; break;+              default: gotspace = FALSE; break;+              }+            if (gotspace == (Lctype == OP_NOT_VSPACE)) break;+            Feptr += len;+            }+          break;++          case OP_NOT_DIGIT:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0) break;+            Feptr+= len;+            }+          break;++          case OP_DIGIT:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc >= 256 ||(mb->ctypes[fc] & ctype_digit) == 0) break;+            Feptr+= len;+            }+          break;++          case OP_NOT_WHITESPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0) break;+            Feptr+= len;+            }+          break;++          case OP_WHITESPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc >= 256 ||(mb->ctypes[fc] & ctype_space) == 0) break;+            Feptr+= len;+            }+          break;++          case OP_NOT_WORDCHAR:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0) break;+            Feptr+= len;+            }+          break;++          case OP_WORDCHAR:+          for (i = Lmin; i < Lmax; i++)+            {+            int len = 1;+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            GETCHARLEN(fc, Feptr, len);+            if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0) break;+            Feptr+= len;+            }+          break;++          default:+          return PCRE2_ERROR_INTERNAL;+          }++        if (reptype == REPTYPE_POS) continue;    /* No backtracking */++        /* After \C in UTF mode, Lstart_eptr might be in the middle of a+        Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't go+        too far. */++        for(;;)+          {+          if (Feptr <= Lstart_eptr) break;+          RMATCH(Fecode, RM221);+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);+          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(Lctype)+          {+          case OP_ANY:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (IS_NEWLINE(Feptr)) break;+            if (mb->partial != 0 &&    /* Take care with CRLF partial */+                Feptr + 1 >= mb->end_subject &&+                NLBLOCK->nltype == NLTYPE_FIXED &&+                NLBLOCK->nllen == 2 &&+                *Feptr == NLBLOCK->nl[0])+              {+              mb->hitend = TRUE;+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;+              }+            Feptr++;+            }+          break;++          case OP_ALLANY:+          case OP_ANYBYTE:+          fc = Lmax - Lmin;+          if (fc > (uint32_t)(mb->end_subject - Feptr))+            {+            Feptr = mb->end_subject;+            SCHECK_PARTIAL();+            }+          else Feptr += fc;+          break;++          case OP_ANYNL:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            fc = *Feptr;+            if (fc == CHAR_CR)+              {+              if (++Feptr >= mb->end_subject) break;+              if (*Feptr == CHAR_LF) Feptr++;+              }+            else+              {+              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+                 && fc != 0x2028 && fc != 0x2029+#endif+                 ))) break;+              Feptr++;+              }+            }+          break;++          case OP_NOT_HSPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            switch(*Feptr)+              {+              default: Feptr++; break;+              HSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              HSPACE_MULTIBYTE_CASES:+#endif+              goto ENDLOOP00;+              }+            }+          ENDLOOP00:+          break;++          case OP_HSPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            switch(*Feptr)+              {+              default: goto ENDLOOP01;+              HSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              HSPACE_MULTIBYTE_CASES:+#endif+              Feptr++; break;+              }+            }+          ENDLOOP01:+          break;++          case OP_NOT_VSPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            switch(*Feptr)+              {+              default: Feptr++; break;+              VSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              VSPACE_MULTIBYTE_CASES:+#endif+              goto ENDLOOP02;+              }+            }+          ENDLOOP02:+          break;++          case OP_VSPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            switch(*Feptr)+              {+              default: goto ENDLOOP03;+              VSPACE_BYTE_CASES:+#if PCRE2_CODE_UNIT_WIDTH != 8+              VSPACE_MULTIBYTE_CASES:+#endif+              Feptr++; break;+              }+            }+          ENDLOOP03:+          break;++          case OP_NOT_DIGIT:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)+              break;+            Feptr++;+            }+          break;++          case OP_DIGIT:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)+              break;+            Feptr++;+            }+          break;++          case OP_NOT_WHITESPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)+              break;+            Feptr++;+            }+          break;++          case OP_WHITESPACE:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)+              break;+            Feptr++;+            }+          break;++          case OP_NOT_WORDCHAR:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)+              break;+            Feptr++;+            }+          break;++          case OP_WORDCHAR:+          for (i = Lmin; i < Lmax; i++)+            {+            if (Feptr >= mb->end_subject)+              {+              SCHECK_PARTIAL();+              break;+              }+            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)+              break;+            Feptr++;+            }+          break;++          default:+          return PCRE2_ERROR_INTERNAL;+          }++        if (reptype == REPTYPE_POS) continue;    /* No backtracking */++        for (;;)+          {+          if (Feptr == Lstart_eptr) break;+          RMATCH(Fecode, RM34);+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);+          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_SCRIPT_RUN:+    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 and mark retained. Any other return is an error. */++#define Lframe_type  F->temp_32[0]++    case OP_ASSERT:+    case OP_ASSERTBACK:+    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    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;+        Fmark = assert_accept_frame->mark;+        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->check_subject) RRETURN(MATCH_NOMATCH);+        Feptr--;+        BACKCHAR(Feptr);+        }+      }+    else+#endif++    /* No UTF-8 support, or not in UTF-8 mode: count is code unit count */++      {+      if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);+      Feptr -= number;+      }++    /* Save the earliest consulted character, then skip to next opcode */++    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+      mark setting and the captures into the frame before N so that they are+      set on return. Doing this for all assertions, both positive and negative,+      seems to match what Perl does. */++      if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT)+        {+        memcpy((char *)P + offsetof(heapframe, ovector), Fovector,+          Foffset_top * sizeof(PCRE2_SIZE));+        P->offset_top = Foffset_top;+        P->mark = Fmark;+        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;++      /* Non-atomic positive assertions are like OP_BRA, except that the+      subject pointer must be put back to where it was at the start of the+      assertion. */++      case OP_ASSERT_NA:+      case OP_ASSERTBACK_NA:+      if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;+      Feptr = P->eptr;+      break;++      /* Atomic 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);+      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);++      /* At the end of a script run, apply the script-checking rules. This code+      will never by exercised if Unicode support it not compiled, because in+      that environment script runs cause an error at compile time. */++      case OP_SCRIPT_RUN:+      if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH);+      break;++      /* 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);+    if (mb->partial != 0)+      {+      mb->hitend = TRUE;+      if (mb->partial > 1) return PCRE2_ERROR_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. */++    if (mb->partial != 0)+      {+      mb->hitend = TRUE;+      if (mb->partial > 1) return PCRE2_ERROR_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->check_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_COMMIT_ARG:+    Fmark = mb->nomatch_mark = Fecode + 2;+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM36);+    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:+    return PCRE2_ERROR_INTERNAL;+    }++  /* 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 */+/* Control never reaches here */+++/* ========================================================================= */+/* 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. */++#define LBL(val) case val: goto L_RM##val;++RETURN_SWITCH:+if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;+if (Frdepth == 0) return rrc;                     /* Exit from the top level */+F = (heapframe *)((char *)F - Fback_frame);       /* Backtrack */+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(16)+  LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)+  LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)+  LBL(33) LBL(34) LBL(35) LBL(36)++#ifdef SUPPORT_WIDE_CHARS+  LBL(100) LBL(101)+#endif++#ifdef SUPPORT_UNICODE+  LBL(200) LBL(201) LBL(202) LBL(203) LBL(204) LBL(205) LBL(206)+  LBL(207) LBL(208) LBL(209) LBL(210) LBL(211) LBL(212) LBL(213)+  LBL(214) LBL(215) LBL(216) LBL(217) LBL(218) LBL(219) LBL(220)+  LBL(221) LBL(222)+#endif++  default:+  return PCRE2_ERROR_INTERNAL;+  }+#undef LBL+}+++/*************************************************+*           Match a Regular Expression           *+*************************************************/++/* This function applies a compiled pattern to a subject string and picks out+portions of the string if it matches. Two elements in the vector are set for+each substring: the offsets to the start and end of the substring.++Arguments:+  code            points to the compiled expression+  subject         points to the subject string+  length          length of subject string (may contain binary zeros)+  start_offset    where to start in the subject string+  options         option bits+  match_data      points to a match_data block+  mcontext        points a PCRE2 context++Returns:          > 0 => success; value is the number of ovector pairs filled+                  = 0 => success, but ovector is not big enough+                  = -1 => failed to match (PCRE2_ERROR_NOMATCH)+                  = -2 => partial match (PCRE2_ERROR_PARTIAL)+                  < -2 => some kind of unexpected problem+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_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 rc;+int was_zero_terminated = 0;+const uint8_t *start_bits = NULL;+const pcre2_real_code *re = (const pcre2_real_code *)code;++BOOL anchored;+BOOL firstline;+BOOL has_first_cu = FALSE;+BOOL has_req_cu = FALSE;+BOOL startline;++#if PCRE2_CODE_UNIT_WIDTH == 8+BOOL memchr_not_found_first_cu;+BOOL memchr_not_found_first_cu2;+#endif++PCRE2_UCHAR first_cu = 0;+PCRE2_UCHAR first_cu2 = 0;+PCRE2_UCHAR req_cu = 0;+PCRE2_UCHAR req_cu2 = 0;++PCRE2_SPTR bumpalong_limit;+PCRE2_SPTR end_subject;+PCRE2_SPTR true_end_subject;+PCRE2_SPTR start_match = subject + start_offset;+PCRE2_SPTR req_cu_ptr = start_match - 1;+PCRE2_SPTR start_partial;+PCRE2_SPTR match_partial;++#ifdef SUPPORT_JIT+BOOL use_jit;+#endif++/* This flag is needed even when Unicode is not supported for convenience+(it is used by the IS_NEWLINE macro). */++BOOL utf = FALSE;++#ifdef SUPPORT_UNICODE+BOOL ucp = FALSE;+BOOL allow_invalid;+uint32_t fragment_options = 0;+#ifdef SUPPORT_JIT+BOOL jit_checked_utf = FALSE;+#endif+#endif  /* SUPPORT_UNICODE */++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;++/* 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)]+    PCRE2_KEEP_UNINITIALIZED;+mb->stack_frames = (heapframe *)stack_frames_vector;++/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated+subject string. */++if (length == PCRE2_ZERO_TERMINATED)+  {+  length = PRIV(strlen)(subject);+  was_zero_terminated = 1;+  }+true_end_subject = end_subject = subject + length;++/* Plausibility checks */++if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;+if (code == NULL || subject == NULL || match_data == NULL)+  return PCRE2_ERROR_NULL;+if (start_offset > length) return PCRE2_ERROR_BADOFFSET;++/* Check that the first field in the block is the magic number. */++if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;++/* Check the code unit width. */++if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)+  return PCRE2_ERROR_BADMODE;++/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the+options variable for this function. Users of PCRE2 who are not calling the+function directly would like to have a way of setting these flags, in the same+way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with+constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and+(*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which we now+transfer to the options for this function. The bits are guaranteed to be+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+occur. */++#define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)+#define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)+options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));+#undef FF+#undef OO++/* If the pattern was successfully studied with JIT support, we will run the+JIT executable instead of the rest of this function. Most options must be set+at compile time for the JIT code to be usable. */++#ifdef SUPPORT_JIT+use_jit = (re->executable_jit != NULL &&+          (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);+#endif++/* Initialize UTF/UCP parameters. */++#ifdef SUPPORT_UNICODE+utf = (re->overall_options & PCRE2_UTF) != 0;+allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;+ucp = (re->overall_options & PCRE2_UCP) != 0;+#endif  /* SUPPORT_UNICODE */++/* Convert the partial matching flags into an integer. */++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;++/* It is an error to set an offset limit without setting the flag at compile+time. */++if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&+     (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)+  return PCRE2_ERROR_BADOFFSETLIMIT;++/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,+free the memory that was obtained. Set the field to NULL for no match cases. */++if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)+  {+  match_data->memctl.free((void *)match_data->subject,+    match_data->memctl.memory_data);+  match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;+  }+match_data->subject = NULL;++/* Zero the error offset in case the first code unit is invalid UTF. */++match_data->startchar = 0;+++/* ============================= JIT matching ============================== */++/* Prepare for JIT matching. Check a UTF string for validity unless no check is+requested or invalid UTF can be handled. We check only the portion of the+subject that might be be inspected during matching - from the offset minus the+maximum lookbehind to the given length. This saves time when a small part of a+large subject is being matched by the use of a starting offset. Note that the+maximum lookbehind is a number of characters, not code units. */++#ifdef SUPPORT_JIT+if (use_jit)+  {+#ifdef SUPPORT_UNICODE+  if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid)+    {+#if PCRE2_CODE_UNIT_WIDTH != 32+    unsigned int i;+#endif++    /* For 8-bit and 16-bit UTF, check that the first code unit is a valid+    character start. */++#if PCRE2_CODE_UNIT_WIDTH != 32+    if (start_match < end_subject && NOT_FIRSTCU(*start_match))+      {+      if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;+#if PCRE2_CODE_UNIT_WIDTH == 8+      return PCRE2_ERROR_UTF8_ERR20;  /* Isolated 0x80 byte */+#else+      return PCRE2_ERROR_UTF16_ERR3;  /* Isolated low surrogate */+#endif+      }+#endif  /* WIDTH != 32 */++    /* Move back by the maximum lookbehind, just in case it happens at the very+    start of matching. */++#if PCRE2_CODE_UNIT_WIDTH != 32+    for (i = re->max_lookbehind; i > 0 && start_match > subject; i--)+      {+      start_match--;+      while (start_match > subject &&+#if PCRE2_CODE_UNIT_WIDTH == 8+      (*start_match & 0xc0) == 0x80)+#else  /* 16-bit */+      (*start_match & 0xfc00) == 0xdc00)+#endif+        start_match--;+      }+#else  /* PCRE2_CODE_UNIT_WIDTH != 32 */++    /* In the 32-bit library, one code unit equals one character. However,+    we cannot just subtract the lookbehind and then compare pointers, because+    a very large lookbehind could create an invalid pointer. */++    if (start_offset >= re->max_lookbehind)+      start_match -= re->max_lookbehind;+    else+      start_match = subject;+#endif  /* PCRE2_CODE_UNIT_WIDTH != 32 */++    /* Validate the relevant portion of the subject. Adjust the offset of an+    invalid code point to be an absolute offset in the whole string. */++    match_data->rc = PRIV(valid_utf)(start_match,+      length - (start_match - subject), &(match_data->startchar));+    if (match_data->rc != 0)+      {+      match_data->startchar += start_match - subject;+      return match_data->rc;+      }+    jit_checked_utf = TRUE;+    }+#endif  /* SUPPORT_UNICODE */++  /* If JIT returns BADOPTION, which means that the selected complete or+  partial matching mode was not compiled, fall through to the interpreter. */++  rc = pcre2_jit_match(code, subject, length, start_offset, options,+    match_data, mcontext);+  if (rc != PCRE2_ERROR_JIT_BADOPTION)+    {+    if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)+      {+      length = CU2BYTES(length + was_zero_terminated);+      match_data->subject = match_data->memctl.malloc(length,+        match_data->memctl.memory_data);+      if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;+      memcpy((void *)match_data->subject, subject, length);+      match_data->flags |= PCRE2_MD_COPIED_SUBJECT;+      }+    return rc;+    }+  }+#endif  /* SUPPORT_JIT */++/* ========================= End of JIT matching ========================== */+++/* Proceed with non-JIT matching. The default is to allow lookbehinds to the+start of the subject. A UTF check when there is a non-zero offset may change+this. */++mb->check_subject = subject;++/* If a UTF subject string was not checked for validity in the JIT code above,+check it here, and handle support for invalid UTF strings. The check above+happens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset.+If we get here in those circumstances, it means the subject string is valid,+but for some reason JIT matching was not successful. There is no need to check+the subject again.++We check only the portion of the subject that might be be inspected during+matching - from the offset minus the maximum lookbehind to the given length.+This saves time when a small part of a large subject is being matched by the+use of a starting offset. Note that the maximum lookbehind is a number of+characters, not code units.++Note also that support for invalid UTF forces a check, overriding the setting+of PCRE2_NO_CHECK_UTF. */++#ifdef SUPPORT_UNICODE+if (utf &&+#ifdef SUPPORT_JIT+    !jit_checked_utf &&+#endif+    ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))+  {+#if PCRE2_CODE_UNIT_WIDTH != 32+  BOOL skipped_bad_start = FALSE;+#endif++  /* For 8-bit and 16-bit UTF, check that the first code unit is a valid+  character start. If we are handling invalid UTF, just skip over such code+  units. Otherwise, give an appropriate error. */++#if PCRE2_CODE_UNIT_WIDTH != 32+  if (allow_invalid)+    {+    while (start_match < end_subject && NOT_FIRSTCU(*start_match))+      {+      start_match++;+      skipped_bad_start = TRUE;+      }+    }+  else if (start_match < end_subject && NOT_FIRSTCU(*start_match))+    {+    if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;+#if PCRE2_CODE_UNIT_WIDTH == 8+    return PCRE2_ERROR_UTF8_ERR20;  /* Isolated 0x80 byte */+#else+    return PCRE2_ERROR_UTF16_ERR3;  /* Isolated low surrogate */+#endif+    }+#endif  /* WIDTH != 32 */++  /* The mb->check_subject field points to the start of UTF checking;+  lookbehinds can go back no further than this. */++  mb->check_subject = start_match;++  /* Move back by the maximum lookbehind, just in case it happens at the very+  start of matching, but don't do this if we skipped bad 8-bit or 16-bit code+  units above. */++#if PCRE2_CODE_UNIT_WIDTH != 32+  if (!skipped_bad_start)+    {+    unsigned int i;+    for (i = re->max_lookbehind; i > 0 && mb->check_subject > subject; i--)+      {+      mb->check_subject--;+      while (mb->check_subject > subject &&+#if PCRE2_CODE_UNIT_WIDTH == 8+      (*mb->check_subject & 0xc0) == 0x80)+#else  /* 16-bit */+      (*mb->check_subject & 0xfc00) == 0xdc00)+#endif+        mb->check_subject--;+      }+    }+#else  /* PCRE2_CODE_UNIT_WIDTH != 32 */++  /* In the 32-bit library, one code unit equals one character. However,+  we cannot just subtract the lookbehind and then compare pointers, because+  a very large lookbehind could create an invalid pointer. */++  if (start_offset >= re->max_lookbehind)+    mb->check_subject -= re->max_lookbehind;+  else+    mb->check_subject = subject;+#endif  /* PCRE2_CODE_UNIT_WIDTH != 32 */++  /* Validate the relevant portion of the subject. There's a loop in case we+  encounter bad UTF in the characters preceding start_match which we are+  scanning because of a lookbehind. */++  for (;;)+    {+    match_data->rc = PRIV(valid_utf)(mb->check_subject,+      length - (mb->check_subject - subject), &(match_data->startchar));++    if (match_data->rc == 0) break;   /* Valid UTF string */++    /* Invalid UTF string. Adjust the offset to be an absolute offset in the+    whole string. If we are handling invalid UTF strings, set end_subject to+    stop before the bad code unit, and set the options to "not end of line".+    Otherwise return the error. */++    match_data->startchar += mb->check_subject - subject;+    if (!allow_invalid || match_data->rc > 0) return match_data->rc;+    end_subject = subject + match_data->startchar;++    /* If the end precedes start_match, it means there is invalid UTF in the+    extra code units we reversed over because of a lookbehind. Advance past the+    first bad code unit, and then skip invalid character starting code units in+    8-bit and 16-bit modes, and try again. */++    if (end_subject < start_match)+      {+      mb->check_subject = end_subject + 1;+#if PCRE2_CODE_UNIT_WIDTH != 32+      while (mb->check_subject < start_match && NOT_FIRSTCU(*mb->check_subject))+        mb->check_subject++;+#endif+      }++    /* Otherwise, set the not end of line option, and do the match. */++    else+      {+      fragment_options = PCRE2_NOTEOL;+      break;+      }+    }+  }+#endif  /* SUPPORT_UNICODE */++/* 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;+startline = (re->flags & PCRE2_STARTLINE) != 0;+bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?+  true_end_subject : subject + mcontext->offset_limit;++/* 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, except for moptions, which+gets set later. */++mb->callout = mcontext->callout;+mb->callout_data = mcontext->callout_data;++mb->start_subject = subject;+mb->start_offset = start_offset;+mb->end_subject = end_subject;+mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;+mb->allowemptypartial = (re->max_lookbehind > 0) ||+    (re->flags & PCRE2_MATCH_EMPTY) != 0;+mb->poptions = re->overall_options;          /* Pattern options */+mb->ignore_skip_arg = 0;+mb->mark = mb->nomatch_mark = NULL;          /* In case never set */++/* The name table is needed for finding all the numbers associated with a+given name, for condition testing. The code follows the name table. */++mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));+mb->name_count = re->name_count;+mb->name_entry_size = re->name_entry_size;+mb->start_code = mb->name_table + re->name_count * re->name_entry_size;++/* Process the \R and newline settings. */++mb->bsr_convention = re->bsr_convention;+mb->nltype = NLTYPE_FIXED;+switch(re->newline_convention)+  {+  case PCRE2_NEWLINE_CR:+  mb->nllen = 1;+  mb->nl[0] = CHAR_CR;+  break;++  case PCRE2_NEWLINE_LF:+  mb->nllen = 1;+  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;+  mb->nl[1] = CHAR_NL;+  break;++  case PCRE2_NEWLINE_ANY:+  mb->nltype = NLTYPE_ANY;+  break;++  case PCRE2_NEWLINE_ANYCRLF:+  mb->nltype = NLTYPE_ANYCRLF;+  break;++  default: return PCRE2_ERROR_INTERNAL;+  }++/* 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.++  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 kibibytes.) */++if (frame_size <= START_FRAMES_SIZE/10)+  {+  mb->match_frames = mb->stack_frames;   /* Initial frame vector on the stack */+  mb->frame_vector_size = ((START_FRAMES_SIZE/frame_size) * frame_size);+  }+else+  {+  mb->frame_vector_size = frame_size * 10;+  if ((mb->frame_vector_size / 1024) > mb->heap_limit)+    {+    if (frame_size > mb->heap_limit * 1024) return PCRE2_ERROR_HEAPLIMIT;+    mb->frame_vector_size = ((mb->heap_limit * 1024)/frame_size) * frame_size;+    }+  mb->match_frames = mb->memctl.malloc(mb->frame_vector_size,+    mb->memctl.memory_data);+  if (mb->match_frames == NULL) return PCRE2_ERROR_NOMEMORY;+  }++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);+#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+    if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu);+#else+    if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu);+#endif+#endif  /* SUPPORT_UNICODE */+    }+  }+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)+  {+  has_req_cu = TRUE;+  req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);+  if ((re->flags & PCRE2_LASTCASELESS) != 0)+    {+    req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);+#ifdef SUPPORT_UNICODE+#if PCRE2_CODE_UNIT_WIDTH == 8+    if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu);+#else+    if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu);+#endif+#endif  /* SUPPORT_UNICODE */+    }+  }+++/* ==========================================================================*/++/* Loop for handling unanchored repeated matching attempts; for anchored regexs+the loop runs just once. */++#ifdef SUPPORT_UNICODE+FRAGMENT_RESTART:+#endif++start_partial = match_partial = NULL;+mb->hitend = FALSE;++#if PCRE2_CODE_UNIT_WIDTH == 8+memchr_not_found_first_cu = FALSE;+memchr_not_found_first_cu2 = FALSE;+#endif++for(;;)+  {+  PCRE2_SPTR new_start_match;++  /* ----------------- Start of match optimizations ---------------- */++  /* There are some optimizations that avoid running the match if a known+  starting point is not found, or if a known later code unit is not present.+  However, there is an option (settable at compile time) that disables these,+  for testing and for ensuring that all callouts do actually occur. */++  if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)+    {+    /* If 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 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)+      {+      PCRE2_SPTR t = start_match;+#ifdef SUPPORT_UNICODE+      if (utf)+        {+        while (t < end_subject && !IS_NEWLINE(t))+          {+          t++;+          ACROSSCHAR(t < end_subject, t, t++);+          }+        }+      else+#endif+      while (t < end_subject && !IS_NEWLINE(t)) t++;+      end_subject = t;+      }++    /* 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 (anchored)+      {+      if (has_first_cu || start_bits != NULL)+        {+        BOOL ok = start_match < end_subject;+        if (ok)+          {+          PCRE2_UCHAR c = UCHAR21TEST(start_match);+          ok = has_first_cu && (c == first_cu || c == first_cu2);+          if (!ok && start_bits != NULL)+            {+#if PCRE2_CODE_UNIT_WIDTH != 8+            if (c > 255) c = 255;+#endif+            ok = (start_bits[c/8] & (1u << (c&7))) != 0;+            }+          }+        if (!ok)+          {+          rc = MATCH_NOMATCH;+          break;+          }+        }+      }++    /* 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. If a call to memchr() that+    searches the rest of the subject fails to find one case, remember that in+    order not to keep on repeating the search. This can make a huge difference+    when the strings are very long and only one case is present. */++    else+      {+      if (has_first_cu)+        {+        if (first_cu != first_cu2)  /* Caseless */+          {+#if PCRE2_CODE_UNIT_WIDTH != 8+          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 = NULL;+          PCRE2_SPTR pp2 = NULL;+          PCRE2_SIZE cu2size = end_subject - start_match;++          if (!memchr_not_found_first_cu)+            {+            pp1 = memchr(start_match, first_cu, end_subject - start_match);+            if (pp1 == NULL) memchr_not_found_first_cu = TRUE;+              else cu2size = pp1 - start_match;+            }++          /* If pp1 is not NULL, we have arranged to search only as far as pp1,+          to see if the other case is earlier, so we can set "not found" only+          when both searches have returned NULL. */++          if (!memchr_not_found_first_cu2)+            {+            pp2 = memchr(start_match, first_cu2, cu2size);+            memchr_not_found_first_cu2 = (pp2 == NULL && pp1 == NULL);+            }++          if (pp1 == NULL)+            start_match = (pp2 == NULL)? end_subject : pp2;+          else+            start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;+#endif+          }++        /* 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 first 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 == 0 && 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] & (1u << (c&7))) != 0) break;+          start_match++;+          }++        /* See comment above in first_cu checking about the next few lines. */++        if (mb->partial == 0 && start_match >= mb->end_subject)+          {+          rc = MATCH_NOMATCH;+          break;+          }+        }+      }   /* End first code unit handling */++    /* Restore fudged end_subject */++    end_subject = mb->end_subject;++    /* The following two optimizations must be disabled for partial matching. */++    if (mb->partial == 0)+      {+      PCRE2_SPTR p;++      /* 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)+        {+        rc = MATCH_NOMATCH;+        break;+        }++      /* If req_cu is set, we know that that code unit must appear in the+      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.++      The search can be skipped if the code unit was found later than the+      current starting point in a previous iteration of the bumpalong loop.++      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+      anchored patterns. This showed up when somebody was matching something+      like /^\d+C/ on a 32-megabyte string... so we don't do this when the+      string is sufficiently long, but it's worth searching a lot more for+      unanchored patterns. */++      p = start_match + (has_first_cu? 1:0);+      if (has_req_cu && p > req_cu_ptr)+        {+        PCRE2_SIZE check_length = end_subject - start_match;++        if (check_length < REQ_CU_MAX ||+              (!anchored && check_length < REQ_CU_MAX * 1000))+          {+          if (req_cu != req_cu2)  /* Caseless */+            {+#if PCRE2_CODE_UNIT_WIDTH != 8+            while (p < end_subject)+              {+              uint32_t pp = UCHAR21INCTEST(p);+              if (pp == req_cu || pp == req_cu2) { p--; break; }+              }+#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 */+            }++          /* The caseful case */++          else+            {+#if PCRE2_CODE_UNIT_WIDTH != 8+            while (p < end_subject)+              {+              if (UCHAR21INCTEST(p) == req_cu) { p--; break; }+              }++#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 bumpalong loop,+          forcing a match failure. */++          if (p >= end_subject)+            {+            rc = MATCH_NOMATCH;+            break;+            }++          /* 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 bumpalong+          loop if the start hasn't yet passed this code unit. */++          req_cu_ptr = p;+          }+        }+      }+    }++  /* ------------ End of start of match optimizations ------------ */++  /* Give no match if we have passed the bumpalong limit. */++  if (start_match > bumpalong_limit)+    {+    rc = MATCH_NOMATCH;+    break;+    }++  /* OK, we can now run the match. If "hitend" is set afterwards, remember the+  first starting point for which a partial match was found. */++  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;+#ifdef SUPPORT_UNICODE+  mb->moptions = options | fragment_options;+#else+  mb->moptions = options;+#endif+  mb->match_call_count = 0;+  mb->end_offset_top = 0;+  mb->skip_arg_count = 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)+    {+    start_partial = mb->start_used_ptr;+    match_partial = start_match;+    }++  switch(rc)+    {+    /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched+    the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP+    entirely. The only way we can do that is to re-do the match at the same+    point, with a flag to force SKIP with an argument to be ignored. Just+    treating this case as NOMATCH does not work because it does not check other+    alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */++    case MATCH_SKIP_ARG:+    new_start_match = start_match;+    mb->ignore_skip_arg = mb->skip_arg_count;+    break;++    /* SKIP passes back the next starting point explicitly, but if it is no+    greater than the match we have just done, treat it as NOMATCH. */++    case MATCH_SKIP:+    if (mb->verb_skip_ptr > start_match)+      {+      new_start_match = mb->verb_skip_ptr;+      break;+      }+    /* Fall through */++    /* NOMATCH and PRUNE advance by one character. THEN at this level acts+    exactly like PRUNE. Unset ignore SKIP-with-argument. */++    case MATCH_NOMATCH:+    case MATCH_PRUNE:+    case MATCH_THEN:+    mb->ignore_skip_arg = 0;+    new_start_match = start_match + 1;+#ifdef SUPPORT_UNICODE+    if (utf)+      ACROSSCHAR(new_start_match < end_subject, new_start_match,+        new_start_match++);+#endif+    break;++    /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */++    case MATCH_COMMIT:+    rc = MATCH_NOMATCH;+    goto ENDLOOP;++    /* Any other return is either a match, or some kind of error. */++    default:+    goto ENDLOOP;+    }++  /* Control reaches here for the various types of "no match at this point"+  result. Reset the code to MATCH_NOMATCH for subsequent checking. */++  rc = MATCH_NOMATCH;++  /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first+  newline in the subject (though it may continue over the newline). Therefore,+  if we have just failed to match, starting at a newline, do not continue. */++  if (firstline && IS_NEWLINE(start_match)) break;++  /* Advance to new matching position */++  start_match = new_start_match;++  /* Break the loop if the pattern is anchored or if we have passed the end of+  the subject. */++  if (anchored || start_match > end_subject) break;++  /* If we have just passed a CR and we are now at a LF, and the pattern does+  not contain any explicit matches for \r or \n, and the newline option is CRLF+  or ANY or ANYCRLF, advance the match position by one more code unit. In+  normal matching start_match will aways be greater than the first position at+  this stage, but a failed *SKIP can cause a return at the same point, which is+  why the first test exists. */++  if (start_match > subject + start_offset &&+      start_match[-1] == CHAR_CR &&+      start_match < end_subject &&+      *start_match == CHAR_NL &&+      (re->flags & PCRE2_HASCRORLF) == 0 &&+        (mb->nltype == NLTYPE_ANY ||+         mb->nltype == NLTYPE_ANYCRLF ||+         mb->nllen == 2))+    start_match++;++  mb->mark = NULL;   /* Reset for start of next match attempt */+  }                  /* End of for(;;) "bumpalong" loop */++/* ==========================================================================*/++/* 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 after (*COMMIT);++(3) We are past the end of the subject or the bumpalong limit;++(4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because+    this option requests that a match occur at or before the first newline in+    the subject.++(5) Some kind of error occurred.++*/++ENDLOOP:++/* If end_subject != true_end_subject, it means we are handling invalid UTF,+and have just processed a non-terminal fragment. If this resulted in no match+or a partial match we must carry on to the next fragment (a partial match is+returned to the caller only at the very end of the subject). A loop is used to+avoid trying to match against empty fragments; if the pattern can match an+empty string it would have done so already. */++#ifdef SUPPORT_UNICODE+if (utf && end_subject != true_end_subject &&+    (rc == MATCH_NOMATCH || rc == PCRE2_ERROR_PARTIAL))+  {+  for (;;)+    {+    /* Advance past the first bad code unit, and then skip invalid character+    starting code units in 8-bit and 16-bit modes. */++    start_match = end_subject + 1;+    +#if PCRE2_CODE_UNIT_WIDTH != 32+    while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))+      start_match++;+#endif++    /* If we have hit the end of the subject, there isn't another non-empty+    fragment, so give up. */++    if (start_match >= true_end_subject)+      {+      rc = MATCH_NOMATCH;  /* In case it was partial */+      break;+      }++    /* Check the rest of the subject */++    mb->check_subject = start_match;+    rc = PRIV(valid_utf)(start_match, length - (start_match - subject),+      &(match_data->startchar));++    /* The rest of the subject is valid UTF. */++    if (rc == 0)+      {+      mb->end_subject = end_subject = true_end_subject;+      fragment_options = PCRE2_NOTBOL;+      goto FRAGMENT_RESTART;+      }++    /* A subsequent UTF error has been found; if the next fragment is+    non-empty, set up to process it. Otherwise, let the loop advance. */++    else if (rc < 0)+      {+      mb->end_subject = end_subject = start_match + match_data->startchar;+      if (end_subject > start_match)+        {+        fragment_options = PCRE2_NOTBOL|PCRE2_NOTEOL;+        goto FRAGMENT_RESTART;+        }+      }+    }+  }+#endif  /* SUPPORT_UNICODE */++/* Release an enlarged frame vector that is on the heap. */++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. */++match_data->code = re;+match_data->mark = mb->mark;+match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;++/* 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. Make a copy of the subject+string if requested. */++if (rc == MATCH_MATCH)+  {+  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)?+    mb->last_used_ptr : mb->end_match_ptr) - subject;+  if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)+    {+    length = CU2BYTES(length + was_zero_terminated);+    match_data->subject = match_data->memctl.malloc(length,+      match_data->memctl.memory_data);+    if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;+    memcpy((void *)match_data->subject, subject, length);+    match_data->flags |= PCRE2_MD_COPIED_SUBJECT;+    }+  else match_data->subject = subject;+  return match_data->rc;+  }++/* Control gets here if there has been a partial match, an error, or if the+overall match attempt has failed at all permitted starting positions. Any mark+data is in the nomatch_mark field. */++match_data->mark = mb->nomatch_mark;++/* For anything other than nomatch or partial match, just return the code. */++if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) match_data->rc = rc;++/* Handle a partial match. If a "soft" partial match was requested, searching+for a complete match will have continued, and the value of rc at this point+will be MATCH_NOMATCH. For a "hard" partial match, it will already be+PCRE2_ERROR_PARTIAL. */++else if (match_partial != NULL)+  {+  match_data->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;+  match_data->rc = PCRE2_ERROR_PARTIAL;+  }++/* Else this is the classic nomatch case. */++else match_data->rc = PCRE2_ERROR_NOMATCH;++return match_data->rc;+}++/* End of pcre2_match.c */
+ src/c/pcre2/src/pcre2_match_data.c view
@@ -0,0 +1,166 @@+/*************************************************+*      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-2019 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"++++/*************************************************+*  Create a match data block given ovector size  *+*************************************************/++/* 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)+{+pcre2_match_data *yield;+if (oveccount < 1) oveccount = 1;+yield = PRIV(memctl_malloc)(+  offsetof(pcre2_match_data, ovector) + 2*oveccount*sizeof(PCRE2_SIZE),+  (pcre2_memctl *)gcontext);+if (yield == NULL) return NULL;+yield->oveccount = oveccount;+yield->flags = 0;+return yield;+}++++/*************************************************+*  Create a match data block using pattern data  *+*************************************************/++/* If no context is supplied, use the memory allocator from the code. */++PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION+pcre2_match_data_create_from_pattern(const pcre2_code *code,+  pcre2_general_context *gcontext)+{+if (gcontext == NULL) gcontext = (pcre2_general_context *)code;+return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1,+  gcontext);+}++++/*************************************************+*            Free a match data block             *+*************************************************/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_match_data_free(pcre2_match_data *match_data)+{+if (match_data != NULL)+  {+  if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)+    match_data->memctl.free((void *)match_data->subject,+      match_data->memctl.memory_data);+  match_data->memctl.free(match_data, match_data->memctl.memory_data);+  }+}++++/*************************************************+*         Get last mark in match                 *+*************************************************/++PCRE2_EXP_DEFN PCRE2_SPTR PCRE2_CALL_CONVENTION+pcre2_get_mark(pcre2_match_data *match_data)+{+return match_data->mark;+}++++/*************************************************+*          Get pointer to ovector                *+*************************************************/++PCRE2_EXP_DEFN PCRE2_SIZE * PCRE2_CALL_CONVENTION+pcre2_get_ovector_pointer(pcre2_match_data *match_data)+{+return match_data->ovector;+}++++/*************************************************+*          Get number of ovector slots           *+*************************************************/++PCRE2_EXP_DEFN uint32_t PCRE2_CALL_CONVENTION+pcre2_get_ovector_count(pcre2_match_data *match_data)+{+return match_data->oveccount;+}++++/*************************************************+*         Get starting code unit in match        *+*************************************************/++PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION+pcre2_get_startchar(pcre2_match_data *match_data)+{+return match_data->startchar;+}++++/*************************************************+*         Get size of match data block           *+*************************************************/++PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION+pcre2_get_match_data_size(pcre2_match_data *match_data)+{+return offsetof(pcre2_match_data, ovector) ++  2 * (match_data->oveccount) * sizeof(PCRE2_SIZE);+}++/* End of pcre2_match_data.c */
+ src/c/pcre2/src/pcre2_newline.c view
@@ -0,0 +1,243 @@+/*************************************************+*      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 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 internal functions for testing newlines when more than+one kind of newline is to be recognized. When a newline is found, its length is+returned. In principle, we could implement several newline "types", each+referring to a different set of newline characters. At present, PCRE2 supports+only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,+and NLTYPE_ANY. The full list of Unicode newline characters is taken from+http://unicode.org/unicode/reports/tr18/. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"++++/*************************************************+*      Check for newline at given position       *+*************************************************/++/* This function is called only via the IS_NEWLINE macro, which does so only+when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed+newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the code unit+pointed to by ptr is less than the end of the string.++Arguments:+  ptr          pointer to possible newline+  type         the newline type+  endptr       pointer to the end of the string+  lenptr       where to return the length+  utf          TRUE if in utf mode++Returns:       TRUE or FALSE+*/++BOOL+PRIV(is_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR endptr,+  uint32_t *lenptr, BOOL utf)+{+uint32_t c;++#ifdef SUPPORT_UNICODE+if (utf) { GETCHAR(c, ptr); } else c = *ptr;+#else+(void)utf;+c = *ptr;+#endif  /* SUPPORT_UNICODE */++if (type == NLTYPE_ANYCRLF) switch(c)+  {+  case CHAR_LF:+  *lenptr = 1;+  return TRUE;++  case CHAR_CR:+  *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;+  return TRUE;++  default:+  return FALSE;+  }++/* NLTYPE_ANY */++else switch(c)+  {+#ifdef EBCDIC+  case CHAR_NEL:+#endif+  case CHAR_LF:+  case CHAR_VT:+  case CHAR_FF:+  *lenptr = 1;+  return TRUE;++  case CHAR_CR:+  *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;+  return TRUE;++#ifndef EBCDIC+#if PCRE2_CODE_UNIT_WIDTH == 8+  case CHAR_NEL:+  *lenptr = utf? 2 : 1;+  return TRUE;++  case 0x2028:   /* LS */+  case 0x2029:   /* PS */+  *lenptr = 3;+  return TRUE;++#else  /* 16-bit or 32-bit code units */+  case CHAR_NEL:+  case 0x2028:   /* LS */+  case 0x2029:   /* PS */+  *lenptr = 1;+  return TRUE;+#endif+#endif /* Not EBCDIC */++  default:+  return FALSE;+  }+}++++/*************************************************+*     Check for newline at previous position     *+*************************************************/++/* This function is called only via the WAS_NEWLINE macro, which does so only+when the newline type is NLTYPE_ANY or NLTYPE_ANYCRLF. The case of a fixed+newline (NLTYPE_FIXED) is handled inline. It is guaranteed that the initial+value of ptr is greater than the start of the string that is being processed.++Arguments:+  ptr          pointer to possible newline+  type         the newline type+  startptr     pointer to the start of the string+  lenptr       where to return the length+  utf          TRUE if in utf mode++Returns:       TRUE or FALSE+*/++BOOL+PRIV(was_newline)(PCRE2_SPTR ptr, uint32_t type, PCRE2_SPTR startptr,+  uint32_t *lenptr, BOOL utf)+{+uint32_t c;+ptr--;++#ifdef SUPPORT_UNICODE+if (utf)+  {+  BACKCHAR(ptr);+  GETCHAR(c, ptr);+  }+else c = *ptr;+#else+(void)utf;+c = *ptr;+#endif  /* SUPPORT_UNICODE */++if (type == NLTYPE_ANYCRLF) switch(c)+  {+  case CHAR_LF:+  *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;+  return TRUE;++  case CHAR_CR:+  *lenptr = 1;+  return TRUE;++  default:+  return FALSE;+  }++/* NLTYPE_ANY */++else switch(c)+  {+  case CHAR_LF:+  *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;+  return TRUE;++#ifdef EBCDIC+  case CHAR_NEL:+#endif+  case CHAR_VT:+  case CHAR_FF:+  case CHAR_CR:+  *lenptr = 1;+  return TRUE;++#ifndef EBCDIC+#if PCRE2_CODE_UNIT_WIDTH == 8+  case CHAR_NEL:+  *lenptr = utf? 2 : 1;+  return TRUE;++  case 0x2028:   /* LS */+  case 0x2029:   /* PS */+  *lenptr = 3;+  return TRUE;++#else /* 16-bit or 32-bit code units */+  case CHAR_NEL:+  case 0x2028:   /* LS */+  case 0x2029:   /* PS */+  *lenptr = 1;+  return TRUE;+#endif+#endif /* Not EBCDIC */++  default:+  return FALSE;+  }+}++/* End of pcre2_newline.c */
+ src/c/pcre2/src/pcre2_ord2utf.c view
@@ -0,0 +1,120 @@+/*************************************************+*      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 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 file contains a function that converts a Unicode character code point+into a UTF string. The behaviour is different for each code unit width. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"+++/* If SUPPORT_UNICODE is not defined, this function will never be called.+Supply a dummy function because some compilers do not like empty source+modules. */++#ifndef SUPPORT_UNICODE+unsigned int+PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)+{+(void)(cvalue);+(void)(buffer);+return 0;+}+#else  /* SUPPORT_UNICODE */+++/*************************************************+*          Convert code point to UTF             *+*************************************************/++/*+Arguments:+  cvalue     the character value+  buffer     pointer to buffer for result++Returns:     number of code units placed in the buffer+*/++unsigned int+PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)+{+/* Convert to UTF-8 */++#if PCRE2_CODE_UNIT_WIDTH == 8+int i, j;+for (i = 0; i < PRIV(utf8_table1_size); i++)+  if ((int)cvalue <= PRIV(utf8_table1)[i]) break;+buffer += i;+for (j = i; j > 0; j--)+ {+ *buffer-- = 0x80 | (cvalue & 0x3f);+ cvalue >>= 6;+ }+*buffer = PRIV(utf8_table2)[i] | cvalue;+return i + 1;++/* Convert to UTF-16 */++#elif PCRE2_CODE_UNIT_WIDTH == 16+if (cvalue <= 0xffff)+  {+  *buffer = (PCRE2_UCHAR)cvalue;+  return 1;+  }+cvalue -= 0x10000;+*buffer++ = 0xd800 | (cvalue >> 10);+*buffer = 0xdc00 | (cvalue & 0x3ff);+return 2;++/* Convert to UTF-32 */++#else+*buffer = (PCRE2_UCHAR)cvalue;+return 1;+#endif+}+#endif  /* SUPPORT_UNICODE */++/* End of pcre_ord2utf.c */
+ src/c/pcre2/src/pcre2_pattern_info.c view
@@ -0,0 +1,432 @@+/*************************************************+*      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.+-----------------------------------------------------------------------------+*/+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"+++/*************************************************+*        Return info about compiled pattern      *+*************************************************/++/*+Arguments:+  code          points to compiled code+  what          what information is required+  where         where to put the information; if NULL, return length++Returns:        0 when data returned+                > 0 when length requested+                < 0 on error or unset value+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where)+{+const pcre2_real_code *re = (pcre2_real_code *)code;++if (where == NULL)   /* Requests field length */+  {+  switch(what)+    {+    case PCRE2_INFO_ALLOPTIONS:+    case PCRE2_INFO_ARGOPTIONS:+    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:+    case PCRE2_INFO_MATCHEMPTY:+    case PCRE2_INFO_MATCHLIMIT:+    case PCRE2_INFO_MAXLOOKBEHIND:+    case PCRE2_INFO_MINLENGTH:+    case PCRE2_INFO_NAMEENTRYSIZE:+    case PCRE2_INFO_NAMECOUNT:+    case PCRE2_INFO_NEWLINE:+    return sizeof(uint32_t);++    case PCRE2_INFO_FIRSTBITMAP:+    return sizeof(const uint8_t *);++    case PCRE2_INFO_JITSIZE:+    case PCRE2_INFO_SIZE:+    case PCRE2_INFO_FRAMESIZE:+    return sizeof(size_t);++    case PCRE2_INFO_NAMETABLE:+    return sizeof(PCRE2_SPTR);+    }+  }++if (re == NULL) return PCRE2_ERROR_NULL;++/* Check that the first field in the block is the magic number. If it is not,+return with PCRE2_ERROR_BADMAGIC. */++if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;++/* Check that this pattern was compiled in the correct bit mode */++if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;++switch(what)+  {+  case PCRE2_INFO_ALLOPTIONS:+  *((uint32_t *)where) = re->overall_options;+  break;++  case PCRE2_INFO_ARGOPTIONS:+  *((uint32_t *)where) = re->compile_options;+  break;++  case PCRE2_INFO_BACKREFMAX:+  *((uint32_t *)where) = re->top_backref;+  break;++  case PCRE2_INFO_BSR:+  *((uint32_t *)where) = re->bsr_convention;+  break;++  case PCRE2_INFO_CAPTURECOUNT:+  *((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;+  break;++  case PCRE2_INFO_FIRSTCODEUNIT:+  *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)?+    re->first_codeunit : 0;+  break;++  case PCRE2_INFO_FIRSTBITMAP:+  *((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)?+    &(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;++  case PCRE2_INFO_HASCRORLF:+  *((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;++  case PCRE2_INFO_JITSIZE:+#ifdef SUPPORT_JIT+  *((size_t *)where) = (re->executable_jit != NULL)?+    PRIV(jit_get_size)(re->executable_jit) : 0;+#else+  *((size_t *)where) = 0;+#endif+  break;++  case PCRE2_INFO_LASTCODETYPE:+  *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0;+  break;++  case PCRE2_INFO_LASTCODEUNIT:+  *((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)?+    re->last_codeunit : 0;+  break;++  case PCRE2_INFO_MATCHEMPTY:+  *((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0;+  break;++  case PCRE2_INFO_MATCHLIMIT:+  *((uint32_t *)where) = re->limit_match;+  if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET;+  break;++  case PCRE2_INFO_MAXLOOKBEHIND:+  *((uint32_t *)where) = re->max_lookbehind;+  break;++  case PCRE2_INFO_MINLENGTH:+  *((uint32_t *)where) = re->minlength;+  break;++  case PCRE2_INFO_NAMEENTRYSIZE:+  *((uint32_t *)where) = re->name_entry_size;+  break;++  case PCRE2_INFO_NAMECOUNT:+  *((uint32_t *)where) = re->name_count;+  break;++  case PCRE2_INFO_NAMETABLE:+  *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code));+  break;++  case PCRE2_INFO_NEWLINE:+  *((uint32_t *)where) = re->newline_convention;+  break;++  case PCRE2_INFO_SIZE:+  *((size_t *)where) = re->blocksize;+  break;++  default: return PCRE2_ERROR_BADOPTION;+  }++return 0;+}++++/*************************************************+*              Callout enumerator                *+*************************************************/++/*+Arguments:+  code          points to compiled code+  callback      function called for each callout block+  callout_data  user data passed to the callback++Returns:        0 when successfully completed+                < 0 on local error+               != 0 for callback error+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_callout_enumerate(const pcre2_code *code,+  int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data)+{+pcre2_real_code *re = (pcre2_real_code *)code;+pcre2_callout_enumerate_block cb;+PCRE2_SPTR cc;+#ifdef SUPPORT_UNICODE+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. */++if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;++/* Check that this pattern was compiled in the correct bit mode */++if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;++cb.version = 0;+cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code))+     + re->name_count * re->name_entry_size;++while (TRUE)+  {+  int rc;+  switch (*cc)+    {+    case OP_END:+    return 0;++    case OP_CHAR:+    case OP_CHARI:+    case OP_NOT:+    case OP_NOTI:+    case OP_STAR:+    case OP_MINSTAR:+    case OP_PLUS:+    case OP_MINPLUS:+    case OP_QUERY:+    case OP_MINQUERY:+    case OP_UPTO:+    case OP_MINUPTO:+    case OP_EXACT:+    case OP_POSSTAR:+    case OP_POSPLUS:+    case OP_POSQUERY:+    case OP_POSUPTO:+    case OP_STARI:+    case OP_MINSTARI:+    case OP_PLUSI:+    case OP_MINPLUSI:+    case OP_QUERYI:+    case OP_MINQUERYI:+    case OP_UPTOI:+    case OP_MINUPTOI:+    case OP_EXACTI:+    case OP_POSSTARI:+    case OP_POSPLUSI:+    case OP_POSQUERYI:+    case OP_POSUPTOI:+    case OP_NOTSTAR:+    case OP_NOTMINSTAR:+    case OP_NOTPLUS:+    case OP_NOTMINPLUS:+    case OP_NOTQUERY:+    case OP_NOTMINQUERY:+    case OP_NOTUPTO:+    case OP_NOTMINUPTO:+    case OP_NOTEXACT:+    case OP_NOTPOSSTAR:+    case OP_NOTPOSPLUS:+    case OP_NOTPOSQUERY:+    case OP_NOTPOSUPTO:+    case OP_NOTSTARI:+    case OP_NOTMINSTARI:+    case OP_NOTPLUSI:+    case OP_NOTMINPLUSI:+    case OP_NOTQUERYI:+    case OP_NOTMINQUERYI:+    case OP_NOTUPTOI:+    case OP_NOTMINUPTOI:+    case OP_NOTEXACTI:+    case OP_NOTPOSSTARI:+    case OP_NOTPOSPLUSI:+    case OP_NOTPOSQUERYI:+    case OP_NOTPOSUPTOI:+    cc += PRIV(OP_lengths)[*cc];+#ifdef SUPPORT_UNICODE+    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+    break;++    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    case OP_TYPEEXACT:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPOSPLUS:+    case OP_TYPEPOSQUERY:+    case OP_TYPEPOSUPTO:+    cc += PRIV(OP_lengths)[*cc];+#ifdef SUPPORT_UNICODE+    if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2;+#endif+    break;++#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8+    case OP_XCLASS:+    cc += GET(cc, 1);+    break;+#endif++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_SKIP_ARG:+    case OP_THEN_ARG:+    cc += PRIV(OP_lengths)[*cc] + cc[1];+    break;++    case OP_CALLOUT:+    cb.pattern_position = GET(cc, 1);+    cb.next_item_length = GET(cc, 1 + LINK_SIZE);+    cb.callout_number = cc[1 + 2*LINK_SIZE];+    cb.callout_string_offset = 0;+    cb.callout_string_length = 0;+    cb.callout_string = NULL;+    rc = callback(&cb, callout_data);+    if (rc != 0) return rc;+    cc += PRIV(OP_lengths)[*cc];+    break;++    case OP_CALLOUT_STR:+    cb.pattern_position = GET(cc, 1);+    cb.next_item_length = GET(cc, 1 + LINK_SIZE);+    cb.callout_number = 0;+    cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE);+    cb.callout_string_length =+      GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2;+    cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1;+    rc = callback(&cb, callout_data);+    if (rc != 0) return rc;+    cc += GET(cc, 1 + 2*LINK_SIZE);+    break;++    default:+    cc += PRIV(OP_lengths)[*cc];+    break;+    }+  }+}++/* End of pcre2_pattern_info.c */
+ src/c/pcre2/src/pcre2_printint.c view
@@ -0,0 +1,836 @@+/*************************************************+*      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-2019 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 a PCRE private debugging function for printing out the+internal form of a compiled regular expression, along with some supporting+local functions. This source file is #included in pcre2test.c at each supported+code unit width, with PCRE2_SUFFIX set appropriately, just like the functions+that comprise the library. It can also optionally be included in+pcre2_compile.c for detailed debugging in error situations. */+++/* Tables of operator names. The same 8-bit table is used for all code unit+widths, so it must be defined only once. The list itself is defined in+pcre2_internal.h, which is #included by pcre2test before this file. */++#ifndef OP_LISTS_DEFINED+static const char *OP_names[] = { OP_NAME_LIST };+#define OP_LISTS_DEFINED+#endif++/* The functions and tables herein must all have mode-dependent names. */++#define OP_lengths            PCRE2_SUFFIX(OP_lengths_)+#define get_ucpname           PCRE2_SUFFIX(get_ucpname_)+#define pcre2_printint        PCRE2_SUFFIX(pcre2_printint_)+#define print_char            PCRE2_SUFFIX(print_char_)+#define print_custring        PCRE2_SUFFIX(print_custring_)+#define print_custring_bylen  PCRE2_SUFFIX(print_custring_bylen_)+#define print_prop            PCRE2_SUFFIX(print_prop_)++/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that+the definition is next to the definition of the opcodes in pcre2_internal.h.+The contents of the table are, however, mode-dependent. */++static const uint8_t OP_lengths[] = { OP_LENGTHS };++++/*************************************************+*       Print one character from a string        *+*************************************************/++/* In UTF mode the character may occupy more than one code unit.++Arguments:+  f           file to write to+  ptr         pointer to first code unit of the character+  utf         TRUE if string is UTF (will be FALSE if UTF is not supported)++Returns:      number of additional code units used+*/++static unsigned int+print_char(FILE *f, PCRE2_SPTR ptr, BOOL utf)+{+uint32_t c = *ptr;+BOOL one_code_unit = !utf;++/* If UTF is supported and requested, check for a valid single code unit. */++#ifdef SUPPORT_UNICODE+if (utf)+  {+#if PCRE2_CODE_UNIT_WIDTH == 8+  one_code_unit = c < 0x80;+#elif PCRE2_CODE_UNIT_WIDTH == 16+  one_code_unit = (c & 0xfc00) != 0xd800;+#else+  one_code_unit = (c & 0xfffff800u) != 0xd800u;+#endif  /* CODE_UNIT_WIDTH */+  }+#endif  /* SUPPORT_UNICODE */++/* Handle a valid one-code-unit character at any width. */++if (one_code_unit)+  {+  if (PRINTABLE(c)) fprintf(f, "%c", (char)c);+  else if (c < 0x80) fprintf(f, "\\x%02x", c);+  else fprintf(f, "\\x{%02x}", c);+  return 0;+  }++/* Code for invalid UTF code units and multi-unit UTF characters is different+for each width. If UTF is not supported, control should never get here, but we+need a return statement to keep the compiler happy. */++#ifndef SUPPORT_UNICODE+return 0;+#else++/* Malformed UTF-8 should occur only if the sanity check has been turned off.+Rather than swallow random bytes, just stop if we hit a bad one. Print it with+\X instead of \x as an indication. */++#if PCRE2_CODE_UNIT_WIDTH == 8+if ((c & 0xc0) != 0xc0)+  {+  fprintf(f, "\\X{%x}", c);       /* Invalid starting byte */+  return 0;+  }+else+  {+  int i;+  int a = PRIV(utf8_table4)[c & 0x3f];  /* Number of additional bytes */+  int s = 6*a;+  c = (c & PRIV(utf8_table3)[a]) << s;+  for (i = 1; i <= a; i++)+    {+    if ((ptr[i] & 0xc0) != 0x80)+      {+      fprintf(f, "\\X{%x}", c);   /* Invalid secondary byte */+      return i - 1;+      }+    s -= 6;+    c |= (ptr[i] & 0x3f) << s;+    }+  fprintf(f, "\\x{%x}", c);+  return a;+}+#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */++/* UTF-16: rather than swallow a low surrogate, just stop if we hit a bad one.+Print it with \X instead of \x as an indication. */++#if PCRE2_CODE_UNIT_WIDTH == 16+if ((ptr[1] & 0xfc00) != 0xdc00)+  {+  fprintf(f, "\\X{%x}", c);+  return 0;+  }+c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;+fprintf(f, "\\x{%x}", c);+return 1;+#endif  /* PCRE2_CODE_UNIT_WIDTH == 16 */++/* For UTF-32 we get here only for a malformed code unit, which should only+occur if the sanity check has been turned off. Print it with \X instead of \x+as an indication. */++#if PCRE2_CODE_UNIT_WIDTH == 32+fprintf(f, "\\X{%x}", c);+return 0;+#endif  /* PCRE2_CODE_UNIT_WIDTH == 32 */+#endif  /* SUPPORT_UNICODE */+}++++/*************************************************+*     Print string as a list of code units       *+*************************************************/++/* These take no account of UTF as they always print each individual code unit.+The string is zero-terminated for print_custring(); the length is given for+print_custring_bylen().++Arguments:+  f          file to write to+  ptr        point to the string+  len        length for print_custring_bylen()++Returns:     nothing+*/++static void+print_custring(FILE *f, PCRE2_SPTR ptr)+{+while (*ptr != '\0')+  {+  uint32_t c = *ptr++;+  if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);+  }+}++static void+print_custring_bylen(FILE *f, PCRE2_SPTR ptr, PCRE2_UCHAR len)+{+for (; len > 0; len--)+  {+  uint32_t c = *ptr++;+  if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);+  }+}++++/*************************************************+*          Find Unicode property name            *+*************************************************/++/* When there is no UTF/UCP support, the table of names does not exist. This+function should not be called in such configurations, because a pattern that+tries to use Unicode properties won't compile. Rather than put lots of #ifdefs+into the main code, however, we just put one into this function. */++static const char *+get_ucpname(unsigned int ptype, unsigned int pvalue)+{+#ifdef SUPPORT_UNICODE+int i;+for (i = PRIV(utt_size) - 1; i >= 0; i--)+  {+  if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break;+  }+return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??";+#else   /* No UTF support */+(void)ptype;+(void)pvalue;+return "??";+#endif  /* SUPPORT_UNICODE */+}++++/*************************************************+*       Print Unicode property value             *+*************************************************/++/* "Normal" properties can be printed from tables. The PT_CLIST property is a+pseudo-property that contains a pointer to a list of case-equivalent+characters.++Arguments:+  f            file to write to+  code         pointer in the compiled code+  before       text to print before+  after        text to print after++Returns:       nothing+*/++static void+print_prop(FILE *f, PCRE2_SPTR code, const char *before, const char *after)+{+if (code[1] != PT_CLIST)+  {+  fprintf(f, "%s%s %s%s", before, OP_names[*code], get_ucpname(code[1],+    code[2]), after);+  }+else+  {+  const char *not = (*code == OP_PROP)? "" : "not ";+  const uint32_t *p = PRIV(ucd_caseless_sets) + code[2];+  fprintf (f, "%s%sclist", before, not);+  while (*p < NOTACHAR) fprintf(f, " %04x", *p++);+  fprintf(f, "%s", after);+  }+}++++/*************************************************+*            Print compiled pattern              *+*************************************************/++/* The print_lengths flag controls whether offsets and lengths of items are+printed. Lenths can be turned off from pcre2test so that automatic tests on+bytecode can be written that do not depend on the value of LINK_SIZE.++Arguments:+  re              a compiled pattern+  f               the file to write to+  print_lengths   show various lengths++Returns:          nothing+*/++static void+pcre2_printint(pcre2_code *re, FILE *f, BOOL print_lengths)+{+PCRE2_SPTR codestart, nametable, code;+uint32_t nesize = re->name_entry_size;+BOOL utf = (re->overall_options & PCRE2_UTF) != 0;++nametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));+code = codestart = nametable + re->name_count * re->name_entry_size;++for(;;)+  {+  PCRE2_SPTR ccode;+  uint32_t c;+  int i;+  const char *flag = "  ";+  unsigned int extra = 0;++  if (print_lengths)+    fprintf(f, "%3d ", (int)(code - codestart));+  else+    fprintf(f, "    ");++  switch(*code)+    {+/* ========================================================================== */+      /* These cases are never obeyed. This is a fudge that causes a compile-+      time error if the vectors OP_names or OP_lengths, which are indexed+      by opcode, are not the correct length. It seems to be the only way to do+      such a check at compile time, as the sizeof() operator does not work in+      the C preprocessor. */++      case OP_TABLE_LENGTH:+      case OP_TABLE_LENGTH ++        ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&+        (sizeof(OP_lengths) == OP_TABLE_LENGTH)):+      return;+/* ========================================================================== */++    case OP_END:+    fprintf(f, "    %s\n", OP_names[*code]);+    fprintf(f, "------------------------------------------------------------------\n");+    return;++    case OP_CHAR:+    fprintf(f, "    ");+    do+      {+      code++;+      code += 1 + print_char(f, code, utf);+      }+    while (*code == OP_CHAR);+    fprintf(f, "\n");+    continue;++    case OP_CHARI:+    fprintf(f, " /i ");+    do+      {+      code++;+      code += 1 + print_char(f, code, utf);+      }+    while (*code == OP_CHARI);+    fprintf(f, "\n");+    continue;++    case OP_CBRA:+    case OP_CBRAPOS:+    case OP_SCBRA:+    case OP_SCBRAPOS:+    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));+      else fprintf(f, "    ");+    fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));+    break;++    case OP_BRA:+    case OP_BRAPOS:+    case OP_SBRA:+    case OP_SBRAPOS:+    case OP_KETRMAX:+    case OP_KETRMIN:+    case OP_KETRPOS:+    case OP_ALT:+    case OP_KET:+    case OP_ASSERT:+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    case OP_ONCE:+    case OP_SCRIPT_RUN:+    case OP_COND:+    case OP_SCOND:+    case OP_REVERSE:+    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));+      else fprintf(f, "    ");+    fprintf(f, "%s", OP_names[*code]);+    break;++    case OP_CLOSE:+    fprintf(f, "    %s %d", OP_names[*code], GET2(code, 1));+    break;++    case OP_CREF:+    fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);+    break;++    case OP_DNCREF:+      {+      PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;+      fprintf(f, " %s Cond ref <", flag);+      print_custring(f, entry);+      fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));+      }+    break;++    case OP_RREF:+    c = GET2(code, 1);+    if (c == RREF_ANY)+      fprintf(f, "    Cond recurse any");+    else+      fprintf(f, "    Cond recurse %d", c);+    break;++    case OP_DNRREF:+      {+      PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;+      fprintf(f, " %s Cond recurse <", flag);+      print_custring(f, entry);+      fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));+      }+    break;++    case OP_FALSE:+    fprintf(f, "    Cond false");+    break;++    case OP_TRUE:+    fprintf(f, "    Cond true");+    break;++    case OP_STARI:+    case OP_MINSTARI:+    case OP_POSSTARI:+    case OP_PLUSI:+    case OP_MINPLUSI:+    case OP_POSPLUSI:+    case OP_QUERYI:+    case OP_MINQUERYI:+    case OP_POSQUERYI:+    flag = "/i";+    /* Fall through */+    case OP_STAR:+    case OP_MINSTAR:+    case OP_POSSTAR:+    case OP_PLUS:+    case OP_MINPLUS:+    case OP_POSPLUS:+    case OP_QUERY:+    case OP_MINQUERY:+    case OP_POSQUERY:+    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEPOSPLUS:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    case OP_TYPEPOSQUERY:+    fprintf(f, " %s ", flag);++    if (*code >= OP_TYPESTAR)+      {+      if (code[1] == OP_PROP || code[1] == OP_NOTPROP)+        {+        print_prop(f, code + 1, "", " ");+        extra = 2;+        }+      else fprintf(f, "%s", OP_names[code[1]]);+      }+    else extra = print_char(f, code+1, utf);+    fprintf(f, "%s", OP_names[*code]);+    break;++    case OP_EXACTI:+    case OP_UPTOI:+    case OP_MINUPTOI:+    case OP_POSUPTOI:+    flag = "/i";+    /* Fall through */+    case OP_EXACT:+    case OP_UPTO:+    case OP_MINUPTO:+    case OP_POSUPTO:+    fprintf(f, " %s ", flag);+    extra = print_char(f, code + 1 + IMM2_SIZE, utf);+    fprintf(f, "{");+    if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");+    fprintf(f, "%d}", GET2(code,1));+    if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");+      else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");+    break;++    case OP_TYPEEXACT:+    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    case OP_TYPEPOSUPTO:+    if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)+      {+      print_prop(f, code + IMM2_SIZE + 1, "    ", " ");+      extra = 2;+      }+    else fprintf(f, "    %s", OP_names[code[1 + IMM2_SIZE]]);+    fprintf(f, "{");+    if (*code != OP_TYPEEXACT) fprintf(f, "0,");+    fprintf(f, "%d}", GET2(code,1));+    if (*code == OP_TYPEMINUPTO) fprintf(f, "?");+      else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");+    break;++    case OP_NOTI:+    flag = "/i";+    /* Fall through */+    case OP_NOT:+    fprintf(f, " %s [^", flag);+    extra = print_char(f, code + 1, utf);+    fprintf(f, "]");+    break;++    case OP_NOTSTARI:+    case OP_NOTMINSTARI:+    case OP_NOTPOSSTARI:+    case OP_NOTPLUSI:+    case OP_NOTMINPLUSI:+    case OP_NOTPOSPLUSI:+    case OP_NOTQUERYI:+    case OP_NOTMINQUERYI:+    case OP_NOTPOSQUERYI:+    flag = "/i";+    /* Fall through */++    case OP_NOTSTAR:+    case OP_NOTMINSTAR:+    case OP_NOTPOSSTAR:+    case OP_NOTPLUS:+    case OP_NOTMINPLUS:+    case OP_NOTPOSPLUS:+    case OP_NOTQUERY:+    case OP_NOTMINQUERY:+    case OP_NOTPOSQUERY:+    fprintf(f, " %s [^", flag);+    extra = print_char(f, code + 1, utf);+    fprintf(f, "]%s", OP_names[*code]);+    break;++    case OP_NOTEXACTI:+    case OP_NOTUPTOI:+    case OP_NOTMINUPTOI:+    case OP_NOTPOSUPTOI:+    flag = "/i";+    /* Fall through */++    case OP_NOTEXACT:+    case OP_NOTUPTO:+    case OP_NOTMINUPTO:+    case OP_NOTPOSUPTO:+    fprintf(f, " %s [^", flag);+    extra = print_char(f, code + 1 + IMM2_SIZE, utf);+    fprintf(f, "]{");+    if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");+    fprintf(f, "%d}", GET2(code,1));+    if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");+      else+    if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");+    break;++    case OP_RECURSE:+    if (print_lengths) fprintf(f, "%3d ", GET(code, 1));+      else fprintf(f, "    ");+    fprintf(f, "%s", OP_names[*code]);+    break;++    case OP_REFI:+    flag = "/i";+    /* Fall through */+    case OP_REF:+    fprintf(f, " %s \\%d", flag, GET2(code,1));+    ccode = code + OP_lengths[*code];+    goto CLASS_REF_REPEAT;++    case OP_DNREFI:+    flag = "/i";+    /* Fall through */+    case OP_DNREF:+      {+      PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE;+      fprintf(f, " %s \\k<", flag);+      print_custring(f, entry);+      fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));+      }+    ccode = code + OP_lengths[*code];+    goto CLASS_REF_REPEAT;++    case OP_CALLOUT:+    fprintf(f, "    %s %d %d %d", OP_names[*code], code[1 + 2*LINK_SIZE],+      GET(code, 1), GET(code, 1 + LINK_SIZE));+    break;++    case OP_CALLOUT_STR:+    c = code[1 + 4*LINK_SIZE];+    fprintf(f, "    %s %c", OP_names[*code], c);+    extra = GET(code, 1 + 2*LINK_SIZE);+    print_custring_bylen(f, code + 2 + 4*LINK_SIZE, extra - 3 - 4*LINK_SIZE);+    for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)+      if (c == PRIV(callout_start_delims)[i])+        {+        c = PRIV(callout_end_delims)[i];+        break;+        }+    fprintf(f, "%c %d %d %d", c, GET(code, 1 + 3*LINK_SIZE), GET(code, 1),+      GET(code, 1 + LINK_SIZE));+    break;++    case OP_PROP:+    case OP_NOTPROP:+    print_prop(f, code, "    ", "");+    break;++    /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm+    in having this code always here, and it makes it less messy without all+    those #ifdefs. */++    case OP_CLASS:+    case OP_NCLASS:+    case OP_XCLASS:+      {+      unsigned int min, max;+      BOOL printmap;+      BOOL invertmap = FALSE;+      uint8_t *map;+      uint8_t inverted_map[32];++      fprintf(f, "    [");++      if (*code == OP_XCLASS)+        {+        extra = GET(code, 1);+        ccode = code + LINK_SIZE + 1;+        printmap = (*ccode & XCL_MAP) != 0;+        if ((*ccode & XCL_NOT) != 0)+          {+          invertmap = (*ccode & XCL_HASPROP) == 0;+          fprintf(f, "^");+          }+        ccode++;+        }+      else+        {+        printmap = TRUE;+        ccode = code + 1;+        }++      /* Print a bit map */++      if (printmap)+        {+        map = (uint8_t *)ccode;+        if (invertmap)+          {+          /* Using 255 ^ instead of ~ avoids clang sanitize warning. */+          for (i = 0; i < 32; i++) inverted_map[i] = 255 ^ map[i];+          map = inverted_map;+          }++        for (i = 0; i < 256; i++)+          {+          if ((map[i/8] & (1u << (i&7))) != 0)+            {+            int j;+            for (j = i+1; j < 256; j++)+              if ((map[j/8] & (1u << (j&7))) == 0) break;+            if (i == '-' || i == ']') fprintf(f, "\\");+            if (PRINTABLE(i)) fprintf(f, "%c", i);+              else fprintf(f, "\\x%02x", i);+            if (--j > i)+              {+              if (j != i + 1) fprintf(f, "-");+              if (j == '-' || j == ']') fprintf(f, "\\");+              if (PRINTABLE(j)) fprintf(f, "%c", j);+                else fprintf(f, "\\x%02x", j);+              }+            i = j;+            }+          }+        ccode += 32 / sizeof(PCRE2_UCHAR);+        }++      /* For an XCLASS there is always some additional data */++      if (*code == OP_XCLASS)+        {+        PCRE2_UCHAR ch;+        while ((ch = *ccode++) != XCL_END)+          {+          BOOL not = FALSE;+          const char *notch = "";++          switch(ch)+            {+            case XCL_NOTPROP:+            not = TRUE;+            notch = "^";+            /* Fall through */++            case XCL_PROP:+              {+              unsigned int ptype = *ccode++;+              unsigned int pvalue = *ccode++;++              switch(ptype)+                {+                case PT_PXGRAPH:+                fprintf(f, "[:%sgraph:]", notch);+                break;++                case PT_PXPRINT:+                fprintf(f, "[:%sprint:]", notch);+                break;++                case PT_PXPUNCT:+                fprintf(f, "[:%spunct:]", notch);+                break;++                default:+                fprintf(f, "\\%c{%s}", (not? 'P':'p'),+                  get_ucpname(ptype, pvalue));+                break;+                }+              }+            break;++            default:+            ccode += 1 + print_char(f, ccode, utf);+            if (ch == XCL_RANGE)+              {+              fprintf(f, "-");+              ccode += 1 + print_char(f, ccode, utf);+              }+            break;+            }+          }+        }++      /* Indicate a non-UTF class which was created by negation */++      fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");++      /* Handle repeats after a class or a back reference */++      CLASS_REF_REPEAT:+      switch(*ccode)+        {+        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:+        fprintf(f, "%s", OP_names[*ccode]);+        extra += OP_lengths[*ccode];+        break;++        case OP_CRRANGE:+        case OP_CRMINRANGE:+        case OP_CRPOSRANGE:+        min = GET2(ccode,1);+        max = GET2(ccode,1 + IMM2_SIZE);+        if (max == 0) fprintf(f, "{%u,}", min);+        else fprintf(f, "{%u,%u}", min, max);+        if (*ccode == OP_CRMINRANGE) fprintf(f, "?");+        else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+");+        extra += OP_lengths[*ccode];+        break;++        /* Do nothing if it's not a repeat; this code stops picky compilers+        warning about the lack of a default code path. */++        default:+        break;+        }+      }+    break;++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_SKIP_ARG:+    case OP_THEN_ARG:+    fprintf(f, "    %s ", OP_names[*code]);+    print_custring_bylen(f, code + 2, code[1]);+    extra += code[1];+    break;++    case OP_THEN:+    fprintf(f, "    %s", OP_names[*code]);+    break;++    case OP_CIRCM:+    case OP_DOLLM:+    flag = "/m";+    /* Fall through */++    /* Anything else is just an item with no data, but possibly a flag. */++    default:+    fprintf(f, " %s %s", flag, OP_names[*code]);+    break;+    }++  code += OP_lengths[*code] + extra;+  fprintf(f, "\n");+  }+}++/* End of pcre2_printint.c */
+ src/c/pcre2/src/pcre2_script_run.c view
@@ -0,0 +1,441 @@+/*************************************************+*      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 the function for checking a script run. */++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"+++/*************************************************+*                Check script run                *+*************************************************/++/* A script run is conceptually a sequence of characters all in the same+Unicode script. However, it isn't quite that simple. There are special rules+for scripts that are commonly used together, and also special rules for digits.+This function implements the appropriate checks, which is possible only when+PCRE2 is compiled with Unicode support. The function returns TRUE if there is+no Unicode support; however, it should never be called in that circumstance+because an error is given by pcre2_compile() if a script run is called for in a+version of PCRE2 compiled without Unicode support.++Arguments:+  pgr       point to the first character+  endptr    point after the last character+  utf       TRUE if in UTF mode++Returns:    TRUE if this is a valid script run+*/++/* These dummy values must be less than the negation of the largest offset in+the PRIV(ucd_script_sets) vector, which is held in a 16-bit field in UCD+records (and is only likely to be a few hundred). */++#define SCRIPT_UNSET        (-99999)+#define SCRIPT_HANPENDING   (-99998)+#define SCRIPT_HANHIRAKATA  (-99997)+#define SCRIPT_HANBOPOMOFO  (-99996)+#define SCRIPT_HANHANGUL    (-99995)+#define SCRIPT_LIST         (-99994)++#define INTERSECTION_LIST_SIZE 50++BOOL+PRIV(script_run)(PCRE2_SPTR ptr, PCRE2_SPTR endptr, BOOL utf)+{+#ifdef SUPPORT_UNICODE+int require_script = SCRIPT_UNSET;+uint8_t intersection_list[INTERSECTION_LIST_SIZE];+const uint8_t *require_list = NULL;+uint32_t require_digitset = 0;+uint32_t c;++#if PCRE2_CODE_UNIT_WIDTH == 32+(void)utf;    /* Avoid compiler warning */+#endif++/* Any string containing fewer than 2 characters is a valid script run. */++if (ptr >= endptr) return TRUE;+GETCHARINCTEST(c, ptr);+if (ptr >= endptr) return TRUE;++/* Scan strings of two or more characters, checking the Unicode characteristics+of each code point. We make use of the Script Extensions property. There is+special code for scripts that can be combined with characters from the Han+Chinese script. This may be used in conjunction with four other scripts in+these combinations:++. Han with Hiragana and Katakana is allowed (for Japanese).+. Han with Bopomofo is allowed (for Taiwanese Mandarin).+. Han with Hangul is allowed (for Korean).++If the first significant character's script is one of the four, the required+script type is immediately known. However, if the first significant+character's script is Han, we have to keep checking for a non-Han character.+Hence the SCRIPT_HANPENDING state. */++for (;;)+  {+  const ucd_record *ucd = GET_UCD(c);+  int32_t scriptx = ucd->scriptx;++  /* If the script extension is Unknown, the string is not a valid script run.+  Such characters can only form script runs of length one. */++  if (scriptx == ucp_Unknown) return FALSE;++  /* A character whose script extension is Inherited is always accepted with+  any script, and plays no further part in this testing. A character whose+  script is Common is always accepted, but must still be tested for a digit+  below. The scriptx value at this point is non-zero, because zero is+  ucp_Unknown, tested for above. */++  if (scriptx != ucp_Inherited)+    {+    if (scriptx != ucp_Common)+      {+      /* If the script extension value is positive, the character is not a mark+      that can be used with many scripts. In the simple case we either set or+      compare with the required script. However, handling the scripts that can+      combine with Han are more complicated, as is the case when the previous+      characters have been man-script marks. */++      if (scriptx > 0)+        {+        switch(require_script)+          {+          /* Either the first significant character (require_script unset) or+          after only Han characters. */++          case SCRIPT_UNSET:+          case SCRIPT_HANPENDING:+          switch(scriptx)+            {+            case ucp_Han:+            require_script = SCRIPT_HANPENDING;+            break;++            case ucp_Hiragana:+            case ucp_Katakana:+            require_script = SCRIPT_HANHIRAKATA;+            break;++            case ucp_Bopomofo:+            require_script = SCRIPT_HANBOPOMOFO;+            break;++            case ucp_Hangul:+            require_script = SCRIPT_HANHANGUL;+            break;++            /* Not a Han-related script. If expecting one, fail. Otherise set+            the requirement to this script. */++            default:+            if (require_script == SCRIPT_HANPENDING) return FALSE;+            require_script = scriptx;+            break;+            }+          break;++          /* Previously encountered one of the "with Han" scripts. Check that+          this character is appropriate. */++          case SCRIPT_HANHIRAKATA:+          if (scriptx != ucp_Han && scriptx != ucp_Hiragana && +              scriptx != ucp_Katakana)+            return FALSE;+          break;++          case SCRIPT_HANBOPOMOFO:+          if (scriptx != ucp_Han && scriptx != ucp_Bopomofo) return FALSE;+          break;++          case SCRIPT_HANHANGUL:+          if (scriptx != ucp_Han && scriptx != ucp_Hangul) return FALSE;+          break;++          /* We have a list of scripts to check that is derived from one or+          more previous characters. This is either one of the lists in+          ucd_script_sets[] (for one previous character) or the intersection of+          several lists for multiple characters. */++          case SCRIPT_LIST:+            {+            const uint8_t *list;+            for (list = require_list; *list != 0; list++)+              {+              if (*list == scriptx) break;+              }+            if (*list == 0) return FALSE;+            }++          /* The rest of the string must be in this script, but we have to +          allow for the Han complications. */+          +          switch(scriptx)+            {+            case ucp_Han:+            require_script = SCRIPT_HANPENDING;+            break;++            case ucp_Hiragana:+            case ucp_Katakana:+            require_script = SCRIPT_HANHIRAKATA;+            break;++            case ucp_Bopomofo:+            require_script = SCRIPT_HANBOPOMOFO;+            break;++            case ucp_Hangul:+            require_script = SCRIPT_HANHANGUL;+            break;++            default:+            require_script = scriptx;+            break;+            }  +          break;++          /* This is the easy case when a single script is required. */++          default:+          if (scriptx != require_script) return FALSE;+          break;+          }+        }  /* End of handing positive scriptx */++      /* If scriptx is negative, this character is a mark-type character that+      has a list of permitted scripts. */++      else+        {+        uint32_t chspecial;+        const uint8_t *clist, *rlist;+        const uint8_t *list = PRIV(ucd_script_sets) - scriptx;+        +        switch(require_script)+          {+          case SCRIPT_UNSET:+          require_list = PRIV(ucd_script_sets) - scriptx;+          require_script = SCRIPT_LIST;+          break;++          /* An inspection of the Unicode 11.0.0 files shows that there are the+          following types of Script Extension list that involve the Han,+          Bopomofo, Hiragana, Katakana, and Hangul scripts:++          . Bopomofo + Han+          . Han + Hiragana + Katakana+          . Hiragana + Katakana+          . Bopopmofo + Hangul + Han + Hiragana + Katakana++          The following code tries to make sense of this. */++#define FOUND_BOPOMOFO 1+#define FOUND_HIRAGANA 2+#define FOUND_KATAKANA 4+#define FOUND_HANGUL   8++          case SCRIPT_HANPENDING:+          chspecial = 0;+          for (; *list != 0; list++)+            {+            switch (*list)+              {+              case ucp_Bopomofo: chspecial |= FOUND_BOPOMOFO; break;+              case ucp_Hiragana: chspecial |= FOUND_HIRAGANA; break;+              case ucp_Katakana: chspecial |= FOUND_KATAKANA; break;+              case ucp_Hangul:   chspecial |= FOUND_HANGUL; break;+              default: break;+              }+            }++           if (chspecial == 0) return FALSE;++           if (chspecial == FOUND_BOPOMOFO)+             {+             require_script = SCRIPT_HANBOPOMOFO;+             }+           else if (chspecial == (FOUND_HIRAGANA|FOUND_KATAKANA))+             {+             require_script = SCRIPT_HANHIRAKATA;+             }++          /* Otherwise it must be allowed with all of them, so remain in+          the pending state. */++          break;++          case SCRIPT_HANHIRAKATA:+          for (; *list != 0; list++)+            {+            if (*list == ucp_Hiragana || *list == ucp_Katakana) break;+            }+          if (*list == 0) return FALSE;+          break;++          case SCRIPT_HANBOPOMOFO:+          for (; *list != 0; list++)+            {+            if (*list == ucp_Bopomofo) break;+            }+          if (*list == 0) return FALSE;+          break;++          case SCRIPT_HANHANGUL:+          for (; *list != 0; list++)+            {+            if (*list == ucp_Hangul) break;+            }+          if (*list == 0) return FALSE;+          break;++          /* Previously encountered one or more characters that are allowed+          with a list of scripts. Build the intersection of the required list+          with this character's list in intersection_list[]. This code is+          written so that it still works OK if the required list is already in+          that vector. */++          case SCRIPT_LIST:+            {+            int i = 0;+            for (rlist = require_list; *rlist != 0; rlist++)+              {+              for (clist = list; *clist != 0; clist++)+                {+                if (*rlist == *clist)+                  {+                  intersection_list[i++] = *rlist;+                  break;+                  }+                }+              }+            if (i == 0) return FALSE;  /* No scripts in common */++            /* If there's just one script in common, we can set it as the+            unique required script. Otherwise, terminate the intersection list+            and make it the required list. */++            if (i == 1)+              {+              require_script = intersection_list[0];+              }+            else+              {+              intersection_list[i] = 0;+              require_list = intersection_list;+              }+            }+          break;++          /* The previously set required script is a single script, not+          Han-related. Check that it is in this character's list. */++          default:+          for (; *list != 0; list++)+            {+            if (*list == require_script) break;+            }+          if (*list == 0) return FALSE;+          break;+          }+        }  /* End of handling negative scriptx */+      }    /* End of checking non-Common character */++    /* The character is in an acceptable script. We must now ensure that all+    decimal digits in the string come from the same set. Some scripts (e.g.+    Common, Arabic) have more than one set of decimal digits. This code does+    not allow mixing sets, even within the same script. The vector called+    PRIV(ucd_digit_sets)[] contains, in its first element, the number of+    following elements, and then, in ascending order, the code points of the+    '9' characters in every set of 10 digits. Each set is identified by the+    offset in the vector of its '9' character. An initial check of the first+    value picks up ASCII digits quickly. Otherwise, a binary chop is used. */++    if (ucd->chartype == ucp_Nd)+      {+      uint32_t digitset;++      if (c <= PRIV(ucd_digit_sets)[1]) digitset = 1; else+        {+        int mid;+        int bot = 1;+        int top = PRIV(ucd_digit_sets)[0];+        for (;;)+          {+          if (top <= bot + 1)    /* <= rather than == is paranoia */+            {+            digitset = top;+            break;+            }+          mid = (top + bot) / 2;+          if (c <= PRIV(ucd_digit_sets)[mid]) top = mid; else bot = mid;+          }+        }++      /* A required value of 0 means "unset". */++      if (require_digitset == 0) require_digitset = digitset;+        else if (digitset != require_digitset) return FALSE;+      }   /* End digit handling */+    }     /* End checking non-Inherited character */++  /* If we haven't yet got to the end, pick up the next character. */++  if (ptr >= endptr) return TRUE;+  GETCHARINCTEST(c, ptr);+  }  /* End checking loop */++#else   /* NOT SUPPORT_UNICODE */+(void)ptr;+(void)endptr;+(void)utf;+return TRUE;+#endif  /* SUPPORT_UNICODE */+}++/* End of pcre2_script_run.c */
+ src/c/pcre2/src/pcre2_serialize.c view
@@ -0,0 +1,286 @@+/*************************************************+*      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-2020 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 functions for serializing and deserializing+a sequence of compiled codes. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif+++#include "pcre2_internal.h"++/* Magic number to provide a small check against being handed junk. */++#define SERIALIZED_DATA_MAGIC 0x50523253u++/* Deserialization is limited to the current PCRE version and+character width. */++#define SERIALIZED_DATA_VERSION \+  ((PCRE2_MAJOR) | ((PCRE2_MINOR) << 16))++#define SERIALIZED_DATA_CONFIG \+  (sizeof(PCRE2_UCHAR) | ((sizeof(void*)) << 8) | ((sizeof(PCRE2_SIZE)) << 16))++++/*************************************************+*           Serialize compiled patterns          *+*************************************************/++PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION+pcre2_serialize_encode(const pcre2_code **codes, int32_t number_of_codes,+   uint8_t **serialized_bytes, PCRE2_SIZE *serialized_size,+   pcre2_general_context *gcontext)+{+uint8_t *bytes;+uint8_t *dst_bytes;+int32_t i;+PCRE2_SIZE total_size;+const pcre2_real_code *re;+const uint8_t *tables;+pcre2_serialized_data *data;++const pcre2_memctl *memctl = (gcontext != NULL) ?+  &gcontext->memctl : &PRIV(default_compile_context).memctl;++if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL)+  return PCRE2_ERROR_NULL;++if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;++/* Compute total size. */+total_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH;+tables = NULL;++for (i = 0; i < number_of_codes; i++)+  {+  if (codes[i] == NULL) return PCRE2_ERROR_NULL;+  re = (const pcre2_real_code *)(codes[i]);+  if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;+  if (tables == NULL)+    tables = re->tables;+  else if (tables != re->tables)+    return PCRE2_ERROR_MIXEDTABLES;+  total_size += re->blocksize;+  }++/* Initialize the byte stream. */+bytes = memctl->malloc(total_size + sizeof(pcre2_memctl), memctl->memory_data);+if (bytes == NULL) return PCRE2_ERROR_NOMEMORY;++/* The controller is stored as a hidden parameter. */+memcpy(bytes, memctl, sizeof(pcre2_memctl));+bytes += sizeof(pcre2_memctl);++data = (pcre2_serialized_data *)bytes;+data->magic = SERIALIZED_DATA_MAGIC;+data->version = SERIALIZED_DATA_VERSION;+data->config = SERIALIZED_DATA_CONFIG;+data->number_of_codes = number_of_codes;++/* Copy all compiled code data. */+dst_bytes = bytes + sizeof(pcre2_serialized_data);+memcpy(dst_bytes, tables, TABLES_LENGTH);+dst_bytes += TABLES_LENGTH;++for (i = 0; i < number_of_codes; i++)+  {+  re = (const pcre2_real_code *)(codes[i]);+  (void)memcpy(dst_bytes, (char *)re, re->blocksize);+  +  /* Certain fields in the compiled code block are re-set during +  deserialization. In order to ensure that the serialized data stream is always +  the same for the same pattern, set them to zero here. We can't assume the +  copy of the pattern is correctly aligned for accessing the fields as part of +  a structure. Note the use of sizeof(void *) in the second of these, to+  specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a +  pointer to uint8_t), gcc gives a warning because the first argument is also a +  pointer to uint8_t. Casting the first argument to (void *) can stop this, but +  it didn't stop Coverity giving the same complaint. */+  +  (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, +    sizeof(pcre2_memctl));+  (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, +    sizeof(void *));+  (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0,+    sizeof(void *));        + +  dst_bytes += re->blocksize;+  }++*serialized_bytes = bytes;+*serialized_size = total_size;+return number_of_codes;+}+++/*************************************************+*          Deserialize compiled patterns         *+*************************************************/++PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION+pcre2_serialize_decode(pcre2_code **codes, int32_t number_of_codes,+   const uint8_t *bytes, pcre2_general_context *gcontext)+{+const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;+const pcre2_memctl *memctl = (gcontext != NULL) ?+  &gcontext->memctl : &PRIV(default_compile_context).memctl;++const uint8_t *src_bytes;+pcre2_real_code *dst_re;+uint8_t *tables;+int32_t i, j;++/* Sanity checks. */++if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL;+if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;+if (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA;+if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;+if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;+if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;++if (number_of_codes > data->number_of_codes)+  number_of_codes = data->number_of_codes;++src_bytes = bytes + sizeof(pcre2_serialized_data);++/* Decode tables. The reference count for the tables is stored immediately+following them. */++tables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data);+if (tables == NULL) return PCRE2_ERROR_NOMEMORY;++memcpy(tables, src_bytes, TABLES_LENGTH);+*(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes;+src_bytes += TABLES_LENGTH;++/* Decode the byte stream. We must not try to read the size from the compiled+code block in the stream, because it might be unaligned, which causes errors on+hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type+of the blocksize field is given its own name to ensure that it is the same here+as in the block. */++for (i = 0; i < number_of_codes; i++)+  {+  CODE_BLOCKSIZE_TYPE blocksize;+  memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize),+    sizeof(CODE_BLOCKSIZE_TYPE));+  if (blocksize <= sizeof(pcre2_real_code))+    return PCRE2_ERROR_BADSERIALIZEDDATA;++  /* The allocator provided by gcontext replaces the original one. */++  dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize,+    (pcre2_memctl *)gcontext);+  if (dst_re == NULL)+    {+    memctl->free(tables, memctl->memory_data);+    for (j = 0; j < i; j++)+      {+      memctl->free(codes[j], memctl->memory_data);+      codes[j] = NULL;+      }+    return PCRE2_ERROR_NOMEMORY;+    }++  /* The new allocator must be preserved. */++  memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl),+    src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl));+  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. */++  dst_re->tables = tables;+  dst_re->executable_jit = NULL;+  dst_re->flags |= PCRE2_DEREF_TABLES;++  codes[i] = dst_re;+  src_bytes += blocksize;+  }++return number_of_codes;+}+++/*************************************************+*    Get the number of serialized patterns       *+*************************************************/++PCRE2_EXP_DEFN int32_t PCRE2_CALL_CONVENTION+pcre2_serialize_get_number_of_codes(const uint8_t *bytes)+{+const pcre2_serialized_data *data = (const pcre2_serialized_data *)bytes;++if (data == NULL) return PCRE2_ERROR_NULL;+if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC;+if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE;+if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE;++return data->number_of_codes;+}+++/*************************************************+*            Free the allocated stream           *+*************************************************/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_serialize_free(uint8_t *bytes)+{+if (bytes != NULL)+  {+  pcre2_memctl *memctl = (pcre2_memctl *)(bytes - sizeof(pcre2_memctl));+  memctl->free(memctl, memctl->memory_data);+  }+}++/* End of pcre2_serialize.c */
+ src/c/pcre2/src/pcre2_string_utils.c view
@@ -0,0 +1,237 @@+/*************************************************+*      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) 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 internal functions for comparing and finding the length+of strings. These are used instead of strcmp() etc because the standard+functions work only on 8-bit data. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"+++/*************************************************+*    Emulated memmove() for systems without it   *+*************************************************/++/* This function can make use of bcopy() if it is available. Otherwise do it by+steam, as there some non-Unix environments that lack both memmove() and+bcopy(). */++#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)+void *+PRIV(memmove)(void *d, const void *s, size_t n)+{+#ifdef HAVE_BCOPY+bcopy(s, d, n);+return d;+#else+size_t i;+unsigned char *dest = (unsigned char *)d;+const unsigned char *src = (const unsigned char *)s;+if (dest > src)+  {+  dest += n;+  src += n;+  for (i = 0; i < n; ++i) *(--dest) = *(--src);+  return (void *)dest;+  }+else+  {+  for (i = 0; i < n; ++i) *dest++ = *src++;+  return (void *)(dest - n);+  }+#endif   /* not HAVE_BCOPY */+}+#endif   /* not VPCOMPAT && not HAVE_MEMMOVE */+++/*************************************************+*    Compare two zero-terminated PCRE2 strings   *+*************************************************/++/*+Arguments:+  str1        first string+  str2        second string++Returns:      0, 1, or -1+*/++int+PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2)+{+PCRE2_UCHAR c1, c2;+while (*str1 != '\0' || *str2 != '\0')+  {+  c1 = *str1++;+  c2 = *str2++;+  if (c1 != c2) return ((c1 > c2) << 1) - 1;+  }+return 0;+}+++/*************************************************+*  Compare zero-terminated PCRE2 & 8-bit strings *+*************************************************/++/* As the 8-bit string is almost always a literal, its type is specified as+const char *.++Arguments:+  str1        first string+  str2        second string++Returns:      0, 1, or -1+*/++int+PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2)+{+PCRE2_UCHAR c1, c2;+while (*str1 != '\0' || *str2 != '\0')+  {+  c1 = *str1++;+  c2 = *str2++;+  if (c1 != c2) return ((c1 > c2) << 1) - 1;+  }+return 0;+}+++/*************************************************+*    Compare two PCRE2 strings, given a length   *+*************************************************/++/*+Arguments:+  str1        first string+  str2        second string+  len         the length++Returns:      0, 1, or -1+*/++int+PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len)+{+PCRE2_UCHAR c1, c2;+for (; len > 0; len--)+  {+  c1 = *str1++;+  c2 = *str2++;+  if (c1 != c2) return ((c1 > c2) << 1) - 1;+  }+return 0;+}+++/*************************************************+* Compare PCRE2 string to 8-bit string by length *+*************************************************/++/* As the 8-bit string is almost always a literal, its type is specified as+const char *.++Arguments:+  str1        first string+  str2        second string+  len         the length++Returns:      0, 1, or -1+*/++int+PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len)+{+PCRE2_UCHAR c1, c2;+for (; len > 0; len--)+  {+  c1 = *str1++;+  c2 = *str2++;+  if (c1 != c2) return ((c1 > c2) << 1) - 1;+  }+return 0;+}+++/*************************************************+*        Find the length of a PCRE2 string       *+*************************************************/++/*+Argument:    the string+Returns:     the length+*/++PCRE2_SIZE+PRIV(strlen)(PCRE2_SPTR str)+{+PCRE2_SIZE c = 0;+while (*str++ != 0) c++;+return c;+}+++/*************************************************+* Copy 8-bit 0-terminated string to PCRE2 string *+*************************************************/++/* Arguments:+  str1     buffer to receive the string+  str2     8-bit string to be copied++Returns:   the number of code units used (excluding trailing zero)+*/++PCRE2_SIZE+PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2)+{+PCRE2_UCHAR *t = str1;+while (*str2 != 0) *t++ = *str2++;+*t = 0;+return t - str1;+}++/* End of pcre2_string_utils.c */
+ src/c/pcre2/src/pcre2_study.c view
@@ -0,0 +1,1825 @@+/*************************************************+*      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-2020 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 functions for scanning a compiled pattern and+collecting data (e.g. minimum matching length). */+++#ifdef HAVE_CONFIG_H+#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. */++#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1u << ((c)&7))++/* Returns from set_start_bits() */++enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN, SSB_TOODEEP };+++/*************************************************+*   Find the minimum subject length for a group  *+*************************************************/++/* Scan a parenthesized group and compute the minimum length of subject that+is needed to match it. This is a lower bound; it does not mean there is a+string of that length that matches. In UTF mode, the result is in characters+rather than code units. The field in a compiled pattern for storing the minimum+length is 16-bits long (on the grounds that anything longer than that is+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)+  startcode       pointer to start of the whole pattern's code+  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.++This function is no longer called when the pattern contains (*ACCEPT); however,+the old code for returning -1 is retained, just in case.++Returns:   the minimum length+           -1 \C in UTF-8 mode+              or (*ACCEPT)+              or pattern too complicated+           -2 internal error (missing capturing bracket)+           -3 internal error (opcode not listed)+*/++static int+find_minlength(const pcre2_real_code *re, PCRE2_SPTR code,+  PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr,+  int *backref_cache)+{+int length = -1;+int branchlength = 0;+int prev_cap_recno = -1;+int prev_cap_d = 0;+int prev_recurse_recno = -1;+int prev_recurse_d = 0;+uint32_t once_fudge = 0;+BOOL had_recurse = FALSE;+BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0;+PCRE2_SPTR nextbranch = code + GET(code, 1);+PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE;+recurse_check this_recurse;++/* If this is a "could be empty" group, its minimum length is 0. */++if (*code >= OP_SBRA && *code <= OP_SCOND) return 0;++/* Skip over capturing bracket number */++if (*code == OP_CBRA || *code == OP_CBRAPOS) cc += IMM2_SIZE;++/* A large and/or complex regex can take too long to process. */++if ((*countptr)++ > 1000) return -1;++/* 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. If the accumulated length+passes 16-bits, reset to that value and skip the rest of the branch. */++for (;;)+  {+  int d, min, recno;+  PCRE2_UCHAR op, *cs, *ce;++  if (branchlength >= UINT16_MAX)+    {+    branchlength = UINT16_MAX;+    cc = (PCRE2_UCHAR *)nextbranch;+    }++  op = *cc;+  switch (op)+    {+    case OP_COND:+    case OP_SCOND:++    /* If there is only one branch in a condition, the implied branch has zero+    length, so we don't add anything. This covers the DEFINE "condition"+    automatically. If there are two branches we can treat it the same as any+    other non-capturing subpattern. */++    cs = cc + GET(cc, 1);+    if (*cs != OP_ALT)+      {+      cc = cs + 1 + LINK_SIZE;+      break;+      }+    goto PROCESS_NON_CAPTURE;++    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. */++    if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET)+      {+      once_fudge = 1 + LINK_SIZE;+      cc += 1 + LINK_SIZE;+      break;+      }+    /* Fall through */++    case OP_ONCE:+    case OP_SCRIPT_RUN:+    case OP_SBRA:+    case OP_BRAPOS:+    case OP_SBRAPOS:+    PROCESS_NON_CAPTURE:+    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);+    cc += 1 + LINK_SIZE;+    break;++    /* To save time for repeated capturing subpatterns, we remember the+    length of the previous one. Unfortunately we can't do the same for+    the unnumbered ones above. Nor can we do this if (?| is present in the+    pattern because captures with the same number are not then identical. */++    case OP_CBRA:+    case OP_SCBRA:+    case OP_CBRAPOS:+    case OP_SCBRAPOS:+    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,+        backref_cache);+      if (prev_cap_d < 0) return prev_cap_d;+      }+    branchlength += prev_cap_d;+    do cc += GET(cc, 1); while (*cc == OP_ALT);+    cc += 1 + LINK_SIZE;+    break;++    /* ACCEPT makes things far too complicated; we have to give up. In fact,+    from 10.34 onwards, if a pattern contains (*ACCEPT), this function is not+    used. However, leave the code in place, just in case. */++    case OP_ACCEPT:+    case OP_ASSERT_ACCEPT:+    return -1;++    /* 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. If it is END it's+    the end of the outer call. All can be handled by the same code. If the+    length of any branch is zero, there is no need to scan any subsequent+    branches. */++    case OP_ALT:+    case OP_KET:+    case OP_KETRMAX:+    case OP_KETRMIN:+    case OP_KETRPOS:+    case OP_END:+    if (length < 0 || (!had_recurse && branchlength < length))+      length = branchlength;+    if (op != OP_ALT || length == 0) return length;+    nextbranch = cc + GET(cc, 1);+    cc += 1 + LINK_SIZE;+    branchlength = 0;+    had_recurse = FALSE;+    break;++    /* Skip over assertive subpatterns */++    case OP_ASSERT:+    case OP_ASSERT_NOT:+    case OP_ASSERTBACK:+    case OP_ASSERTBACK_NOT:+    case OP_ASSERT_NA:+    case OP_ASSERTBACK_NA:+    do cc += GET(cc, 1); while (*cc == OP_ALT);+    /* Fall through */++    /* Skip over things that don't match chars */++    case OP_REVERSE:+    case OP_CREF:+    case OP_DNCREF:+    case OP_RREF:+    case OP_DNRREF:+    case OP_FALSE:+    case OP_TRUE:+    case OP_CALLOUT:+    case OP_SOD:+    case OP_SOM:+    case OP_EOD:+    case OP_EODN:+    case OP_CIRC:+    case OP_CIRCM:+    case OP_DOLL:+    case OP_DOLLM:+    case OP_NOT_WORD_BOUNDARY:+    case OP_WORD_BOUNDARY:+    cc += PRIV(OP_lengths)[*cc];+    break;++    case OP_CALLOUT_STR:+    cc += GET(cc, 1 + 2*LINK_SIZE);+    break;++    /* Skip over a subpattern that has a {0} or {0,x} quantifier */++    case OP_BRAZERO:+    case OP_BRAMINZERO:+    case OP_BRAPOSZERO:+    case OP_SKIPZERO:+    cc += PRIV(OP_lengths)[*cc];+    do cc += GET(cc, 1); while (*cc == OP_ALT);+    cc += 1 + LINK_SIZE;+    break;++    /* Handle literal characters and + repetitions */++    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_POSPLUS:+    case OP_POSPLUSI:+    case OP_NOTPLUS:+    case OP_NOTPLUSI:+    case OP_NOTMINPLUS:+    case OP_NOTMINPLUSI:+    case OP_NOTPOSPLUS:+    case OP_NOTPOSPLUSI:+    branchlength++;+    cc += 2;+#ifdef SUPPORT_UNICODE+    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+    break;++    case OP_TYPEPLUS:+    case OP_TYPEMINPLUS:+    case OP_TYPEPOSPLUS:+    branchlength++;+    cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;+    break;++    /* Handle exact repetitions. The count is already in characters, but we+    may need to skip over a multibyte character in UTF mode.  */++    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);+    cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP+      || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);+    break;++    /* Handle single-char non-literal matchers */++    case OP_PROP:+    case OP_NOTPROP:+    cc += 2;+    /* Fall through */++    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:+    case OP_EXTUNI:+    case OP_HSPACE:+    case OP_NOT_HSPACE:+    case OP_VSPACE:+    case OP_NOT_VSPACE:+    branchlength++;+    cc++;+    break;++    /* "Any newline" might match two characters, but it also might match just+    one. */++    case OP_ANYNL:+    branchlength += 1;+    cc++;+    break;++    /* The single-byte matcher means we can't proceed in UTF mode. (In+    non-UTF mode \C will actually be turned into OP_ALLANY, so won't ever+    appear, but leave the code, just in case.) */++    case OP_ANYBYTE:+#ifdef SUPPORT_UNICODE+    if (utf) return -1;+#endif+    branchlength++;+    cc++;+    break;++    /* For repeated character types, we have to test for \p and \P, which have+    an extra two bytes of parameters. */++    case OP_TYPESTAR:+    case OP_TYPEMINSTAR:+    case OP_TYPEQUERY:+    case OP_TYPEMINQUERY:+    case OP_TYPEPOSSTAR:+    case OP_TYPEPOSQUERY:+    if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;+    cc += PRIV(OP_lengths)[op];+    break;++    case OP_TYPEUPTO:+    case OP_TYPEMINUPTO:+    case OP_TYPEPOSUPTO:+    if (cc[1 + IMM2_SIZE] == OP_PROP+      || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;+    cc += PRIV(OP_lengths)[op];+    break;++    /* 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);+    else+      cc += PRIV(OP_lengths)[OP_CLASS];+#else+    cc += PRIV(OP_lengths)[OP_CLASS];+#endif++    switch (*cc)+      {+      case OP_CRPLUS:+      case OP_CRMINPLUS:+      case OP_CRPOSPLUS:+      branchlength++;+      /* Fall through */++      case OP_CRSTAR:+      case OP_CRMINSTAR:+      case OP_CRQUERY:+      case OP_CRMINQUERY:+      case OP_CRPOSSTAR:+      case OP_CRPOSQUERY:+      cc++;+      break;++      case OP_CRRANGE:+      case OP_CRMINRANGE:+      case OP_CRPOSRANGE:+      branchlength += GET2(cc,1);+      cc += 1 + 2 * IMM2_SIZE;+      break;++      default:+      branchlength++;+      break;+      }+    break;++    /* Backreferences and subroutine calls (OP_RECURSE) are treated in the same+    way: we find the minimum length for the subpattern. A recursion+    (backreference or subroutine) causes an a flag to be set that causes the+    length of this branch to be ignored. The logic is that a recursion can only+    make sense if there is another alternative that stops the recursing. That+    will provide the minimum length (when no recursion happens).++    If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket+    matches an empty string (by default it causes a matching failure), so in+    that case we must set the minimum length to zero.++    For backreferenes, if duplicate numbers are present in the pattern we check+    for a reference to a duplicate. If it is, we don't know which version will+    be referenced, so we have to set the minimum length to zero. */++    /* Duplicate named pattern back reference. */++    case OP_DNREF:+    case OP_DNREFI:+    if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)+      {+      int count = GET2(cc, 1+IMM2_SIZE);+      PCRE2_UCHAR *slot =+        (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) ++          GET2(cc, 1) * re->name_entry_size;++      d = INT_MAX;++      /* Scan all groups with the same name; find the shortest. */++      while (count-- > 0)+        {+        int dd, i;+        recno = GET2(slot, 0);++        if (recno <= backref_cache[0] && backref_cache[recno] >= 0)+          dd = backref_cache[recno];+        else+          {+          ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);+          if (cs == NULL) return -2;+          do ce += GET(ce, 1); while (*ce == OP_ALT);++          dd = 0;+          if (!dupcapused ||+              (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL)+            {+            if (cc > cs && cc < ce)    /* Simple recursion */+              {+              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 */+                {+                had_recurse = TRUE;+                }+              else+                {+                this_recurse.prev = recurses;  /* No recursion */+                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;+        }+      }+    else d = 0;+    cc += 1 + 2*IMM2_SIZE;+    goto REPEAT_BACK_REFERENCE;++    /* Single back reference by number. References by name are converted to by+    number when there is no duplication. */++    case OP_REF:+    case OP_REFI:+    recno = GET2(cc, 1);+    if (recno <= backref_cache[0] && backref_cache[recno] >= 0)+      d = backref_cache[recno];+    else+      {+      int i;+      d = 0;++      if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)+        {+        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 (!dupcapused ||+            (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL)+          {+          if (cc > cs && cc < ce)    /* Simple recursion */+            {+            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 */+              {+              had_recurse = TRUE;+              }+            else                     /* No recursion */+              {+              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;+              }+            }+          }+        }++      backref_cache[recno] = d;+      for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;+      backref_cache[0] = recno;+      }++    cc += 1 + IMM2_SIZE;++    /* Handle repeated back references */++    REPEAT_BACK_REFERENCE:+    switch (*cc)+      {+      case OP_CRSTAR:+      case OP_CRMINSTAR:+      case OP_CRQUERY:+      case OP_CRMINQUERY:+      case OP_CRPOSSTAR:+      case OP_CRPOSQUERY:+      min = 0;+      cc++;+      break;++      case OP_CRPLUS:+      case OP_CRMINPLUS:+      case OP_CRPOSPLUS:+      min = 1;+      cc++;+      break;++      case OP_CRRANGE:+      case OP_CRMINRANGE:+      case OP_CRPOSRANGE:+      min = GET2(cc, 1);+      cc += 1 + 2 * IMM2_SIZE;+      break;++      default:+      min = 1;+      break;+      }++     /* Take care not to overflow: (1) min and d are ints, so check that their+     product is not greater than INT_MAX. (2) branchlength is limited to+     UINT16_MAX (checked at the top of the loop). */++    if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d)+      branchlength = UINT16_MAX;+    else branchlength += min * d;+    break;++    /* Recursion always refers to the first occurrence of a subpattern with a+    given number. Therefore, we can always make use of caching, even when the+    pattern contains multiple subpatterns with the same number. */++    case OP_RECURSE:+    cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1);+    recno = GET2(cs, 1+LINK_SIZE);+    if (recno == prev_recurse_recno)+      {+      branchlength += prev_recurse_d;+      }+    else+      {+      do ce += GET(ce, 1); while (*ce == OP_ALT);+      if (cc > cs && cc < ce)    /* Simple recursion */+        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 */+          had_recurse = TRUE;+        else+          {+          this_recurse.prev = recurses;+          this_recurse.group = cs;+          prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse,+            countptr, backref_cache);+          if (prev_recurse_d < 0) return prev_recurse_d;+          prev_recurse_recno = recno;+          branchlength += prev_recurse_d;+          }+        }+      }+    cc += 1 + LINK_SIZE + once_fudge;+    once_fudge = 0;+    break;++    /* Anything else does not or need not match a character. We can get the+    item's length from the table, but for those that can match zero occurrences+    of a character, we must take special action for UTF-8 characters. As it+    happens, the "NOT" versions of these opcodes are used at present only for+    ASCII characters, so they could be omitted from this list. However, in+    future that may change, so we include them here so as not to leave a+    gotcha for a future maintainer. */++    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:++    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:++    cc += PRIV(OP_lengths)[op];+#ifdef SUPPORT_UNICODE+    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);+#endif+    break;++    /* Skip these, but we need to add in the name length. */++    case OP_MARK:+    case OP_COMMIT_ARG:+    case OP_PRUNE_ARG:+    case OP_SKIP_ARG:+    case OP_THEN_ARG:+    cc += PRIV(OP_lengths)[op] + cc[1];+    break;++    /* The remaining opcodes are just skipped over. */++    case OP_CLOSE:+    case OP_COMMIT:+    case OP_FAIL:+    case OP_PRUNE:+    case OP_SET_SOM:+    case OP_SKIP:+    case OP_THEN:+    cc += PRIV(OP_lengths)[op];+    break;++    /* This should not occur: we list all opcodes explicitly so that when+    new ones get added they are properly considered. */++    default:+    return -3;+    }+  }+/* Control never gets here */+}++++/*************************************************+*      Set a bit and maybe its alternate case    *+*************************************************/++/* Given a character, set its first code unit's bit in the table, and also the+corresponding bit for the other version of a letter if we are caseless.++Arguments:+  re            points to the regex block+  p             points to the first code unit of the character+  caseless      TRUE if caseless+  utf           TRUE for UTF mode+  ucp           TRUE for UCP mode++Returns:        pointer after the character+*/++static PCRE2_SPTR+set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf,+  BOOL ucp)+{+uint32_t c = *p++;   /* First code unit */++(void)utf;           /* Stop compiler warnings when UTF not supported */+(void)ucp;++/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for+0xff. */++#if PCRE2_CODE_UNIT_WIDTH != 8+if (c > 0xff) SET_BIT(0xff); else+#endif++SET_BIT(c);++/* In UTF-8 or UTF-16 mode, pick up the remaining code units in order to find+the end of the character, even when caseless. */++#ifdef SUPPORT_UNICODE+if (utf)+  {+#if PCRE2_CODE_UNIT_WIDTH == 8+  if (c >= 0xc0) GETUTF8INC(c, p);+#elif PCRE2_CODE_UNIT_WIDTH == 16+  if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, p);+#endif+  }+#endif  /* SUPPORT_UNICODE */++/* If caseless, handle the other case of the character. */++if (caseless)+  {+#ifdef SUPPORT_UNICODE+  if (utf || ucp)+    {+    c = UCD_OTHERCASE(c);+#if PCRE2_CODE_UNIT_WIDTH == 8+    if (utf)+      {+      PCRE2_UCHAR buff[6];+      (void)PRIV(ord2utf)(c, buff);+      SET_BIT(buff[0]);+      }+    else if (c < 256) SET_BIT(c);+#else  /* 16-bit or 32-bit mode */+    if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);+#endif+    }++  else+#endif  /* SUPPORT_UNICODE */++  /* Not UTF or UCP */++  if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);+  }++return p;+}++++/*************************************************+*     Set bits for a positive character type     *+*************************************************/++/* This function sets starting bits for a character type. In UTF-8 mode, we can+only do a direct setting for bytes less than 128, as otherwise there can be+confusion with bytes in the middle of UTF-8 characters. In a "traditional"+environment, the tables will only recognize ASCII characters anyway, but in at+least one Windows environment, some higher bytes bits were set in the tables.+So we deal with that case by considering the UTF-8 encoding.++Arguments:+  re             the regex block+  cbit type      the type of character wanted+  table_limit    32 for non-UTF-8; 16 for UTF-8++Returns:         nothing+*/++static void+set_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)+{+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+if (table_limit == 32) return;+for (c = 128; c < 256; c++)+  {+  if ((re->tables[cbits_offset + c/8] & (1u << (c&7))) != 0)+    {+    PCRE2_UCHAR buff[6];+    (void)PRIV(ord2utf)(c, buff);+    SET_BIT(buff[0]);+    }+  }+#endif  /* UTF-8 */+}+++/*************************************************+*     Set bits for a negative character type     *+*************************************************/++/* This function sets starting bits for a negative character type such as \D.+In UTF-8 mode, we can only do a direct setting for bytes less than 128, as+otherwise there can be confusion with bytes in the middle of UTF-8 characters.+Unlike in the positive case, where we can set appropriate starting bits for+specific high-valued UTF-8 characters, in this case we have to set the bits for+all high-valued characters. The lowest is 0xc2, but we overkill by starting at+0xc0 (192) for simplicity.++Arguments:+  re             the regex block+  cbit type      the type of character wanted+  table_limit    32 for non-UTF-8; 16 for UTF-8++Returns:         nothing+*/++static void+set_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)+{+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+if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff;+#endif+}++++/*************************************************+*      Create bitmap of starting code units      *+*************************************************/++/* This function scans a compiled unanchored expression recursively and+attempts to build a bitmap of the set of possible starting code units whose+values are less than 256. In 16-bit and 32-bit mode, values above 255 all cause+the 255 bit to be set. When calling set[_not]_type_bits() in UTF-8 (sic) mode+we pass a value of 16 rather than 32 as the final argument. (See comments in+those functions for the reason.)++The SSB_CONTINUE return is useful for parenthesized groups in patterns such as+(a*)b where the group provides some optional starting code units but scanning+must continue at the outer level to find at least one mandatory code unit. At+the outermost level, this function fails unless the result is SSB_DONE.++We restrict recursion (for nested groups) to 1000 to avoid stack overflow+issues.++Arguments:+  re           points to the compiled regex block+  code         points to an expression+  utf          TRUE if in UTF mode+  ucp          TRUE if in UCP mode+  depthptr     pointer to recurse depth++Returns:       SSB_FAIL     => Failed to find any starting code units+               SSB_DONE     => Found mandatory starting code units+               SSB_CONTINUE => Found optional starting code units+               SSB_UNKNOWN  => Hit an unrecognized opcode+               SSB_TOODEEP  => Recursion is too deep+*/++static int+set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf, BOOL ucp,+  int *depthptr)+{+uint32_t c;+int yield = SSB_DONE;++#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+int table_limit = utf? 16:32;+#else+int table_limit = 32;+#endif++*depthptr += 1;+if (*depthptr > 1000) return SSB_TOODEEP;++do+  {+  BOOL try_next = TRUE;+  PCRE2_SPTR tcode = code + 1 + LINK_SIZE;++  if (*code == OP_CBRA || *code == OP_SCBRA ||+      *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;++  while (try_next)    /* Loop for items in this branch */+    {+    int rc;+    uint8_t *classmap = NULL;+#ifdef SUPPORT_WIDE_CHARS+    PCRE2_UCHAR xclassflags;+#endif++    switch(*tcode)+      {+      /* If we reach something we don't understand, it means a new opcode has+      been created that hasn't been added to this function. Hopefully this+      problem will be discovered during testing. */++      default:+      return SSB_UNKNOWN;++      /* Fail for a valid opcode that implies no starting bits. */++      case OP_ACCEPT:+      case OP_ASSERT_ACCEPT:+      case OP_ALLANY:+      case OP_ANY:+      case OP_ANYBYTE:+      case OP_CIRCM:+      case OP_CLOSE:+      case OP_COMMIT:+      case OP_COMMIT_ARG:+      case OP_COND:+      case OP_CREF:+      case OP_FALSE:+      case OP_TRUE:+      case OP_DNCREF:+      case OP_DNREF:+      case OP_DNREFI:+      case OP_DNRREF:+      case OP_DOLL:+      case OP_DOLLM:+      case OP_END:+      case OP_EOD:+      case OP_EODN:+      case OP_EXTUNI:+      case OP_FAIL:+      case OP_MARK:+      case OP_NOT:+      case OP_NOTEXACT:+      case OP_NOTEXACTI:+      case OP_NOTI:+      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_NOTPROP:+      case OP_NOTQUERY:+      case OP_NOTQUERYI:+      case OP_NOTSTAR:+      case OP_NOTSTARI:+      case OP_NOTUPTO:+      case OP_NOTUPTOI:+      case OP_NOT_HSPACE:+      case OP_NOT_VSPACE:+      case OP_PRUNE:+      case OP_PRUNE_ARG:+      case OP_RECURSE:+      case OP_REF:+      case OP_REFI:+      case OP_REVERSE:+      case OP_RREF:+      case OP_SCOND:+      case OP_SET_SOM:+      case OP_SKIP:+      case OP_SKIP_ARG:+      case OP_SOD:+      case OP_SOM:+      case OP_THEN:+      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+      point in recognizing them for OP_NOTPROP. */++      case OP_PROP:+      if (tcode[1] != PT_CLIST) return SSB_FAIL;+        {+        const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2];+        while ((c = *p++) < NOTACHAR)+          {+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+          if (utf)+            {+            PCRE2_UCHAR buff[6];+            (void)PRIV(ord2utf)(c, buff);+            c = buff[0];+            }+#endif+          if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);+          }+        }+      try_next = FALSE;+      break;++      /* We can ignore word boundary tests. */++      case OP_WORD_BOUNDARY:+      case OP_NOT_WORD_BOUNDARY:+      tcode++;+      break;++      /* If we hit a bracket or a positive lookahead assertion, recurse to set+      bits from within the subpattern. If it can't find anything, we have to+      give up. If it finds some mandatory character(s), we are done for this+      branch. Otherwise, carry on scanning after the subpattern. */++      case OP_BRA:+      case OP_SBRA:+      case OP_CBRA:+      case OP_SCBRA:+      case OP_BRAPOS:+      case OP_SBRAPOS:+      case OP_CBRAPOS:+      case OP_SCBRAPOS:+      case OP_ONCE:+      case OP_SCRIPT_RUN:+      case OP_ASSERT:+      case OP_ASSERT_NA:+      rc = set_start_bits(re, tcode, utf, ucp, depthptr);+      if (rc == SSB_DONE)+        {+        try_next = FALSE;+        }+      else if (rc == SSB_CONTINUE)+        {+        do tcode += GET(tcode, 1); while (*tcode == OP_ALT);+        tcode += 1 + LINK_SIZE;+        }+      else return rc;   /* FAIL, UNKNOWN, or TOODEEP */+      break;++      /* If we hit ALT or KET, it means we haven't found anything mandatory in+      this branch, though we might have found something optional. For ALT, we+      continue with the next alternative, but we have to arrange that the final+      result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,+      return SSB_CONTINUE: if this is the top level, that indicates failure,+      but after a nested subpattern, it causes scanning to continue. */++      case OP_ALT:+      yield = SSB_CONTINUE;+      try_next = FALSE;+      break;++      case OP_KET:+      case OP_KETRMAX:+      case OP_KETRMIN:+      case OP_KETRPOS:+      return SSB_CONTINUE;++      /* Skip over callout */++      case OP_CALLOUT:+      tcode += PRIV(OP_lengths)[OP_CALLOUT];+      break;++      case OP_CALLOUT_STR:+      tcode += GET(tcode, 1 + 2*LINK_SIZE);+      break;++      /* Skip over lookbehind and negative lookahead assertions */++      case OP_ASSERT_NOT:+      case OP_ASSERTBACK:+      case OP_ASSERTBACK_NOT:+      case OP_ASSERTBACK_NA:+      do tcode += GET(tcode, 1); while (*tcode == OP_ALT);+      tcode += 1 + LINK_SIZE;+      break;++      /* BRAZERO does the bracket, but carries on. */++      case OP_BRAZERO:+      case OP_BRAMINZERO:+      case OP_BRAPOSZERO:+      rc = set_start_bits(re, ++tcode, utf, ucp, depthptr);+      if (rc == SSB_FAIL || rc == SSB_UNKNOWN || rc == SSB_TOODEEP) return rc;+      do tcode += GET(tcode,1); while (*tcode == OP_ALT);+      tcode += 1 + LINK_SIZE;+      break;++      /* SKIPZERO skips the bracket. */++      case OP_SKIPZERO:+      tcode++;+      do tcode += GET(tcode,1); while (*tcode == OP_ALT);+      tcode += 1 + LINK_SIZE;+      break;++      /* Single-char * or ? sets the bit and tries the next item */++      case OP_STAR:+      case OP_MINSTAR:+      case OP_POSSTAR:+      case OP_QUERY:+      case OP_MINQUERY:+      case OP_POSQUERY:+      tcode = set_table_bit(re, tcode + 1, FALSE, utf, ucp);+      break;++      case OP_STARI:+      case OP_MINSTARI:+      case OP_POSSTARI:+      case OP_QUERYI:+      case OP_MINQUERYI:+      case OP_POSQUERYI:+      tcode = set_table_bit(re, tcode + 1, TRUE, utf, ucp);+      break;++      /* Single-char upto sets the bit and tries the next */++      case OP_UPTO:+      case OP_MINUPTO:+      case OP_POSUPTO:+      tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf, ucp);+      break;++      case OP_UPTOI:+      case OP_MINUPTOI:+      case OP_POSUPTOI:+      tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf, ucp);+      break;++      /* At least one single char sets the bit and stops */++      case OP_EXACT:+      tcode += IMM2_SIZE;+      /* Fall through */+      case OP_CHAR:+      case OP_PLUS:+      case OP_MINPLUS:+      case OP_POSPLUS:+      (void)set_table_bit(re, tcode + 1, FALSE, utf, ucp);+      try_next = FALSE;+      break;++      case OP_EXACTI:+      tcode += IMM2_SIZE;+      /* Fall through */+      case OP_CHARI:+      case OP_PLUSI:+      case OP_MINPLUSI:+      case OP_POSPLUSI:+      (void)set_table_bit(re, tcode + 1, TRUE, utf, ucp);+      try_next = FALSE;+      break;++      /* Special spacing and line-terminating items. These recognize specific+      lists of characters. The difference between VSPACE and ANYNL is that the+      latter can match the two-character CRLF sequence, but that is not+      relevant for finding the first character, so their code here is+      identical. */++      case OP_HSPACE:+      SET_BIT(CHAR_HT);+      SET_BIT(CHAR_SPACE);++      /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set+      the bits for 0xA0 and for code units >= 255, independently of UTF. */++#if PCRE2_CODE_UNIT_WIDTH != 8+      SET_BIT(0xA0);+      SET_BIT(0xFF);+#else+      /* For the 8-bit library in UTF-8 mode, set the bits for the first code+      units of horizontal space characters. */++#ifdef SUPPORT_UNICODE+      if (utf)+        {+        SET_BIT(0xC2);  /* For U+00A0 */+        SET_BIT(0xE1);  /* For U+1680, U+180E */+        SET_BIT(0xE2);  /* For U+2000 - U+200A, U+202F, U+205F */+        SET_BIT(0xE3);  /* For U+3000 */+        }+      else+#endif+      /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless+      the code is EBCDIC. */+        {+#ifndef EBCDIC+        SET_BIT(0xA0);+#endif  /* Not EBCDIC */+        }+#endif  /* 8-bit support */++      try_next = FALSE;+      break;++      case OP_ANYNL:+      case OP_VSPACE:+      SET_BIT(CHAR_LF);+      SET_BIT(CHAR_VT);+      SET_BIT(CHAR_FF);+      SET_BIT(CHAR_CR);++      /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set+      the bits for NEL and for code units >= 255, independently of UTF. */++#if PCRE2_CODE_UNIT_WIDTH != 8+      SET_BIT(CHAR_NEL);+      SET_BIT(0xFF);+#else+      /* For the 8-bit library in UTF-8 mode, set the bits for the first code+      units of vertical space characters. */++#ifdef SUPPORT_UNICODE+      if (utf)+        {+        SET_BIT(0xC2);  /* For U+0085 (NEL) */+        SET_BIT(0xE2);  /* For U+2028, U+2029 */+        }+      else+#endif+      /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */+        {+        SET_BIT(CHAR_NEL);+        }+#endif  /* 8-bit support */++      try_next = FALSE;+      break;++      /* Single character types set the bits and stop. Note that if PCRE2_UCP+      is set, we do not see these opcodes because \d etc are converted to+      properties. Therefore, these apply in the case when only characters less+      than 256 are recognized to match the types. */++      case OP_NOT_DIGIT:+      set_nottype_bits(re, cbit_digit, table_limit);+      try_next = FALSE;+      break;++      case OP_DIGIT:+      set_type_bits(re, cbit_digit, table_limit);+      try_next = FALSE;+      break;++      case OP_NOT_WHITESPACE:+      set_nottype_bits(re, cbit_space, table_limit);+      try_next = FALSE;+      break;++      case OP_WHITESPACE:+      set_type_bits(re, cbit_space, table_limit);+      try_next = FALSE;+      break;++      case OP_NOT_WORDCHAR:+      set_nottype_bits(re, cbit_word, table_limit);+      try_next = FALSE;+      break;++      case OP_WORDCHAR:+      set_type_bits(re, cbit_word, table_limit);+      try_next = FALSE;+      break;++      /* One or more character type fudges the pointer and restarts, knowing+      it will hit a single character type and stop there. */++      case OP_TYPEPLUS:+      case OP_TYPEMINPLUS:+      case OP_TYPEPOSPLUS:+      tcode++;+      break;++      case OP_TYPEEXACT:+      tcode += 1 + IMM2_SIZE;+      break;++      /* Zero or more repeats of character types set the bits and then+      try again. */++      case OP_TYPEUPTO:+      case OP_TYPEMINUPTO:+      case OP_TYPEPOSUPTO:+      tcode += IMM2_SIZE;  /* Fall through */++      case OP_TYPESTAR:+      case OP_TYPEMINSTAR:+      case OP_TYPEPOSSTAR:+      case OP_TYPEQUERY:+      case OP_TYPEMINQUERY:+      case OP_TYPEPOSQUERY:+      switch(tcode[1])+        {+        default:+        case OP_ANY:+        case OP_ALLANY:+        return SSB_FAIL;++        case OP_HSPACE:+        SET_BIT(CHAR_HT);+        SET_BIT(CHAR_SPACE);++        /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set+        the bits for 0xA0 and for code units >= 255, independently of UTF. */++#if PCRE2_CODE_UNIT_WIDTH != 8+        SET_BIT(0xA0);+        SET_BIT(0xFF);+#else+        /* For the 8-bit library in UTF-8 mode, set the bits for the first code+        units of horizontal space characters. */++#ifdef SUPPORT_UNICODE+        if (utf)+          {+          SET_BIT(0xC2);  /* For U+00A0 */+          SET_BIT(0xE1);  /* For U+1680, U+180E */+          SET_BIT(0xE2);  /* For U+2000 - U+200A, U+202F, U+205F */+          SET_BIT(0xE3);  /* For U+3000 */+          }+        else+#endif+        /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless+        the code is EBCDIC. */+          {+#ifndef EBCDIC+          SET_BIT(0xA0);+#endif  /* Not EBCDIC */+          }+#endif  /* 8-bit support */+        break;++        case OP_ANYNL:+        case OP_VSPACE:+        SET_BIT(CHAR_LF);+        SET_BIT(CHAR_VT);+        SET_BIT(CHAR_FF);+        SET_BIT(CHAR_CR);++        /* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set+        the bits for NEL and for code units >= 255, independently of UTF. */++#if PCRE2_CODE_UNIT_WIDTH != 8+        SET_BIT(CHAR_NEL);+        SET_BIT(0xFF);+#else+        /* For the 8-bit library in UTF-8 mode, set the bits for the first code+        units of vertical space characters. */++#ifdef SUPPORT_UNICODE+        if (utf)+          {+          SET_BIT(0xC2);  /* For U+0085 (NEL) */+          SET_BIT(0xE2);  /* For U+2028, U+2029 */+          }+        else+#endif+        /* For the 8-bit library not in UTF-8 mode, set the bit for NEL. */+          {+          SET_BIT(CHAR_NEL);+          }+#endif  /* 8-bit support */+        break;++        case OP_NOT_DIGIT:+        set_nottype_bits(re, cbit_digit, table_limit);+        break;++        case OP_DIGIT:+        set_type_bits(re, cbit_digit, table_limit);+        break;++        case OP_NOT_WHITESPACE:+        set_nottype_bits(re, cbit_space, table_limit);+        break;++        case OP_WHITESPACE:+        set_type_bits(re, cbit_space, table_limit);+        break;++        case OP_NOT_WORDCHAR:+        set_nottype_bits(re, cbit_word, table_limit);+        break;++        case OP_WORDCHAR:+        set_type_bits(re, cbit_word, table_limit);+        break;+        }++      tcode += 2;+      break;++      /* Extended class: if there are any property checks, or if this is a+      negative XCLASS without a map, give up. If there are no property checks,+      there must be wide characters on the XCLASS list, because otherwise an+      XCLASS would not have been created. This means that code points >= 255+      are potential starters. In the UTF-8 case we can scan them and set bits+      for the relevant leading bytes. */++#ifdef SUPPORT_WIDE_CHARS+      case OP_XCLASS:+      xclassflags = tcode[1 + LINK_SIZE];+      if ((xclassflags & XCL_HASPROP) != 0 ||+          (xclassflags & (XCL_MAP|XCL_NOT)) == XCL_NOT)+        return SSB_FAIL;++      /* We have a positive XCLASS or a negative one without a map. Set up the+      map pointer if there is one, and fall through. */++      classmap = ((xclassflags & XCL_MAP) == 0)? NULL :+        (uint8_t *)(tcode + 1 + LINK_SIZE + 1);++      /* In UTF-8 mode, scan the character list and set bits for leading bytes,+      then jump to handle the map. */++#if PCRE2_CODE_UNIT_WIDTH == 8+      if (utf && (xclassflags & XCL_NOT) == 0)+        {+        PCRE2_UCHAR b, e;+        PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32);+        tcode += GET(tcode, 1);++        for (;;) switch (*p++)+          {+          case XCL_SINGLE:+          b = *p++;+          while ((*p & 0xc0) == 0x80) p++;+          re->start_bitmap[b/8] |= (1u << (b&7));+          break;++          case XCL_RANGE:+          b = *p++;+          while ((*p & 0xc0) == 0x80) p++;+          e = *p++;+          while ((*p & 0xc0) == 0x80) p++;+          for (; b <= e; b++)+            re->start_bitmap[b/8] |= (1u << (b&7));+          break;++          case XCL_END:+          goto HANDLE_CLASSMAP;++          default:+          return SSB_UNKNOWN;   /* Internal error, should not occur */+          }+        }+#endif  /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */+#endif  /* SUPPORT_WIDE_CHARS */++      /* 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+      because it starts a character with a value > 255. In 8-bit non-UTF mode,+      there is no difference between CLASS and NCLASS. In all other wide+      character modes, set the 0xFF bit to indicate code units >= 255. */++      case OP_NCLASS:+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+      if (utf)+        {+        re->start_bitmap[24] |= 0xf0;            /* Bits for 0xc4 - 0xc8 */+        memset(re->start_bitmap+25, 0xff, 7);    /* Bits for 0xc9 - 0xff */+        }+#elif PCRE2_CODE_UNIT_WIDTH != 8+      SET_BIT(0xFF);                             /* For characters >= 255 */+#endif+      /* Fall through */++      /* Enter here for a positive non-XCLASS. If we have fallen through from+      an XCLASS, classmap will already be set; just advance the code pointer.+      Otherwise, set up classmap for a a non-XCLASS and advance past it. */++      case OP_CLASS:+      if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else+        {+        classmap = (uint8_t *)(++tcode);+        tcode += 32 / sizeof(PCRE2_UCHAR);+        }++      /* When wide characters are supported, classmap may be NULL. In UTF-8+      (sic) mode, the bits in a class bit map correspond to character values,+      not to byte values. However, the bit map we are constructing is for byte+      values. So we have to do a conversion for characters whose code point is+      greater than 127. In fact, there are only two possible starting bytes for+      characters in the range 128 - 255. */++#if defined SUPPORT_WIDE_CHARS && PCRE2_CODE_UNIT_WIDTH == 8+      HANDLE_CLASSMAP:+#endif+      if (classmap != NULL)+        {+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8+        if (utf)+          {+          for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c];+          for (c = 128; c < 256; c++)+            {+            if ((classmap[c/8] & (1u << (c&7))) != 0)+              {+              int d = (c >> 6) | 0xc0;                 /* Set bit for this starter */+              re->start_bitmap[d/8] |= (1u << (d&7));  /* and then skip on to the */+              c = (c & 0xc0) + 0x40 - 1;               /* next relevant character. */+              }+            }+          }+        else+#endif+        /* In all modes except UTF-8, the two bit maps are compatible. */++          {+          for (c = 0; c < 32; c++) re->start_bitmap[c] |= classmap[c];+          }+        }++      /* Act on what follows the class. For a zero minimum repeat, continue;+      otherwise stop processing. */++      switch (*tcode)+        {+        case OP_CRSTAR:+        case OP_CRMINSTAR:+        case OP_CRQUERY:+        case OP_CRMINQUERY:+        case OP_CRPOSSTAR:+        case OP_CRPOSQUERY:+        tcode++;+        break;++        case OP_CRRANGE:+        case OP_CRMINRANGE:+        case OP_CRPOSRANGE:+        if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;+          else try_next = FALSE;+        break;++        default:+        try_next = FALSE;+        break;+        }+      break; /* End of class handling case */+      }      /* End of switch for opcodes */+    }        /* End of try_next loop */++  code += GET(code, 1);   /* Advance to next branch */+  }+while (*code == OP_ALT);++return yield;+}++++/*************************************************+*          Study a compiled expression           *+*************************************************/++/* This function is handed a compiled expression that it must study to produce+information that will speed up the matching.++Argument:+  re       points to the compiled expression++Returns:   0 normally; non-zero should never normally occur+           1 unknown opcode in set_start_bits+           2 missing capturing bracket+           3 unknown opcode in find_minlength+*/++int+PRIV(study)(pcre2_real_code *re)+{+int count = 0;+PCRE2_UCHAR *code;+BOOL utf = (re->overall_options & PCRE2_UTF) != 0;+BOOL ucp = (re->overall_options & PCRE2_UCP) != 0;++/* Find start of compiled code */++code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) ++  re->name_entry_size * re->name_count;++/* 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->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)+  {+  int depth = 0;+  int rc = set_start_bits(re, code, utf, ucp, &depth);+  if (rc == SSB_UNKNOWN) return 1;++  /* If a list of starting code units was set up, scan the list to see if only+  one or two were listed. Having only one listed is rare because usually a+  single starting code unit will have been recognized and PCRE2_FIRSTSET set.+  If two are listed, see if they are caseless versions of the same character;+  if so we can replace the list with a caseless first code unit. This gives+  better performance and is plausibly worth doing for patterns such as [Ww]ord+  or (word|WORD). */++  if (rc == SSB_DONE)+    {+    int i;+    int a = -1;+    int b = -1;+    uint8_t *p = re->start_bitmap;+    uint32_t flags = PCRE2_FIRSTMAPSET;++    for (i = 0; i < 256; p++, i += 8)+      {+      uint8_t x = *p;+      if (x != 0)+        {+        int c;+        uint8_t y = x & (~x + 1);   /* Least significant bit */+        if (y != x) goto DONE;      /* More than one bit set */++        /* In the 16-bit and 32-bit libraries, the bit for 0xff means "0xff and+        all wide characters", so we cannot use it here. */++#if PCRE2_CODE_UNIT_WIDTH != 8+        if (i == 248 && x == 0x80) goto DONE;+#endif++        /* Compute the character value */++        c = i;+        switch (x)+          {+          case 1:   break;+          case 2:   c += 1; break;  case 4:  c += 2; break;+          case 8:   c += 3; break;  case 16: c += 4; break;+          case 32:  c += 5; break;  case 64: c += 6; break;+          case 128: c += 7; break;+          }++        /* c contains the code unit value, in the range 0-255. In 8-bit UTF+        mode, only values < 128 can be used. In all the other cases, c is a+        character value. */++#if PCRE2_CODE_UNIT_WIDTH == 8+        if (utf && c > 127) goto DONE;+#endif+        if (a < 0) a = c;   /* First one found, save in a */+        else if (b < 0)     /* Second one found */+          {+          int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c);++#ifdef SUPPORT_UNICODE+          if (utf || ucp)+            {+            if (UCD_CASESET(c) != 0) goto DONE;     /* Multiple case set */+            if (c > 127) d = UCD_OTHERCASE(c);+            }+#endif  /* SUPPORT_UNICODE */++          if (d != a) goto DONE;   /* Not the other case of a */+          b = c;                   /* Save second in b */+          }+        else goto DONE;   /* More than two characters found */+        }+      }++    /* Replace the start code unit bits with a first code unit, but only if it+    is not the same as a required later code unit. This is because a search for+    a required code unit starts after an explicit first code unit, but at a+    code unit found from the bitmap. Patterns such as /a*a/ don't work+    if both the start unit and required unit are the same. */++    if (a >= 0 &&+        (+        (re->flags & PCRE2_LASTSET) == 0 ||+          (+          re->last_codeunit != (uint32_t)a &&+          (b < 0 || re->last_codeunit != (uint32_t)b)+          )+        ))+      {+      re->first_codeunit = a;+      flags = PCRE2_FIRSTSET;+      if (b >= 0) flags |= PCRE2_FIRSTCASELESS;+      }++    DONE:+    re->flags |= flags;+    }+  }++/* Find the minimum length of subject string. If the pattern can match an empty+string, the minimum length is already known. If the pattern contains (*ACCEPT)+all bets are off, and we don't even try to find a minimum length. 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|PCRE2_HASACCEPT)) == 0 &&+     re->top_backref <= MAX_CACHE_BACKREF)+  {+  int min;+  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 over-complex regex */+    break;    /* Leave minlength unchanged (will be zero) */++    case -2:+    return 2; /* missing capturing bracket */++    case -3:+    return 3; /* unrecognized opcode */++    default:+    re->minlength = (min > UINT16_MAX)? UINT16_MAX : min;+    break;+    }+  }++return 0;+}++/* End of pcre2_study.c */
+ src/c/pcre2/src/pcre2_substitute.c view
@@ -0,0 +1,987 @@+/*************************************************+*      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-2020 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 PTR_STACK_SIZE 20++#define SUBSTITUTE_OPTIONS \+  (PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \+   PCRE2_SUBSTITUTE_LITERAL|PCRE2_SUBSTITUTE_MATCHED| \+   PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_REPLACEMENT_ONLY| \+   PCRE2_SUBSTITUTE_UNKNOWN_UNSET|PCRE2_SUBSTITUTE_UNSET_EMPTY)++++/*************************************************+*           Find end of substitute text          *+*************************************************/++/* In extended mode, we recognize ${name:+set text:unset text} and similar+constructions. This requires the identification of unescaped : and }+characters. This function scans for such. It must deal with nested ${+constructions. The pointer to the text is updated, either to the required end+character, or to where an error was detected.++Arguments:+  code      points to the compiled expression (for options)+  ptrptr    points to the pointer to the start of the text (updated)+  ptrend    end of the whole string+  last      TRUE if the last expected string (only } recognized)++Returns:    0 on success+            negative error code on failure+*/++static int+find_text_end(const pcre2_code *code, PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend,+  BOOL last)+{+int rc = 0;+uint32_t nestlevel = 0;+BOOL literal = FALSE;+PCRE2_SPTR ptr = *ptrptr;++for (; ptr < ptrend; ptr++)+  {+  if (literal)+    {+    if (ptr[0] == CHAR_BACKSLASH && ptr < ptrend - 1 && ptr[1] == CHAR_E)+      {+      literal = FALSE;+      ptr += 1;+      }+    }++  else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)+    {+    if (nestlevel == 0) goto EXIT;+    nestlevel--;+    }++  else if (*ptr == CHAR_COLON && !last && nestlevel == 0) goto EXIT;++  else if (*ptr == CHAR_DOLLAR_SIGN)+    {+    if (ptr < ptrend - 1 && ptr[1] == CHAR_LEFT_CURLY_BRACKET)+      {+      nestlevel++;+      ptr += 1;+      }+    }++  else if (*ptr == CHAR_BACKSLASH)+    {+    int erc;+    int errorcode;+    uint32_t ch;++    if (ptr < ptrend - 1) switch (ptr[1])+      {+      case CHAR_L:+      case CHAR_l:+      case CHAR_U:+      case CHAR_u:+      ptr += 1;+      continue;+      }++    ptr += 1;  /* Must point after \ */+    erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode,+      code->overall_options, code->extra_options, FALSE, NULL);+    ptr -= 1;  /* Back to last code unit of escape */+    if (errorcode != 0)+      {+      rc = errorcode;+      goto EXIT;+      }++    switch(erc)+      {+      case 0:      /* Data character */+      case ESC_E:  /* Isolated \E is ignored */+      break;++      case ESC_Q:+      literal = TRUE;+      break;++      default:+      rc = PCRE2_ERROR_BADREPESCAPE;+      goto EXIT;+      }+    }+  }++rc = PCRE2_ERROR_REPMISSINGBRACE;   /* Terminator not found */++EXIT:+*ptrptr = ptr;+return rc;+}++++/*************************************************+*              Match and substitute              *+*************************************************/++/* This function applies a compiled re to a subject string and creates a new+string with substitutions. The first 7 arguments are the same as for+pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED.++Arguments:+  code            points to the compiled expression+  subject         points to the subject string+  length          length of subject string (may contain binary zeros)+  start_offset    where to start in the subject string+  options         option bits+  match_data      points to a match_data block, or is NULL+  context         points a PCRE2 context+  replacement     points to the replacement string+  rlength         length of replacement string+  buffer          where to put the substituted string+  blength         points to length of buffer; updated to length of string++Returns:          >= 0 number of substitutions made+                  < 0 an error code+                  PCRE2_ERROR_BADREPLACEMENT means invalid use of $+*/++/* This macro checks for space in the buffer before copying into it. On+overflow, either give an error immediately, or keep on, accumulating the+length. */++#define CHECKMEMCPY(from,length) \+  { \+  if (!overflowed && lengthleft < length) \+    { \+    if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \+    overflowed = TRUE; \+    extra_needed = length - lengthleft; \+    } \+  else if (overflowed) \+    { \+    extra_needed += length; \+    }  \+  else \+    {  \+    memcpy(buffer + buff_offset, from, CU2BYTES(length)); \+    buff_offset += length; \+    lengthleft -= length; \+    } \+  }++/* Here's the function */++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substitute(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, PCRE2_SPTR replacement, PCRE2_SIZE rlength,+  PCRE2_UCHAR *buffer, PCRE2_SIZE *blength)+{+int rc;+int subs;+int forcecase = 0;+int forcecasereset = 0;+uint32_t ovector_count;+uint32_t goptions = 0;+uint32_t suboptions;+pcre2_match_data *internal_match_data = NULL;+BOOL escaped_literal = FALSE;+BOOL overflowed = FALSE;+BOOL use_existing_match;+BOOL replacement_only;+#ifdef SUPPORT_UNICODE+BOOL utf = (code->overall_options & PCRE2_UTF) != 0;+BOOL ucp = (code->overall_options & PCRE2_UCP) != 0;+#endif+PCRE2_UCHAR temp[6];+PCRE2_SPTR ptr;+PCRE2_SPTR repend;+PCRE2_SIZE extra_needed = 0;+PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength;+PCRE2_SIZE *ovector;+PCRE2_SIZE ovecsave[3];+pcre2_substitute_callout_block scb;++/* General initialization */++buff_offset = 0;+lengthleft = buff_length = *blength;+*blength = PCRE2_UNSET;+ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;++/* Partial matching is not valid. This must come after setting *blength to+PCRE2_UNSET, so as not to imply an offset in the replacement. */++if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)+  return PCRE2_ERROR_BADOPTION;++/* Check for using a match that has already happened. Note that the subject+pointer in the match data may be NULL after a no-match. */++use_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0);+replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0);++/* If starting from an existing match, there must be an externally provided+match data block. We create an internal match_data block in two cases: (a) an+external one is not supplied (and we are not starting from an existing match);+(b) an existing match is to be used for the first substitution. In the latter+case, we copy the existing match into the internal block. This ensures that no+changes are made to the existing match data block. */++if (match_data == NULL)+  {+  pcre2_general_context *gcontext;+  if (use_existing_match) return PCRE2_ERROR_NULL;+  gcontext = (mcontext == NULL)?+    (pcre2_general_context *)code :+    (pcre2_general_context *)mcontext;+  match_data = internal_match_data =+    pcre2_match_data_create_from_pattern(code, gcontext);+  if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;+  }++else if (use_existing_match)+  {+  pcre2_general_context *gcontext = (mcontext == NULL)?+    (pcre2_general_context *)code :+    (pcre2_general_context *)mcontext;+  int pairs = (code->top_bracket + 1 < match_data->oveccount)?+    code->top_bracket + 1 : match_data->oveccount;+  internal_match_data = pcre2_match_data_create(match_data->oveccount,+    gcontext);+  if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;+  memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector)+    + 2*pairs*sizeof(PCRE2_SIZE));+  match_data = internal_match_data;+  }++/* Remember ovector details */++ovector = pcre2_get_ovector_pointer(match_data);+ovector_count = pcre2_get_ovector_count(match_data);++/* Fixed things in the callout block */++scb.version = 0;+scb.input = subject;+scb.output = (PCRE2_SPTR)buffer;+scb.ovector = ovector;++/* Find lengths of zero-terminated strings and the end of the replacement. */++if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);+if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement);+repend = replacement + rlength;++/* Check UTF replacement string if necessary. */++#ifdef SUPPORT_UNICODE+if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)+  {+  rc = PRIV(valid_utf)(replacement, rlength, &(match_data->startchar));+  if (rc != 0)+    {+    match_data->leftchar = 0;+    goto EXIT;+    }+  }+#endif  /* SUPPORT_UNICODE */++/* Save the substitute options and remove them from the match options. */++suboptions = options & SUBSTITUTE_OPTIONS;+options &= ~SUBSTITUTE_OPTIONS;++/* Error if the start match offset is greater than the length of the subject. */++if (start_offset > length)+  {+  match_data->leftchar = 0;+  rc = PCRE2_ERROR_BADOFFSET;+  goto EXIT;+  }++/* Copy up to the start offset, unless only the replacement is required. */++if (!replacement_only) CHECKMEMCPY(subject, start_offset);++/* Loop for global substituting. If PCRE2_SUBSTITUTE_MATCHED is set, the first+match is taken from the match_data that was passed in. */++subs = 0;+do+  {+  PCRE2_SPTR ptrstack[PTR_STACK_SIZE];+  uint32_t ptrstackptr = 0;++  if (use_existing_match)+    {+    rc = match_data->rc;+    use_existing_match = FALSE;+    }+  else rc = pcre2_match(code, subject, length, start_offset, options|goptions,+    match_data, mcontext);++#ifdef SUPPORT_UNICODE+  if (utf) options |= PCRE2_NO_UTF_CHECK;  /* Only need to check once */+#endif++  /* Any error other than no match returns the error code. No match when not+  doing the special after-empty-match global rematch, or when at the end of the+  subject, breaks the global loop. Otherwise, advance the starting point by one+  character, copying it to the output, and try again. */++  if (rc < 0)+    {+    PCRE2_SIZE save_start;++    if (rc != PCRE2_ERROR_NOMATCH) goto EXIT;+    if (goptions == 0 || start_offset >= length) break;++    /* Advance by one code point. Then, if CRLF is a valid newline sequence and+    we have advanced into the middle of it, advance one more code point. In+    other words, do not start in the middle of CRLF, even if CR and LF on their+    own are valid newlines. */++    save_start = start_offset++;+    if (subject[start_offset-1] == CHAR_CR &&+        code->newline_convention != PCRE2_NEWLINE_CR &&+        code->newline_convention != PCRE2_NEWLINE_LF &&+        start_offset < length &&+        subject[start_offset] == CHAR_LF)+      start_offset++;++    /* Otherwise, in UTF mode, advance past any secondary code points. */++    else if ((code->overall_options & PCRE2_UTF) != 0)+      {+#if PCRE2_CODE_UNIT_WIDTH == 8+      while (start_offset < length && (subject[start_offset] & 0xc0) == 0x80)+        start_offset++;+#elif PCRE2_CODE_UNIT_WIDTH == 16+      while (start_offset < length &&+            (subject[start_offset] & 0xfc00) == 0xdc00)+        start_offset++;+#endif+      }++    /* Copy what we have advanced past (unless not required), reset the special+    global options, and continue to the next match. */++    fraglength = start_offset - save_start;+    if (!replacement_only) CHECKMEMCPY(subject + save_start, fraglength);+    goptions = 0;+    continue;+    }++  /* Handle a successful match. Matches that use \K to end before they start+  or start before the current point in the subject are not supported. */++  if (ovector[1] < ovector[0] || ovector[0] < start_offset)+    {+    rc = PCRE2_ERROR_BADSUBSPATTERN;+    goto EXIT;+    }++  /* Check for the same match as previous. This is legitimate after matching an+  empty string that starts after the initial match offset. We have tried again+  at the match point in case the pattern is one like /(?<=\G.)/ which can never+  match at its starting point, so running the match achieves the bumpalong. If+  we do get the same (null) match at the original match point, it isn't such a+  pattern, so we now do the empty string magic. In all other cases, a repeat+  match should never occur. */++  if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])+    {+    if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)+      {+      goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;+      ovecsave[2] = start_offset;+      continue;    /* Back to the top of the loop */+      }+    rc = PCRE2_ERROR_INTERNAL_DUPMATCH;+    goto EXIT;+    }++  /* Count substitutions with a paranoid check for integer overflow; surely no+  real call to this function would ever hit this! */++  if (subs == INT_MAX)+    {+    rc = PCRE2_ERROR_TOOMANYREPLACE;+    goto EXIT;+    }+  subs++;++  /* Copy the text leading up to the match (unless not required), and remember+  where the insert begins and how many ovector pairs are set. */++  if (rc == 0) rc = ovector_count;+  fraglength = ovector[0] - start_offset;+  if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength);+  scb.output_offsets[0] = buff_offset;+  scb.oveccount = rc;++  /* Process the replacement string. If the entire replacement is literal, just+  copy it with length check. */++  ptr = replacement;+  if ((suboptions & PCRE2_SUBSTITUTE_LITERAL) != 0)+    {+    CHECKMEMCPY(ptr, rlength);+    }++  /* Within a non-literal replacement, which must be scanned character by+  character, local literal mode can be set by \Q, but only in extended mode+  when backslashes are being interpreted. In extended mode we must handle+  nested substrings that are to be reprocessed. */++  else for (;;)+    {+    uint32_t ch;+    unsigned int chlen;++    /* If at the end of a nested substring, pop the stack. */++    if (ptr >= repend)+      {+      if (ptrstackptr == 0) break;       /* End of replacement string */+      repend = ptrstack[--ptrstackptr];+      ptr = ptrstack[--ptrstackptr];+      continue;+      }++    /* Handle the next character */++    if (escaped_literal)+      {+      if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E)+        {+        escaped_literal = FALSE;+        ptr += 2;+        continue;+        }+      goto LOADLITERAL;+      }++    /* Not in literal mode. */++    if (*ptr == CHAR_DOLLAR_SIGN)+      {+      int group, n;+      uint32_t special = 0;+      BOOL inparens;+      BOOL star;+      PCRE2_SIZE sublength;+      PCRE2_SPTR text1_start = NULL;+      PCRE2_SPTR text1_end = NULL;+      PCRE2_SPTR text2_start = NULL;+      PCRE2_SPTR text2_end = NULL;+      PCRE2_UCHAR next;+      PCRE2_UCHAR name[33];++      if (++ptr >= repend) goto BAD;+      if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL;++      group = -1;+      n = 0;+      inparens = FALSE;+      star = FALSE;++      if (next == CHAR_LEFT_CURLY_BRACKET)+        {+        if (++ptr >= repend) goto BAD;+        next = *ptr;+        inparens = TRUE;+        }++      if (next == CHAR_ASTERISK)+        {+        if (++ptr >= repend) goto BAD;+        next = *ptr;+        star = TRUE;+        }++      if (!star && next >= CHAR_0 && next <= CHAR_9)+        {+        group = next - CHAR_0;+        while (++ptr < repend)+          {+          next = *ptr;+          if (next < CHAR_0 || next > CHAR_9) break;+          group = group * 10 + next - CHAR_0;++          /* A check for a number greater than the hightest captured group+          is sufficient here; no need for a separate overflow check. If unknown+          groups are to be treated as unset, just skip over any remaining+          digits and carry on. */++          if (group > code->top_bracket)+            {+            if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)+              {+              while (++ptr < repend && *ptr >= CHAR_0 && *ptr <= CHAR_9);+              break;+              }+            else+              {+              rc = PCRE2_ERROR_NOSUBSTRING;+              goto PTREXIT;+              }+            }+          }+        }+      else+        {+        const uint8_t *ctypes = code->tables + ctypes_offset;+        while (MAX_255(next) && (ctypes[next] & ctype_word) != 0)+          {+          name[n++] = next;+          if (n > 32) goto BAD;+          if (++ptr >= repend) break;+          next = *ptr;+          }+        if (n == 0) goto BAD;+        name[n] = 0;+        }++      /* In extended mode we recognize ${name:+set text:unset text} and+      ${name:-default text}. */++      if (inparens)+        {+        if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&+             !star && ptr < repend - 2 && next == CHAR_COLON)+          {+          special = *(++ptr);+          if (special != CHAR_PLUS && special != CHAR_MINUS)+            {+            rc = PCRE2_ERROR_BADSUBSTITUTION;+            goto PTREXIT;+            }++          text1_start = ++ptr;+          rc = find_text_end(code, &ptr, repend, special == CHAR_MINUS);+          if (rc != 0) goto PTREXIT;+          text1_end = ptr;++          if (special == CHAR_PLUS && *ptr == CHAR_COLON)+            {+            text2_start = ++ptr;+            rc = find_text_end(code, &ptr, repend, TRUE);+            if (rc != 0) goto PTREXIT;+            text2_end = ptr;+            }+          }++        else+          {+          if (ptr >= repend || *ptr != CHAR_RIGHT_CURLY_BRACKET)+            {+            rc = PCRE2_ERROR_REPMISSINGBRACE;+            goto PTREXIT;+            }+          }++        ptr++;+        }++      /* Have found a syntactically correct group number or name, or *name.+      Only *MARK is currently recognized. */++      if (star)+        {+        if (PRIV(strcmp_c8)(name, STRING_MARK) == 0)+          {+          PCRE2_SPTR mark = pcre2_get_mark(match_data);+          if (mark != NULL)+            {+            PCRE2_SPTR mark_start = mark;+            while (*mark != 0) mark++;+            fraglength = mark - mark_start;+            CHECKMEMCPY(mark_start, fraglength);+            }+          }+        else goto BAD;+        }++      /* Substitute the contents of a group. We don't use substring_copy+      functions any more, in order to support case forcing. */++      else+        {+        PCRE2_SPTR subptr, subptrend;++        /* Find a number for a named group. In case there are duplicate names,+        search for the first one that is set. If the name is not found when+        PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a+        non-existent group. */++        if (group < 0)+          {+          PCRE2_SPTR first, last, entry;+          rc = pcre2_substring_nametable_scan(code, name, &first, &last);+          if (rc == PCRE2_ERROR_NOSUBSTRING &&+              (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)+            {+            group = code->top_bracket + 1;+            }+          else+            {+            if (rc < 0) goto PTREXIT;+            for (entry = first; entry <= last; entry += rc)+              {+              uint32_t ng = GET2(entry, 0);+              if (ng < ovector_count)+                {+                if (group < 0) group = ng;          /* First in ovector */+                if (ovector[ng*2] != PCRE2_UNSET)+                  {+                  group = ng;                       /* First that is set */+                  break;+                  }+                }+              }++            /* If group is still negative, it means we did not find a group+            that is in the ovector. Just set the first group. */++            if (group < 0) group = GET2(first, 0);+            }+          }++        /* We now have a group that is identified by number. Find the length of+        the captured string. If a group in a non-special substitution is unset+        when PCRE2_SUBSTITUTE_UNSET_EMPTY is set, substitute nothing. */++        rc = pcre2_substring_length_bynumber(match_data, group, &sublength);+        if (rc < 0)+          {+          if (rc == PCRE2_ERROR_NOSUBSTRING &&+              (suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) != 0)+            {+            rc = PCRE2_ERROR_UNSET;+            }+          if (rc != PCRE2_ERROR_UNSET) goto PTREXIT;  /* Non-unset errors */+          if (special == 0)                           /* Plain substitution */+            {+            if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue;+            goto PTREXIT;                             /* Else error */+            }+          }++        /* If special is '+' we have a 'set' and possibly an 'unset' text,+        both of which are reprocessed when used. If special is '-' we have a+        default text for when the group is unset; it must be reprocessed. */++        if (special != 0)+          {+          if (special == CHAR_MINUS)+            {+            if (rc == 0) goto LITERAL_SUBSTITUTE;+            text2_start = text1_start;+            text2_end = text1_end;+            }++          if (ptrstackptr >= PTR_STACK_SIZE) goto BAD;+          ptrstack[ptrstackptr++] = ptr;+          ptrstack[ptrstackptr++] = repend;++          if (rc == 0)+            {+            ptr = text1_start;+            repend = text1_end;+            }+          else+            {+            ptr = text2_start;+            repend = text2_end;+            }+          continue;+          }++        /* Otherwise we have a literal substitution of a group's contents. */++        LITERAL_SUBSTITUTE:+        subptr = subject + ovector[group*2];+        subptrend = subject + ovector[group*2 + 1];++        /* Substitute a literal string, possibly forcing alphabetic case. */++        while (subptr < subptrend)+          {+          GETCHARINCTEST(ch, subptr);+          if (forcecase != 0)+            {+#ifdef SUPPORT_UNICODE+            if (utf || ucp)+              {+              uint32_t type = UCD_CHARTYPE(ch);+              if (PRIV(ucp_gentype)[type] == ucp_L &&+                  type != ((forcecase > 0)? ucp_Lu : ucp_Ll))+                ch = UCD_OTHERCASE(ch);+              }+            else+#endif+              {+              if (((code->tables + cbits_offset ++                  ((forcecase > 0)? cbit_upper:cbit_lower)+                  )[ch/8] & (1u << (ch%8))) == 0)+                ch = (code->tables + fcc_offset)[ch];+              }+            forcecase = forcecasereset;+            }++#ifdef SUPPORT_UNICODE+          if (utf) chlen = PRIV(ord2utf)(ch, temp); else+#endif+            {+            temp[0] = ch;+            chlen = 1;+            }+          CHECKMEMCPY(temp, chlen);+          }+        }+      }++    /* Handle an escape sequence in extended mode. We can use check_escape()+    to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but+    the case-forcing escapes are not supported in pcre2_compile() so must be+    recognized here. */++    else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&+              *ptr == CHAR_BACKSLASH)+      {+      int errorcode;++      if (ptr < repend - 1) switch (ptr[1])+        {+        case CHAR_L:+        forcecase = forcecasereset = -1;+        ptr += 2;+        continue;++        case CHAR_l:+        forcecase = -1;+        forcecasereset = 0;+        ptr += 2;+        continue;++        case CHAR_U:+        forcecase = forcecasereset = 1;+        ptr += 2;+        continue;++        case CHAR_u:+        forcecase = 1;+        forcecasereset = 0;+        ptr += 2;+        continue;++        default:+        break;+        }++      ptr++;  /* Point after \ */+      rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode,+        code->overall_options, code->extra_options, FALSE, NULL);+      if (errorcode != 0) goto BADESCAPE;++      switch(rc)+        {+        case ESC_E:+        forcecase = forcecasereset = 0;+        continue;++        case ESC_Q:+        escaped_literal = TRUE;+        continue;++        case 0:      /* Data character */+        goto LITERAL;++        default:+        goto BADESCAPE;+        }+      }++    /* Handle a literal code unit */++    else+      {+      LOADLITERAL:+      GETCHARINCTEST(ch, ptr);    /* Get character value, increment pointer */++      LITERAL:+      if (forcecase != 0)+        {+#ifdef SUPPORT_UNICODE+        if (utf || ucp)+          {+          uint32_t type = UCD_CHARTYPE(ch);+          if (PRIV(ucp_gentype)[type] == ucp_L &&+              type != ((forcecase > 0)? ucp_Lu : ucp_Ll))+            ch = UCD_OTHERCASE(ch);+          }+        else+#endif+          {+          if (((code->tables + cbits_offset ++              ((forcecase > 0)? cbit_upper:cbit_lower)+              )[ch/8] & (1u << (ch%8))) == 0)+            ch = (code->tables + fcc_offset)[ch];+          }+        forcecase = forcecasereset;+        }++#ifdef SUPPORT_UNICODE+      if (utf) chlen = PRIV(ord2utf)(ch, temp); else+#endif+        {+        temp[0] = ch;+        chlen = 1;+        }+      CHECKMEMCPY(temp, chlen);+      } /* End handling a literal code unit */+    }   /* End of loop for scanning the replacement. */++  /* The replacement has been copied to the output, or its size has been+  remembered. Do the callout if there is one and we have done an actual+  replacement. */++  if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL)+    {+    scb.subscount = subs;+    scb.output_offsets[1] = buff_offset;+    rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data);++    /* A non-zero return means cancel this substitution. Instead, copy the+    matched string fragment. */++    if (rc != 0)+      {+      PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0];+      PCRE2_SIZE oldlength = ovector[1] - ovector[0];++      buff_offset -= newlength;+      lengthleft += newlength;+      if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength);++      /* A negative return means do not do any more. */++      if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL);+      }+    }++  /* Save the details of this match. See above for how this data is used. If we+  matched an empty string, do the magic for global matches. Update the start+  offset to point to the rest of the subject string. If we re-used an existing+  match for the first match, switch to the internal match data block. */++  ovecsave[0] = ovector[0];+  ovecsave[1] = ovector[1];+  ovecsave[2] = start_offset;++  goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 :+    PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;+  start_offset = ovector[1];+  } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0);  /* Repeat "do" loop */++/* Copy the rest of the subject unless not required, and terminate the output+with a binary zero. */++if (!replacement_only)+  {+  fraglength = length - start_offset;+  CHECKMEMCPY(subject + start_offset, fraglength);+  }++temp[0] = 0;+CHECKMEMCPY(temp, 1);++/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set,+and matching has carried on after a full buffer, in order to compute the length+needed. Otherwise, an overflow generates an immediate error return. */++if (overflowed)+  {+  rc = PCRE2_ERROR_NOMEMORY;+  *blength = buff_length + extra_needed;+  }++/* After a successful execution, return the number of substitutions and set the+length of buffer used, excluding the trailing zero. */++else+  {+  rc = subs;+  *blength = buff_offset - 1;+  }++EXIT:+if (internal_match_data != NULL) pcre2_match_data_free(internal_match_data);+  else match_data->rc = rc;+return rc;++NOROOM:+rc = PCRE2_ERROR_NOMEMORY;+goto EXIT;++BAD:+rc = PCRE2_ERROR_BADREPLACEMENT;+goto PTREXIT;++BADESCAPE:+rc = PCRE2_ERROR_BADREPESCAPE;++PTREXIT:+*blength = (PCRE2_SIZE)(ptr - replacement);+goto EXIT;+}++/* End of pcre2_substitute.c */
+ src/c/pcre2/src/pcre2_substring.c view
@@ -0,0 +1,547 @@+/*************************************************+*      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.+-----------------------------------------------------------------------------+*/+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"++++/*************************************************+*   Copy named captured string to given buffer   *+*************************************************/++/* This function copies a single captured substring into a given buffer,+identifying it by name. If the regex permits duplicate names, the first+substring that is set is chosen.++Arguments:+  match_data     points to the match data+  stringname     the name of the required substring+  buffer         where to put the substring+  sizeptr        the size of the buffer, updated to the size of the substring++Returns:         if successful: zero+                 if not successful, a negative error code:+                   (1) an error from nametable_scan()+                   (2) an error from copy_bynumber()+                   (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector+                   (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_copy_byname(pcre2_match_data *match_data, PCRE2_SPTR stringname,+  PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)+{+PCRE2_SPTR first, last, entry;+int failrc, entrysize;+if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)+  return PCRE2_ERROR_DFA_UFUNC;+entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,+  &first, &last);+if (entrysize < 0) return entrysize;+failrc = PCRE2_ERROR_UNAVAILABLE;+for (entry = first; entry <= last; entry += entrysize)+  {+  uint32_t n = GET2(entry, 0);+  if (n < match_data->oveccount)+    {+    if (match_data->ovector[n*2] != PCRE2_UNSET)+      return pcre2_substring_copy_bynumber(match_data, n, buffer, sizeptr);+    failrc = PCRE2_ERROR_UNSET;+    }+  }+return failrc;+}++++/*************************************************+*  Copy numbered captured string to given buffer *+*************************************************/++/* This function copies a single captured substring into a given buffer,+identifying it by number.++Arguments:+  match_data     points to the match data+  stringnumber   the number of the required substring+  buffer         where to put the substring+  sizeptr        the size of the buffer, updated to the size of the substring++Returns:         if successful: 0+                 if not successful, a negative error code:+                   PCRE2_ERROR_NOMEMORY: buffer too small+                   PCRE2_ERROR_NOSUBSTRING: no such substring+                   PCRE2_ERROR_UNAVAILABLE: ovector too small+                   PCRE2_ERROR_UNSET: substring is not set+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_copy_bynumber(pcre2_match_data *match_data,+  uint32_t stringnumber, PCRE2_UCHAR *buffer, PCRE2_SIZE *sizeptr)+{+int rc;+PCRE2_SIZE size;+rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);+if (rc < 0) return rc;+if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY;+memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],+  CU2BYTES(size));+buffer[size] = 0;+*sizeptr = size;+return 0;+}++++/*************************************************+*          Extract named captured string         *+*************************************************/++/* This function copies a single captured substring, identified by name, into+new memory. If the regex permits duplicate names, the first substring that is+set is chosen.++Arguments:+  match_data     pointer to match_data+  stringname     the name of the required substring+  stringptr      where to put the pointer to the new memory+  sizeptr        where to put the length of the substring++Returns:         if successful: zero+                 if not successful, a negative value:+                   (1) an error from nametable_scan()+                   (2) an error from get_bynumber()+                   (3) PCRE2_ERROR_UNAVAILABLE: no group is in ovector+                   (4) PCRE2_ERROR_UNSET: all named groups in ovector are unset+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_get_byname(pcre2_match_data *match_data,+  PCRE2_SPTR stringname, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)+{+PCRE2_SPTR first, last, entry;+int failrc, entrysize;+if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)+  return PCRE2_ERROR_DFA_UFUNC;+entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,+  &first, &last);+if (entrysize < 0) return entrysize;+failrc = PCRE2_ERROR_UNAVAILABLE;+for (entry = first; entry <= last; entry += entrysize)+  {+  uint32_t n = GET2(entry, 0);+  if (n < match_data->oveccount)+    {+    if (match_data->ovector[n*2] != PCRE2_UNSET)+      return pcre2_substring_get_bynumber(match_data, n, stringptr, sizeptr);+    failrc = PCRE2_ERROR_UNSET;+    }+  }+return failrc;+}++++/*************************************************+*      Extract captured string to new memory     *+*************************************************/++/* This function copies a single captured substring into a piece of new+memory.++Arguments:+  match_data     points to match data+  stringnumber   the number of the required substring+  stringptr      where to put a pointer to the new memory+  sizeptr        where to put the size of the substring++Returns:         if successful: 0+                 if not successful, a negative error code:+                   PCRE2_ERROR_NOMEMORY: failed to get memory+                   PCRE2_ERROR_NOSUBSTRING: no such substring+                   PCRE2_ERROR_UNAVAILABLE: ovector too small+                   PCRE2_ERROR_UNSET: substring is not set+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_get_bynumber(pcre2_match_data *match_data,+  uint32_t stringnumber, PCRE2_UCHAR **stringptr, PCRE2_SIZE *sizeptr)+{+int rc;+PCRE2_SIZE size;+PCRE2_UCHAR *yield;+rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);+if (rc < 0) return rc;+yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) ++  (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);+if (yield == NULL) return PCRE2_ERROR_NOMEMORY;+yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));+memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],+  CU2BYTES(size));+yield[size] = 0;+*stringptr = yield;+*sizeptr = size;+return 0;+}++++/*************************************************+*       Free memory obtained by get_substring    *+*************************************************/++/*+Argument:     the result of a previous pcre2_substring_get_byxxx()+Returns:      nothing+*/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_substring_free(PCRE2_UCHAR *string)+{+if (string != NULL)+  {+  pcre2_memctl *memctl = (pcre2_memctl *)((char *)string - sizeof(pcre2_memctl));+  memctl->free(memctl, memctl->memory_data);+  }+}++++/*************************************************+*         Get length of a named substring        *+*************************************************/++/* This function returns the length of a named captured substring. If the regex+permits duplicate names, the first substring that is set is chosen.++Arguments:+  match_data      pointer to match data+  stringname      the name of the required substring+  sizeptr         where to put the length++Returns:          0 if successful, else a negative error number+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_length_byname(pcre2_match_data *match_data,+  PCRE2_SPTR stringname, PCRE2_SIZE *sizeptr)+{+PCRE2_SPTR first, last, entry;+int failrc, entrysize;+if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)+  return PCRE2_ERROR_DFA_UFUNC;+entrysize = pcre2_substring_nametable_scan(match_data->code, stringname,+  &first, &last);+if (entrysize < 0) return entrysize;+failrc = PCRE2_ERROR_UNAVAILABLE;+for (entry = first; entry <= last; entry += entrysize)+  {+  uint32_t n = GET2(entry, 0);+  if (n < match_data->oveccount)+    {+    if (match_data->ovector[n*2] != PCRE2_UNSET)+      return pcre2_substring_length_bynumber(match_data, n, sizeptr);+    failrc = PCRE2_ERROR_UNSET;+    }+  }+return failrc;+}++++/*************************************************+*        Get length of a numbered substring      *+*************************************************/++/* This function returns the length of a captured substring. If the start is+beyond the end (which can happen when \K is used in an assertion), it sets the+length to zero.++Arguments:+  match_data      pointer to match data+  stringnumber    the number of the required substring+  sizeptr         where to put the length, if not NULL++Returns:         if successful: 0+                 if not successful, a negative error code:+                   PCRE2_ERROR_NOSUBSTRING: no such substring+                   PCRE2_ERROR_UNAVAILABLE: ovector is too small+                   PCRE2_ERROR_UNSET: substring is not set+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_length_bynumber(pcre2_match_data *match_data,+  uint32_t stringnumber, PCRE2_SIZE *sizeptr)+{+PCRE2_SIZE left, right;+int count = match_data->rc;+if (count == PCRE2_ERROR_PARTIAL)+  {+  if (stringnumber > 0) return PCRE2_ERROR_PARTIAL;+  count = 0;+  }+else if (count < 0) return count;            /* Match failed */++if (match_data->matchedby != PCRE2_MATCHEDBY_DFA_INTERPRETER)+  {+  if (stringnumber > match_data->code->top_bracket)+    return PCRE2_ERROR_NOSUBSTRING;+  if (stringnumber >= match_data->oveccount)+    return PCRE2_ERROR_UNAVAILABLE;+  if (match_data->ovector[stringnumber*2] == PCRE2_UNSET)+    return PCRE2_ERROR_UNSET;+  }+else  /* Matched using pcre2_dfa_match() */+  {+  if (stringnumber >= match_data->oveccount) return PCRE2_ERROR_UNAVAILABLE;+  if (count != 0 && stringnumber >= (uint32_t)count) return PCRE2_ERROR_UNSET;+  }++left = match_data->ovector[stringnumber*2];+right = match_data->ovector[stringnumber*2+1];+if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;+return 0;+}++++/*************************************************+*    Extract all captured strings to new memory  *+*************************************************/++/* This function gets one chunk of memory and builds a list of pointers and all+the captured substrings in it. A NULL pointer is put on the end of the list.+The substrings are zero-terminated, but also, if the final argument is+non-NULL, a list of lengths is also returned. This allows binary data to be+handled.++Arguments:+  match_data     points to the match data+  listptr        set to point to the list of pointers+  lengthsptr     set to point to the list of lengths (may be NULL)++Returns:         if successful: 0+                 if not successful, a negative error code:+                   PCRE2_ERROR_NOMEMORY: failed to get memory,+                   or a match failure code+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_list_get(pcre2_match_data *match_data, PCRE2_UCHAR ***listptr,+  PCRE2_SIZE **lengthsptr)+{+int i, count, count2;+PCRE2_SIZE size;+PCRE2_SIZE *lensp;+pcre2_memctl *memp;+PCRE2_UCHAR **listp;+PCRE2_UCHAR *sp;+PCRE2_SIZE *ovector;++if ((count = match_data->rc) < 0) return count;   /* Match failed */+if (count == 0) count = match_data->oveccount;    /* Ovector too small */++count2 = 2*count;+ovector = match_data->ovector;+size = sizeof(pcre2_memctl) + sizeof(PCRE2_UCHAR *);      /* For final NULL */+if (lengthsptr != NULL) size += sizeof(PCRE2_SIZE) * count;  /* For lengths */++for (i = 0; i < count2; i += 2)+  {+  size += sizeof(PCRE2_UCHAR *) + CU2BYTES(1);+  if (ovector[i+1] > ovector[i]) size += CU2BYTES(ovector[i+1] - ovector[i]);+  }++memp = PRIV(memctl_malloc)(size, (pcre2_memctl *)match_data);+if (memp == NULL) return PCRE2_ERROR_NOMEMORY;++*listptr = listp = (PCRE2_UCHAR **)((char *)memp + sizeof(pcre2_memctl));+lensp = (PCRE2_SIZE *)((char *)listp + sizeof(PCRE2_UCHAR *) * (count + 1));++if (lengthsptr == NULL)+  {+  sp = (PCRE2_UCHAR *)lensp;+  lensp = NULL;+  }+else+  {+  *lengthsptr = lensp;+  sp = (PCRE2_UCHAR *)((char *)lensp + sizeof(PCRE2_SIZE) * count);+  }++for (i = 0; i < count2; i += 2)+  {+  size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;++  /* 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;+  *sp++ = 0;+  }++*listp = NULL;+return 0;+}++++/*************************************************+*   Free memory obtained by substring_list_get   *+*************************************************/++/*+Argument:     the result of a previous pcre2_substring_list_get()+Returns:      nothing+*/++PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_substring_list_free(PCRE2_SPTR *list)+{+if (list != NULL)+  {+  pcre2_memctl *memctl = (pcre2_memctl *)((char *)list - sizeof(pcre2_memctl));+  memctl->free(memctl, memctl->memory_data);+  }+}++++/*************************************************+*     Find (multiple) entries for named string   *+*************************************************/++/* This function scans the nametable for a given name, using binary chop. It+returns either two pointers to the entries in the table, or, if no pointers are+given, the number of a unique group with the given name. If duplicate names are+permitted, and the name is not unique, an error is generated.++Arguments:+  code        the compiled regex+  stringname  the name whose entries required+  firstptr    where to put the pointer to the first entry+  lastptr     where to put the pointer to the last entry++Returns:      PCRE2_ERROR_NOSUBSTRING if the name is not found+              otherwise, if firstptr and lastptr are NULL:+                a group number for a unique substring+                else PCRE2_ERROR_NOUNIQUESUBSTRING+              otherwise:+                the length of each entry, having set firstptr and lastptr+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname,+  PCRE2_SPTR *firstptr, PCRE2_SPTR *lastptr)+{+uint16_t bot = 0;+uint16_t top = code->name_count;+uint16_t entrysize = code->name_entry_size;+PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code));++while (top > bot)+  {+  uint16_t mid = (top + bot) / 2;+  PCRE2_SPTR entry = nametable + entrysize*mid;+  int c = PRIV(strcmp)(stringname, entry + IMM2_SIZE);+  if (c == 0)+    {+    PCRE2_SPTR first;+    PCRE2_SPTR last;+    PCRE2_SPTR lastentry;+    lastentry = nametable + entrysize * (code->name_count - 1);+    first = last = entry;+    while (first > nametable)+      {+      if (PRIV(strcmp)(stringname, (first - entrysize + IMM2_SIZE)) != 0) break;+      first -= entrysize;+      }+    while (last < lastentry)+      {+      if (PRIV(strcmp)(stringname, (last + entrysize + IMM2_SIZE)) != 0) break;+      last += entrysize;+      }+    if (firstptr == NULL) return (first == last)?+      (int)GET2(entry, 0) : PCRE2_ERROR_NOUNIQUESUBSTRING;+    *firstptr = first;+    *lastptr = last;+    return entrysize;+    }+  if (c > 0) bot = mid + 1; else top = mid;+  }++return PCRE2_ERROR_NOSUBSTRING;+}+++/*************************************************+*           Find number for named string         *+*************************************************/++/* This function is a convenience wrapper for pcre2_substring_nametable_scan()+when it is known that names are unique. If there are duplicate names, it is not+defined which number is returned.++Arguments:+  code        the compiled regex+  stringname  the name whose number is required++Returns:      the number of the named parenthesis, or a negative number+                PCRE2_ERROR_NOSUBSTRING if not found+                PCRE2_ERROR_NOUNIQUESUBSTRING if not unique+*/++PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_substring_number_from_name(const pcre2_code *code,+  PCRE2_SPTR stringname)+{+return pcre2_substring_nametable_scan(code, stringname, NULL, NULL);+}++/* End of pcre2_substring.c */
+ src/c/pcre2/src/pcre2_tables.c view
@@ -0,0 +1,854 @@+/*************************************************+*      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-2019 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 some fixed tables that are used by more than one of the+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. */++#ifndef PCRE2_PCRE2TEST           /* We're compiling the library */+#ifdef HAVE_CONFIG_H+#include "config.h"+#endif+#include "pcre2_internal.h"+#endif /* PCRE2_PCRE2TEST */+++/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that+the definition is next to the definition of the opcodes in pcre2_internal.h.+This is mode-dependent, so is skipped when this file is included by pcre2test. */++#ifndef PCRE2_PCRE2TEST+const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS };+#endif++/* Tables of horizontal and vertical whitespace characters, suitable for+adding to classes. */++const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST };+const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST };++/* These tables are the pairs of delimiters that are valid for callout string+arguments. For each starting delimiter there must be a matching ending+delimiter, which in fact is different only for bracket-like delimiters. */++const uint32_t PRIV(callout_start_delims)[] = {+  CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,+  CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,+  CHAR_DOLLAR_SIGN, CHAR_LEFT_CURLY_BRACKET, 0 };++const uint32_t PRIV(callout_end_delims[]) = {+  CHAR_GRAVE_ACCENT, CHAR_APOSTROPHE, CHAR_QUOTATION_MARK,+  CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,+  CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 };+++/*************************************************+*           Tables for UTF-8 support             *+*************************************************/++/* These tables are required by pcre2test in 16- or 32-bit mode, as well+as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for+handling wide characters. */++#if defined PCRE2_PCRE2TEST || \+   (defined SUPPORT_UNICODE && \+    defined PCRE2_CODE_UNIT_WIDTH && \+    PCRE2_CODE_UNIT_WIDTH == 8)++/* These are the breakpoints for different numbers of bytes in a UTF-8+character. */++const int PRIV(utf8_table1)[] =+  { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};++const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);++/* These are the indicator bits and the mask for the data bits to set in the+first byte of a character, indexed by the number of additional bytes. */++const int PRIV(utf8_table2)[] = { 0,    0xc0, 0xe0, 0xf0, 0xf8, 0xfc};+const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};++/* Table of the number of extra bytes, indexed by the first byte masked with+0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */++const uint8_t PRIV(utf8_table4)[] = {+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+  3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };++#endif /* UTF-8 support needed */+++#ifdef SUPPORT_UNICODE++/* Table to translate from particular type value to the general value. */++const uint32_t PRIV(ucp_gentype)[] = {+  ucp_C, ucp_C, ucp_C, ucp_C, ucp_C,  /* Cc, Cf, Cn, Co, Cs */+  ucp_L, ucp_L, ucp_L, ucp_L, ucp_L,  /* Ll, Lu, Lm, Lo, Lt */+  ucp_M, ucp_M, ucp_M,                /* Mc, Me, Mn */+  ucp_N, ucp_N, ucp_N,                /* Nd, Nl, No */+  ucp_P, ucp_P, ucp_P, ucp_P, ucp_P,  /* Pc, Pd, Pe, Pf, Pi */+  ucp_P, ucp_P,                       /* Ps, Po */+  ucp_S, ucp_S, ucp_S, ucp_S,         /* Sc, Sk, Sm, So */+  ucp_Z, ucp_Z, ucp_Z                 /* Zl, Zp, Zs */+};++/* This table encodes the rules for finding the end of an extended grapheme+cluster. Every code point has a grapheme break property which is one of the+ucp_gbXX values defined in pcre2_ucp.h. These changed between Unicode versions+10 and 11. The 2-dimensional table is indexed by the properties of two adjacent+code points. The left property selects a word from the table, and the right+property selects a bit from that word like this:++  PRIV(ucp_gbtable)[left-property] & (1u << right-property)++The value is non-zero if a grapheme break is NOT permitted between the relevant+two code points. The breaking rules are as follows:++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+   controls.++3. Do not break Hangul syllable sequences, the rules for which are:++    L may be followed by L, V, LV or LVT+    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 or zero-width-joiner (ZWJ).++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. Do not break within emoji modifier sequences or emoji zwj sequences. That+   is, do not break between characters with the Extended_Pictographic property.+   Extend and ZWJ characters are allowed between the characters; this cannot be+   represented in this table, the code has to deal with it.++8. 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.++9. Otherwise, break everywhere.+*/++#define ESZ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbZWJ)++const uint32_t PRIV(ucp_gbtable)[] = {+   (1u<<ucp_gbLF),                                      /*  0 CR */+   0,                                                   /*  1 LF */+   0,                                                   /*  2 Control */+   ESZ,                                                 /*  3 Extend */+   ESZ|(1u<<ucp_gbPrepend)|                             /*  4 Prepend */+       (1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbT)|+       (1u<<ucp_gbLV)|(1u<<ucp_gbLVT)|(1u<<ucp_gbOther)|+       (1u<<ucp_gbRegionalIndicator),+   ESZ,                                                 /*  5 SpacingMark */+   ESZ|(1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbLV)|      /*  6 L */+       (1u<<ucp_gbLVT),+   ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT),                     /*  7 V */+   ESZ|(1u<<ucp_gbT),                                   /*  8 T */+   ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT),                     /*  9 LV */+   ESZ|(1u<<ucp_gbT),                                   /* 10 LVT */+   (1u<<ucp_gbRegionalIndicator),                       /* 11 RegionalIndicator */+   ESZ,                                                 /* 12 Other */+   ESZ,                                                 /* 13 ZWJ */+   ESZ|(1u<<ucp_gbExtended_Pictographic)                /* 14 Extended Pictographic */+};++#undef ESZ++#ifdef SUPPORT_JIT+/* This table reverses PRIV(ucp_gentype). We can save the cost+of a memory load. */++const int PRIV(ucp_typerange)[] = {+  ucp_Cc, ucp_Cs,+  ucp_Ll, ucp_Lu,+  ucp_Mc, ucp_Mn,+  ucp_Nd, ucp_No,+  ucp_Pc, ucp_Ps,+  ucp_Sc, ucp_So,+  ucp_Zl, ucp_Zs,+};+#endif /* SUPPORT_JIT */++/* The PRIV(utt)[] table below translates Unicode property names into type and+code values. It is searched by binary chop, so must be in collating sequence of+name. Originally, the table contained pointers to the name strings in the first+field of each entry. However, that leads to a large number of relocations when+a shared library is dynamically loaded. A significant reduction is made by+putting all the names into a single, large string and then using offsets in the+table itself. Maintenance is more error-prone, but frequent changes to this+data are unlikely.++July 2008: There is now a script called maint/GenerateUtt.py that can be used+to generate this data automatically instead of maintaining it by hand.++The script was updated in March 2009 to generate a new EBCDIC-compliant+version. Like all other character and string literals that are compared against+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"+#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"+#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"+#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"+#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"+#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"+#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"+#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"+#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"+#define STRING_C0 STR_C "\0"+#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"+#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"+#define STRING_Caucasian_Albanian0 STR_C STR_a STR_u STR_c STR_a STR_s STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_l STR_b STR_a STR_n STR_i STR_a STR_n "\0"+#define STRING_Cc0 STR_C STR_c "\0"+#define STRING_Cf0 STR_C STR_f "\0"+#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"+#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"+#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"+#define STRING_Chorasmian0 STR_C STR_h STR_o STR_r STR_a STR_s STR_m STR_i STR_a STR_n "\0"+#define STRING_Cn0 STR_C STR_n "\0"+#define STRING_Co0 STR_C STR_o "\0"+#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"+#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"+#define STRING_Cs0 STR_C STR_s "\0"+#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"+#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"+#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"+#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"+#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"+#define STRING_Dives_Akuru0 STR_D STR_i STR_v STR_e STR_s STR_UNDERSCORE STR_A STR_k STR_u STR_r STR_u "\0"+#define STRING_Dogra0 STR_D STR_o STR_g STR_r STR_a "\0"+#define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"+#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t 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_Elbasan0 STR_E STR_l STR_b STR_a STR_s STR_a STR_n "\0"+#define STRING_Elymaic0 STR_E STR_l STR_y STR_m STR_a STR_i STR_c "\0"+#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"+#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"+#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"+#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"+#define STRING_Grantha0 STR_G STR_r STR_a STR_n STR_t STR_h STR_a "\0"+#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"+#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"+#define STRING_Gunjala_Gondi0 STR_G STR_u STR_n STR_j STR_a STR_l STR_a STR_UNDERSCORE STR_G STR_o STR_n STR_d STR_i "\0"+#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"+#define STRING_Han0 STR_H STR_a STR_n "\0"+#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"+#define STRING_Hanifi_Rohingya0 STR_H STR_a STR_n STR_i STR_f STR_i STR_UNDERSCORE STR_R STR_o STR_h STR_i STR_n STR_g STR_y STR_a "\0"+#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"+#define STRING_Hatran0 STR_H STR_a STR_t STR_r STR_a STR_n "\0"+#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"+#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"+#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"+#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"+#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"+#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"+#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"+#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"+#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"+#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"+#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"+#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"+#define STRING_Khitan_Small_Script0 STR_K STR_h STR_i STR_t STR_a STR_n STR_UNDERSCORE STR_S STR_m STR_a STR_l STR_l STR_UNDERSCORE STR_S STR_c STR_r STR_i STR_p STR_t "\0"+#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"+#define STRING_Khojki0 STR_K STR_h STR_o STR_j STR_k STR_i "\0"+#define STRING_Khudawadi0 STR_K STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0"+#define STRING_L0 STR_L "\0"+#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"+#define STRING_Lao0 STR_L STR_a STR_o "\0"+#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"+#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"+#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"+#define STRING_Linear_A0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_A "\0"+#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"+#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"+#define STRING_Ll0 STR_L STR_l "\0"+#define STRING_Lm0 STR_L STR_m "\0"+#define STRING_Lo0 STR_L STR_o "\0"+#define STRING_Lt0 STR_L STR_t "\0"+#define STRING_Lu0 STR_L STR_u "\0"+#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"+#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"+#define STRING_M0 STR_M "\0"+#define STRING_Mahajani0 STR_M STR_a STR_h STR_a STR_j STR_a STR_n STR_i "\0"+#define STRING_Makasar0 STR_M STR_a STR_k STR_a STR_s STR_a STR_r "\0"+#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_Medefaidrin0 STR_M STR_e STR_d STR_e STR_f STR_a STR_i STR_d STR_r STR_i STR_n "\0"+#define STRING_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"+#define STRING_Mende_Kikakui0 STR_M STR_e STR_n STR_d STR_e STR_UNDERSCORE STR_K STR_i STR_k STR_a STR_k STR_u STR_i "\0"+#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0"+#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c 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_Miao0 STR_M STR_i STR_a STR_o "\0"+#define STRING_Mn0 STR_M STR_n "\0"+#define STRING_Modi0 STR_M STR_o STR_d STR_i "\0"+#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"+#define STRING_Mro0 STR_M STR_r STR_o "\0"+#define STRING_Multani0 STR_M STR_u STR_l STR_t STR_a STR_n STR_i "\0"+#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"+#define STRING_N0 STR_N "\0"+#define STRING_Nabataean0 STR_N STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"+#define STRING_Nandinagari0 STR_N STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\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_Nyiakeng_Puachue_Hmong0 STR_N STR_y STR_i STR_a STR_k STR_e STR_n STR_g STR_UNDERSCORE STR_P STR_u STR_a STR_c STR_h STR_u STR_e STR_UNDERSCORE STR_H STR_m STR_o STR_n STR_g "\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"+#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"+#define STRING_Old_North_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_N STR_o STR_r STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"+#define STRING_Old_Permic0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_m STR_i STR_c "\0"+#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"+#define STRING_Old_Sogdian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_g STR_d STR_i STR_a STR_n "\0"+#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"+#define STRING_Palmyrene0 STR_P STR_a STR_l STR_m STR_y STR_r STR_e STR_n STR_e "\0"+#define STRING_Pau_Cin_Hau0 STR_P STR_a STR_u STR_UNDERSCORE STR_C STR_i STR_n STR_UNDERSCORE STR_H STR_a STR_u "\0"+#define STRING_Pc0 STR_P STR_c "\0"+#define STRING_Pd0 STR_P STR_d "\0"+#define STRING_Pe0 STR_P STR_e "\0"+#define STRING_Pf0 STR_P STR_f "\0"+#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"+#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"+#define STRING_Pi0 STR_P STR_i "\0"+#define STRING_Po0 STR_P STR_o "\0"+#define STRING_Ps0 STR_P STR_s "\0"+#define STRING_Psalter_Pahlavi0 STR_P STR_s STR_a STR_l STR_t STR_e STR_r STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"+#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"+#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"+#define STRING_S0 STR_S "\0"+#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"+#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"+#define STRING_Sc0 STR_S STR_c "\0"+#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0"+#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"+#define STRING_Siddham0 STR_S STR_i STR_d STR_d STR_h STR_a STR_m "\0"+#define STRING_SignWriting0 STR_S STR_i STR_g STR_n STR_W STR_r STR_i STR_t STR_i STR_n STR_g "\0"+#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"+#define STRING_Sk0 STR_S STR_k "\0"+#define STRING_Sm0 STR_S STR_m "\0"+#define STRING_So0 STR_S STR_o "\0"+#define STRING_Sogdian0 STR_S STR_o STR_g STR_d STR_i STR_a STR_n "\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"+#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"+#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"+#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"+#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"+#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"+#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"+#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"+#define STRING_Tirhuta0 STR_T STR_i STR_r STR_h STR_u STR_t STR_a "\0"+#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"+#define STRING_Unknown0 STR_U STR_n STR_k STR_n STR_o STR_w STR_n "\0"+#define STRING_Vai0 STR_V STR_a STR_i "\0"+#define STRING_Wancho0 STR_W STR_a STR_n STR_c STR_h STR_o "\0"+#define STRING_Warang_Citi0 STR_W STR_a STR_r STR_a STR_n STR_g STR_UNDERSCORE STR_C STR_i STR_t STR_i "\0"+#define STRING_Xan0 STR_X STR_a STR_n "\0"+#define STRING_Xps0 STR_X STR_p STR_s "\0"+#define STRING_Xsp0 STR_X STR_s STR_p "\0"+#define STRING_Xuc0 STR_X STR_u STR_c "\0"+#define STRING_Xwd0 STR_X STR_w STR_d "\0"+#define STRING_Yezidi0 STR_Y STR_e STR_z STR_i STR_d STR_i "\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+  STRING_Arabic0+  STRING_Armenian0+  STRING_Avestan0+  STRING_Balinese0+  STRING_Bamum0+  STRING_Bassa_Vah0+  STRING_Batak0+  STRING_Bengali0+  STRING_Bhaiksuki0+  STRING_Bopomofo0+  STRING_Brahmi0+  STRING_Braille0+  STRING_Buginese0+  STRING_Buhid0+  STRING_C0+  STRING_Canadian_Aboriginal0+  STRING_Carian0+  STRING_Caucasian_Albanian0+  STRING_Cc0+  STRING_Cf0+  STRING_Chakma0+  STRING_Cham0+  STRING_Cherokee0+  STRING_Chorasmian0+  STRING_Cn0+  STRING_Co0+  STRING_Common0+  STRING_Coptic0+  STRING_Cs0+  STRING_Cuneiform0+  STRING_Cypriot0+  STRING_Cyrillic0+  STRING_Deseret0+  STRING_Devanagari0+  STRING_Dives_Akuru0+  STRING_Dogra0+  STRING_Duployan0+  STRING_Egyptian_Hieroglyphs0+  STRING_Elbasan0+  STRING_Elymaic0+  STRING_Ethiopic0+  STRING_Georgian0+  STRING_Glagolitic0+  STRING_Gothic0+  STRING_Grantha0+  STRING_Greek0+  STRING_Gujarati0+  STRING_Gunjala_Gondi0+  STRING_Gurmukhi0+  STRING_Han0+  STRING_Hangul0+  STRING_Hanifi_Rohingya0+  STRING_Hanunoo0+  STRING_Hatran0+  STRING_Hebrew0+  STRING_Hiragana0+  STRING_Imperial_Aramaic0+  STRING_Inherited0+  STRING_Inscriptional_Pahlavi0+  STRING_Inscriptional_Parthian0+  STRING_Javanese0+  STRING_Kaithi0+  STRING_Kannada0+  STRING_Katakana0+  STRING_Kayah_Li0+  STRING_Kharoshthi0+  STRING_Khitan_Small_Script0+  STRING_Khmer0+  STRING_Khojki0+  STRING_Khudawadi0+  STRING_L0+  STRING_L_AMPERSAND0+  STRING_Lao0+  STRING_Latin0+  STRING_Lepcha0+  STRING_Limbu0+  STRING_Linear_A0+  STRING_Linear_B0+  STRING_Lisu0+  STRING_Ll0+  STRING_Lm0+  STRING_Lo0+  STRING_Lt0+  STRING_Lu0+  STRING_Lycian0+  STRING_Lydian0+  STRING_M0+  STRING_Mahajani0+  STRING_Makasar0+  STRING_Malayalam0+  STRING_Mandaic0+  STRING_Manichaean0+  STRING_Marchen0+  STRING_Masaram_Gondi0+  STRING_Mc0+  STRING_Me0+  STRING_Medefaidrin0+  STRING_Meetei_Mayek0+  STRING_Mende_Kikakui0+  STRING_Meroitic_Cursive0+  STRING_Meroitic_Hieroglyphs0+  STRING_Miao0+  STRING_Mn0+  STRING_Modi0+  STRING_Mongolian0+  STRING_Mro0+  STRING_Multani0+  STRING_Myanmar0+  STRING_N0+  STRING_Nabataean0+  STRING_Nandinagari0+  STRING_Nd0+  STRING_New_Tai_Lue0+  STRING_Newa0+  STRING_Nko0+  STRING_Nl0+  STRING_No0+  STRING_Nushu0+  STRING_Nyiakeng_Puachue_Hmong0+  STRING_Ogham0+  STRING_Ol_Chiki0+  STRING_Old_Hungarian0+  STRING_Old_Italic0+  STRING_Old_North_Arabian0+  STRING_Old_Permic0+  STRING_Old_Persian0+  STRING_Old_Sogdian0+  STRING_Old_South_Arabian0+  STRING_Old_Turkic0+  STRING_Oriya0+  STRING_Osage0+  STRING_Osmanya0+  STRING_P0+  STRING_Pahawh_Hmong0+  STRING_Palmyrene0+  STRING_Pau_Cin_Hau0+  STRING_Pc0+  STRING_Pd0+  STRING_Pe0+  STRING_Pf0+  STRING_Phags_Pa0+  STRING_Phoenician0+  STRING_Pi0+  STRING_Po0+  STRING_Ps0+  STRING_Psalter_Pahlavi0+  STRING_Rejang0+  STRING_Runic0+  STRING_S0+  STRING_Samaritan0+  STRING_Saurashtra0+  STRING_Sc0+  STRING_Sharada0+  STRING_Shavian0+  STRING_Siddham0+  STRING_SignWriting0+  STRING_Sinhala0+  STRING_Sk0+  STRING_Sm0+  STRING_So0+  STRING_Sogdian0+  STRING_Sora_Sompeng0+  STRING_Soyombo0+  STRING_Sundanese0+  STRING_Syloti_Nagri0+  STRING_Syriac0+  STRING_Tagalog0+  STRING_Tagbanwa0+  STRING_Tai_Le0+  STRING_Tai_Tham0+  STRING_Tai_Viet0+  STRING_Takri0+  STRING_Tamil0+  STRING_Tangut0+  STRING_Telugu0+  STRING_Thaana0+  STRING_Thai0+  STRING_Tibetan0+  STRING_Tifinagh0+  STRING_Tirhuta0+  STRING_Ugaritic0+  STRING_Unknown0+  STRING_Vai0+  STRING_Wancho0+  STRING_Warang_Citi0+  STRING_Xan0+  STRING_Xps0+  STRING_Xsp0+  STRING_Xuc0+  STRING_Xwd0+  STRING_Yezidi0+  STRING_Yi0+  STRING_Z0+  STRING_Zanabazar_Square0+  STRING_Zl0+  STRING_Zp0+  STRING_Zs0;++const ucp_type_table PRIV(utt)[] = {+  {   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_SC, ucp_Chorasmian },+  { 235, PT_PC, ucp_Cn },+  { 238, PT_PC, ucp_Co },+  { 241, PT_SC, ucp_Common },+  { 248, PT_SC, ucp_Coptic },+  { 255, PT_PC, ucp_Cs },+  { 258, PT_SC, ucp_Cuneiform },+  { 268, PT_SC, ucp_Cypriot },+  { 276, PT_SC, ucp_Cyrillic },+  { 285, PT_SC, ucp_Deseret },+  { 293, PT_SC, ucp_Devanagari },+  { 304, PT_SC, ucp_Dives_Akuru },+  { 316, PT_SC, ucp_Dogra },+  { 322, PT_SC, ucp_Duployan },+  { 331, PT_SC, ucp_Egyptian_Hieroglyphs },+  { 352, PT_SC, ucp_Elbasan },+  { 360, PT_SC, ucp_Elymaic },+  { 368, PT_SC, ucp_Ethiopic },+  { 377, PT_SC, ucp_Georgian },+  { 386, PT_SC, ucp_Glagolitic },+  { 397, PT_SC, ucp_Gothic },+  { 404, PT_SC, ucp_Grantha },+  { 412, PT_SC, ucp_Greek },+  { 418, PT_SC, ucp_Gujarati },+  { 427, PT_SC, ucp_Gunjala_Gondi },+  { 441, PT_SC, ucp_Gurmukhi },+  { 450, PT_SC, ucp_Han },+  { 454, PT_SC, ucp_Hangul },+  { 461, PT_SC, ucp_Hanifi_Rohingya },+  { 477, PT_SC, ucp_Hanunoo },+  { 485, PT_SC, ucp_Hatran },+  { 492, PT_SC, ucp_Hebrew },+  { 499, PT_SC, ucp_Hiragana },+  { 508, PT_SC, ucp_Imperial_Aramaic },+  { 525, PT_SC, ucp_Inherited },+  { 535, PT_SC, ucp_Inscriptional_Pahlavi },+  { 557, PT_SC, ucp_Inscriptional_Parthian },+  { 580, PT_SC, ucp_Javanese },+  { 589, PT_SC, ucp_Kaithi },+  { 596, PT_SC, ucp_Kannada },+  { 604, PT_SC, ucp_Katakana },+  { 613, PT_SC, ucp_Kayah_Li },+  { 622, PT_SC, ucp_Kharoshthi },+  { 633, PT_SC, ucp_Khitan_Small_Script },+  { 653, PT_SC, ucp_Khmer },+  { 659, PT_SC, ucp_Khojki },+  { 666, PT_SC, ucp_Khudawadi },+  { 676, PT_GC, ucp_L },+  { 678, PT_LAMP, 0 },+  { 681, PT_SC, ucp_Lao },+  { 685, PT_SC, ucp_Latin },+  { 691, PT_SC, ucp_Lepcha },+  { 698, PT_SC, ucp_Limbu },+  { 704, PT_SC, ucp_Linear_A },+  { 713, PT_SC, ucp_Linear_B },+  { 722, PT_SC, ucp_Lisu },+  { 727, PT_PC, ucp_Ll },+  { 730, PT_PC, ucp_Lm },+  { 733, PT_PC, ucp_Lo },+  { 736, PT_PC, ucp_Lt },+  { 739, PT_PC, ucp_Lu },+  { 742, PT_SC, ucp_Lycian },+  { 749, PT_SC, ucp_Lydian },+  { 756, PT_GC, ucp_M },+  { 758, PT_SC, ucp_Mahajani },+  { 767, PT_SC, ucp_Makasar },+  { 775, PT_SC, ucp_Malayalam },+  { 785, PT_SC, ucp_Mandaic },+  { 793, PT_SC, ucp_Manichaean },+  { 804, PT_SC, ucp_Marchen },+  { 812, PT_SC, ucp_Masaram_Gondi },+  { 826, PT_PC, ucp_Mc },+  { 829, PT_PC, ucp_Me },+  { 832, PT_SC, ucp_Medefaidrin },+  { 844, PT_SC, ucp_Meetei_Mayek },+  { 857, PT_SC, ucp_Mende_Kikakui },+  { 871, PT_SC, ucp_Meroitic_Cursive },+  { 888, PT_SC, ucp_Meroitic_Hieroglyphs },+  { 909, PT_SC, ucp_Miao },+  { 914, PT_PC, ucp_Mn },+  { 917, PT_SC, ucp_Modi },+  { 922, PT_SC, ucp_Mongolian },+  { 932, PT_SC, ucp_Mro },+  { 936, PT_SC, ucp_Multani },+  { 944, PT_SC, ucp_Myanmar },+  { 952, PT_GC, ucp_N },+  { 954, PT_SC, ucp_Nabataean },+  { 964, PT_SC, ucp_Nandinagari },+  { 976, PT_PC, ucp_Nd },+  { 979, PT_SC, ucp_New_Tai_Lue },+  { 991, PT_SC, ucp_Newa },+  { 996, PT_SC, ucp_Nko },+  { 1000, PT_PC, ucp_Nl },+  { 1003, PT_PC, ucp_No },+  { 1006, PT_SC, ucp_Nushu },+  { 1012, PT_SC, ucp_Nyiakeng_Puachue_Hmong },+  { 1035, PT_SC, ucp_Ogham },+  { 1041, PT_SC, ucp_Ol_Chiki },+  { 1050, PT_SC, ucp_Old_Hungarian },+  { 1064, PT_SC, ucp_Old_Italic },+  { 1075, PT_SC, ucp_Old_North_Arabian },+  { 1093, PT_SC, ucp_Old_Permic },+  { 1104, PT_SC, ucp_Old_Persian },+  { 1116, PT_SC, ucp_Old_Sogdian },+  { 1128, PT_SC, ucp_Old_South_Arabian },+  { 1146, PT_SC, ucp_Old_Turkic },+  { 1157, PT_SC, ucp_Oriya },+  { 1163, PT_SC, ucp_Osage },+  { 1169, PT_SC, ucp_Osmanya },+  { 1177, PT_GC, ucp_P },+  { 1179, PT_SC, ucp_Pahawh_Hmong },+  { 1192, PT_SC, ucp_Palmyrene },+  { 1202, PT_SC, ucp_Pau_Cin_Hau },+  { 1214, PT_PC, ucp_Pc },+  { 1217, PT_PC, ucp_Pd },+  { 1220, PT_PC, ucp_Pe },+  { 1223, PT_PC, ucp_Pf },+  { 1226, PT_SC, ucp_Phags_Pa },+  { 1235, PT_SC, ucp_Phoenician },+  { 1246, PT_PC, ucp_Pi },+  { 1249, PT_PC, ucp_Po },+  { 1252, PT_PC, ucp_Ps },+  { 1255, PT_SC, ucp_Psalter_Pahlavi },+  { 1271, PT_SC, ucp_Rejang },+  { 1278, PT_SC, ucp_Runic },+  { 1284, PT_GC, ucp_S },+  { 1286, PT_SC, ucp_Samaritan },+  { 1296, PT_SC, ucp_Saurashtra },+  { 1307, PT_PC, ucp_Sc },+  { 1310, PT_SC, ucp_Sharada },+  { 1318, PT_SC, ucp_Shavian },+  { 1326, PT_SC, ucp_Siddham },+  { 1334, PT_SC, ucp_SignWriting },+  { 1346, PT_SC, ucp_Sinhala },+  { 1354, PT_PC, ucp_Sk },+  { 1357, PT_PC, ucp_Sm },+  { 1360, PT_PC, ucp_So },+  { 1363, PT_SC, ucp_Sogdian },+  { 1371, PT_SC, ucp_Sora_Sompeng },+  { 1384, PT_SC, ucp_Soyombo },+  { 1392, PT_SC, ucp_Sundanese },+  { 1402, PT_SC, ucp_Syloti_Nagri },+  { 1415, PT_SC, ucp_Syriac },+  { 1422, PT_SC, ucp_Tagalog },+  { 1430, PT_SC, ucp_Tagbanwa },+  { 1439, PT_SC, ucp_Tai_Le },+  { 1446, PT_SC, ucp_Tai_Tham },+  { 1455, PT_SC, ucp_Tai_Viet },+  { 1464, PT_SC, ucp_Takri },+  { 1470, PT_SC, ucp_Tamil },+  { 1476, PT_SC, ucp_Tangut },+  { 1483, PT_SC, ucp_Telugu },+  { 1490, PT_SC, ucp_Thaana },+  { 1497, PT_SC, ucp_Thai },+  { 1502, PT_SC, ucp_Tibetan },+  { 1510, PT_SC, ucp_Tifinagh },+  { 1519, PT_SC, ucp_Tirhuta },+  { 1527, PT_SC, ucp_Ugaritic },+  { 1536, PT_SC, ucp_Unknown },+  { 1544, PT_SC, ucp_Vai },+  { 1548, PT_SC, ucp_Wancho },+  { 1555, PT_SC, ucp_Warang_Citi },+  { 1567, PT_ALNUM, 0 },+  { 1571, PT_PXSPACE, 0 },+  { 1575, PT_SPACE, 0 },+  { 1579, PT_UCNC, 0 },+  { 1583, PT_WORD, 0 },+  { 1587, PT_SC, ucp_Yezidi },+  { 1594, PT_SC, ucp_Yi },+  { 1597, PT_GC, ucp_Z },+  { 1599, PT_SC, ucp_Zanabazar_Square },+  { 1616, PT_PC, ucp_Zl },+  { 1619, PT_PC, ucp_Zp },+  { 1622, PT_PC, ucp_Zs }+};++const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);++#endif /* SUPPORT_UNICODE */++/* End of pcre2_tables.c */
+ src/c/pcre2/src/pcre2_ucd.c view
@@ -0,0 +1,4538 @@+/* This module is generated by the maint/MultiStage2.py script.+Do not modify it by hand. Instead modify the script and run it+to regenerate this code.++As well as being part of the PCRE2 library, this module is #included+by the pcre2test program, which redefines the PRIV macro to change+table names from _pcre2_xxx to xxxx, thereby avoiding name clashes+with the library. At present, just one of these tables is actually+needed. */++#ifndef PCRE2_PCRE2TEST++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"++#endif /* PCRE2_PCRE2TEST */++/* Unicode character database. */+/* This file was autogenerated by the MultiStage2.py script. */+/* Total size: 101044 bytes, block size: 128. */++/* The tables herein are needed only when UCP support is built,+and in PCRE2 that happens automatically with UTF support.+This module should not be referenced otherwise, so+it should not matter whether it is compiled or not. However+a comment was received about space saving - maybe the guy linked+all the modules rather than using a library - so we include a+condition to cut out the tables when not needed. But don't leave+a totally empty module because some compilers barf at that.+Instead, just supply some small dummy tables. */++#ifndef SUPPORT_UNICODE+const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0 }};+const uint16_t PRIV(ucd_stage1)[] = {0};+const uint16_t PRIV(ucd_stage2)[] = {0};+const uint32_t PRIV(ucd_caseless_sets)[] = {0};+#else++const char *PRIV(unicode_version) = "13.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_Unknown,    /* script */+  ucp_Cn,         /* type unassigned */+  ucp_gbOther,    /* grapheme break property */+  0,              /* case set */+  0,              /* other case */+  ucp_Unknown,    /* script extension */+  0,              /* dummy filler */+  }};+#endif++/* When recompiling tables with a new Unicode version, please check the+types in this structure definition from pcre2_internal.h (the actual+field names will be different):++typedef struct {+uint8_t property_0;+uint8_t property_1;+uint8_t property_2;+uint8_t property_3;+pcre_int32 property_4;+pcre_int16 property_5;+uint16_t property_6;+} ucd_record;+*/++/* This table contains lists of characters that are caseless sets of+more than one character. Each list is terminated by NOTACHAR. */++const uint32_t PRIV(ucd_caseless_sets)[] = {+  NOTACHAR,+  0x0053,   0x0073,   0x017f,   NOTACHAR,+  0x01c4,   0x01c5,   0x01c6,   NOTACHAR,+  0x01c7,   0x01c8,   0x01c9,   NOTACHAR,+  0x01ca,   0x01cb,   0x01cc,   NOTACHAR,+  0x01f1,   0x01f2,   0x01f3,   NOTACHAR,+  0x0345,   0x0399,   0x03b9,   0x1fbe,   NOTACHAR,+  0x00b5,   0x039c,   0x03bc,   NOTACHAR,+  0x03a3,   0x03c2,   0x03c3,   NOTACHAR,+  0x0392,   0x03b2,   0x03d0,   NOTACHAR,+  0x0398,   0x03b8,   0x03d1,   0x03f4,   NOTACHAR,+  0x03a6,   0x03c6,   0x03d5,   NOTACHAR,+  0x03a0,   0x03c0,   0x03d6,   NOTACHAR,+  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 the table of digit+sets, nor the the large main UCD tables. */++#ifndef PCRE2_PCRE2TEST++/* This table lists the code points for the '9' characters in each+set of decimal digits. It is used to ensure that all the digits in+a script run come from the same set. */++const uint32_t PRIV(ucd_digit_sets)[] = {+  65,  /* Number of subsequent values */+  0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef,+  0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9,+  0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89,+  0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909,+  0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f,+  0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9,+  0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59,+  0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959,+  0x1fbf9,+};++/* This vector is a list of lists of scripts for the Script Extension+property. Each sublist is zero-terminated. */++const uint8_t PRIV(ucd_script_sets)[] = {+  /*   0 */   0,+  /*   1 */   1,  11,   0,+  /*   4 */   1, 144,   0,+  /*   7 */   1,  50,   0,+  /*  10 */   1,  56,   0,+  /*  13 */   3,  15,   0,+  /*  16 */   4,  23,   0,+  /*  19 */   6,  84,   0,+  /*  22 */  12,  36,   0,+  /*  25 */  13,  18,   0,+  /*  28 */  13,  34,   0,+  /*  31 */  13, 118,   0,+  /*  34 */  13,  50,   0,+  /*  37 */  15, 107,   0,+  /*  40 */  15, 150,   0,+  /*  43 */  15, 100,   0,+  /*  46 */  15,  54,   0,+  /*  49 */  17,  34,   0,+  /*  52 */ 107,  54,   0,+  /*  55 */  21, 108,   0,+  /*  58 */  22, 129,   0,+  /*  61 */  23,  34,   0,+  /*  64 */  27,  30,   0,+  /*  67 */  29, 150,   0,+  /*  70 */  34,  38,   0,+  /*  73 */  38,  65,   0,+  /*  76 */   1,  50,  56,   0,+  /*  80 */   1,  56, 156,   0,+  /*  84 */   3,  96,  49,   0,+  /*  88 */  96,  39,  53,   0,+  /*  92 */  12, 110,  36,   0,+  /*  96 */  15, 107,  29,   0,+  /* 100 */  15, 107,  34,   0,+  /* 104 */  23,  27,  30,   0,+  /* 108 */  69,  34,  39,   0,+  /* 112 */   3,  15, 107,  29,   0,+  /* 117 */   7,  25,  52,  51,   0,+  /* 122 */  15, 142,  85, 111,   0,+  /* 127 */   1, 144,  50,  56, 156,   0,+  /* 133 */   4,  24,  23,  27,  30,   0,+  /* 139 */   4,  24,  23,  27,  30,  61,   0,+  /* 146 */  15,  29,  37,  44,  54,  55,   0,+  /* 153 */ 132,   1,  95, 112, 121, 144, 148,  50,   0,+  /* 162 */   3,  15, 107,  29, 150,  44,  55, 124,   0,+  /* 171 */  15, 142,  21,  22, 108,  85, 111, 114, 109, 102, 124,   0,+  /* 183 */   3,  15, 107,  21,  22,  29,  34,  37,  44,  54,  55, 124,   0,+  /* 196 */   3,  15, 107,  21,  22,  29,  34,  37,  44, 100,  54,  55, 124,   0,+  /* 210 */  15, 142,  21,  22, 108,  29,  85, 111, 114, 150, 109, 102, 124,   0,+  /* 224 */  15, 142,  21,  22, 108,  29,  85, 111,  37, 114, 150, 109, 102, 124,   0,+  /* 239 */   3,  15, 142, 143, 138, 107,  21,  22,  29, 111,  37, 150,  44, 109,  48,  49, 102,  54,  55, 124,   0,+  /* 260 */   3,  15, 142, 143, 138, 107,  21,  22,  29,  35, 111,  37, 150,  44, 109,  48,  49, 102,  54,  55, 124,   0,+  /* 282 */+};++/* These are the main two-stage UCD tables. The fields in each record are:+script (8 bits), character type (8 bits), grapheme break property (8 bits),+offset to multichar other cases or zero (8 bits), offset to other case+or zero (32 bits, signed), script extension (16 bits, signed), and a dummy+16-bit field to make the whole thing a multiple of 4 bytes. */++const ucd_record PRIV(ucd_records)[] = { /* 11700 bytes, record size 12 */+  {    10,      0,      2,      0,      0,     10,    256, }, /*   0 */+  {    10,      0,      2,      0,      0,     10,      0, }, /*   1 */+  {    10,      0,      1,      0,      0,     10,      0, }, /*   2 */+  {    10,      0,      0,      0,      0,     10,      0, }, /*   3 */+  {    10,     29,     12,      0,      0,     10,      0, }, /*   4 */+  {    10,     21,     12,      0,      0,     10,      0, }, /*   5 */+  {    10,     23,     12,      0,      0,     10,      0, }, /*   6 */+  {    10,     22,     12,      0,      0,     10,      0, }, /*   7 */+  {    10,     18,     12,      0,      0,     10,      0, }, /*   8 */+  {    10,     25,     12,      0,      0,     10,      0, }, /*   9 */+  {    10,     17,     12,      0,      0,     10,      0, }, /*  10 */+  {    10,     13,     12,      0,      0,     10,      0, }, /*  11 */+  {    34,      9,     12,      0,     32,     34,      0, }, /*  12 */+  {    34,      9,     12,    100,     32,     34,      0, }, /*  13 */+  {    34,      9,     12,      1,     32,     34,      0, }, /*  14 */+  {    10,     24,     12,      0,      0,     10,      0, }, /*  15 */+  {    10,     16,     12,      0,      0,     10,      0, }, /*  16 */+  {    34,      5,     12,      0,    -32,     34,      0, }, /*  17 */+  {    34,      5,     12,    100,    -32,     34,      0, }, /*  18 */+  {    34,      5,     12,      1,    -32,     34,      0, }, /*  19 */+  {    10,     26,     12,      0,      0,     10,      0, }, /*  20 */+  {    10,     26,     14,      0,      0,     10,      0, }, /*  21 */+  {    34,      7,     12,      0,      0,     34,      0, }, /*  22 */+  {    10,     20,     12,      0,      0,     10,      0, }, /*  23 */+  {    10,      1,      2,      0,      0,     10,      0, }, /*  24 */+  {    10,     15,     12,      0,      0,     10,      0, }, /*  25 */+  {    10,      5,     12,     26,    775,     10,      0, }, /*  26 */+  {    10,     19,     12,      0,      0,     10,      0, }, /*  27 */+  {    34,      9,     12,    104,     32,     34,      0, }, /*  28 */+  {    34,      5,     12,      0,   7615,     34,      0, }, /*  29 */+  {    34,      5,     12,    104,    -32,     34,      0, }, /*  30 */+  {    34,      5,     12,      0,    121,     34,      0, }, /*  31 */+  {    34,      9,     12,      0,      1,     34,      0, }, /*  32 */+  {    34,      5,     12,      0,     -1,     34,      0, }, /*  33 */+  {    34,      9,     12,      0,      0,     34,      0, }, /*  34 */+  {    34,      5,     12,      0,      0,     34,      0, }, /*  35 */+  {    34,      9,     12,      0,   -121,     34,      0, }, /*  36 */+  {    34,      5,     12,      1,   -268,     34,      0, }, /*  37 */+  {    34,      5,     12,      0,    195,     34,      0, }, /*  38 */+  {    34,      9,     12,      0,    210,     34,      0, }, /*  39 */+  {    34,      9,     12,      0,    206,     34,      0, }, /*  40 */+  {    34,      9,     12,      0,    205,     34,      0, }, /*  41 */+  {    34,      9,     12,      0,     79,     34,      0, }, /*  42 */+  {    34,      9,     12,      0,    202,     34,      0, }, /*  43 */+  {    34,      9,     12,      0,    203,     34,      0, }, /*  44 */+  {    34,      9,     12,      0,    207,     34,      0, }, /*  45 */+  {    34,      5,     12,      0,     97,     34,      0, }, /*  46 */+  {    34,      9,     12,      0,    211,     34,      0, }, /*  47 */+  {    34,      9,     12,      0,    209,     34,      0, }, /*  48 */+  {    34,      5,     12,      0,    163,     34,      0, }, /*  49 */+  {    34,      9,     12,      0,    213,     34,      0, }, /*  50 */+  {    34,      5,     12,      0,    130,     34,      0, }, /*  51 */+  {    34,      9,     12,      0,    214,     34,      0, }, /*  52 */+  {    34,      9,     12,      0,    218,     34,      0, }, /*  53 */+  {    34,      9,     12,      0,    217,     34,      0, }, /*  54 */+  {    34,      9,     12,      0,    219,     34,      0, }, /*  55 */+  {    34,      5,     12,      0,     56,     34,      0, }, /*  56 */+  {    34,      9,     12,      5,      2,     34,      0, }, /*  57 */+  {    34,      8,     12,      5,      1,     34,      0, }, /*  58 */+  {    34,      5,     12,      5,     -2,     34,      0, }, /*  59 */+  {    34,      9,     12,      9,      2,     34,      0, }, /*  60 */+  {    34,      8,     12,      9,      1,     34,      0, }, /*  61 */+  {    34,      5,     12,      9,     -2,     34,      0, }, /*  62 */+  {    34,      9,     12,     13,      2,     34,      0, }, /*  63 */+  {    34,      8,     12,     13,      1,     34,      0, }, /*  64 */+  {    34,      5,     12,     13,     -2,     34,      0, }, /*  65 */+  {    34,      5,     12,      0,    -79,     34,      0, }, /*  66 */+  {    34,      9,     12,     17,      2,     34,      0, }, /*  67 */+  {    34,      8,     12,     17,      1,     34,      0, }, /*  68 */+  {    34,      5,     12,     17,     -2,     34,      0, }, /*  69 */+  {    34,      9,     12,      0,    -97,     34,      0, }, /*  70 */+  {    34,      9,     12,      0,    -56,     34,      0, }, /*  71 */+  {    34,      9,     12,      0,   -130,     34,      0, }, /*  72 */+  {    34,      9,     12,      0,  10795,     34,      0, }, /*  73 */+  {    34,      9,     12,      0,   -163,     34,      0, }, /*  74 */+  {    34,      9,     12,      0,  10792,     34,      0, }, /*  75 */+  {    34,      5,     12,      0,  10815,     34,      0, }, /*  76 */+  {    34,      9,     12,      0,   -195,     34,      0, }, /*  77 */+  {    34,      9,     12,      0,     69,     34,      0, }, /*  78 */+  {    34,      9,     12,      0,     71,     34,      0, }, /*  79 */+  {    34,      5,     12,      0,  10783,     34,      0, }, /*  80 */+  {    34,      5,     12,      0,  10780,     34,      0, }, /*  81 */+  {    34,      5,     12,      0,  10782,     34,      0, }, /*  82 */+  {    34,      5,     12,      0,   -210,     34,      0, }, /*  83 */+  {    34,      5,     12,      0,   -206,     34,      0, }, /*  84 */+  {    34,      5,     12,      0,   -205,     34,      0, }, /*  85 */+  {    34,      5,     12,      0,   -202,     34,      0, }, /*  86 */+  {    34,      5,     12,      0,   -203,     34,      0, }, /*  87 */+  {    34,      5,     12,      0,  42319,     34,      0, }, /*  88 */+  {    34,      5,     12,      0,  42315,     34,      0, }, /*  89 */+  {    34,      5,     12,      0,   -207,     34,      0, }, /*  90 */+  {    34,      5,     12,      0,  42280,     34,      0, }, /*  91 */+  {    34,      5,     12,      0,  42308,     34,      0, }, /*  92 */+  {    34,      5,     12,      0,   -209,     34,      0, }, /*  93 */+  {    34,      5,     12,      0,   -211,     34,      0, }, /*  94 */+  {    34,      5,     12,      0,  10743,     34,      0, }, /*  95 */+  {    34,      5,     12,      0,  42305,     34,      0, }, /*  96 */+  {    34,      5,     12,      0,  10749,     34,      0, }, /*  97 */+  {    34,      5,     12,      0,   -213,     34,      0, }, /*  98 */+  {    34,      5,     12,      0,   -214,     34,      0, }, /*  99 */+  {    34,      5,     12,      0,  10727,     34,      0, }, /* 100 */+  {    34,      5,     12,      0,   -218,     34,      0, }, /* 101 */+  {    34,      5,     12,      0,  42307,     34,      0, }, /* 102 */+  {    34,      5,     12,      0,  42282,     34,      0, }, /* 103 */+  {    34,      5,     12,      0,    -69,     34,      0, }, /* 104 */+  {    34,      5,     12,      0,   -217,     34,      0, }, /* 105 */+  {    34,      5,     12,      0,    -71,     34,      0, }, /* 106 */+  {    34,      5,     12,      0,   -219,     34,      0, }, /* 107 */+  {    34,      5,     12,      0,  42261,     34,      0, }, /* 108 */+  {    34,      5,     12,      0,  42258,     34,      0, }, /* 109 */+  {    34,      6,     12,      0,      0,     34,      0, }, /* 110 */+  {    10,      6,     12,      0,      0,     10,      0, }, /* 111 */+  {     4,     24,     12,      0,      0,      4,      0, }, /* 112 */+  {    28,     12,      3,      0,      0,     28,      0, }, /* 113 */+  {    28,     12,      3,      0,      0,     20,      0, }, /* 114 */+  {    28,     12,      3,     21,    116,     20,      0, }, /* 115 */+  {    28,     12,      3,      0,      0,     34,      0, }, /* 116 */+  {    20,      9,     12,      0,      1,     20,      0, }, /* 117 */+  {    20,      5,     12,      0,     -1,     20,      0, }, /* 118 */+  {    20,     24,     12,      0,      0,     20,      0, }, /* 119 */+  {     0,      2,     12,      0,      0,      0,      0, }, /* 120 */+  {    20,      6,     12,      0,      0,     20,      0, }, /* 121 */+  {    20,      5,     12,      0,    130,     20,      0, }, /* 122 */+  {    20,      9,     12,      0,    116,     20,      0, }, /* 123 */+  {    20,      9,     12,      0,     38,     20,      0, }, /* 124 */+  {    20,      9,     12,      0,     37,     20,      0, }, /* 125 */+  {    20,      9,     12,      0,     64,     20,      0, }, /* 126 */+  {    20,      9,     12,      0,     63,     20,      0, }, /* 127 */+  {    20,      5,     12,      0,      0,     20,      0, }, /* 128 */+  {    20,      9,     12,      0,     32,     20,      0, }, /* 129 */+  {    20,      9,     12,     34,     32,     20,      0, }, /* 130 */+  {    20,      9,     12,     59,     32,     20,      0, }, /* 131 */+  {    20,      9,     12,     38,     32,     20,      0, }, /* 132 */+  {    20,      9,     12,     21,     32,     20,      0, }, /* 133 */+  {    20,      9,     12,     51,     32,     20,      0, }, /* 134 */+  {    20,      9,     12,     26,     32,     20,      0, }, /* 135 */+  {    20,      9,     12,     47,     32,     20,      0, }, /* 136 */+  {    20,      9,     12,     55,     32,     20,      0, }, /* 137 */+  {    20,      9,     12,     30,     32,     20,      0, }, /* 138 */+  {    20,      9,     12,     43,     32,     20,      0, }, /* 139 */+  {    20,      9,     12,     96,     32,     20,      0, }, /* 140 */+  {    20,      5,     12,      0,    -38,     20,      0, }, /* 141 */+  {    20,      5,     12,      0,    -37,     20,      0, }, /* 142 */+  {    20,      5,     12,      0,    -32,     20,      0, }, /* 143 */+  {    20,      5,     12,     34,    -32,     20,      0, }, /* 144 */+  {    20,      5,     12,     59,    -32,     20,      0, }, /* 145 */+  {    20,      5,     12,     38,    -32,     20,      0, }, /* 146 */+  {    20,      5,     12,     21,   -116,     20,      0, }, /* 147 */+  {    20,      5,     12,     51,    -32,     20,      0, }, /* 148 */+  {    20,      5,     12,     26,   -775,     20,      0, }, /* 149 */+  {    20,      5,     12,     47,    -32,     20,      0, }, /* 150 */+  {    20,      5,     12,     55,    -32,     20,      0, }, /* 151 */+  {    20,      5,     12,     30,      1,     20,      0, }, /* 152 */+  {    20,      5,     12,     30,    -32,     20,      0, }, /* 153 */+  {    20,      5,     12,     43,    -32,     20,      0, }, /* 154 */+  {    20,      5,     12,     96,    -32,     20,      0, }, /* 155 */+  {    20,      5,     12,      0,    -64,     20,      0, }, /* 156 */+  {    20,      5,     12,      0,    -63,     20,      0, }, /* 157 */+  {    20,      9,     12,      0,      8,     20,      0, }, /* 158 */+  {    20,      5,     12,     34,    -30,     20,      0, }, /* 159 */+  {    20,      5,     12,     38,    -25,     20,      0, }, /* 160 */+  {    20,      9,     12,      0,      0,     20,      0, }, /* 161 */+  {    20,      5,     12,     43,    -15,     20,      0, }, /* 162 */+  {    20,      5,     12,     47,    -22,     20,      0, }, /* 163 */+  {    20,      5,     12,      0,     -8,     20,      0, }, /* 164 */+  {    11,      9,     12,      0,      1,     11,      0, }, /* 165 */+  {    11,      5,     12,      0,     -1,     11,      0, }, /* 166 */+  {    20,      5,     12,     51,    -54,     20,      0, }, /* 167 */+  {    20,      5,     12,     55,    -48,     20,      0, }, /* 168 */+  {    20,      5,     12,      0,      7,     20,      0, }, /* 169 */+  {    20,      5,     12,      0,   -116,     20,      0, }, /* 170 */+  {    20,      9,     12,     38,    -60,     20,      0, }, /* 171 */+  {    20,      5,     12,     59,    -64,     20,      0, }, /* 172 */+  {    20,     25,     12,      0,      0,     20,      0, }, /* 173 */+  {    20,      9,     12,      0,     -7,     20,      0, }, /* 174 */+  {    20,      9,     12,      0,   -130,     20,      0, }, /* 175 */+  {    13,      9,     12,      0,     80,     13,      0, }, /* 176 */+  {    13,      9,     12,      0,     32,     13,      0, }, /* 177 */+  {    13,      9,     12,     63,     32,     13,      0, }, /* 178 */+  {    13,      9,     12,     67,     32,     13,      0, }, /* 179 */+  {    13,      9,     12,     71,     32,     13,      0, }, /* 180 */+  {    13,      9,     12,     75,     32,     13,      0, }, /* 181 */+  {    13,      9,     12,     79,     32,     13,      0, }, /* 182 */+  {    13,      9,     12,     84,     32,     13,      0, }, /* 183 */+  {    13,      5,     12,      0,    -32,     13,      0, }, /* 184 */+  {    13,      5,     12,     63,    -32,     13,      0, }, /* 185 */+  {    13,      5,     12,     67,    -32,     13,      0, }, /* 186 */+  {    13,      5,     12,     71,    -32,     13,      0, }, /* 187 */+  {    13,      5,     12,     75,    -32,     13,      0, }, /* 188 */+  {    13,      5,     12,     79,    -32,     13,      0, }, /* 189 */+  {    13,      5,     12,     84,    -32,     13,      0, }, /* 190 */+  {    13,      5,     12,      0,    -80,     13,      0, }, /* 191 */+  {    13,      9,     12,      0,      1,     13,      0, }, /* 192 */+  {    13,      5,     12,      0,     -1,     13,      0, }, /* 193 */+  {    13,      9,     12,     88,      1,     13,      0, }, /* 194 */+  {    13,      5,     12,     88,     -1,     13,      0, }, /* 195 */+  {    13,     26,     12,      0,      0,     13,      0, }, /* 196 */+  {    13,     12,      3,      0,      0,    -31,      0, }, /* 197 */+  {    13,     12,      3,      0,      0,    -25,      0, }, /* 198 */+  {    28,     12,      3,      0,      0,    -28,      0, }, /* 199 */+  {    13,     11,      3,      0,      0,     13,      0, }, /* 200 */+  {    13,      9,     12,      0,     15,     13,      0, }, /* 201 */+  {    13,      5,     12,      0,    -15,     13,      0, }, /* 202 */+  {     2,      9,     12,      0,     48,      2,      0, }, /* 203 */+  {     2,      6,     12,      0,      0,      2,      0, }, /* 204 */+  {     2,     21,     12,      0,      0,      2,      0, }, /* 205 */+  {     2,      5,     12,      0,      0,      2,      0, }, /* 206 */+  {     2,      5,     12,      0,    -48,      2,      0, }, /* 207 */+  {     2,     17,     12,      0,      0,      2,      0, }, /* 208 */+  {     2,     26,     12,      0,      0,      2,      0, }, /* 209 */+  {     2,     23,     12,      0,      0,      2,      0, }, /* 210 */+  {    26,     12,      3,      0,      0,     26,      0, }, /* 211 */+  {    26,     17,     12,      0,      0,     26,      0, }, /* 212 */+  {    26,     21,     12,      0,      0,     26,      0, }, /* 213 */+  {    26,      7,     12,      0,      0,     26,      0, }, /* 214 */+  {     1,      1,      4,      0,      0,      1,      0, }, /* 215 */+  {    10,      1,      4,      0,      0,     10,      0, }, /* 216 */+  {     1,     25,     12,      0,      0,      1,      0, }, /* 217 */+  {     1,     21,     12,      0,      0,      1,      0, }, /* 218 */+  {     1,     23,     12,      0,      0,      1,      0, }, /* 219 */+  {    10,     21,     12,      0,      0,   -127,      0, }, /* 220 */+  {     1,     26,     12,      0,      0,      1,      0, }, /* 221 */+  {     1,     12,      3,      0,      0,      1,      0, }, /* 222 */+  {     1,      1,      2,      0,      0,    -76,      0, }, /* 223 */+  {     1,      7,     12,      0,      0,      1,      0, }, /* 224 */+  {    10,      6,     12,      0,      0,   -153,      0, }, /* 225 */+  {    28,     12,      3,      0,      0,     -7,      0, }, /* 226 */+  {     1,     13,     12,      0,      0,    -80,      0, }, /* 227 */+  {     1,     21,     12,      0,      0,     -4,      0, }, /* 228 */+  {     1,      6,     12,      0,      0,      1,      0, }, /* 229 */+  {     1,     13,     12,      0,      0,      1,      0, }, /* 230 */+  {    50,     21,     12,      0,      0,     50,      0, }, /* 231 */+  {    50,      1,      4,      0,      0,     50,      0, }, /* 232 */+  {    50,      7,     12,      0,      0,     50,      0, }, /* 233 */+  {    50,     12,      3,      0,      0,     50,      0, }, /* 234 */+  {    56,      7,     12,      0,      0,     56,      0, }, /* 235 */+  {    56,     12,      3,      0,      0,     56,      0, }, /* 236 */+  {    64,     13,     12,      0,      0,     64,      0, }, /* 237 */+  {    64,      7,     12,      0,      0,     64,      0, }, /* 238 */+  {    64,     12,      3,      0,      0,     64,      0, }, /* 239 */+  {    64,      6,     12,      0,      0,     64,      0, }, /* 240 */+  {    64,     26,     12,      0,      0,     64,      0, }, /* 241 */+  {    64,     21,     12,      0,      0,     64,      0, }, /* 242 */+  {    64,     23,     12,      0,      0,     64,      0, }, /* 243 */+  {    90,      7,     12,      0,      0,     90,      0, }, /* 244 */+  {    90,     12,      3,      0,      0,     90,      0, }, /* 245 */+  {    90,      6,     12,      0,      0,     90,      0, }, /* 246 */+  {    90,     21,     12,      0,      0,     90,      0, }, /* 247 */+  {    95,      7,     12,      0,      0,     95,      0, }, /* 248 */+  {    95,     12,      3,      0,      0,     95,      0, }, /* 249 */+  {    95,     21,     12,      0,      0,     95,      0, }, /* 250 */+  {    15,     12,      3,      0,      0,     15,      0, }, /* 251 */+  {    15,     10,      5,      0,      0,     15,      0, }, /* 252 */+  {    15,      7,     12,      0,      0,     15,      0, }, /* 253 */+  {    28,     12,      3,      0,      0,   -196,      0, }, /* 254 */+  {    28,     12,      3,      0,      0,   -183,      0, }, /* 255 */+  {    10,     21,     12,      0,      0,   -239,      0, }, /* 256 */+  {    10,     21,     12,      0,      0,   -260,      0, }, /* 257 */+  {    15,     13,     12,      0,      0,   -122,      0, }, /* 258 */+  {    15,     21,     12,      0,      0,     15,      0, }, /* 259 */+  {    15,      6,     12,      0,      0,     15,      0, }, /* 260 */+  {     3,      7,     12,      0,      0,      3,      0, }, /* 261 */+  {     3,     12,      3,      0,      0,      3,      0, }, /* 262 */+  {     3,     10,      5,      0,      0,      3,      0, }, /* 263 */+  {     3,     10,      3,      0,      0,      3,      0, }, /* 264 */+  {     3,     13,     12,      0,      0,    -84,      0, }, /* 265 */+  {     3,     23,     12,      0,      0,      3,      0, }, /* 266 */+  {     3,     15,     12,      0,      0,      3,      0, }, /* 267 */+  {     3,     26,     12,      0,      0,      3,      0, }, /* 268 */+  {     3,     21,     12,      0,      0,      3,      0, }, /* 269 */+  {    22,     12,      3,      0,      0,     22,      0, }, /* 270 */+  {    22,     10,      5,      0,      0,     22,      0, }, /* 271 */+  {    22,      7,     12,      0,      0,     22,      0, }, /* 272 */+  {    22,     13,     12,      0,      0,    -58,      0, }, /* 273 */+  {    22,     21,     12,      0,      0,     22,      0, }, /* 274 */+  {    21,     12,      3,      0,      0,     21,      0, }, /* 275 */+  {    21,     10,      5,      0,      0,     21,      0, }, /* 276 */+  {    21,      7,     12,      0,      0,     21,      0, }, /* 277 */+  {    21,     13,     12,      0,      0,    -55,      0, }, /* 278 */+  {    21,     21,     12,      0,      0,     21,      0, }, /* 279 */+  {    21,     23,     12,      0,      0,     21,      0, }, /* 280 */+  {    44,     12,      3,      0,      0,     44,      0, }, /* 281 */+  {    44,     10,      5,      0,      0,     44,      0, }, /* 282 */+  {    44,      7,     12,      0,      0,     44,      0, }, /* 283 */+  {    44,     10,      3,      0,      0,     44,      0, }, /* 284 */+  {    44,     13,     12,      0,      0,     44,      0, }, /* 285 */+  {    44,     26,     12,      0,      0,     44,      0, }, /* 286 */+  {    44,     15,     12,      0,      0,     44,      0, }, /* 287 */+  {    54,     12,      3,      0,      0,     54,      0, }, /* 288 */+  {    54,      7,     12,      0,      0,     54,      0, }, /* 289 */+  {    54,     10,      3,      0,      0,     54,      0, }, /* 290 */+  {    54,     10,      5,      0,      0,     54,      0, }, /* 291 */+  {    54,     13,     12,      0,      0,    -52,      0, }, /* 292 */+  {    54,     15,     12,      0,      0,    -52,      0, }, /* 293 */+  {    54,     26,     12,      0,      0,    -52,      0, }, /* 294 */+  {    54,     26,     12,      0,      0,     54,      0, }, /* 295 */+  {    54,     23,     12,      0,      0,     54,      0, }, /* 296 */+  {    55,     12,      3,      0,      0,     55,      0, }, /* 297 */+  {    55,     10,      5,      0,      0,     55,      0, }, /* 298 */+  {    55,      7,     12,      0,      0,     55,      0, }, /* 299 */+  {    55,     13,     12,      0,      0,     55,      0, }, /* 300 */+  {    55,     21,     12,      0,      0,     55,      0, }, /* 301 */+  {    55,     15,     12,      0,      0,     55,      0, }, /* 302 */+  {    55,     26,     12,      0,      0,     55,      0, }, /* 303 */+  {    29,      7,     12,      0,      0,     29,      0, }, /* 304 */+  {    29,     12,      3,      0,      0,     29,      0, }, /* 305 */+  {    29,     10,      5,      0,      0,     29,      0, }, /* 306 */+  {    29,     21,     12,      0,      0,     29,      0, }, /* 307 */+  {    29,     10,      3,      0,      0,     29,      0, }, /* 308 */+  {    29,     13,     12,      0,      0,    -67,      0, }, /* 309 */+  {    37,     12,      3,      0,      0,     37,      0, }, /* 310 */+  {    37,     10,      5,      0,      0,     37,      0, }, /* 311 */+  {    37,      7,     12,      0,      0,     37,      0, }, /* 312 */+  {    37,     10,      3,      0,      0,     37,      0, }, /* 313 */+  {    37,      7,      4,      0,      0,     37,      0, }, /* 314 */+  {    37,     26,     12,      0,      0,     37,      0, }, /* 315 */+  {    37,     15,     12,      0,      0,     37,      0, }, /* 316 */+  {    37,     13,     12,      0,      0,     37,      0, }, /* 317 */+  {    48,     12,      3,      0,      0,     48,      0, }, /* 318 */+  {    48,     10,      5,      0,      0,     48,      0, }, /* 319 */+  {    48,      7,     12,      0,      0,     48,      0, }, /* 320 */+  {    48,     10,      3,      0,      0,     48,      0, }, /* 321 */+  {    48,     13,     12,      0,      0,     48,      0, }, /* 322 */+  {    48,     21,     12,      0,      0,     48,      0, }, /* 323 */+  {    57,      7,     12,      0,      0,     57,      0, }, /* 324 */+  {    57,     12,      3,      0,      0,     57,      0, }, /* 325 */+  {    57,      7,      5,      0,      0,     57,      0, }, /* 326 */+  {    57,      6,     12,      0,      0,     57,      0, }, /* 327 */+  {    57,     21,     12,      0,      0,     57,      0, }, /* 328 */+  {    57,     13,     12,      0,      0,     57,      0, }, /* 329 */+  {    33,      7,     12,      0,      0,     33,      0, }, /* 330 */+  {    33,     12,      3,      0,      0,     33,      0, }, /* 331 */+  {    33,      7,      5,      0,      0,     33,      0, }, /* 332 */+  {    33,      6,     12,      0,      0,     33,      0, }, /* 333 */+  {    33,     13,     12,      0,      0,     33,      0, }, /* 334 */+  {    58,      7,     12,      0,      0,     58,      0, }, /* 335 */+  {    58,     26,     12,      0,      0,     58,      0, }, /* 336 */+  {    58,     21,     12,      0,      0,     58,      0, }, /* 337 */+  {    58,     12,      3,      0,      0,     58,      0, }, /* 338 */+  {    58,     13,     12,      0,      0,     58,      0, }, /* 339 */+  {    58,     15,     12,      0,      0,     58,      0, }, /* 340 */+  {    58,     22,     12,      0,      0,     58,      0, }, /* 341 */+  {    58,     18,     12,      0,      0,     58,      0, }, /* 342 */+  {    58,     10,      5,      0,      0,     58,      0, }, /* 343 */+  {    39,      7,     12,      0,      0,     39,      0, }, /* 344 */+  {    39,     10,     12,      0,      0,     39,      0, }, /* 345 */+  {    39,     12,      3,      0,      0,     39,      0, }, /* 346 */+  {    39,     10,      5,      0,      0,     39,      0, }, /* 347 */+  {    39,     13,     12,      0,      0,    -88,      0, }, /* 348 */+  {    39,     21,     12,      0,      0,     39,      0, }, /* 349 */+  {    39,     13,     12,      0,      0,     39,      0, }, /* 350 */+  {    39,     26,     12,      0,      0,     39,      0, }, /* 351 */+  {    17,      9,     12,      0,   7264,     17,      0, }, /* 352 */+  {    17,      5,     12,      0,   3008,     17,      0, }, /* 353 */+  {    10,     21,     12,      0,      0,    -49,      0, }, /* 354 */+  {    17,      6,     12,      0,      0,     17,      0, }, /* 355 */+  {    24,      7,      6,      0,      0,     24,      0, }, /* 356 */+  {    24,      7,      7,      0,      0,     24,      0, }, /* 357 */+  {    24,      7,      8,      0,      0,     24,      0, }, /* 358 */+  {    16,      7,     12,      0,      0,     16,      0, }, /* 359 */+  {    16,     12,      3,      0,      0,     16,      0, }, /* 360 */+  {    16,     21,     12,      0,      0,     16,      0, }, /* 361 */+  {    16,     15,     12,      0,      0,     16,      0, }, /* 362 */+  {    16,     26,     12,      0,      0,     16,      0, }, /* 363 */+  {     9,      9,     12,      0,  38864,      9,      0, }, /* 364 */+  {     9,      9,     12,      0,      8,      9,      0, }, /* 365 */+  {     9,      5,     12,      0,     -8,      9,      0, }, /* 366 */+  {     8,     17,     12,      0,      0,      8,      0, }, /* 367 */+  {     8,      7,     12,      0,      0,      8,      0, }, /* 368 */+  {     8,     26,     12,      0,      0,      8,      0, }, /* 369 */+  {     8,     21,     12,      0,      0,      8,      0, }, /* 370 */+  {    41,     29,     12,      0,      0,     41,      0, }, /* 371 */+  {    41,      7,     12,      0,      0,     41,      0, }, /* 372 */+  {    41,     22,     12,      0,      0,     41,      0, }, /* 373 */+  {    41,     18,     12,      0,      0,     41,      0, }, /* 374 */+  {    46,      7,     12,      0,      0,     46,      0, }, /* 375 */+  {    46,     14,     12,      0,      0,     46,      0, }, /* 376 */+  {    51,      7,     12,      0,      0,     51,      0, }, /* 377 */+  {    51,     12,      3,      0,      0,     51,      0, }, /* 378 */+  {    25,      7,     12,      0,      0,     25,      0, }, /* 379 */+  {    25,     12,      3,      0,      0,     25,      0, }, /* 380 */+  {    10,     21,     12,      0,      0,   -117,      0, }, /* 381 */+  {     7,      7,     12,      0,      0,      7,      0, }, /* 382 */+  {     7,     12,      3,      0,      0,      7,      0, }, /* 383 */+  {    52,      7,     12,      0,      0,     52,      0, }, /* 384 */+  {    52,     12,      3,      0,      0,     52,      0, }, /* 385 */+  {    32,      7,     12,      0,      0,     32,      0, }, /* 386 */+  {    32,     12,      3,      0,      0,     32,      0, }, /* 387 */+  {    32,     10,      5,      0,      0,     32,      0, }, /* 388 */+  {    32,     21,     12,      0,      0,     32,      0, }, /* 389 */+  {    32,      6,     12,      0,      0,     32,      0, }, /* 390 */+  {    32,     23,     12,      0,      0,     32,      0, }, /* 391 */+  {    32,     13,     12,      0,      0,     32,      0, }, /* 392 */+  {    32,     15,     12,      0,      0,     32,      0, }, /* 393 */+  {    38,     21,     12,      0,      0,     38,      0, }, /* 394 */+  {    10,     21,     12,      0,      0,    -73,      0, }, /* 395 */+  {    38,     17,     12,      0,      0,     38,      0, }, /* 396 */+  {    38,     12,      3,      0,      0,     38,      0, }, /* 397 */+  {    38,      1,      2,      0,      0,     38,      0, }, /* 398 */+  {    38,     13,     12,      0,      0,     38,      0, }, /* 399 */+  {    38,      7,     12,      0,      0,     38,      0, }, /* 400 */+  {    38,      6,     12,      0,      0,     38,      0, }, /* 401 */+  {    35,      7,     12,      0,      0,     35,      0, }, /* 402 */+  {    35,     12,      3,      0,      0,     35,      0, }, /* 403 */+  {    35,     10,      5,      0,      0,     35,      0, }, /* 404 */+  {    35,     26,     12,      0,      0,     35,      0, }, /* 405 */+  {    35,     21,     12,      0,      0,     35,      0, }, /* 406 */+  {    35,     13,     12,      0,      0,     35,      0, }, /* 407 */+  {    53,      7,     12,      0,      0,     53,      0, }, /* 408 */+  {    40,      7,     12,      0,      0,     40,      0, }, /* 409 */+  {    40,     13,     12,      0,      0,     40,      0, }, /* 410 */+  {    40,     15,     12,      0,      0,     40,      0, }, /* 411 */+  {    40,     26,     12,      0,      0,     40,      0, }, /* 412 */+  {    32,     26,     12,      0,      0,     32,      0, }, /* 413 */+  {     6,      7,     12,      0,      0,      6,      0, }, /* 414 */+  {     6,     12,      3,      0,      0,      6,      0, }, /* 415 */+  {     6,     10,      5,      0,      0,      6,      0, }, /* 416 */+  {     6,     21,     12,      0,      0,      6,      0, }, /* 417 */+  {    91,      7,     12,      0,      0,     91,      0, }, /* 418 */+  {    91,     10,      5,      0,      0,     91,      0, }, /* 419 */+  {    91,     12,      3,      0,      0,     91,      0, }, /* 420 */+  {    91,     10,     12,      0,      0,     91,      0, }, /* 421 */+  {    91,     13,     12,      0,      0,     91,      0, }, /* 422 */+  {    91,     21,     12,      0,      0,     91,      0, }, /* 423 */+  {    91,      6,     12,      0,      0,     91,      0, }, /* 424 */+  {    28,     11,      3,      0,      0,     28,      0, }, /* 425 */+  {    62,     12,      3,      0,      0,     62,      0, }, /* 426 */+  {    62,     10,      5,      0,      0,     62,      0, }, /* 427 */+  {    62,      7,     12,      0,      0,     62,      0, }, /* 428 */+  {    62,     10,      3,      0,      0,     62,      0, }, /* 429 */+  {    62,     13,     12,      0,      0,     62,      0, }, /* 430 */+  {    62,     21,     12,      0,      0,     62,      0, }, /* 431 */+  {    62,     26,     12,      0,      0,     62,      0, }, /* 432 */+  {    76,     12,      3,      0,      0,     76,      0, }, /* 433 */+  {    76,     10,      5,      0,      0,     76,      0, }, /* 434 */+  {    76,      7,     12,      0,      0,     76,      0, }, /* 435 */+  {    76,     13,     12,      0,      0,     76,      0, }, /* 436 */+  {    93,      7,     12,      0,      0,     93,      0, }, /* 437 */+  {    93,     12,      3,      0,      0,     93,      0, }, /* 438 */+  {    93,     10,      5,      0,      0,     93,      0, }, /* 439 */+  {    93,     21,     12,      0,      0,     93,      0, }, /* 440 */+  {    70,      7,     12,      0,      0,     70,      0, }, /* 441 */+  {    70,     10,      5,      0,      0,     70,      0, }, /* 442 */+  {    70,     12,      3,      0,      0,     70,      0, }, /* 443 */+  {    70,     21,     12,      0,      0,     70,      0, }, /* 444 */+  {    70,     13,     12,      0,      0,     70,      0, }, /* 445 */+  {    73,     13,     12,      0,      0,     73,      0, }, /* 446 */+  {    73,      7,     12,      0,      0,     73,      0, }, /* 447 */+  {    73,      6,     12,      0,      0,     73,      0, }, /* 448 */+  {    73,     21,     12,      0,      0,     73,      0, }, /* 449 */+  {    13,      5,     12,     63,  -6222,     13,      0, }, /* 450 */+  {    13,      5,     12,     67,  -6221,     13,      0, }, /* 451 */+  {    13,      5,     12,     71,  -6212,     13,      0, }, /* 452 */+  {    13,      5,     12,     75,  -6210,     13,      0, }, /* 453 */+  {    13,      5,     12,     79,  -6210,     13,      0, }, /* 454 */+  {    13,      5,     12,     79,  -6211,     13,      0, }, /* 455 */+  {    13,      5,     12,     84,  -6204,     13,      0, }, /* 456 */+  {    13,      5,     12,     88,  -6180,     13,      0, }, /* 457 */+  {    13,      5,     12,    108,  35267,     13,      0, }, /* 458 */+  {    17,      9,     12,      0,  -3008,     17,      0, }, /* 459 */+  {    76,     21,     12,      0,      0,     76,      0, }, /* 460 */+  {    28,     12,      3,      0,      0,   -112,      0, }, /* 461 */+  {    28,     12,      3,      0,      0,     15,      0, }, /* 462 */+  {    10,     21,     12,      0,      0,    -37,      0, }, /* 463 */+  {    28,     12,      3,      0,      0,    -13,      0, }, /* 464 */+  {    28,     12,      3,      0,      0,    -43,      0, }, /* 465 */+  {    28,     12,      3,      0,      0,   -146,      0, }, /* 466 */+  {    10,     10,      5,      0,      0,    -13,      0, }, /* 467 */+  {    10,      7,     12,      0,      0,    -40,      0, }, /* 468 */+  {    10,      7,     12,      0,      0,    -13,      0, }, /* 469 */+  {    10,      7,     12,      0,      0,     15,      0, }, /* 470 */+  {    10,      7,     12,      0,      0,   -162,      0, }, /* 471 */+  {    10,      7,     12,      0,      0,    -37,      0, }, /* 472 */+  {    28,     12,      3,      0,      0,    -96,      0, }, /* 473 */+  {    10,     10,      5,      0,      0,      3,      0, }, /* 474 */+  {    28,     12,      3,      0,      0,    -37,      0, }, /* 475 */+  {    10,      7,     12,      0,      0,    150,      0, }, /* 476 */+  {    13,      5,     12,      0,      0,     13,      0, }, /* 477 */+  {    13,      6,     12,      0,      0,     13,      0, }, /* 478 */+  {    34,      5,     12,      0,  35332,     34,      0, }, /* 479 */+  {    34,      5,     12,      0,   3814,     34,      0, }, /* 480 */+  {    34,      5,     12,      0,  35384,     34,      0, }, /* 481 */+  {    28,     12,      3,      0,      0,    -34,      0, }, /* 482 */+  {    34,      9,     12,     92,      1,     34,      0, }, /* 483 */+  {    34,      5,     12,     92,     -1,     34,      0, }, /* 484 */+  {    34,      5,     12,     92,    -58,     34,      0, }, /* 485 */+  {    34,      9,     12,      0,  -7615,     34,      0, }, /* 486 */+  {    20,      5,     12,      0,      8,     20,      0, }, /* 487 */+  {    20,      9,     12,      0,     -8,     20,      0, }, /* 488 */+  {    20,      5,     12,      0,     74,     20,      0, }, /* 489 */+  {    20,      5,     12,      0,     86,     20,      0, }, /* 490 */+  {    20,      5,     12,      0,    100,     20,      0, }, /* 491 */+  {    20,      5,     12,      0,    128,     20,      0, }, /* 492 */+  {    20,      5,     12,      0,    112,     20,      0, }, /* 493 */+  {    20,      5,     12,      0,    126,     20,      0, }, /* 494 */+  {    20,      8,     12,      0,     -8,     20,      0, }, /* 495 */+  {    20,      5,     12,      0,      9,     20,      0, }, /* 496 */+  {    20,      9,     12,      0,    -74,     20,      0, }, /* 497 */+  {    20,      8,     12,      0,     -9,     20,      0, }, /* 498 */+  {    20,      5,     12,     21,  -7173,     20,      0, }, /* 499 */+  {    20,      9,     12,      0,    -86,     20,      0, }, /* 500 */+  {    20,      9,     12,      0,   -100,     20,      0, }, /* 501 */+  {    20,      9,     12,      0,   -112,     20,      0, }, /* 502 */+  {    20,      9,     12,      0,   -128,     20,      0, }, /* 503 */+  {    20,      9,     12,      0,   -126,     20,      0, }, /* 504 */+  {    28,      1,      3,      0,      0,     28,      0, }, /* 505 */+  {    28,      1,     13,      0,      0,     28,      0, }, /* 506 */+  {    10,     27,      2,      0,      0,     10,      0, }, /* 507 */+  {    10,     28,      2,      0,      0,     10,      0, }, /* 508 */+  {    10,     29,     12,      0,      0,    -70,      0, }, /* 509 */+  {    10,     21,     14,      0,      0,     10,      0, }, /* 510 */+  {     0,      2,      2,      0,      0,      0,      0, }, /* 511 */+  {    28,     12,      3,      0,      0,   -100,      0, }, /* 512 */+  {    10,      9,     12,      0,      0,     10,      0, }, /* 513 */+  {    10,      5,     12,      0,      0,     10,      0, }, /* 514 */+  {    20,      9,     12,     96,  -7517,     20,      0, }, /* 515 */+  {    34,      9,     12,    100,  -8383,     34,      0, }, /* 516 */+  {    34,      9,     12,    104,  -8262,     34,      0, }, /* 517 */+  {    34,      9,     12,      0,     28,     34,      0, }, /* 518 */+  {    10,      7,     12,      0,      0,     10,      0, }, /* 519 */+  {    10,      5,     14,      0,      0,     10,      0, }, /* 520 */+  {    34,      5,     12,      0,    -28,     34,      0, }, /* 521 */+  {    34,     14,     12,      0,     16,     34,      0, }, /* 522 */+  {    34,     14,     12,      0,    -16,     34,      0, }, /* 523 */+  {    34,     14,     12,      0,      0,     34,      0, }, /* 524 */+  {    10,     25,     14,      0,      0,     10,      0, }, /* 525 */+  {    10,     26,     12,      0,     26,     10,      0, }, /* 526 */+  {    10,     26,     14,      0,     26,     10,      0, }, /* 527 */+  {    10,     26,     12,      0,    -26,     10,      0, }, /* 528 */+  {     5,     26,     12,      0,      0,      5,      0, }, /* 529 */+  {    18,      9,     12,      0,     48,     18,      0, }, /* 530 */+  {    18,      5,     12,      0,    -48,     18,      0, }, /* 531 */+  {    34,      9,     12,      0, -10743,     34,      0, }, /* 532 */+  {    34,      9,     12,      0,  -3814,     34,      0, }, /* 533 */+  {    34,      9,     12,      0, -10727,     34,      0, }, /* 534 */+  {    34,      5,     12,      0, -10795,     34,      0, }, /* 535 */+  {    34,      5,     12,      0, -10792,     34,      0, }, /* 536 */+  {    34,      9,     12,      0, -10780,     34,      0, }, /* 537 */+  {    34,      9,     12,      0, -10749,     34,      0, }, /* 538 */+  {    34,      9,     12,      0, -10783,     34,      0, }, /* 539 */+  {    34,      9,     12,      0, -10782,     34,      0, }, /* 540 */+  {    34,      9,     12,      0, -10815,     34,      0, }, /* 541 */+  {    11,      5,     12,      0,      0,     11,      0, }, /* 542 */+  {    11,     26,     12,      0,      0,     11,      0, }, /* 543 */+  {    11,     12,      3,      0,      0,     11,      0, }, /* 544 */+  {    11,     21,     12,      0,      0,     11,      0, }, /* 545 */+  {    11,     15,     12,      0,      0,     11,      0, }, /* 546 */+  {    17,      5,     12,      0,  -7264,     17,      0, }, /* 547 */+  {    59,      7,     12,      0,      0,     59,      0, }, /* 548 */+  {    59,      6,     12,      0,      0,     59,      0, }, /* 549 */+  {    59,     21,     12,      0,      0,     59,      0, }, /* 550 */+  {    59,     12,      3,      0,      0,     59,      0, }, /* 551 */+  {    13,     12,      3,      0,      0,     13,      0, }, /* 552 */+  {    10,     21,     12,      0,      0,    -25,      0, }, /* 553 */+  {    23,     26,     12,      0,      0,     23,      0, }, /* 554 */+  {    10,     21,     12,      0,      0,   -139,      0, }, /* 555 */+  {    10,     21,     12,      0,      0,   -133,      0, }, /* 556 */+  {    23,      6,     12,      0,      0,     23,      0, }, /* 557 */+  {    10,      7,     12,      0,      0,     23,      0, }, /* 558 */+  {    23,     14,     12,      0,      0,     23,      0, }, /* 559 */+  {    10,     22,     12,      0,      0,   -139,      0, }, /* 560 */+  {    10,     18,     12,      0,      0,   -139,      0, }, /* 561 */+  {    10,     26,     12,      0,      0,   -133,      0, }, /* 562 */+  {    10,     17,     12,      0,      0,   -133,      0, }, /* 563 */+  {    10,     22,     12,      0,      0,   -133,      0, }, /* 564 */+  {    10,     18,     12,      0,      0,   -133,      0, }, /* 565 */+  {    28,     12,      3,      0,      0,    -16,      0, }, /* 566 */+  {    24,     10,      3,      0,      0,     24,      0, }, /* 567 */+  {    10,     17,     14,      0,      0,   -133,      0, }, /* 568 */+  {    10,      6,     12,      0,      0,    -64,      0, }, /* 569 */+  {    10,      7,     12,      0,      0,   -104,      0, }, /* 570 */+  {    10,     21,     14,      0,      0,   -104,      0, }, /* 571 */+  {    10,     26,     12,      0,      0,     23,      0, }, /* 572 */+  {    27,      7,     12,      0,      0,     27,      0, }, /* 573 */+  {    28,     12,      3,      0,      0,    -64,      0, }, /* 574 */+  {    10,     24,     12,      0,      0,    -64,      0, }, /* 575 */+  {    27,      6,     12,      0,      0,     27,      0, }, /* 576 */+  {    10,     17,     12,      0,      0,    -64,      0, }, /* 577 */+  {    30,      7,     12,      0,      0,     30,      0, }, /* 578 */+  {    30,      6,     12,      0,      0,     30,      0, }, /* 579 */+  {     4,      7,     12,      0,      0,      4,      0, }, /* 580 */+  {    24,      7,     12,      0,      0,     24,      0, }, /* 581 */+  {    10,     15,     12,      0,      0,     23,      0, }, /* 582 */+  {    24,     26,     12,      0,      0,     24,      0, }, /* 583 */+  {    10,     26,     14,      0,      0,     23,      0, }, /* 584 */+  {    30,     26,     12,      0,      0,     30,      0, }, /* 585 */+  {    23,      7,     12,      0,      0,     23,      0, }, /* 586 */+  {    61,      7,     12,      0,      0,     61,      0, }, /* 587 */+  {    61,      6,     12,      0,      0,     61,      0, }, /* 588 */+  {    61,     26,     12,      0,      0,     61,      0, }, /* 589 */+  {    86,      7,     12,      0,      0,     86,      0, }, /* 590 */+  {    86,      6,     12,      0,      0,     86,      0, }, /* 591 */+  {    86,     21,     12,      0,      0,     86,      0, }, /* 592 */+  {    77,      7,     12,      0,      0,     77,      0, }, /* 593 */+  {    77,      6,     12,      0,      0,     77,      0, }, /* 594 */+  {    77,     21,     12,      0,      0,     77,      0, }, /* 595 */+  {    77,     13,     12,      0,      0,     77,      0, }, /* 596 */+  {    13,      9,     12,    108,      1,     13,      0, }, /* 597 */+  {    13,      5,     12,    108, -35267,     13,      0, }, /* 598 */+  {    13,      7,     12,      0,      0,     13,      0, }, /* 599 */+  {    13,     21,     12,      0,      0,     13,      0, }, /* 600 */+  {    79,      7,     12,      0,      0,     79,      0, }, /* 601 */+  {    79,     14,     12,      0,      0,     79,      0, }, /* 602 */+  {    79,     12,      3,      0,      0,     79,      0, }, /* 603 */+  {    79,     21,     12,      0,      0,     79,      0, }, /* 604 */+  {    10,     24,     12,      0,      0,    -61,      0, }, /* 605 */+  {    34,      9,     12,      0, -35332,     34,      0, }, /* 606 */+  {    34,      9,     12,      0, -42280,     34,      0, }, /* 607 */+  {    34,      5,     12,      0,     48,     34,      0, }, /* 608 */+  {    34,      9,     12,      0, -42308,     34,      0, }, /* 609 */+  {    34,      9,     12,      0, -42319,     34,      0, }, /* 610 */+  {    34,      9,     12,      0, -42315,     34,      0, }, /* 611 */+  {    34,      9,     12,      0, -42305,     34,      0, }, /* 612 */+  {    34,      9,     12,      0, -42258,     34,      0, }, /* 613 */+  {    34,      9,     12,      0, -42282,     34,      0, }, /* 614 */+  {    34,      9,     12,      0, -42261,     34,      0, }, /* 615 */+  {    34,      9,     12,      0,    928,     34,      0, }, /* 616 */+  {    34,      9,     12,      0,    -48,     34,      0, }, /* 617 */+  {    34,      9,     12,      0, -42307,     34,      0, }, /* 618 */+  {    34,      9,     12,      0, -35384,     34,      0, }, /* 619 */+  {    49,      7,     12,      0,      0,     49,      0, }, /* 620 */+  {    49,     12,      3,      0,      0,     49,      0, }, /* 621 */+  {    49,     10,      5,      0,      0,     49,      0, }, /* 622 */+  {    49,     26,     12,      0,      0,     49,      0, }, /* 623 */+  {    10,     15,     12,      0,      0,   -224,      0, }, /* 624 */+  {    10,     15,     12,      0,      0,   -210,      0, }, /* 625 */+  {    10,     26,     12,      0,      0,   -171,      0, }, /* 626 */+  {    10,     23,     12,      0,      0,   -171,      0, }, /* 627 */+  {    65,      7,     12,      0,      0,     65,      0, }, /* 628 */+  {    65,     21,     12,      0,      0,     65,      0, }, /* 629 */+  {    75,     10,      5,      0,      0,     75,      0, }, /* 630 */+  {    75,      7,     12,      0,      0,     75,      0, }, /* 631 */+  {    75,     12,      3,      0,      0,     75,      0, }, /* 632 */+  {    75,     21,     12,      0,      0,     75,      0, }, /* 633 */+  {    75,     13,     12,      0,      0,     75,      0, }, /* 634 */+  {    15,     12,      3,      0,      0,    -13,      0, }, /* 635 */+  {    15,      7,     12,      0,      0,    -46,      0, }, /* 636 */+  {    69,     13,     12,      0,      0,     69,      0, }, /* 637 */+  {    69,      7,     12,      0,      0,     69,      0, }, /* 638 */+  {    69,     12,      3,      0,      0,     69,      0, }, /* 639 */+  {    10,     21,     12,      0,      0,   -108,      0, }, /* 640 */+  {    69,     21,     12,      0,      0,     69,      0, }, /* 641 */+  {    74,      7,     12,      0,      0,     74,      0, }, /* 642 */+  {    74,     12,      3,      0,      0,     74,      0, }, /* 643 */+  {    74,     10,      5,      0,      0,     74,      0, }, /* 644 */+  {    74,     21,     12,      0,      0,     74,      0, }, /* 645 */+  {    84,     12,      3,      0,      0,     84,      0, }, /* 646 */+  {    84,     10,      5,      0,      0,     84,      0, }, /* 647 */+  {    84,      7,     12,      0,      0,     84,      0, }, /* 648 */+  {    84,     21,     12,      0,      0,     84,      0, }, /* 649 */+  {    10,      6,     12,      0,      0,    -19,      0, }, /* 650 */+  {    84,     13,     12,      0,      0,     84,      0, }, /* 651 */+  {    39,      6,     12,      0,      0,     39,      0, }, /* 652 */+  {    68,      7,     12,      0,      0,     68,      0, }, /* 653 */+  {    68,     12,      3,      0,      0,     68,      0, }, /* 654 */+  {    68,     10,      5,      0,      0,     68,      0, }, /* 655 */+  {    68,     13,     12,      0,      0,     68,      0, }, /* 656 */+  {    68,     21,     12,      0,      0,     68,      0, }, /* 657 */+  {    92,      7,     12,      0,      0,     92,      0, }, /* 658 */+  {    92,     12,      3,      0,      0,     92,      0, }, /* 659 */+  {    92,      6,     12,      0,      0,     92,      0, }, /* 660 */+  {    92,     21,     12,      0,      0,     92,      0, }, /* 661 */+  {    87,      7,     12,      0,      0,     87,      0, }, /* 662 */+  {    87,     10,      5,      0,      0,     87,      0, }, /* 663 */+  {    87,     12,      3,      0,      0,     87,      0, }, /* 664 */+  {    87,     21,     12,      0,      0,     87,      0, }, /* 665 */+  {    87,      6,     12,      0,      0,     87,      0, }, /* 666 */+  {    34,      5,     12,      0,   -928,     34,      0, }, /* 667 */+  {     9,      5,     12,      0, -38864,      9,      0, }, /* 668 */+  {    87,     13,     12,      0,      0,     87,      0, }, /* 669 */+  {    24,      7,      9,      0,      0,     24,      0, }, /* 670 */+  {    24,      7,     10,      0,      0,     24,      0, }, /* 671 */+  {     0,      4,     12,      0,      0,      0,      0, }, /* 672 */+  {     0,      3,     12,      0,      0,      0,      0, }, /* 673 */+  {    26,     25,     12,      0,      0,     26,      0, }, /* 674 */+  {     1,     24,     12,      0,      0,      1,      0, }, /* 675 */+  {     1,      7,     12,      0,      0,    -10,      0, }, /* 676 */+  {     1,     26,     12,      0,      0,    -10,      0, }, /* 677 */+  {    10,      6,      3,      0,      0,    -64,      0, }, /* 678 */+  {    36,      7,     12,      0,      0,     36,      0, }, /* 679 */+  {    10,     21,     12,      0,      0,    -22,      0, }, /* 680 */+  {    10,     15,     12,      0,      0,    -92,      0, }, /* 681 */+  {    10,     26,     12,      0,      0,    -22,      0, }, /* 682 */+  {    20,     14,     12,      0,      0,     20,      0, }, /* 683 */+  {    20,     15,     12,      0,      0,     20,      0, }, /* 684 */+  {    20,     26,     12,      0,      0,     20,      0, }, /* 685 */+  {    71,      7,     12,      0,      0,     71,      0, }, /* 686 */+  {    67,      7,     12,      0,      0,     67,      0, }, /* 687 */+  {    28,     12,      3,      0,      0,     -1,      0, }, /* 688 */+  {    10,     15,     12,      0,      0,     -1,      0, }, /* 689 */+  {    42,      7,     12,      0,      0,     42,      0, }, /* 690 */+  {    42,     15,     12,      0,      0,     42,      0, }, /* 691 */+  {    19,      7,     12,      0,      0,     19,      0, }, /* 692 */+  {    19,     14,     12,      0,      0,     19,      0, }, /* 693 */+  {   118,      7,     12,      0,      0,    118,      0, }, /* 694 */+  {   118,     12,      3,      0,      0,    118,      0, }, /* 695 */+  {    60,      7,     12,      0,      0,     60,      0, }, /* 696 */+  {    60,     21,     12,      0,      0,     60,      0, }, /* 697 */+  {    43,      7,     12,      0,      0,     43,      0, }, /* 698 */+  {    43,     21,     12,      0,      0,     43,      0, }, /* 699 */+  {    43,     14,     12,      0,      0,     43,      0, }, /* 700 */+  {    14,      9,     12,      0,     40,     14,      0, }, /* 701 */+  {    14,      5,     12,      0,    -40,     14,      0, }, /* 702 */+  {    47,      7,     12,      0,      0,     47,      0, }, /* 703 */+  {    45,      7,     12,      0,      0,     45,      0, }, /* 704 */+  {    45,     13,     12,      0,      0,     45,      0, }, /* 705 */+  {   136,      9,     12,      0,     40,    136,      0, }, /* 706 */+  {   136,      5,     12,      0,    -40,    136,      0, }, /* 707 */+  {   106,      7,     12,      0,      0,    106,      0, }, /* 708 */+  {   104,      7,     12,      0,      0,    104,      0, }, /* 709 */+  {   104,     21,     12,      0,      0,    104,      0, }, /* 710 */+  {   110,      7,     12,      0,      0,    110,      0, }, /* 711 */+  {    12,      7,     12,      0,      0,     12,      0, }, /* 712 */+  {    81,      7,     12,      0,      0,     81,      0, }, /* 713 */+  {    81,     21,     12,      0,      0,     81,      0, }, /* 714 */+  {    81,     15,     12,      0,      0,     81,      0, }, /* 715 */+  {   120,      7,     12,      0,      0,    120,      0, }, /* 716 */+  {   120,     26,     12,      0,      0,    120,      0, }, /* 717 */+  {   120,     15,     12,      0,      0,    120,      0, }, /* 718 */+  {   116,      7,     12,      0,      0,    116,      0, }, /* 719 */+  {   116,     15,     12,      0,      0,    116,      0, }, /* 720 */+  {   128,      7,     12,      0,      0,    128,      0, }, /* 721 */+  {   128,     15,     12,      0,      0,    128,      0, }, /* 722 */+  {    66,      7,     12,      0,      0,     66,      0, }, /* 723 */+  {    66,     15,     12,      0,      0,     66,      0, }, /* 724 */+  {    66,     21,     12,      0,      0,     66,      0, }, /* 725 */+  {    72,      7,     12,      0,      0,     72,      0, }, /* 726 */+  {    72,     21,     12,      0,      0,     72,      0, }, /* 727 */+  {    98,      7,     12,      0,      0,     98,      0, }, /* 728 */+  {    97,      7,     12,      0,      0,     97,      0, }, /* 729 */+  {    97,     15,     12,      0,      0,     97,      0, }, /* 730 */+  {    31,      7,     12,      0,      0,     31,      0, }, /* 731 */+  {    31,     12,      3,      0,      0,     31,      0, }, /* 732 */+  {    31,     15,     12,      0,      0,     31,      0, }, /* 733 */+  {    31,     21,     12,      0,      0,     31,      0, }, /* 734 */+  {    88,      7,     12,      0,      0,     88,      0, }, /* 735 */+  {    88,     15,     12,      0,      0,     88,      0, }, /* 736 */+  {    88,     21,     12,      0,      0,     88,      0, }, /* 737 */+  {   117,      7,     12,      0,      0,    117,      0, }, /* 738 */+  {   117,     15,     12,      0,      0,    117,      0, }, /* 739 */+  {   112,      7,     12,      0,      0,    112,      0, }, /* 740 */+  {   112,     26,     12,      0,      0,    112,      0, }, /* 741 */+  {   112,     12,      3,      0,      0,    112,      0, }, /* 742 */+  {   112,     15,     12,      0,      0,    112,      0, }, /* 743 */+  {   112,     21,     12,      0,      0,    112,      0, }, /* 744 */+  {    78,      7,     12,      0,      0,     78,      0, }, /* 745 */+  {    78,     21,     12,      0,      0,     78,      0, }, /* 746 */+  {    83,      7,     12,      0,      0,     83,      0, }, /* 747 */+  {    83,     15,     12,      0,      0,     83,      0, }, /* 748 */+  {    82,      7,     12,      0,      0,     82,      0, }, /* 749 */+  {    82,     15,     12,      0,      0,     82,      0, }, /* 750 */+  {   121,      7,     12,      0,      0,    121,      0, }, /* 751 */+  {   121,     21,     12,      0,      0,    121,      0, }, /* 752 */+  {   121,     15,     12,      0,      0,    121,      0, }, /* 753 */+  {    89,      7,     12,      0,      0,     89,      0, }, /* 754 */+  {   130,      9,     12,      0,     64,    130,      0, }, /* 755 */+  {   130,      5,     12,      0,    -64,    130,      0, }, /* 756 */+  {   130,     15,     12,      0,      0,    130,      0, }, /* 757 */+  {   144,      7,     12,      0,      0,    144,      0, }, /* 758 */+  {   144,     12,      3,      0,      0,    144,      0, }, /* 759 */+  {   144,     13,     12,      0,      0,    144,      0, }, /* 760 */+  {     1,     15,     12,      0,      0,      1,      0, }, /* 761 */+  {   156,      7,     12,      0,      0,    156,      0, }, /* 762 */+  {   156,     12,      3,      0,      0,    156,      0, }, /* 763 */+  {   156,     17,     12,      0,      0,    156,      0, }, /* 764 */+  {   147,      7,     12,      0,      0,    147,      0, }, /* 765 */+  {   147,     15,     12,      0,      0,    147,      0, }, /* 766 */+  {   148,      7,     12,      0,      0,    148,      0, }, /* 767 */+  {   148,     12,      3,      0,      0,    148,      0, }, /* 768 */+  {   148,     15,     12,      0,      0,    148,      0, }, /* 769 */+  {   148,     21,     12,      0,      0,    148,      0, }, /* 770 */+  {   153,      7,     12,      0,      0,    153,      0, }, /* 771 */+  {   153,     15,     12,      0,      0,    153,      0, }, /* 772 */+  {   149,      7,     12,      0,      0,    149,      0, }, /* 773 */+  {    94,     10,      5,      0,      0,     94,      0, }, /* 774 */+  {    94,     12,      3,      0,      0,     94,      0, }, /* 775 */+  {    94,      7,     12,      0,      0,     94,      0, }, /* 776 */+  {    94,     21,     12,      0,      0,     94,      0, }, /* 777 */+  {    94,     15,     12,      0,      0,     94,      0, }, /* 778 */+  {    94,     13,     12,      0,      0,     94,      0, }, /* 779 */+  {    85,     12,      3,      0,      0,     85,      0, }, /* 780 */+  {    85,     10,      5,      0,      0,     85,      0, }, /* 781 */+  {    85,      7,     12,      0,      0,     85,      0, }, /* 782 */+  {    85,     21,     12,      0,      0,     85,      0, }, /* 783 */+  {    85,      1,      4,      0,      0,     85,      0, }, /* 784 */+  {   101,      7,     12,      0,      0,    101,      0, }, /* 785 */+  {   101,     13,     12,      0,      0,    101,      0, }, /* 786 */+  {    96,     12,      3,      0,      0,     96,      0, }, /* 787 */+  {    96,      7,     12,      0,      0,     96,      0, }, /* 788 */+  {    96,     10,      5,      0,      0,     96,      0, }, /* 789 */+  {    96,     13,     12,      0,      0,     96,      0, }, /* 790 */+  {    96,     21,     12,      0,      0,     96,      0, }, /* 791 */+  {   111,      7,     12,      0,      0,    111,      0, }, /* 792 */+  {   111,     12,      3,      0,      0,    111,      0, }, /* 793 */+  {   111,     21,     12,      0,      0,    111,      0, }, /* 794 */+  {   100,     12,      3,      0,      0,    100,      0, }, /* 795 */+  {   100,     10,      5,      0,      0,    100,      0, }, /* 796 */+  {   100,      7,     12,      0,      0,    100,      0, }, /* 797 */+  {   100,      7,      4,      0,      0,    100,      0, }, /* 798 */+  {   100,     21,     12,      0,      0,    100,      0, }, /* 799 */+  {   100,     13,     12,      0,      0,    100,      0, }, /* 800 */+  {    48,     15,     12,      0,      0,     48,      0, }, /* 801 */+  {   108,      7,     12,      0,      0,    108,      0, }, /* 802 */+  {   108,     10,      5,      0,      0,    108,      0, }, /* 803 */+  {   108,     12,      3,      0,      0,    108,      0, }, /* 804 */+  {   108,     21,     12,      0,      0,    108,      0, }, /* 805 */+  {   129,      7,     12,      0,      0,    129,      0, }, /* 806 */+  {   129,     21,     12,      0,      0,    129,      0, }, /* 807 */+  {   109,      7,     12,      0,      0,    109,      0, }, /* 808 */+  {   109,     12,      3,      0,      0,    109,      0, }, /* 809 */+  {   109,     10,      5,      0,      0,    109,      0, }, /* 810 */+  {   109,     13,     12,      0,      0,    109,      0, }, /* 811 */+  {   107,     12,      3,      0,      0,    107,      0, }, /* 812 */+  {   107,     12,      3,      0,      0,    -52,      0, }, /* 813 */+  {   107,     10,      5,      0,      0,    107,      0, }, /* 814 */+  {   107,     10,      5,      0,      0,    -52,      0, }, /* 815 */+  {   107,      7,     12,      0,      0,    107,      0, }, /* 816 */+  {    28,     12,      3,      0,      0,    -52,      0, }, /* 817 */+  {   107,     10,      3,      0,      0,    107,      0, }, /* 818 */+  {   135,      7,     12,      0,      0,    135,      0, }, /* 819 */+  {   135,     10,      5,      0,      0,    135,      0, }, /* 820 */+  {   135,     12,      3,      0,      0,    135,      0, }, /* 821 */+  {   135,     21,     12,      0,      0,    135,      0, }, /* 822 */+  {   135,     13,     12,      0,      0,    135,      0, }, /* 823 */+  {   124,      7,     12,      0,      0,    124,      0, }, /* 824 */+  {   124,     10,      3,      0,      0,    124,      0, }, /* 825 */+  {   124,     10,      5,      0,      0,    124,      0, }, /* 826 */+  {   124,     12,      3,      0,      0,    124,      0, }, /* 827 */+  {   124,     21,     12,      0,      0,    124,      0, }, /* 828 */+  {   124,     13,     12,      0,      0,    124,      0, }, /* 829 */+  {   123,      7,     12,      0,      0,    123,      0, }, /* 830 */+  {   123,     10,      3,      0,      0,    123,      0, }, /* 831 */+  {   123,     10,      5,      0,      0,    123,      0, }, /* 832 */+  {   123,     12,      3,      0,      0,    123,      0, }, /* 833 */+  {   123,     21,     12,      0,      0,    123,      0, }, /* 834 */+  {   114,      7,     12,      0,      0,    114,      0, }, /* 835 */+  {   114,     10,      5,      0,      0,    114,      0, }, /* 836 */+  {   114,     12,      3,      0,      0,    114,      0, }, /* 837 */+  {   114,     21,     12,      0,      0,    114,      0, }, /* 838 */+  {   114,     13,     12,      0,      0,    114,      0, }, /* 839 */+  {   102,      7,     12,      0,      0,    102,      0, }, /* 840 */+  {   102,     12,      3,      0,      0,    102,      0, }, /* 841 */+  {   102,     10,      5,      0,      0,    102,      0, }, /* 842 */+  {   102,     13,     12,      0,      0,    102,      0, }, /* 843 */+  {   126,      7,     12,      0,      0,    126,      0, }, /* 844 */+  {   126,     12,      3,      0,      0,    126,      0, }, /* 845 */+  {   126,     10,      5,      0,      0,    126,      0, }, /* 846 */+  {   126,     13,     12,      0,      0,    126,      0, }, /* 847 */+  {   126,     15,     12,      0,      0,    126,      0, }, /* 848 */+  {   126,     21,     12,      0,      0,    126,      0, }, /* 849 */+  {   126,     26,     12,      0,      0,    126,      0, }, /* 850 */+  {   142,      7,     12,      0,      0,    142,      0, }, /* 851 */+  {   142,     10,      5,      0,      0,    142,      0, }, /* 852 */+  {   142,     12,      3,      0,      0,    142,      0, }, /* 853 */+  {   142,     21,     12,      0,      0,    142,      0, }, /* 854 */+  {   125,      9,     12,      0,     32,    125,      0, }, /* 855 */+  {   125,      5,     12,      0,    -32,    125,      0, }, /* 856 */+  {   125,     13,     12,      0,      0,    125,      0, }, /* 857 */+  {   125,     15,     12,      0,      0,    125,      0, }, /* 858 */+  {   125,      7,     12,      0,      0,    125,      0, }, /* 859 */+  {   154,      7,     12,      0,      0,    154,      0, }, /* 860 */+  {   154,     10,      3,      0,      0,    154,      0, }, /* 861 */+  {   154,     10,      5,      0,      0,    154,      0, }, /* 862 */+  {   154,     12,      3,      0,      0,    154,      0, }, /* 863 */+  {   154,      7,      4,      0,      0,    154,      0, }, /* 864 */+  {   154,     21,     12,      0,      0,    154,      0, }, /* 865 */+  {   154,     13,     12,      0,      0,    154,      0, }, /* 866 */+  {   150,      7,     12,      0,      0,    150,      0, }, /* 867 */+  {   150,     10,      5,      0,      0,    150,      0, }, /* 868 */+  {   150,     12,      3,      0,      0,    150,      0, }, /* 869 */+  {   150,     21,     12,      0,      0,    150,      0, }, /* 870 */+  {   141,      7,     12,      0,      0,    141,      0, }, /* 871 */+  {   141,     12,      3,      0,      0,    141,      0, }, /* 872 */+  {   141,     10,      5,      0,      0,    141,      0, }, /* 873 */+  {   141,      7,      4,      0,      0,    141,      0, }, /* 874 */+  {   141,     21,     12,      0,      0,    141,      0, }, /* 875 */+  {   140,      7,     12,      0,      0,    140,      0, }, /* 876 */+  {   140,     12,      3,      0,      0,    140,      0, }, /* 877 */+  {   140,     10,      5,      0,      0,    140,      0, }, /* 878 */+  {   140,      7,      4,      0,      0,    140,      0, }, /* 879 */+  {   140,     21,     12,      0,      0,    140,      0, }, /* 880 */+  {   122,      7,     12,      0,      0,    122,      0, }, /* 881 */+  {   133,      7,     12,      0,      0,    133,      0, }, /* 882 */+  {   133,     10,      5,      0,      0,    133,      0, }, /* 883 */+  {   133,     12,      3,      0,      0,    133,      0, }, /* 884 */+  {   133,     21,     12,      0,      0,    133,      0, }, /* 885 */+  {   133,     13,     12,      0,      0,    133,      0, }, /* 886 */+  {   133,     15,     12,      0,      0,    133,      0, }, /* 887 */+  {   134,     21,     12,      0,      0,    134,      0, }, /* 888 */+  {   134,      7,     12,      0,      0,    134,      0, }, /* 889 */+  {   134,     12,      3,      0,      0,    134,      0, }, /* 890 */+  {   134,     10,      5,      0,      0,    134,      0, }, /* 891 */+  {   138,      7,     12,      0,      0,    138,      0, }, /* 892 */+  {   138,     12,      3,      0,      0,    138,      0, }, /* 893 */+  {   138,      7,      4,      0,      0,    138,      0, }, /* 894 */+  {   138,     13,     12,      0,      0,    138,      0, }, /* 895 */+  {   143,      7,     12,      0,      0,    143,      0, }, /* 896 */+  {   143,     10,      5,      0,      0,    143,      0, }, /* 897 */+  {   143,     12,      3,      0,      0,    143,      0, }, /* 898 */+  {   143,     13,     12,      0,      0,    143,      0, }, /* 899 */+  {   145,      7,     12,      0,      0,    145,      0, }, /* 900 */+  {   145,     12,      3,      0,      0,    145,      0, }, /* 901 */+  {   145,     10,      5,      0,      0,    145,      0, }, /* 902 */+  {   145,     21,     12,      0,      0,    145,      0, }, /* 903 */+  {    54,     15,     12,      0,      0,     54,      0, }, /* 904 */+  {    54,     21,     12,      0,      0,     54,      0, }, /* 905 */+  {    63,      7,     12,      0,      0,     63,      0, }, /* 906 */+  {    63,     14,     12,      0,      0,     63,      0, }, /* 907 */+  {    63,     21,     12,      0,      0,     63,      0, }, /* 908 */+  {    80,      7,     12,      0,      0,     80,      0, }, /* 909 */+  {    80,      1,      2,      0,      0,     80,      0, }, /* 910 */+  {   127,      7,     12,      0,      0,    127,      0, }, /* 911 */+  {   115,      7,     12,      0,      0,    115,      0, }, /* 912 */+  {   115,     13,     12,      0,      0,    115,      0, }, /* 913 */+  {   115,     21,     12,      0,      0,    115,      0, }, /* 914 */+  {   103,      7,     12,      0,      0,    103,      0, }, /* 915 */+  {   103,     12,      3,      0,      0,    103,      0, }, /* 916 */+  {   103,     21,     12,      0,      0,    103,      0, }, /* 917 */+  {   119,      7,     12,      0,      0,    119,      0, }, /* 918 */+  {   119,     12,      3,      0,      0,    119,      0, }, /* 919 */+  {   119,     21,     12,      0,      0,    119,      0, }, /* 920 */+  {   119,     26,     12,      0,      0,    119,      0, }, /* 921 */+  {   119,      6,     12,      0,      0,    119,      0, }, /* 922 */+  {   119,     13,     12,      0,      0,    119,      0, }, /* 923 */+  {   119,     15,     12,      0,      0,    119,      0, }, /* 924 */+  {   146,      9,     12,      0,     32,    146,      0, }, /* 925 */+  {   146,      5,     12,      0,    -32,    146,      0, }, /* 926 */+  {   146,     15,     12,      0,      0,    146,      0, }, /* 927 */+  {   146,     21,     12,      0,      0,    146,      0, }, /* 928 */+  {    99,      7,     12,      0,      0,     99,      0, }, /* 929 */+  {    99,     12,      3,      0,      0,     99,      0, }, /* 930 */+  {    99,     10,      5,      0,      0,     99,      0, }, /* 931 */+  {    99,      6,     12,      0,      0,     99,      0, }, /* 932 */+  {   137,      6,     12,      0,      0,    137,      0, }, /* 933 */+  {   139,      6,     12,      0,      0,    139,      0, }, /* 934 */+  {   155,     12,      3,      0,      0,    155,      0, }, /* 935 */+  {    23,     10,      5,      0,      0,     23,      0, }, /* 936 */+  {   137,      7,     12,      0,      0,    137,      0, }, /* 937 */+  {   155,      7,     12,      0,      0,    155,      0, }, /* 938 */+  {   139,      7,     12,      0,      0,    139,      0, }, /* 939 */+  {   105,      7,     12,      0,      0,    105,      0, }, /* 940 */+  {   105,     26,     12,      0,      0,    105,      0, }, /* 941 */+  {   105,     12,      3,      0,      0,    105,      0, }, /* 942 */+  {   105,     21,     12,      0,      0,    105,      0, }, /* 943 */+  {    10,      1,      2,      0,      0,    105,      0, }, /* 944 */+  {    10,     10,      3,      0,      0,     10,      0, }, /* 945 */+  {    10,     10,      5,      0,      0,     10,      0, }, /* 946 */+  {    20,     12,      3,      0,      0,     20,      0, }, /* 947 */+  {   131,     26,     12,      0,      0,    131,      0, }, /* 948 */+  {   131,     12,      3,      0,      0,    131,      0, }, /* 949 */+  {   131,     21,     12,      0,      0,    131,      0, }, /* 950 */+  {    18,     12,      3,      0,      0,     18,      0, }, /* 951 */+  {   151,      7,     12,      0,      0,    151,      0, }, /* 952 */+  {   151,     12,      3,      0,      0,    151,      0, }, /* 953 */+  {   151,      6,     12,      0,      0,    151,      0, }, /* 954 */+  {   151,     13,     12,      0,      0,    151,      0, }, /* 955 */+  {   151,     26,     12,      0,      0,    151,      0, }, /* 956 */+  {   152,      7,     12,      0,      0,    152,      0, }, /* 957 */+  {   152,     12,      3,      0,      0,    152,      0, }, /* 958 */+  {   152,     13,     12,      0,      0,    152,      0, }, /* 959 */+  {   152,     23,     12,      0,      0,    152,      0, }, /* 960 */+  {   113,      7,     12,      0,      0,    113,      0, }, /* 961 */+  {   113,     15,     12,      0,      0,    113,      0, }, /* 962 */+  {   113,     12,      3,      0,      0,    113,      0, }, /* 963 */+  {   132,      9,     12,      0,     34,    132,      0, }, /* 964 */+  {   132,      5,     12,      0,    -34,    132,      0, }, /* 965 */+  {   132,     12,      3,      0,      0,    132,      0, }, /* 966 */+  {   132,      6,     12,      0,      0,    132,      0, }, /* 967 */+  {   132,     13,     12,      0,      0,    132,      0, }, /* 968 */+  {   132,     21,     12,      0,      0,    132,      0, }, /* 969 */+  {     0,      2,     14,      0,      0,      0,      0, }, /* 970 */+  {    10,     26,     11,      0,      0,     10,      0, }, /* 971 */+  {    27,     26,     12,      0,      0,     27,      0, }, /* 972 */+  {    10,     24,      3,      0,      0,     10,      0, }, /* 973 */+  {    10,      1,      3,      0,      0,     10,      0, }, /* 974 */+};++const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */+  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* U+0000 */+ 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, 74, 75, 76, /* U+2000 */+ 77, 77, 78, 79, 66, 66, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, /* U+2800 */+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, 98, 98, 98, 98, 98, 98, /* U+3000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+3800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+4000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 98, 98, 98, 98, /* U+4800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+5000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+5800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+6000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+6800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+7000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+7800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+8000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+8800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+9000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,100, /* U+9800 */+101,102,102,102,102,102,102,102,102,103,104,104,105,106,107,108, /* U+A000 */+109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,117, /* U+A800 */+118,119,120,121,122,123,117,118,119,120,121,122,123,117,118,119, /* U+B000 */+120,121,122,123,117,118,119,120,121,122,123,117,118,119,120,121, /* U+B800 */+122,123,117,118,119,120,121,122,123,117,118,119,120,121,122,123, /* U+C000 */+117,118,119,120,121,122,123,117,118,119,120,121,122,123,117,118, /* U+C800 */+119,120,121,122,123,117,118,119,120,121,122,123,117,118,119,124, /* U+D000 */+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+D800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+E000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+E800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F000 */+126,126, 98, 98,127,128,129,130,131,131,132,133,134,135,136,137, /* U+F800 */+138,139,140,141,142,143,144,145,146,147,148,142,149,149,150,142, /* U+10000 */+151,152,153,154,155,156,157,158,159,160,161,142,162,163,164,165, /* U+10800 */+166,167,168,169,170,171,172,142,173,174,142,175,176,177,178,142, /* U+11000 */+179,180,181,182,183,184,142,142,185,186,187,188,142,189,142,190, /* U+11800 */+191,191,191,191,191,191,191,192,193,191,194,142,142,142,142,142, /* U+12000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+12800 */+195,195,195,195,195,195,195,195,196,142,142,142,142,142,142,142, /* U+13000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+13800 */+142,142,142,142,142,142,142,142,197,197,197,197,198,142,142,142, /* U+14000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+14800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+16000 */+199,199,199,199,200,201,202,203,142,142,142,142,204,205,206,207, /* U+16800 */+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, /* U+17000 */+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, /* U+17800 */+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,209, /* U+18000 */+208,208,208,208,208,208,210,210,210,211,212,142,142,142,142,142, /* U+18800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A800 */+213,214,215,216,216,217,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */+142,142,142,142,142,142,142,142,218,219,142,142,142,142,142,142, /* U+1B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C800 */+ 71,220,221,222,223,224,225,142,226,227,228,229,230,231,232,233, /* U+1D000 */+234,234,234,234,235,236,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */+237,142,238,142,142,239,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */+240,241,242,142,142,142,142,142,243,244,245,142,246,247,142,142, /* U+1E800 */+248,249,250,251,252,253,254,255,254,254,256,254,257,258,259,260, /* U+1F000 */+261,262,263,264,265,266, 71,267,253,253,253,253,253,253,253,268, /* U+1F800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+22000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+22800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+23000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+23800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+24000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+24800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+25000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+25800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+26000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+26800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+27000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+27800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,269, 98, 98, /* U+2A000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2A800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,270, 98, /* U+2B000 */+271, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2C000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,272, 98, 98, /* U+2C800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2E000 */+ 98, 98, 98, 98, 98, 98, 98,273,142,142,142,142,142,142,142,142, /* U+2E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+2F000 */+ 98, 98, 98, 98,274,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+30000 */+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+30800 */+ 98, 98, 98, 98, 98, 98,275,142,142,142,142,142,142,142,142,142, /* U+31000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+32000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+32800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+33000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+33800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+34000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+34800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+35000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+35800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+36000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+36800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+37000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+37800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+38000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+38800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+39000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+39800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+40000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+40800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+41000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+41800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+42000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+42800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+43000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+43800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+44000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+44800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+45000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+45800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+46000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+46800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+47000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+47800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+48000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+48800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+49000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+49800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+50000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+50800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+51000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+51800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+52000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+52800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+53000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+53800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+54000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+54800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+55000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+55800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+56000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+56800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+57000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+57800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+58000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+58800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+59000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+59800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+60000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+60800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+61000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+61800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+62000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+62800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+63000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+63800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+64000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+64800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+65000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+65800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+66000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+66800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+67000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+67800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+68000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+68800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+69000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+69800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+70000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+70800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+71000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+71800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+72000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+72800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+73000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+73800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+74000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+74800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+75000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+75800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+76000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+76800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+77000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+77800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+78000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+78800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+79000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+79800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+80000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+80800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+81000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+81800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+82000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+82800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+83000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+83800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+84000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+84800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+85000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+85800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+86000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+86800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+87000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+87800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+88000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+88800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+89000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+89800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+90000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+90800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+91000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+91800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+92000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+92800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+93000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+93800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+94000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+94800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+95000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+95800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+96000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+96800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+97000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+97800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+98000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+98800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+99000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+99800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9A000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9A800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9B000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9B800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9C000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9C800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9D000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9D800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9E000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9E800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9F000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9F800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A0000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A0800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A1000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A1800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A2000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A2800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A3000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A3800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A4000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A4800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A5000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A5800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A6000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A6800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A7000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A7800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A8000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A8800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A9000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A9800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AA000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AA800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AB000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AB800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AC000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AC800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AD000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AD800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AE000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AE800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AF000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AF800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B0000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B0800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B1000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B1800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B2000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B2800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B3000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B3800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B4000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B4800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B5000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B5800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B6000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B6800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B7000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B7800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B8000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B8800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B9000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B9800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BA000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BA800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BB000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BB800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BC000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BC800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BD000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BD800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BE000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BE800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BF000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BF800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C0000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C0800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C1000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C1800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C2000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C2800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C3000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C3800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C4000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C4800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C5000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C5800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C6000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C6800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C7000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C7800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C8000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C8800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C9000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C9800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CA000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CA800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CB000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CB800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CC000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CC800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CD000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CD800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CE000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CE800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CF000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CF800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D0000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D0800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D1000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D1800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D2000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D2800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D3000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D3800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D4000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D4800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D5000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D5800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D6000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D6800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D7000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D7800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D8000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D8800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D9000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D9800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DA000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DA800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DB000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DB800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DC000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DC800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DD000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DD800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF800 */+276,277,278,279,277,277,277,277,277,277,277,277,277,277,277,277, /* U+E0000 */+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, /* U+E0800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E3000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E3800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E4000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E4800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E5000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E5800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E6000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E6800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E7000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E7800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E8000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E8800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E9000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E9800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EA000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EA800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EB000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EB800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EC000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EC800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+ED000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+ED800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EE000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EE800 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EF000 */+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EF800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F0000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F0800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F1000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F1800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F2000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F2800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F3000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F3800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F4000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F4800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F5000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F5800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F6000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F6800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F7000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F7800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F8000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F8800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F9000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F9800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FA000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FA800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FB000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FB800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FC000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FC800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FD000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FD800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FF000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,280, /* U+FF800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+102000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+102800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+103000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+103800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+104000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+104800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+105000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+105800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+106000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+106800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+107000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+107800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+108000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+108800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+109000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+109800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10A000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10A800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10B000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10B800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10C000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10C800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10D000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10D800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E800 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10F000 */+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,280, /* U+10F800 */+};++const uint16_t PRIV(ucd_stage2)[] = { /* 71936 bytes, block = 128 */+/* block 0 */+  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  1,  1,  3,  1,  1,+  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,+  4,  5,  5,  5,  6,  5,  5,  5,  7,  8,  5,  9,  5, 10,  5,  5,+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  5,  5,  9,  9,  9,  5,+  5, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 12, 12,+ 12, 12, 12, 14, 12, 12, 12, 12, 12, 12, 12,  7,  5,  8, 15, 16,+ 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, 17,+ 17, 17, 17, 19, 17, 17, 17, 17, 17, 17, 17,  7,  9,  8,  9,  1,++/* block 1 */+  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,+  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,+  4,  5,  6,  6,  6,  6, 20,  5, 15, 21, 22, 23,  9, 24, 21, 15,+ 20,  9, 25, 25, 15, 26,  5,  5, 15, 25, 22, 27, 25, 25, 25,  5,+ 12, 12, 12, 12, 12, 28, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,+ 12, 12, 12, 12, 12, 12, 12,  9, 12, 12, 12, 12, 12, 12, 12, 29,+ 17, 17, 17, 17, 17, 30, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,+ 17, 17, 17, 17, 17, 17, 17,  9, 17, 17, 17, 17, 17, 17, 17, 31,++/* block 2 */+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 34, 35, 32, 33, 32, 33, 32, 33, 35, 32, 33, 32, 33, 32, 33, 32,+ 33, 32, 33, 32, 33, 32, 33, 32, 33, 35, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 36, 32, 33, 32, 33, 32, 33, 37,++/* block 3 */+ 38, 39, 32, 33, 32, 33, 40, 32, 33, 41, 41, 32, 33, 35, 42, 43,+ 44, 32, 33, 41, 45, 46, 47, 48, 32, 33, 49, 35, 47, 50, 51, 52,+ 32, 33, 32, 33, 32, 33, 53, 32, 33, 53, 35, 35, 32, 33, 53, 32,+ 33, 54, 54, 32, 33, 32, 33, 55, 32, 33, 35, 22, 32, 33, 35, 56,+ 22, 22, 22, 22, 57, 58, 59, 60, 61, 62, 63, 64, 65, 32, 33, 32,+ 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 66, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 35, 67, 68, 69, 32, 33, 70, 71, 32, 33, 32, 33, 32, 33, 32, 33,++/* block 4 */+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 72, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 35, 35, 35, 35, 35, 35, 73, 32, 33, 74, 75, 76,+ 76, 32, 33, 77, 78, 79, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 80, 81, 82, 83, 84, 35, 85, 85, 35, 86, 35, 87, 88, 35, 35, 35,+ 85, 89, 35, 90, 35, 91, 92, 35, 93, 94, 92, 95, 96, 35, 35, 94,+ 35, 97, 98, 35, 35, 99, 35, 35, 35, 35, 35, 35, 35,100, 35, 35,++/* block 5 */+101, 35,102,101, 35, 35, 35,103,101,104,105,105,106, 35, 35, 35,+ 35, 35,107, 35, 22, 35, 35, 35, 35, 35, 35, 35, 35,108,109, 35,+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,+110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,+111,111, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111,111,+111,111, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,+110,110,110,110,110, 15, 15, 15, 15, 15,112,112,111, 15,111, 15,+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,++/* block 6 */+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,114,113,113,115,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,116,116,116,116,116,116,116,116,116,116,116,116,116,+117,118,117,118,111,119,117,118,120,120,121,122,122,122,  5,123,++/* block 7 */+120,120,120,120,119, 15,124,  5,125,125,125,120,126,120,127,127,+128,129,130,129,129,131,129,129,132,133,134,129,135,129,129,129,+136,137,120,138,129,129,139,129,129,140,129,129,141,142,142,142,+128,143,144,143,143,145,143,143,146,147,148,143,149,143,143,143,+150,151,152,153,143,143,154,143,143,155,143,143,156,157,157,158,+159,160,161,161,161,162,163,164,117,118,117,118,117,118,117,118,+117,118,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+167,168,169,170,171,172,173,117,118,174,117,118,128,175,175,175,++/* block 8 */+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,+177,177,178,177,179,177,177,177,177,177,177,177,177,177,180,177,+177,181,182,177,177,177,177,177,177,177,183,177,177,177,177,177,+184,184,185,184,186,184,184,184,184,184,184,184,184,184,187,184,+184,188,189,184,184,184,184,184,184,184,190,184,184,184,184,184,+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,+192,193,194,195,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,++/* block 9 */+192,193,196,197,198,199,199,198,200,200,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+201,192,193,192,193,192,193,192,193,192,193,192,193,192,193,202,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,++/* block 10 */+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+120,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,+203,203,203,203,203,203,203,120,120,204,205,205,205,205,205,205,+206,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,++/* block 11 */+207,207,207,207,207,207,207,206,206,205,208,120,120,209,209,210,+120,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,+211,211,211,211,211,211,211,211,211,211,211,211,211,211,212,211,+213,211,211,213,211,211,213,211,120,120,120,120,120,120,120,120,+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,120,120,120,120,214,+214,214,214,213,213,120,120,120,120,120,120,120,120,120,120,120,++/* block 12 */+215,215,215,215,215,216,217,217,217,218,218,219,220,218,221,221,+222,222,222,222,222,222,222,222,222,222,222,220,223,120,218,220,+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,+225,224,224,224,224,224,224,224,224,224,224,226,226,226,226,226,+226,226,226,226,226,226,222,222,222,222,222,222,222,222,222,222,+227,227,227,227,227,227,227,227,227,227,218,218,218,218,224,224,+226,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,++/* block 13 */+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,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,228,224,222,222,222,222,222,222,222,216,221,222,+222,222,222,222,222,229,229,222,222,221,222,222,222,222,224,224,+230,230,230,230,230,230,230,230,230,230,224,224,224,221,221,224,++/* block 14 */+231,231,231,231,231,231,231,231,231,231,231,231,231,231,120,232,+233,234,233,233,233,233,233,233,233,233,233,233,233,233,233,233,+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,+234,234,234,234,234,234,234,234,234,234,234,120,120,233,233,233,+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,++/* block 15 */+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,235,235,235,235,235,235,235,+235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236,+236,235,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+237,237,237,237,237,237,237,237,237,237,238,238,238,238,238,238,+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,+238,238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,+239,239,239,239,240,240,241,242,242,242,240,120,120,239,243,243,++/* block 16 */+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,+244,244,244,244,244,244,245,245,245,245,246,245,245,245,245,245,+245,245,245,245,246,245,245,245,246,245,245,245,245,245,120,120,+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,120,+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,+248,248,248,248,248,248,248,248,248,249,249,249,120,120,250,120,+233,233,233,233,233,233,233,233,233,233,233,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 17 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,+224,224,224,224,224,120,224,224,224,224,224,224,224,224,224,224,+224,224,224,224,224,224,224,224,120,120,120,120,120,120,120,120,+120,120,120,222,222,222,222,222,222,222,222,222,222,222,222,222,+222,222,216,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,222,222,++/* block 18 */+251,251,251,252,253,253,253,253,253,253,253,253,253,253,253,253,+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,+253,253,253,253,253,253,253,253,253,253,251,252,251,253,252,252,+252,251,251,251,251,251,251,251,251,252,252,252,252,251,252,252,+253,254,255,113,113,251,251,251,253,253,253,253,253,253,253,253,+253,253,251,251,256,257,258,258,258,258,258,258,258,258,258,258,+259,260,253,253,253,253,253,253,253,253,253,253,253,253,253,253,++/* block 19 */+261,262,263,263,120,261,261,261,261,261,261,261,261,120,120,261,+261,120,120,261,261,261,261,261,261,261,261,261,261,261,261,261,+261,261,261,261,261,261,261,261,261,120,261,261,261,261,261,261,+261,120,261,120,120,120,261,261,261,261,120,120,262,261,264,263,+263,262,262,262,262,120,120,263,263,120,120,263,263,262,261,120,+120,120,120,120,120,120,120,264,120,120,120,120,261,261,120,261,+261,261,262,262,120,120,265,265,265,265,265,265,265,265,265,265,+261,261,266,266,267,267,267,267,267,267,268,266,261,269,262,120,++/* block 20 */+120,270,270,271,120,272,272,272,272,272,272,120,120,120,120,272,+272,120,120,272,272,272,272,272,272,272,272,272,272,272,272,272,+272,272,272,272,272,272,272,272,272,120,272,272,272,272,272,272,+272,120,272,272,120,272,272,120,272,272,120,120,270,120,271,271,+271,270,270,120,120,120,120,270,270,120,120,270,270,270,120,120,+120,270,120,120,120,120,120,120,120,272,272,272,272,120,272,120,+120,120,120,120,120,120,273,273,273,273,273,273,273,273,273,273,+270,270,272,272,272,270,274,120,120,120,120,120,120,120,120,120,++/* block 21 */+120,275,275,276,120,277,277,277,277,277,277,277,277,277,120,277,+277,277,120,277,277,277,277,277,277,277,277,277,277,277,277,277,+277,277,277,277,277,277,277,277,277,120,277,277,277,277,277,277,+277,120,277,277,120,277,277,277,277,277,120,120,275,277,276,276,+276,275,275,275,275,275,120,275,275,276,120,276,276,275,120,120,+277,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+277,277,275,275,120,120,278,278,278,278,278,278,278,278,278,278,+279,280,120,120,120,120,120,120,120,277,275,275,275,275,275,275,++/* block 22 */+120,281,282,282,120,283,283,283,283,283,283,283,283,120,120,283,+283,120,120,283,283,283,283,283,283,283,283,283,283,283,283,283,+283,283,283,283,283,283,283,283,283,120,283,283,283,283,283,283,+283,120,283,283,120,283,283,283,283,283,120,120,281,283,284,281,+282,281,281,281,281,120,120,282,282,120,120,282,282,281,120,120,+120,120,120,120,120,281,281,284,120,120,120,120,283,283,120,283,+283,283,281,281,120,120,285,285,285,285,285,285,285,285,285,285,+286,283,287,287,287,287,287,287,120,120,120,120,120,120,120,120,++/* block 23 */+120,120,288,289,120,289,289,289,289,289,289,120,120,120,289,289,+289,120,289,289,289,289,120,120,120,289,289,120,289,120,289,289,+120,120,120,289,289,120,120,120,289,289,289,120,120,120,289,289,+289,289,289,289,289,289,289,289,289,289,120,120,120,120,290,291,+288,291,291,120,120,120,291,291,291,120,291,291,291,288,120,120,+289,120,120,120,120,120,120,290,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,292,292,292,292,292,292,292,292,292,292,+293,293,293,294,295,295,295,295,295,296,295,120,120,120,120,120,++/* block 24 */+297,298,298,298,297,299,299,299,299,299,299,299,299,120,299,299,+299,120,299,299,299,299,299,299,299,299,299,299,299,299,299,299,+299,299,299,299,299,299,299,299,299,120,299,299,299,299,299,299,+299,299,299,299,299,299,299,299,299,299,120,120,120,299,297,297,+297,298,298,298,298,120,297,297,297,120,297,297,297,297,120,120,+120,120,120,120,120,297,297,120,299,299,299,120,120,120,120,120,+299,299,297,297,120,120,300,300,300,300,300,300,300,300,300,300,+120,120,120,120,120,120,120,301,302,302,302,302,302,302,302,303,++/* block 25 */+304,305,306,306,307,304,304,304,304,304,304,304,304,120,304,304,+304,120,304,304,304,304,304,304,304,304,304,304,304,304,304,304,+304,304,304,304,304,304,304,304,304,120,304,304,304,304,304,304,+304,304,304,304,120,304,304,304,304,304,120,120,305,304,306,305,+306,306,308,306,306,120,305,306,306,120,306,306,305,305,120,120,+120,120,120,120,120,308,308,120,120,120,120,120,120,120,304,120,+304,304,305,305,120,120,309,309,309,309,309,309,309,309,309,309,+120,304,304,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 26 */+310,310,311,311,312,312,312,312,312,312,312,312,312,120,312,312,+312,120,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,312,312,312,310,310,312,313,311,+311,310,310,310,310,120,311,311,311,120,311,311,311,310,314,315,+120,120,120,120,312,312,312,313,316,316,316,316,316,316,316,312,+312,312,310,310,120,120,317,317,317,317,317,317,317,317,317,317,+316,316,316,316,316,316,316,316,316,315,312,312,312,312,312,312,++/* block 27 */+120,318,319,319,120,320,320,320,320,320,320,320,320,320,320,320,+320,320,320,320,320,320,320,120,120,120,320,320,320,320,320,320,+320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,+320,320,120,320,320,320,320,320,320,320,320,320,120,320,120,120,+320,320,320,320,320,320,320,120,120,120,318,120,120,120,120,321,+319,319,318,318,318,120,318,120,319,319,319,319,319,319,319,321,+120,120,120,120,120,120,322,322,322,322,322,322,322,322,322,322,+120,120,319,319,323,120,120,120,120,120,120,120,120,120,120,120,++/* block 28 */+120,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,+324,325,324,326,325,325,325,325,325,325,325,120,120,120,120,  6,+324,324,324,324,324,324,327,325,325,325,325,325,325,325,325,328,+329,329,329,329,329,329,329,329,329,329,328,328,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 29 */+120,330,330,120,330,120,330,330,330,330,330,120,330,330,330,330,+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,+330,330,330,330,120,330,120,330,330,330,330,330,330,330,330,330,+330,331,330,332,331,331,331,331,331,331,331,331,331,330,120,120,+330,330,330,330,330,120,333,120,331,331,331,331,331,331,120,120,+334,334,334,334,334,334,334,334,334,334,120,120,330,330,330,330,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 30 */+335,336,336,336,337,337,337,337,337,337,337,337,337,337,337,337,+337,337,337,336,337,336,336,336,338,338,336,336,336,336,336,336,+339,339,339,339,339,339,339,339,339,339,340,340,340,340,340,340,+340,340,340,340,336,338,336,338,336,338,341,342,341,342,343,343,+335,335,335,335,335,335,335,335,120,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,120,120,120,+120,338,338,338,338,338,338,338,338,338,338,338,338,338,338,343,++/* block 31 */+338,338,338,338,338,337,338,338,335,335,335,335,335,338,338,338,+338,338,338,338,338,338,338,338,120,338,338,338,338,338,338,338,+338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,+338,338,338,338,338,338,338,338,338,338,338,338,338,120,336,336,+336,336,336,336,336,336,338,336,336,336,336,336,336,120,336,336,+337,337,337,337,337, 20, 20, 20, 20,337,337,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 32 */+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,+344,344,344,344,344,344,344,344,344,344,344,345,345,346,346,346,+346,347,346,346,346,346,346,346,345,346,346,347,347,346,346,344,+348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349,+344,344,344,344,344,344,347,347,346,346,344,344,344,344,346,346,+346,344,345,345,345,344,344,345,345,345,345,345,345,345,344,344,+344,346,346,346,346,344,344,344,344,344,344,344,344,344,344,344,++/* block 33 */+344,344,346,345,347,346,346,345,345,345,345,345,345,346,344,345,+350,350,350,350,350,350,350,350,350,350,345,345,345,346,351,351,+352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,+352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,+352,352,352,352,352,352,120,352,120,120,120,120,120,352,120,120,+353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,+353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,+353,353,353,353,353,353,353,353,353,353,353,354,355,353,353,353,++/* block 34 */+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,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,+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,++/* block 35 */+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,+357,357,357,357,357,357,357,357,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,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,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,++/* block 36 */+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,120,359,359,359,359,120,120,+359,359,359,359,359,359,359,120,359,120,359,359,359,359,120,120,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,++/* block 37 */+359,359,359,359,359,359,359,359,359,120,359,359,359,359,120,120,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,120,+359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,++/* block 38 */+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,359,359,359,359,120,120,360,360,360,+361,361,361,361,361,361,361,361,361,362,362,362,362,362,362,362,+362,362,362,362,362,362,362,362,362,362,362,362,362,120,120,120,++/* block 39 */+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+363,363,363,363,363,363,363,363,363,363,120,120,120,120,120,120,+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,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,364,364,364,364,+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,+365,365,365,365,365,365,120,120,366,366,366,366,366,366,120,120,++/* block 40 */+367,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,++/* block 41 */+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,++/* block 42 */+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,369,370,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,++/* block 43 */+371,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,+372,372,372,372,372,372,372,372,372,372,372,373,374,120,120,120,+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,+375,375,375,375,375,375,375,375,375,375,375,  5,  5,  5,376,376,+376,375,375,375,375,375,375,375,375,120,120,120,120,120,120,120,++/* block 44 */+377,377,377,377,377,377,377,377,377,377,377,377,377,120,377,377,+377,377,378,378,378,120,120,120,120,120,120,120,120,120,120,120,+379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,+379,379,380,380,380,381,381,120,120,120,120,120,120,120,120,120,+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,+382,382,383,383,120,120,120,120,120,120,120,120,120,120,120,120,+384,384,384,384,384,384,384,384,384,384,384,384,384,120,384,384,+384,120,385,385,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 45 */+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,+386,386,386,386,387,387,388,387,387,387,387,387,387,387,388,388,+388,388,388,388,388,388,387,388,388,387,387,387,387,387,387,387,+387,387,387,387,389,389,389,390,389,389,389,391,386,387,120,120,+392,392,392,392,392,392,392,392,392,392,120,120,120,120,120,120,+393,393,393,393,393,393,393,393,393,393,120,120,120,120,120,120,++/* block 46 */+394,394,395,395,394,395,396,394,394,394,394,397,397,397,398,120,+399,399,399,399,399,399,399,399,399,399,120,120,120,120,120,120,+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,+400,400,400,401,400,400,400,400,400,400,400,400,400,400,400,400,+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,+400,400,400,400,400,400,400,400,400,120,120,120,120,120,120,120,++/* block 47 */+400,400,400,400,400,397,397,400,400,400,400,400,400,400,400,400,+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,+400,400,400,400,400,400,400,400,400,397,400,120,120,120,120,120,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,+368,368,368,368,368,368,120,120,120,120,120,120,120,120,120,120,++/* block 48 */+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,120,+403,403,403,404,404,404,404,403,403,404,404,404,120,120,120,120,+404,404,403,404,404,404,404,404,404,403,403,403,120,120,120,120,+405,120,120,120,406,406,407,407,407,407,407,407,407,407,407,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,120,120,+408,408,408,408,408,120,120,120,120,120,120,120,120,120,120,120,++/* block 49 */+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,+409,409,409,409,409,409,409,409,409,409,409,409,120,120,120,120,+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,+409,409,409,409,409,409,409,409,409,409,120,120,120,120,120,120,+410,410,410,410,410,410,410,410,410,410,411,120,120,120,412,412,+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,++/* block 50 */+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,416,416,415,120,120,417,417,+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,+418,418,418,418,418,419,420,419,420,420,420,420,420,420,420,120,+420,421,420,421,421,420,420,420,420,420,420,420,420,419,419,419,+419,419,419,420,420,420,420,420,420,420,420,420,420,120,120,420,++/* block 51 */+422,422,422,422,422,422,422,422,422,422,120,120,120,120,120,120,+422,422,422,422,422,422,422,422,422,422,120,120,120,120,120,120,+423,423,423,423,423,423,423,424,423,423,423,423,423,423,120,120,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,425,113,+113,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 52 */+426,426,426,426,427,428,428,428,428,428,428,428,428,428,428,428,+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,+428,428,428,428,426,429,426,426,426,426,426,427,426,427,427,427,+427,427,426,427,427,428,428,428,428,428,428,428,120,120,120,120,+430,430,430,430,430,430,430,430,430,430,431,431,431,431,431,431,+431,432,432,432,432,432,432,432,432,432,432,426,426,426,426,426,+426,426,426,426,432,432,432,432,432,432,432,432,432,120,120,120,++/* block 53 */+433,433,434,435,435,435,435,435,435,435,435,435,435,435,435,435,+435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,+435,434,433,433,433,433,434,434,433,433,434,433,433,433,435,435,+436,436,436,436,436,436,436,436,436,436,435,435,435,435,435,435,+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,438,439,438,438,439,439,439,438,439,438,+438,438,439,439,120,120,120,120,120,120,120,120,440,440,440,440,++/* block 54 */+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,+441,441,441,441,442,442,442,442,442,442,442,442,443,443,443,443,+443,443,443,443,442,442,443,443,120,120,120,444,444,444,444,444,+445,445,445,445,445,445,445,445,445,445,120,120,120,441,441,441,+446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447,+447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,+447,447,447,447,447,447,447,447,448,448,448,448,448,448,449,449,++/* block 55 */+450,451,452,453,454,455,456,457,458,120,120,120,120,120,120,120,+459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,+459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,+459,459,459,459,459,459,459,459,459,459,459,120,120,459,459,459,+460,460,460,460,460,460,460,460,120,120,120,120,120,120,120,120,+461,462,461,463,462,464,464,465,464,465,466,462,465,465,462,462,+465,467,462,462,462,462,462,462,462,468,469,470,470,464,470,470,+470,470,471,472,473,469,469,474,475,475,476,120,120,120,120,120,++/* block 56 */+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,+ 35, 35, 35, 35, 35, 35,128,128,128,128,128,477,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,121,121,121,+121,121,110,110,110,110,121,121,121,121,121, 35, 35, 35, 35, 35,+ 35, 35, 35, 35, 35, 35, 35, 35,478,479, 35, 35, 35,480, 35, 35,++/* block 57 */+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,481, 35,+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,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,121,+114,114,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,482,113,120,113,113,113,113,113,++/* block 58 */+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+483,484, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,++/* block 59 */+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 35, 35, 35, 35, 35,485, 35, 35,486, 35,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,++/* block 60 */+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,+487,487,487,487,487,487,120,120,488,488,488,488,488,488,120,120,+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,+487,487,487,487,487,487,120,120,488,488,488,488,488,488,120,120,+128,487,128,487,128,487,128,487,120,488,120,488,120,488,120,488,+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,+489,489,490,490,490,490,491,491,492,492,493,493,494,494,120,120,++/* block 61 */+487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495,+487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495,+487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495,+487,487,128,496,128,120,128,128,488,488,497,497,498,119,499,119,+119,119,128,496,128,120,128,128,500,500,500,500,498,119,119,119,+487,487,128,128,120,120,128,128,488,488,501,501,120,119,119,119,+487,487,128,128,128,169,128,128,488,488,502,502,174,119,119,119,+120,120,128,496,128,120,128,128,503,503,504,504,498,119,119,120,++/* block 62 */+  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4, 24,505,506, 24, 24,+ 10, 10, 10, 10, 10, 10,  5,  5, 23, 27,  7, 23, 23, 27,  7, 23,+  5,  5,  5,  5,  5,  5,  5,  5,507,508, 24, 24, 24, 24, 24,509,+  5,  5,  5,  5,  5,  5,  5,  5,  5, 23, 27,  5,510,  5,  5, 16,+ 16,  5,  5,  5,  9,  7,  8,  5,  5,510,  5,  5,  5,  5,  5,  5,+  5,  5,  9,  5, 16,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  4,+ 24, 24, 24, 24, 24,511, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,+ 25,110,120,120, 25, 25, 25, 25, 25, 25,  9,  9,  9,  7,  8,110,++/* block 63 */+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  9,  9,  9,  7,  8,120,+110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,+  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,+  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+113,113,113,113,113,113,113,113,113,113,113,113,113,425,425,425,+425,113,425,425,425,113,113,113,113,113,113,113,113,113,113,113,+512,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 64 */+ 20, 20,513, 20, 20, 20, 20,513, 20, 20,514,513,513,513,514,514,+513,513,513,514, 20,513, 20, 20,  9,513,513,513,513,513, 20, 20,+ 20, 20, 21, 20,513, 20,515, 20,513, 20,516,517,513,513, 20,514,+513,513,518,513,514,519,519,519,519,520, 20, 20,514,514,513,513,+  9,  9,  9,  9,  9,513,514,514,514,514, 20,  9, 20, 20,521, 20,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,+523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,++/* block 65 */+524,524,524, 32, 33,524,524,524,524, 25, 20, 20,120,120,120,120,+  9,  9,  9,  9,525, 21, 21, 21, 21, 21,  9,  9, 20, 20, 20, 20,+  9, 20, 20,  9, 20, 20,  9, 20, 20, 21, 21, 20, 20, 20,  9, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  9,  9,+ 20, 20,  9, 20,  9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,++/* block 66 */+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,++/* block 67 */+ 20, 20, 20, 20, 20, 20, 20, 20,  7,  8,  7,  8, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 20, 20, 20, 20,+  9,  9, 20, 20, 20, 20, 20, 20, 21,  7,  8, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  9, 20, 20, 20,++/* block 68 */+ 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  9,  9,  9,  9,+  9,  9, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 20, 20, 20, 20, 21, 21, 21, 20, 20, 20, 20, 20,++/* block 69 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,++/* block 70 */+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20,526,526,526,526,526,526,526,526,526,526,+526,526,527,526,526,526,526,526,526,526,526,526,526,526,526,526,+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,+528,528,528,528,528,528,528,528,528,528, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,++/* block 71 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,++/* block 72 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 21,  9, 20, 20, 20, 20, 20, 20, 20, 20,+ 21,  9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20,  9,  9,  9,525,525,525,525,  9,++/* block 73 */+ 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,525,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,++/* block 74 */+ 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,++/* block 75 */+ 21, 21, 21, 21, 21, 21, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 20, 21, 20, 21, 20, 20, 20, 20, 20, 20, 21, 20, 20,+ 20, 21, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 21, 20, 20, 21, 20, 20, 20, 20, 21, 20, 21, 20,+ 20, 20, 20, 21, 21, 21, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 21, 21, 21, 21, 21,  7,  8,  7,  8,  7,  8,  7,  8,+  7,  8,  7,  8,  7,  8, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,++/* block 76 */+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 20, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,+  9,  9,  9,  9,  9,  7,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  7,  8,  7,  8,  7,  8,  7,  8,  7,  8,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,++/* block 77 */+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,++/* block 78 */+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,525,525,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,++/* block 79 */+  9,  9,  9,  7,  8,  7,  8,  7,  8,  7,  8,  7,  8,  7,  8,  7,+  8,  7,  8,  7,  8,  7,  8,  7,  8,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  7,  8,  7,  8,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  7,  8,  9,  9,++/* block 80 */+ 20, 20, 20, 20, 20, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,+  9,  9,  9,  9,  9, 20, 20,  9,  9,  9,  9,  9,  9, 20, 20, 20,+ 21, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,++/* block 81 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20,120, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,++/* block 82 */+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,120,+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,120,+ 32, 33,532,533,534,535,536, 32, 33, 32, 33, 32, 33,537,538,539,+540, 35, 32, 33, 35, 32, 33, 35, 35, 35, 35, 35,110,110,541,541,++/* block 83 */+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,+165,166,165,166,542,543,543,543,543,543,543,165,166,165,166,544,+544,544,165,166,120,120,120,120,120,545,545,545,545,546,545,545,++/* block 84 */+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,+547,547,547,547,547,547,120,547,120,120,120,120,120,547,120,120,+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,548,548,548,548,120,120,120,120,120,120,120,549,+550,120,120,120,120,120,120,120,120,120,120,120,120,120,120,551,++/* block 85 */+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,+359,359,359,359,359,359,359,120,120,120,120,120,120,120,120,120,+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,+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,++/* block 86 */+  5,  5, 23, 27, 23, 27,  5,  5,  5, 23, 27,  5, 23, 27,  5,  5,+  5,  5,  5,  5,  5,  5,  5, 10,  5,  5, 10,  5, 23, 27,  5,  5,+ 23, 27,  7,  8,  7,  8,  7,  8,  7,  8,  5,  5,  5,  5,  5,111,+  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 10, 10,  5,  5,  5,  5,+ 10,  5,  7,553,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,+ 20, 20,  5,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 87 */+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,120,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 88 */+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,++/* block 89 */+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,+554,554,554,554,554,554,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,++/* block 90 */+  4,555,555,556, 20,557,558,559,560,561,560,561,560,561,560,561,+560,561, 20,562,560,561,560,561,560,561,560,561,563,564,565,565,+ 20,559,559,559,559,559,559,559,559,559,566,566,566,566,567,567,+568,569,569,569,569,569, 20,562,559,559,559,557,570,571,572,572,+120,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,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,573,573,573,++/* block 91 */+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,+573,573,573,573,573,573,573,120,120,574,574,575,575,576,576,573,+577,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,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,578,578,578,578,578,578,578,578,578,578,555,569,579,579,578,++/* block 92 */+120,120,120,120,120,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,+120,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,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,581,581,581,+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,++/* block 93 */+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120,+572,572,582,582,582,582,572,572,572,572,572,572,572,572,572,572,+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,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,+572,572,572,572,120,120,120,120,120,120,120,120,120,120,120,120,+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,++/* block 94 */+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,120,+582,582,582,582,582,582,582,582,582,582,572,572,572,572,572,572,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,+572,572,572,572,572,572,572,572, 25, 25, 25, 25, 25, 25, 25, 25,+ 20, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+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, 20,++/* block 95 */+582,582,582,582,582,582,582,582,582,582,572,572,572,572,572,572,+572,572,572,572,572,572,572,584,572,584,572,572,572,572,572,572,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,+572, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+572,572,572,572,572,572,572,572,572,572,572,572, 20, 20, 20, 20,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,572,++/* block 96 */+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,+585,585,585,585,585,585,585,585,572,572,572,572,572,572,572,572,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,+572, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,572,572,572,572,572,++/* block 97 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, 20,++/* block 98 */+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,++/* block 99 */+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,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,++/* block 100 */+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,120,120,120,++/* block 101 */+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,+587,587,587,587,587,588,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,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,587,587,+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,++/* block 102 */+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,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,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,++/* block 103 */+587,587,587,587,587,587,587,587,587,587,587,587,587,120,120,120,+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,120,120,120,120,120,120,120,120,120,+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,+590,590,590,590,590,590,590,590,591,591,591,591,591,591,592,592,++/* block 104 */+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,593,593,593,593,593,++/* block 105 */+593,593,593,593,593,593,593,593,593,593,593,593,594,595,595,595,+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,+596,596,596,596,596,596,596,596,596,596,593,593,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+192,193,192,193,192,193,192,193,192,193,597,598,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,192,193,599,198,+200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,478,++/* block 106 */+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,+192,193,192,193,192,193,192,193,192,193,192,193,478,478,552,552,+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,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,601,601,601,601,601,601,601,601,601,601,601,601,+601,601,601,601,601,601,602,602,602,602,602,602,602,602,602,602,+603,603,604,604,604,604,604,604,120,120,120,120,120,120,120,120,++/* block 107 */+605,605,605,605,605,605,605,605, 15, 15, 15, 15, 15, 15, 15, 15,+ 15, 15, 15, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111,+ 15, 15, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,606, 32, 33,++/* block 108 */+ 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,607, 35, 22,+ 32, 33, 32, 33,608, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,609,610,611,612,609, 35,+613,614,615,616, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,+120,120, 32, 33,617,618,619, 32, 33, 32, 33,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120, 32, 33, 22,110,110, 35, 22, 22, 22, 22, 22,++/* block 109 */+620,620,621,620,620,620,621,620,620,620,620,621,620,620,620,620,+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,+620,620,620,622,622,621,621,622,623,623,623,623,621,120,120,120,+624,624,624,625,625,625,626,626,627,626,120,120,120,120,120,120,+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,628,+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,+628,628,628,628,629,629,629,629,120,120,120,120,120,120,120,120,++/* block 110 */+630,630,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,630,630,630,630,630,630,630,630,630,630,630,630,+630,630,630,630,632,632,120,120,120,120,120,120,120,120,633,633,+634,634,634,634,634,634,634,634,634,634,120,120,120,120,120,120,+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,+251,635,253,636,253,253,253,253,259,259,259,253,259,253,253,251,++/* block 111 */+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,638,638,638,638,639,639,639,639,639,639,639,639,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,643,643,643,643,643,643,643,643,643,+643,643,644,644,120,120,120,120,120,120,120,120,120,120,120,645,+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,120,120,120,++/* block 112 */+646,646,646,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,648,648,648,648,648,648,648,648,+648,648,648,646,647,647,646,646,646,646,647,647,646,646,647,647,+647,649,649,649,649,649,649,649,649,649,649,649,649,649,120,650,+651,651,651,651,651,651,651,651,651,651,120,120,120,120,649,649,+344,344,344,344,344,346,652,344,344,344,344,344,344,344,344,344,+350,350,350,350,350,350,350,350,350,350,344,344,344,344,344,120,++/* block 113 */+653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,+653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,+653,653,653,653,653,653,653,653,653,654,654,654,654,654,654,655,+655,654,654,655,655,654,654,120,120,120,120,120,120,120,120,120,+653,653,653,654,653,653,653,653,653,653,653,653,654,655,120,120,+656,656,656,656,656,656,656,656,656,656,120,120,657,657,657,657,+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,+652,344,344,344,344,344,344,351,351,351,344,345,346,345,344,344,++/* block 114 */+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,+659,658,659,659,659,658,658,659,659,658,658,658,658,658,659,659,+658,659,658,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,658,658,660,661,661,+662,662,662,662,662,662,662,662,662,662,662,663,664,664,663,663,+665,665,662,666,666,663,664,120,120,120,120,120,120,120,120,120,++/* block 115 */+120,359,359,359,359,359,359,120,120,359,359,359,359,359,359,120,+120,359,359,359,359,359,359,120,120,120,120,120,120,120,120,120,+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,+ 35, 35, 35,667, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110,+ 35, 35, 35, 35, 35,128, 35, 35, 35,110, 15, 15,120,120,120,120,+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,++/* block 116 */+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,+662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,+662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,+662,662,662,663,663,664,663,663,664,663,663,665,663,664,120,120,+669,669,669,669,669,669,669,669,669,669,120,120,120,120,120,120,++/* block 117 */+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,++/* block 118 */+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,++/* block 119 */+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,++/* block 120 */+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,++/* block 121 */+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,++/* block 122 */+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,++/* block 123 */+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,++/* block 124 */+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,+671,671,671,671,120,120,120,120,120,120,120,120,120,120,120,120,+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,+357,357,357,357,357,357,357,120,120,120,120,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,358,358,358,358,358,358,+358,358,358,358,358,358,358,358,358,358,358,358,120,120,120,120,++/* block 125 */+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,++/* block 126 */+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,++/* block 127 */+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,120,120,+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,++/* block 128 */+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,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 129 */+ 35, 35, 35, 35, 35, 35, 35,120,120,120,120,120,120,120,120,120,+120,120,120,206,206,206,206,206,120,120,120,120,120,214,211,214,+214,214,214,214,214,214,214,214,214,674,214,214,214,214,214,214,+214,214,214,214,214,214,214,120,214,214,214,214,214,120,214,120,+214,214,120,214,214,120,214,214,214,214,214,214,214,214,214,214,+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,++/* block 130 */+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,675,675,675,675,675,675,675,675,675,675,675,675,675,675,+675,675,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,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,++/* block 131 */+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,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,224,224,224,224,+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,++/* block 132 */+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,224,224,224,224,224,224,224,224,  8,  7,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+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,++/* block 133 */+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,+120,120,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,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+224,224,676,224,224,224,224,224,224,224,224,224,219,677,120,120,++/* block 134 */+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+  5,  5,  5,  5,  5,  5,  5,  7,  8,  5,120,120,120,120,120,120,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,552,552,+  5, 10, 10, 16, 16,  7,  8,  7,  8,  7,  8,  7,  8,  7,  8,  7,+  8,  7,  8,  7,  8,556,556,  7,  8,  5,  5,  5,  5, 16, 16, 16,+  5,  5,  5,120,  5,  5,  5,  5, 10,  7,  8,  7,  8,  7,  8,  5,+  5,  5,  9, 10,  9,  9,  9,120,  5,  6,  5,  5,120,120,120,120,+224,224,224,224,224,120,224,224,224,224,224,224,224,224,224,224,++/* block 135 */+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,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,224,224,224,224,+224,224,224,224,224,224,224,224,224,224,224,224,224,120,120, 24,++/* block 136 */+120,  5,  5,  5,  6,  5,  5,  5,  7,  8,  5,  9,  5, 10,  5,  5,+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  5,  5,  9,  9,  9,  5,+  5, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7,  5,  8, 15, 16,+ 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,  7,  9,  8,  9,  7,+  8,555,560,561,555,555,578,578,578,578,578,578,578,578,578,578,+569,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,++/* block 137 */+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,678,678,+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,581,120,+120,120,581,581,581,581,581,581,120,120,581,581,581,581,581,581,+120,120,581,581,581,581,581,581,120,120,581,581,581,120,120,120,+  6,  6,  9, 15, 20,  6,  6,120, 20,  9,  9,  9,  9, 20, 20,120,+511,511,511,511,511,511,511,511,511, 24, 24, 24, 20, 20,120,120,++/* block 138 */+679,679,679,679,679,679,679,679,679,679,679,679,120,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,679,120,679,679,679,679,679,679,679,679,+679,679,679,679,679,679,679,679,679,679,679,120,679,679,120,679,+679,679,679,679,679,679,679,679,679,679,679,679,679,679,120,120,+679,679,679,679,679,679,679,679,679,679,679,679,679,679,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 139 */+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,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,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,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,679,679,679,679,679,679,679,679,679,679,679,679,+679,679,679,679,679,679,679,679,679,679,679,120,120,120,120,120,++/* block 140 */+680,680,680,120,120,120,120,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,120,120,120,682,682,682,682,682,682,682,682,682,+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,+683,683,683,683,683,684,684,684,684,685,685,685,685,685,685,685,++/* block 141 */+685,685,685,685,685,685,685,685,685,685,684,684,685,685,685,120,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,+685,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,120,120,++/* block 142 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 143 */+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,120,120,120,+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,+687,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+688,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,+689,689,689,689,689,689,689,689,689,689,689,689,120,120,120,120,++/* block 144 */+690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,+690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,+691,691,691,691,120,120,120,120,120,120,120,120,120,690,690,690,+692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,+692,693,692,692,692,692,692,692,692,692,693,120,120,120,120,120,+694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,+694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,+694,694,694,694,694,694,695,695,695,695,695,120,120,120,120,120,++/* block 145 */+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,696,696,696,696,696,120,697,+698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,+698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,+698,698,698,698,120,120,120,120,698,698,698,698,698,698,698,698,+699,700,700,700,700,700,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 146 */+701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,+701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,+701,701,701,701,701,701,701,701,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,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,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,++/* block 147 */+704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,+704,704,704,704,704,704,704,704,704,704,704,704,704,704,120,120,+705,705,705,705,705,705,705,705,705,705,120,120,120,120,120,120,+706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,+706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,+706,706,706,706,120,120,120,120,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,120,120,120,120,++/* block 148 */+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,+708,708,708,708,708,708,708,708,120,120,120,120,120,120,120,120,+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,120,120,120,120,120,120,120,120,120,120,120,710,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 149 */+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,++/* block 150 */+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,120,120,120,120,120,120,120,120,120,+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,+711,711,711,711,711,711,120,120,120,120,120,120,120,120,120,120,+711,711,711,711,711,711,711,711,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 151 */+712,712,712,712,712,712,120,120,712,120,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,120,712,712,120,120,120,712,120,120,712,+713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,+713,713,713,713,713,713,120,714,715,715,715,715,715,715,715,715,+716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,+716,716,716,716,716,716,716,717,717,718,718,718,718,718,718,718,++/* block 152 */+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,120,+120,120,120,120,120,120,120,720,720,720,720,720,720,720,720,720,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,+721,721,721,120,721,721,120,120,120,120,120,722,722,722,722,722,++/* block 153 */+723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,+723,723,723,723,723,723,724,724,724,724,724,724,120,120,120,725,+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,120,120,120,120,120,727,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 154 */+728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,+728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,+729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,+729,729,729,729,729,729,729,729,120,120,120,120,730,730,729,729,+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,+120,120,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,++/* block 155 */+731,732,732,732,120,732,732,120,120,120,120,120,732,732,732,732,+731,731,731,731,120,731,731,731,120,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,120,120,732,732,732,120,120,120,120,732,+733,733,733,733,733,733,733,733,733,120,120,120,120,120,120,120,+734,734,734,734,734,734,734,734,734,120,120,120,120,120,120,120,+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,735,735,735,736,736,737,++/* block 156 */+738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,+738,738,738,738,738,738,738,738,738,738,738,738,738,739,739,739,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+740,740,740,740,740,740,740,740,741,740,740,740,740,740,740,740,+740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,+740,740,740,740,740,742,742,120,120,120,120,743,743,743,743,743,+744,744,744,744,744,744,744,120,120,120,120,120,120,120,120,120,++/* block 157 */+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,+745,745,745,745,745,745,120,120,120,746,746,746,746,746,746,746,+747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,+747,747,747,747,747,747,120,120,748,748,748,748,748,748,748,748,+749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,+749,749,749,120,120,120,120,120,750,750,750,750,750,750,750,750,++/* block 158 */+751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,+751,751,120,120,120,120,120,120,120,752,752,752,752,120,120,120,+120,120,120,120,120,120,120,120,120,753,753,753,753,753,753,753,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 159 */+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,+754,754,754,754,754,754,754,754,754,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 160 */+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,+755,755,755,120,120,120,120,120,120,120,120,120,120,120,120,120,+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,+756,756,756,120,120,120,120,120,120,120,757,757,757,757,757,757,++/* block 161 */+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,759,759,759,120,120,120,120,120,120,120,120,+760,760,760,760,760,760,760,760,760,760,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 162 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,+761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,120,++/* block 163 */+762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,+762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,+762,762,762,762,762,762,762,762,762,762,120,763,763,764,120,120,+762,762,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 164 */+765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,+765,765,765,765,765,765,765,765,765,765,765,765,765,766,766,766,+766,766,766,766,766,766,766,765,120,120,120,120,120,120,120,120,+767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,+767,767,767,767,767,767,768,768,768,768,768,768,768,768,768,768,+768,769,769,769,769,770,770,770,770,770,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 165 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,+771,771,771,771,771,772,772,772,772,772,772,772,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,+773,773,773,773,773,773,773,120,120,120,120,120,120,120,120,120,++/* block 166 */+774,775,774,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,775,775,775,775,775,775,775,775,+775,775,775,775,775,775,775,777,777,777,777,777,777,777,120,120,+120,120,778,778,778,778,778,778,778,778,778,778,778,778,778,778,+778,778,778,778,778,778,779,779,779,779,779,779,779,779,779,779,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,775,++/* block 167 */+780,780,781,782,782,782,782,782,782,782,782,782,782,782,782,782,+782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,+782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,+781,781,781,780,780,780,780,781,781,780,780,783,783,784,783,783,+783,783,120,120,120,120,120,120,120,120,120,120,120,784,120,120,+785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,+785,785,785,785,785,785,785,785,785,120,120,120,120,120,120,120,+786,786,786,786,786,786,786,786,786,786,120,120,120,120,120,120,++/* block 168 */+787,787,787,788,788,788,788,788,788,788,788,788,788,788,788,788,+788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,+788,788,788,788,788,788,788,787,787,787,787,787,789,787,787,787,+787,787,787,787,787,120,790,790,790,790,790,790,790,790,790,790,+791,791,791,791,788,789,789,788,120,120,120,120,120,120,120,120,+792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,+792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,+792,792,792,793,794,794,792,120,120,120,120,120,120,120,120,120,++/* block 169 */+795,795,796,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,796,796,796,795,795,795,795,795,795,795,795,795,796,+796,797,798,798,797,799,799,799,799,795,795,795,795,799,796,795,+800,800,800,800,800,800,800,800,800,800,797,799,797,799,799,799,+120,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,+801,801,801,801,801,120,120,120,120,120,120,120,120,120,120,120,++/* block 170 */+802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,+802,802,120,802,802,802,802,802,802,802,802,802,802,802,802,802,+802,802,802,802,802,802,802,802,802,802,802,802,803,803,803,804,+804,804,803,803,804,803,804,804,805,805,805,805,805,805,804,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 171 */+806,806,806,806,806,806,806,120,806,120,806,806,806,806,120,806,+806,806,806,806,806,806,806,806,806,806,806,806,806,806,120,806,+806,806,806,806,806,806,806,806,806,807,120,120,120,120,120,120,+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,809,+810,810,810,809,809,809,809,809,809,809,809,120,120,120,120,120,+811,811,811,811,811,811,811,811,811,811,120,120,120,120,120,120,++/* block 172 */+812,813,814,815,120,816,816,816,816,816,816,816,816,120,120,816,+816,120,120,816,816,816,816,816,816,816,816,816,816,816,816,816,+816,816,816,816,816,816,816,816,816,120,816,816,816,816,816,816,+816,120,816,816,120,816,816,816,816,816,120,817,813,816,818,814,+812,814,814,814,814,120,120,814,814,120,120,814,814,814,120,120,+816,120,120,120,120,120,120,818,120,120,120,120,120,816,816,816,+816,816,814,814,120,120,812,812,812,812,812,812,812,120,120,120,+812,812,812,812,812,120,120,120,120,120,120,120,120,120,120,120,++/* block 173 */+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,+819,819,819,819,819,820,820,820,821,821,821,821,821,821,821,821,+820,820,821,821,821,820,821,819,819,819,819,822,822,822,822,822,+823,823,823,823,823,823,823,823,823,823,822,822,120,822,821,819,+819,819,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 174 */+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,+825,826,826,827,827,827,827,827,827,826,827,826,826,825,826,827,+827,826,827,827,824,824,828,824,120,120,120,120,120,120,120,120,+829,829,829,829,829,829,829,829,829,829,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 175 */+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,831,+832,832,833,833,833,833,120,120,832,832,832,832,833,833,832,833,+833,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,+834,834,834,834,834,834,834,834,830,830,830,830,833,833,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 176 */+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,+836,836,836,837,837,837,837,837,837,837,837,836,836,837,836,837,+837,838,838,838,835,120,120,120,120,120,120,120,120,120,120,120,+839,839,839,839,839,839,839,839,839,839,120,120,120,120,120,120,+394,394,394,394,394,394,394,394,394,394,394,394,394,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 177 */+840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,+840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,+840,840,840,840,840,840,840,840,840,840,840,841,842,841,842,842,+841,841,841,841,841,841,842,841,840,120,120,120,120,120,120,120,+843,843,843,843,843,843,843,843,843,843,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 178 */+844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,+844,844,844,844,844,844,844,844,844,844,844,120,120,845,845,845,+846,846,845,845,845,845,846,845,845,845,845,845,120,120,120,120,+847,847,847,847,847,847,847,847,847,847,848,848,849,849,849,850,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 179 */+851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,+851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,+851,851,851,851,851,851,851,851,851,851,851,851,852,852,852,853,+853,853,853,853,853,853,853,853,852,853,853,854,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 180 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,+855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,+856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,+856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,+857,857,857,857,857,857,857,857,857,857,858,858,858,858,858,858,+858,858,858,120,120,120,120,120,120,120,120,120,120,120,120,859,++/* block 181 */+860,860,860,860,860,860,860,120,120,860,120,120,860,860,860,860,+860,860,860,860,120,860,860,120,860,860,860,860,860,860,860,860,+860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,+861,862,862,862,862,862,120,862,862,120,120,863,863,862,863,864,+862,864,862,863,865,865,865,120,120,120,120,120,120,120,120,120,+866,866,866,866,866,866,866,866,866,866,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 182 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+867,867,867,867,867,867,867,867,120,120,867,867,867,867,867,867,+867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,+867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,+867,868,868,868,869,869,869,869,120,120,869,869,868,868,868,868,+869,867,870,867,868,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 183 */+871,872,872,872,872,872,872,872,872,872,872,871,871,871,871,871,+871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,+871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,+871,871,871,872,872,872,872,872,872,873,874,872,872,872,872,875,+875,875,875,875,875,875,875,872,120,120,120,120,120,120,120,120,+876,877,877,877,877,877,877,878,878,877,877,877,876,876,876,876,+876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,+876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,++/* block 184 */+876,876,876,876,879,879,879,879,879,879,877,877,877,877,877,877,+877,877,877,877,877,877,877,878,877,877,880,880,880,876,880,880,+880,880,880,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,+881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,+881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,+881,881,881,881,881,881,881,881,881,120,120,120,120,120,120,120,++/* block 185 */+882,882,882,882,882,882,882,882,882,120,882,882,882,882,882,882,+882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,+882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,883,+884,884,884,884,884,884,884,120,884,884,884,884,884,884,883,884,+882,885,885,885,885,885,120,120,120,120,120,120,120,120,120,120,+886,886,886,886,886,886,886,886,886,886,887,887,887,887,887,887,+887,887,887,887,887,887,887,887,887,887,887,887,887,120,120,120,+888,888,889,889,889,889,889,889,889,889,889,889,889,889,889,889,++/* block 186 */+889,889,889,889,889,889,889,889,889,889,889,889,889,889,889,889,+120,120,890,890,890,890,890,890,890,890,890,890,890,890,890,890,+890,890,890,890,890,890,890,890,120,891,890,890,890,890,890,890,+890,891,890,890,891,890,890,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 187 */+892,892,892,892,892,892,892,120,892,892,120,892,892,892,892,892,+892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,+892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,+892,893,893,893,893,893,893,120,120,120,893,120,893,893,120,893,+893,893,893,893,893,893,894,893,120,120,120,120,120,120,120,120,+895,895,895,895,895,895,895,895,895,895,120,120,120,120,120,120,+896,896,896,896,896,896,120,896,896,120,896,896,896,896,896,896,+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,++/* block 188 */+896,896,896,896,896,896,896,896,896,896,897,897,897,897,897,120,+898,898,120,897,897,898,897,898,896,120,120,120,120,120,120,120,+899,899,899,899,899,899,899,899,899,899,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 189 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,+900,900,900,901,901,902,902,903,903,120,120,120,120,120,120,120,++/* block 190 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+590,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,+293,293,904,293,904,295,295,295,295,295,295,295,295,296,296,296,+296,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,+295,295,120,120,120,120,120,120,120,120,120,120,120,120,120,905,++/* block 191 */+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,++/* block 192 */+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 193 */+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,120,+908,908,908,908,908,120,120,120,120,120,120,120,120,120,120,120,++/* block 194 */+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,+906,906,906,906,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 195 */+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,++/* block 196 */+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,120,+910,910,910,910,910,910,910,910,910,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 197 */+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,++/* block 198 */+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,+911,911,911,911,911,911,911,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 199 */+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,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,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,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,601,601,601,601,601,601,601,601,+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,++/* block 200 */+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,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,601,601,601,601,601,120,120,120,120,120,120,120,+912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,+912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,120,+913,913,913,913,913,913,913,913,913,913,120,120,120,120,914,914,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 201 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,+915,915,915,915,915,915,915,915,915,915,915,915,915,915,120,120,+916,916,916,916,916,917,120,120,120,120,120,120,120,120,120,120,++/* block 202 */+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,+919,919,919,919,919,919,919,920,920,920,920,920,921,921,921,921,+922,922,922,922,920,921,120,120,120,120,120,120,120,120,120,120,+923,923,923,923,923,923,923,923,923,923,120,924,924,924,924,924,+924,924,120,918,918,918,918,918,918,918,918,918,918,918,918,918,+918,918,918,918,918,918,918,918,120,120,120,120,120,918,918,918,++/* block 203 */+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 204 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,+925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,+926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,+926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,++/* block 205 */+927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,+927,927,927,927,927,927,927,928,928,928,928,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 206 */+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,+929,929,929,929,929,929,929,929,929,929,929,120,120,120,120,930,+929,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,+931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,+931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,++/* block 207 */+931,931,931,931,931,931,931,931,120,120,120,120,120,120,120,930,+930,930,930,932,932,932,932,932,932,932,932,932,932,932,932,932,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+933,934,  5,111,935,120,120,120,120,120,120,120,120,120,120,120,+936,936,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 208 */+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,++/* block 209 */+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,+937,937,937,937,937,937,937,937,120,120,120,120,120,120,120,120,++/* block 210 */+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,++/* block 211 */+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,+938,938,938,938,938,938,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 212 */+937,937,937,937,937,937,937,937,937,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 213 */+578,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,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,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,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,573,573,573,573,573,573,573,++/* block 214 */+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,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,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,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,573,573,573,573,573,573,573,573,++/* block 215 */+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,573,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+573,573,573,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,578,578,578,578,120,120,120,120,120,120,120,120,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,++/* block 216 */+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,++/* block 217 */+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,+939,939,939,939,939,939,939,939,939,939,939,939,120,120,120,120,++/* block 218 */+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,+940,940,940,940,940,940,940,940,940,940,940,120,120,120,120,120,+940,940,940,940,940,940,940,940,940,940,940,940,940,120,120,120,++/* block 219 */+940,940,940,940,940,940,940,940,940,120,120,120,120,120,120,120,+940,940,940,940,940,940,940,940,940,940,120,120,941,942,942,943,+944,944,944,944,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 220 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,120,++/* block 221 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20,945,946,113,113,113, 20, 20, 20,946,945,945,+945,945,945, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113,++/* block 222 */+113,113,113, 20, 20,113,113,113,113,113,113,113, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,113,113,113, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 223 */+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,+685,685,947,947,947,685,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 224 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 225 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,+582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,+582,582, 25, 25, 25, 25, 25, 25, 25,120,120,120,120,120,120,120,++/* block 226 */+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,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,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,514,514,+514,514,514,514,514,120,514,514,514,514,514,514,514,514,514,514,+514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513,+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,++/* block 227 */+513,513,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,513,120,513,513,+120,120,513,120,120,513,513,120,120,513,513,513,513,120,513,513,+513,513,513,513,513,513,514,514,514,514,120,514,120,514,514,514,+514,514,514,514,120,514,514,514,514,514,514,514,514,514,514,514,+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,514,514,514,514,514,514,+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,++/* block 228 */+514,514,514,514,513,513,120,513,513,513,513,120,120,513,513,513,+513,513,513,513,513,120,513,513,513,513,513,513,513,120,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,513,513,120,513,513,513,513,120,+513,513,513,513,513,120,513,120,120,120,513,513,513,513,513,513,+513,120,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,513,513,513,513,+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,++/* block 229 */+513,513,513,513,513,513,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,+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,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,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,514,514,+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,++/* block 230 */+514,514,514,514,514,514,514,514,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,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,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,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,+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,++/* block 231 */+513,513,513,513,513,513,513,513,513,513,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,120,120,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,  9,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,  9,514,514,514,514,+514,514,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,  9,514,514,514,514,++/* block 232 */+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,+514,514,514,514,514,  9,514,514,514,514,514,514,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,  9,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,  9,+514,514,514,514,514,514,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,  9,+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,++/* block 233 */+514,514,514,514,514,514,514,514,514,  9,514,514,514,514,514,514,+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,  9,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,  9,514,514,514,514,514,514,513,514,120,120, 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, 11, 11, 11, 11, 11, 11, 11, 11,+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,++/* block 234 */+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,++/* block 235 */+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,+949,949,949,949,949,949,949,948,948,948,948,949,949,949,949,949,+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,+949,949,949,949,949,949,949,949,949,949,949,949,949,948,948,948,+948,948,948,948,948,949,948,948,948,948,948,948,948,948,948,948,++/* block 236 */+948,948,948,948,949,948,948,950,950,950,950,950,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,949,949,949,949,949,+120,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 237 */+951,951,951,951,951,951,951,120,951,951,951,951,951,951,951,951,+951,951,951,951,951,951,951,951,951,120,120,951,951,951,951,951,+951,951,120,951,951,120,951,951,951,951,951,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 238 */+952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,+952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,+952,952,952,952,952,952,952,952,952,952,952,952,952,120,120,120,+953,953,953,953,953,953,953,954,954,954,954,954,954,954,120,120,+955,955,955,955,955,955,955,955,955,955,120,120,120,120,952,956,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 239 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,+957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,+957,957,957,957,957,957,957,957,957,957,957,957,958,958,958,958,+959,959,959,959,959,959,959,959,959,959,120,120,120,120,120,960,++/* block 240 */+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,++/* block 241 */+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,+961,961,961,961,961,120,120,962,962,962,962,962,962,962,962,962,+963,963,963,963,963,963,963,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 242 */+964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,+964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,+964,964,965,965,965,965,965,965,965,965,965,965,965,965,965,965,+965,965,965,965,965,965,965,965,965,965,965,965,965,965,965,965,+965,965,965,965,966,966,966,966,966,966,966,967,120,120,120,120,+968,968,968,968,968,968,968,968,968,968,120,120,120,120,969,969,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 243 */+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,++/* block 244 */+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25,+  6, 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 245 */+120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25,+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 246 */+224,224,224,224,120,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,+120,224,224,120,224,120,120,224,120,224,224,224,224,224,224,224,+224,224,224,120,224,224,224,224,120,224,120,224,120,120,120,120,+120,120,224,120,120,120,120,224,120,224,120,224,120,224,224,224,+120,224,224,120,224,120,120,224,120,224,120,224,120,224,120,224,+120,224,224,120,224,120,120,224,224,224,224,120,224,224,224,224,+224,224,224,120,224,224,224,224,120,224,224,224,224,120,224,120,++/* block 247 */+224,224,224,224,224,224,224,224,224,224,120,224,224,224,224,224,+224,224,224,224,224,224,224,224,224,224,224,224,120,120,120,120,+120,224,224,224,120,224,224,224,224,224,120,224,224,224,224,224,+224,224,224,224,224,224,224,224,224,224,224,224,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+217,217,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 248 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,++/* block 249 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,+970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,++/* block 250 */+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 21, 21, 21,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21,+ 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21,++/* block 251 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20,+ 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,971,971,971,971,971,971,971,971,971,971,+971,971,971,971,971,971,971,971,971,971,971,971,971,971,971,971,++/* block 252 */+972, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,+ 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,970,970,970,970,+ 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,+584,584,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,++/* block 253 */+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,++/* block 254 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,++/* block 255 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,973,973,973,973,973,++/* block 256 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20,+ 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,++/* block 257 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,++/* block 258 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,++/* block 259 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20,970,970,970,970,970,970,970,970,970,970,970,970,++/* block 260 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 21, 21, 21, 21,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,++/* block 261 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,970,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,++/* block 262 */+ 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,970,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,+ 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,++/* block 263 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21,970, 21, 21, 21, 21, 21, 21,++/* block 264 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,++/* block 265 */+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,+ 21, 21, 21, 21, 21,970,970,970, 21, 21, 21,970,970,970,970,970,++/* block 266 */+ 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,+ 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,+ 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,+ 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,++/* block 267 */+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,120,120,120,120,120,120,++/* block 268 */+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,+970,970,970,970,970,970,970,970,970,970,970,970,970,970,120,120,++/* block 269 */+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,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 270 */+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,120,120,120,120,120,120,120,120,120,120,120,+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,++/* block 271 */+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,120,120,+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,++/* block 272 */+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,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+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,++/* block 273 */+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,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 274 */+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,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 275 */+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,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,++/* block 276 */+511, 24,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,+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,++/* block 277 */+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,+511,511,511,511,511,511,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,++/* block 278 */+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,++/* block 279 */+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,++/* block 280 */+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,+673,673,673,673,673,673,673,673,673,673,673,673,673,673,120,120,++};++#if UCD_BLOCK_SIZE != 128+#error Please correct UCD_BLOCK_SIZE in pcre2_internal.h+#endif+#endif  /* SUPPORT_UNICODE */++#endif  /* PCRE2_PCRE2TEST */
+ src/c/pcre2/src/pcre2_ucp.h view
@@ -0,0 +1,299 @@+/*************************************************+*      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.+-----------------------------------------------------------------------------+*/+++#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+should always be at the end of each enum, for backwards compatibility.++IMPORTANT: Note also that the specific numeric values of the enums have to be+the same as the values that are generated by the maint/MultiStage2.py script,+where the equivalent property descriptive names are listed in vectors.++ALSO: The specific values of the first two enums are assumed for the table+called catposstab in pcre2_compile.c. */++/* These are the general character categories. */++enum {+  ucp_C,     /* Other */+  ucp_L,     /* Letter */+  ucp_M,     /* Mark */+  ucp_N,     /* Number */+  ucp_P,     /* Punctuation */+  ucp_S,     /* Symbol */+  ucp_Z      /* Separator */+};++/* These are the particular character categories. */++enum {+  ucp_Cc,    /* Control */+  ucp_Cf,    /* Format */+  ucp_Cn,    /* Unassigned */+  ucp_Co,    /* Private use */+  ucp_Cs,    /* Surrogate */+  ucp_Ll,    /* Lower case letter */+  ucp_Lm,    /* Modifier letter */+  ucp_Lo,    /* Other letter */+  ucp_Lt,    /* Title case letter */+  ucp_Lu,    /* Upper case letter */+  ucp_Mc,    /* Spacing mark */+  ucp_Me,    /* Enclosing mark */+  ucp_Mn,    /* Non-spacing mark */+  ucp_Nd,    /* Decimal number */+  ucp_Nl,    /* Letter number */+  ucp_No,    /* Other number */+  ucp_Pc,    /* Connector punctuation */+  ucp_Pd,    /* Dash punctuation */+  ucp_Pe,    /* Close punctuation */+  ucp_Pf,    /* Final punctuation */+  ucp_Pi,    /* Initial punctuation */+  ucp_Po,    /* Other punctuation */+  ucp_Ps,    /* Open punctuation */+  ucp_Sc,    /* Currency symbol */+  ucp_Sk,    /* Modifier symbol */+  ucp_Sm,    /* Mathematical symbol */+  ucp_So,    /* Other symbol */+  ucp_Zl,    /* Line separator */+  ucp_Zp,    /* Paragraph separator */+  ucp_Zs     /* Space separator */+};++/* These are grapheme break properties. The Extended Pictographic property+comes from the emoji-data.txt file. */++enum {+  ucp_gbCR,                    /*  0 */+  ucp_gbLF,                    /*  1 */+  ucp_gbControl,               /*  2 */+  ucp_gbExtend,                /*  3 */+  ucp_gbPrepend,               /*  4 */+  ucp_gbSpacingMark,           /*  5 */+  ucp_gbL,                     /*  6 Hangul syllable type L */+  ucp_gbV,                     /*  7 Hangul syllable type V */+  ucp_gbT,                     /*  8 Hangul syllable type T */+  ucp_gbLV,                    /*  9 Hangul syllable type LV */+  ucp_gbLVT,                   /* 10 Hangul syllable type LVT */+  ucp_gbRegionalIndicator,     /* 11 */+  ucp_gbOther,                 /* 12 */+  ucp_gbZWJ,                   /* 13 */+  ucp_gbExtended_Pictographic  /* 14 */+};++/* These are the script identifications. */++enum {+  ucp_Unknown,+  ucp_Arabic,+  ucp_Armenian,+  ucp_Bengali,+  ucp_Bopomofo,+  ucp_Braille,+  ucp_Buginese,+  ucp_Buhid,+  ucp_Canadian_Aboriginal,+  ucp_Cherokee,+  ucp_Common,+  ucp_Coptic,+  ucp_Cypriot,+  ucp_Cyrillic,+  ucp_Deseret,+  ucp_Devanagari,+  ucp_Ethiopic,+  ucp_Georgian,+  ucp_Glagolitic,+  ucp_Gothic,+  ucp_Greek,+  ucp_Gujarati,+  ucp_Gurmukhi,+  ucp_Han,+  ucp_Hangul,+  ucp_Hanunoo,+  ucp_Hebrew,+  ucp_Hiragana,+  ucp_Inherited,+  ucp_Kannada,+  ucp_Katakana,+  ucp_Kharoshthi,+  ucp_Khmer,+  ucp_Lao,+  ucp_Latin,+  ucp_Limbu,+  ucp_Linear_B,+  ucp_Malayalam,+  ucp_Mongolian,+  ucp_Myanmar,+  ucp_New_Tai_Lue,+  ucp_Ogham,+  ucp_Old_Italic,+  ucp_Old_Persian,+  ucp_Oriya,+  ucp_Osmanya,+  ucp_Runic,+  ucp_Shavian,+  ucp_Sinhala,+  ucp_Syloti_Nagri,+  ucp_Syriac,+  ucp_Tagalog,+  ucp_Tagbanwa,+  ucp_Tai_Le,+  ucp_Tamil,+  ucp_Telugu,+  ucp_Thaana,+  ucp_Thai,+  ucp_Tibetan,+  ucp_Tifinagh,+  ucp_Ugaritic,+  ucp_Yi,+  /* New for Unicode 5.0 */+  ucp_Balinese,+  ucp_Cuneiform,+  ucp_Nko,+  ucp_Phags_Pa,+  ucp_Phoenician,+  /* New for Unicode 5.1 */+  ucp_Carian,+  ucp_Cham,+  ucp_Kayah_Li,+  ucp_Lepcha,+  ucp_Lycian,+  ucp_Lydian,+  ucp_Ol_Chiki,+  ucp_Rejang,+  ucp_Saurashtra,+  ucp_Sundanese,+  ucp_Vai,+  /* New for Unicode 5.2 */+  ucp_Avestan,+  ucp_Bamum,+  ucp_Egyptian_Hieroglyphs,+  ucp_Imperial_Aramaic,+  ucp_Inscriptional_Pahlavi,+  ucp_Inscriptional_Parthian,+  ucp_Javanese,+  ucp_Kaithi,+  ucp_Lisu,+  ucp_Meetei_Mayek,+  ucp_Old_South_Arabian,+  ucp_Old_Turkic,+  ucp_Samaritan,+  ucp_Tai_Tham,+  ucp_Tai_Viet,+  /* New for Unicode 6.0.0 */+  ucp_Batak,+  ucp_Brahmi,+  ucp_Mandaic,+  /* New for Unicode 6.1.0 */+  ucp_Chakma,+  ucp_Meroitic_Cursive,+  ucp_Meroitic_Hieroglyphs,+  ucp_Miao,+  ucp_Sharada,+  ucp_Sora_Sompeng,+  ucp_Takri,+  /* New for Unicode 7.0.0 */+  ucp_Bassa_Vah,+  ucp_Caucasian_Albanian,+  ucp_Duployan,+  ucp_Elbasan,+  ucp_Grantha,+  ucp_Khojki,+  ucp_Khudawadi,+  ucp_Linear_A,+  ucp_Mahajani,+  ucp_Manichaean,+  ucp_Mende_Kikakui,+  ucp_Modi,+  ucp_Mro,+  ucp_Nabataean,+  ucp_Old_North_Arabian,+  ucp_Old_Permic,+  ucp_Pahawh_Hmong,+  ucp_Palmyrene,+  ucp_Psalter_Pahlavi,+  ucp_Pau_Cin_Hau,+  ucp_Siddham,+  ucp_Tirhuta,+  ucp_Warang_Citi,+  /* New for Unicode 8.0.0 */+  ucp_Ahom,+  ucp_Anatolian_Hieroglyphs,+  ucp_Hatran,+  ucp_Multani,+  ucp_Old_Hungarian,+  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,+  /* New for Unicode 11.0.0 */+  ucp_Dogra,+  ucp_Gunjala_Gondi,+  ucp_Hanifi_Rohingya,+  ucp_Makasar,+  ucp_Medefaidrin,+  ucp_Old_Sogdian,+  ucp_Sogdian,+  /* New for Unicode 12.0.0 */+  ucp_Elymaic,+  ucp_Nandinagari,+  ucp_Nyiakeng_Puachue_Hmong,+  ucp_Wancho,+  /* New for Unicode 13.0.0 */+  ucp_Chorasmian,+  ucp_Dives_Akuru,+  ucp_Khitan_Small_Script,+  ucp_Yezidi+};++#endif  /* PCRE2_UCP_H_IDEMPOTENT_GUARD */++/* End of pcre2_ucp.h */
+ src/c/pcre2/src/pcre2_valid_utf.c view
@@ -0,0 +1,398 @@+/*************************************************+*      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-2020 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 for validating UTF character+strings. This file is also #included by the pcre2test program, which uses+macros to change names from _pcre2_xxx to xxxx, thereby avoiding name clashes+with the library. In this case, PCRE2_PCRE2TEST is defined. */++#ifndef PCRE2_PCRE2TEST           /* We're compiling the library */+#ifdef HAVE_CONFIG_H+#include "config.h"+#endif+#include "pcre2_internal.h"+#endif /* PCRE2_PCRE2TEST */+++#ifndef SUPPORT_UNICODE+/*************************************************+*  Dummy function when Unicode is not supported  *+*************************************************/++/* This function should never be called when Unicode is not supported. */++int+PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)+{+(void)string;+(void)length;+(void)erroroffset;+return 0;+}+#else  /* UTF is supported */++++/*************************************************+*           Validate a UTF string                *+*************************************************/++/* This function is called (optionally) at the start of compile or match, to+check that a supposed UTF string is actually valid. The early check means+that subsequent code can assume it is dealing with a valid string. The check+can be turned off for maximum performance, but the consequences of supplying an+invalid string are then undefined.++Arguments:+  string       points to the string+  length       length of string+  errp         pointer to an error position offset variable++Returns:       == 0    if the string is a valid UTF string+               != 0    otherwise, setting the offset of the bad character+*/++int+PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)+{+PCRE2_SPTR p;+uint32_t c;++/* ----------------- Check a UTF-8 string ----------------- */++#if PCRE2_CODE_UNIT_WIDTH == 8++/* Originally, this function checked according to RFC 2279, allowing for values+in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were+in the canonical format. Once somebody had pointed out RFC 3629 to me (it+obsoletes 2279), additional restrictions were applied. The values are now+limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the+subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte+characters is still checked. Error returns are as follows:++PCRE2_ERROR_UTF8_ERR1   Missing 1 byte at the end of the string+PCRE2_ERROR_UTF8_ERR2   Missing 2 bytes at the end of the string+PCRE2_ERROR_UTF8_ERR3   Missing 3 bytes at the end of the string+PCRE2_ERROR_UTF8_ERR4   Missing 4 bytes at the end of the string+PCRE2_ERROR_UTF8_ERR5   Missing 5 bytes at the end of the string+PCRE2_ERROR_UTF8_ERR6   2nd-byte's two top bits are not 0x80+PCRE2_ERROR_UTF8_ERR7   3rd-byte's two top bits are not 0x80+PCRE2_ERROR_UTF8_ERR8   4th-byte's two top bits are not 0x80+PCRE2_ERROR_UTF8_ERR9   5th-byte's two top bits are not 0x80+PCRE2_ERROR_UTF8_ERR10  6th-byte's two top bits are not 0x80+PCRE2_ERROR_UTF8_ERR11  5-byte character is not permitted by RFC 3629+PCRE2_ERROR_UTF8_ERR12  6-byte character is not permitted by RFC 3629+PCRE2_ERROR_UTF8_ERR13  4-byte character with value > 0x10ffff is not permitted+PCRE2_ERROR_UTF8_ERR14  3-byte character with value 0xd800-0xdfff is not permitted+PCRE2_ERROR_UTF8_ERR15  Overlong 2-byte sequence+PCRE2_ERROR_UTF8_ERR16  Overlong 3-byte sequence+PCRE2_ERROR_UTF8_ERR17  Overlong 4-byte sequence+PCRE2_ERROR_UTF8_ERR18  Overlong 5-byte sequence (won't ever occur)+PCRE2_ERROR_UTF8_ERR19  Overlong 6-byte sequence (won't ever occur)+PCRE2_ERROR_UTF8_ERR20  Isolated 0x80 byte (not within UTF-8 character)+PCRE2_ERROR_UTF8_ERR21  Byte with the illegal value 0xfe or 0xff+*/++for (p = string; length > 0; p++)+  {+  uint32_t ab, d;++  c = *p;+  length--;++  if (c < 128) continue;                /* ASCII character */++  if (c < 0xc0)                         /* Isolated 10xx xxxx byte */+    {+    *erroroffset = (PCRE2_SIZE)(p - string);+    return PCRE2_ERROR_UTF8_ERR20;+    }++  if (c >= 0xfe)                        /* Invalid 0xfe or 0xff bytes */+    {+    *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 = (PCRE2_SIZE)(p - string);+    switch(ab - length)+      {+      case 1: return PCRE2_ERROR_UTF8_ERR1;+      case 2: return PCRE2_ERROR_UTF8_ERR2;+      case 3: return PCRE2_ERROR_UTF8_ERR3;+      case 4: return PCRE2_ERROR_UTF8_ERR4;+      case 5: return PCRE2_ERROR_UTF8_ERR5;+      }+    }+  length -= ab;                         /* Length remaining */++  /* Check top bits in the second byte */++  if (((d = *(++p)) & 0xc0) != 0x80)+    {+    *erroroffset = (int)(p - string) - 1;+    return PCRE2_ERROR_UTF8_ERR6;+    }++  /* For each length, check that the remaining bytes start with the 0x80 bit+  set and not the 0x40 bit. Then check for an overlong sequence, and for the+  excluded range 0xd800 to 0xdfff. */++  switch (ab)+    {+    /* 2-byte character. No further bytes to check for 0x80. Check first byte+    for for xx00 000x (overlong sequence). */++    case 1: if ((c & 0x3e) == 0)+      {+      *erroroffset = (int)(p - string) - 1;+      return PCRE2_ERROR_UTF8_ERR15;+      }+    break;++    /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes+      for 1110 0000, xx0x xxxx (overlong sequence) or+          1110 1101, 1010 xxxx (0xd800 - 0xdfff) */++    case 2:+    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */+      {+      *erroroffset = (int)(p - string) - 2;+      return PCRE2_ERROR_UTF8_ERR7;+      }+    if (c == 0xe0 && (d & 0x20) == 0)+      {+      *erroroffset = (int)(p - string) - 2;+      return PCRE2_ERROR_UTF8_ERR16;+      }+    if (c == 0xed && d >= 0xa0)+      {+      *erroroffset = (int)(p - string) - 2;+      return PCRE2_ERROR_UTF8_ERR14;+      }+    break;++    /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2+       bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a+       character greater than 0x0010ffff (f4 8f bf bf) */++    case 3:+    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */+      {+      *erroroffset = (int)(p - string) - 2;+      return PCRE2_ERROR_UTF8_ERR7;+      }+    if ((*(++p) & 0xc0) != 0x80)     /* Fourth byte */+      {+      *erroroffset = (int)(p - string) - 3;+      return PCRE2_ERROR_UTF8_ERR8;+      }+    if (c == 0xf0 && (d & 0x30) == 0)+      {+      *erroroffset = (int)(p - string) - 3;+      return PCRE2_ERROR_UTF8_ERR17;+      }+    if (c > 0xf4 || (c == 0xf4 && d > 0x8f))+      {+      *erroroffset = (int)(p - string) - 3;+      return PCRE2_ERROR_UTF8_ERR13;+      }+    break;++    /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be+    rejected by the length test below. However, we do the appropriate tests+    here so that overlong sequences get diagnosed, and also in case there is+    ever an option for handling these larger code points. */++    /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for+    1111 1000, xx00 0xxx */++    case 4:+    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */+      {+      *erroroffset = (int)(p - string) - 2;+      return PCRE2_ERROR_UTF8_ERR7;+      }+    if ((*(++p) & 0xc0) != 0x80)     /* Fourth byte */+      {+      *erroroffset = (int)(p - string) - 3;+      return PCRE2_ERROR_UTF8_ERR8;+      }+    if ((*(++p) & 0xc0) != 0x80)     /* Fifth byte */+      {+      *erroroffset = (int)(p - string) - 4;+      return PCRE2_ERROR_UTF8_ERR9;+      }+    if (c == 0xf8 && (d & 0x38) == 0)+      {+      *erroroffset = (int)(p - string) - 4;+      return PCRE2_ERROR_UTF8_ERR18;+      }+    break;++    /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for+    1111 1100, xx00 00xx. */++    case 5:+    if ((*(++p) & 0xc0) != 0x80)     /* Third byte */+      {+      *erroroffset = (int)(p - string) - 2;+      return PCRE2_ERROR_UTF8_ERR7;+      }+    if ((*(++p) & 0xc0) != 0x80)     /* Fourth byte */+      {+      *erroroffset = (int)(p - string) - 3;+      return PCRE2_ERROR_UTF8_ERR8;+      }+    if ((*(++p) & 0xc0) != 0x80)     /* Fifth byte */+      {+      *erroroffset = (int)(p - string) - 4;+      return PCRE2_ERROR_UTF8_ERR9;+      }+    if ((*(++p) & 0xc0) != 0x80)     /* Sixth byte */+      {+      *erroroffset = (int)(p - string) - 5;+      return PCRE2_ERROR_UTF8_ERR10;+      }+    if (c == 0xfc && (d & 0x3c) == 0)+      {+      *erroroffset = (int)(p - string) - 5;+      return PCRE2_ERROR_UTF8_ERR19;+      }+    break;+    }++  /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are+  excluded by RFC 3629. The pointer p is currently at the last byte of the+  character. */++  if (ab > 3)+    {+    *erroroffset = (int)(p - string) - ab;+    return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12;+    }+  }+return 0;+++/* ----------------- Check a UTF-16 string ----------------- */++#elif PCRE2_CODE_UNIT_WIDTH == 16++/* There's not so much work, nor so many errors, for UTF-16.+PCRE2_ERROR_UTF16_ERR1  Missing low surrogate at the end of the string+PCRE2_ERROR_UTF16_ERR2  Invalid low surrogate+PCRE2_ERROR_UTF16_ERR3  Isolated low surrogate+*/++for (p = string; length > 0; p++)+  {+  c = *p;+  length--;++  if ((c & 0xf800) != 0xd800)+    {+    /* Normal UTF-16 code point. Neither high nor low surrogate. */+    }+  else if ((c & 0x0400) == 0)+    {+    /* High surrogate. Must be a followed by a low surrogate. */+    if (length == 0)+      {+      *erroroffset = p - string;+      return PCRE2_ERROR_UTF16_ERR1;+      }+    p++;+    length--;+    if ((*p & 0xfc00) != 0xdc00)+      {+      *erroroffset = p - string - 1;+      return PCRE2_ERROR_UTF16_ERR2;+      }+    }+  else+    {+    /* Isolated low surrogate. Always an error. */+    *erroroffset = p - string;+    return PCRE2_ERROR_UTF16_ERR3;+    }+  }+return 0;++++/* ----------------- Check a UTF-32 string ----------------- */++#else++/* There is very little to do for a UTF-32 string.+PCRE2_ERROR_UTF32_ERR1  Surrogate character+PCRE2_ERROR_UTF32_ERR2  Character > 0x10ffff+*/++for (p = string; length > 0; length--, p++)+  {+  c = *p;+  if ((c & 0xfffff800u) != 0xd800u)+    {+    /* Normal UTF-32 code point. Neither high nor low surrogate. */+    if (c > 0x10ffffu)+      {+      *erroroffset = p - string;+      return PCRE2_ERROR_UTF32_ERR2;+      }+    }+  else+    {+    /* A surrogate */+    *erroroffset = p - string;+    return PCRE2_ERROR_UTF32_ERR1;+    }+  }+return 0;+#endif  /* CODE_UNIT_WIDTH */+}+#endif  /* SUPPORT_UNICODE */++/* End of pcre2_valid_utf.c */
+ src/c/pcre2/src/pcre2_xclass.c view
@@ -0,0 +1,271 @@+/*************************************************+*      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-2019 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 an extended+class. It is used by pcre2_auto_possessify() and by both pcre2_match() and+pcre2_def_match(). */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif+++#include "pcre2_internal.h"++/*************************************************+*       Match character against an XCLASS        *+*************************************************/++/* This function is called to match a character against an extended class that+might contain codepoints above 255 and/or Unicode properties.++Arguments:+  c           the character+  data        points to the flag code unit of the XCLASS data+  utf         TRUE if in UTF mode++Returns:      TRUE if character matches, else FALSE+*/++BOOL+PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf)+{+PCRE2_UCHAR t;+BOOL negated = (*data & XCL_NOT) != 0;++#if PCRE2_CODE_UNIT_WIDTH == 8+/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */+utf = TRUE;+#endif++/* Code points < 256 are matched against a bitmap, if one is present. If not,+we still carry on, because there may be ranges that start below 256 in the+additional data. */++if (c < 256)+  {+  if ((*data & XCL_HASPROP) == 0)+    {+    if ((*data & XCL_MAP) == 0) return negated;+    return (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0;+    }+  if ((*data & XCL_MAP) != 0 &&+    (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0)+    return !negated; /* char found */+  }++/* First skip the bit map if present. Then match against the list of Unicode+properties or large chars or ranges that end with a large char. We won't ever+encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */++if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR);++while ((t = *data++) != XCL_END)+  {+  uint32_t x, y;+  if (t == XCL_SINGLE)+    {+#ifdef SUPPORT_UNICODE+    if (utf)+      {+      GETCHARINC(x, data); /* macro generates multiple statements */+      }+    else+#endif+    x = *data++;+    if (c == x) return !negated;+    }+  else if (t == XCL_RANGE)+    {+#ifdef SUPPORT_UNICODE+    if (utf)+      {+      GETCHARINC(x, data); /* macro generates multiple statements */+      GETCHARINC(y, data); /* macro generates multiple statements */+      }+    else+#endif+      {+      x = *data++;+      y = *data++;+      }+    if (c >= x && c <= y) return !negated;+    }++#ifdef SUPPORT_UNICODE+  else  /* XCL_PROP & XCL_NOTPROP */+    {+    const ucd_record *prop = GET_UCD(c);+    BOOL isprop = t == XCL_PROP;++    switch(*data)+      {+      case PT_ANY:+      if (isprop) return !negated;+      break;++      case PT_LAMP:+      if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||+           prop->chartype == ucp_Lt) == isprop) return !negated;+      break;++      case PT_GC:+      if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)+        return !negated;+      break;++      case PT_PC:+      if ((data[1] == prop->chartype) == isprop) return !negated;+      break;++      case PT_SC:+      if ((data[1] == prop->script) == isprop) return !negated;+      break;++      case PT_ALNUM:+      if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+           PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)+        return !negated;+      break;++      /* Perl space used to exclude VT, but from Perl 5.18 it is included,+      which means that Perl space and POSIX space are now identical. PCRE+      was changed at release 8.34. */++      case PT_SPACE:    /* Perl space */+      case PT_PXSPACE:  /* POSIX space */+      switch(c)+        {+        HSPACE_CASES:+        VSPACE_CASES:+        if (isprop) return !negated;+        break;++        default:+        if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)+          return !negated;+        break;+        }+      break;++      case PT_WORD:+      if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||+           PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)+             == isprop)+        return !negated;+      break;++      case PT_UCNC:+      if (c < 0xa0)+        {+        if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||+             c == CHAR_GRAVE_ACCENT) == isprop)+          return !negated;+        }+      else+        {+        if ((c < 0xd800 || c > 0xdfff) == isprop)+          return !negated;+        }+      break;++      /* The following three properties can occur only in an XCLASS, as there+      is no \p or \P coding for them. */++      /* Graphic character. Implement this as not Z (space or separator) and+      not C (other), except for Cf (format) with a few exceptions. This seems+      to be what Perl does. The exceptional characters are:++      U+061C           Arabic Letter Mark+      U+180E           Mongolian Vowel Separator+      U+2066 - U+2069  Various "isolate"s+      */++      case PT_PXGRAPH:+      if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&+            (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||+              (prop->chartype == ucp_Cf &&+                c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))+         )) == isprop)+        return !negated;+      break;++      /* Printable character: same as graphic, with the addition of Zs, i.e.+      not Zl and not Zp, and U+180E. */++      case PT_PXPRINT:+      if ((prop->chartype != ucp_Zl &&+           prop->chartype != ucp_Zp &&+            (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||+              (prop->chartype == ucp_Cf &&+                c != 0x061c && (c < 0x2066 || c > 0x2069))+         )) == isprop)+        return !negated;+      break;++      /* Punctuation: all Unicode punctuation, plus ASCII characters that+      Unicode treats as symbols rather than punctuation, for Perl+      compatibility (these are $+<=>^`|~). */++      case PT_PXPUNCT:+      if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||+            (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)+        return !negated;+      break;++      /* This should never occur, but compilers may mutter if there is no+      default. */++      default:+      return FALSE;+      }++    data += 2;+    }+#else+  (void)utf;  /* Avoid compiler warning */+#endif  /* SUPPORT_UNICODE */+  }++return negated;   /* char did not match */+}++/* End of pcre2_xclass.c */
+ src/c/pcre2/src/pcre2demo.c view
@@ -0,0 +1,494 @@+/*************************************************+*           PCRE2 DEMONSTRATION PROGRAM          *+*************************************************/++/* This is a demonstration program to illustrate a straightforward way of+using the PCRE2 regular expression library from a C program. See the+pcre2sample documentation for a short discussion ("man pcre2sample" if you have+the PCRE2 man pages installed). PCRE2 is a revised API for the library, and is+incompatible with the original PCRE API.++There are actually three libraries, each supporting a different code unit+width. This demonstration program uses the 8-bit library. The default is to+process each code unit as a separate character, but if the pattern begins with+"(*UTF)", both it and the subject are treated as UTF-8 strings, where+characters may occupy multiple code units.++In Unix-like environments, if PCRE2 is installed in your standard system+libraries, you should be able to compile this program using this command:++cc -Wall pcre2demo.c -lpcre2-8 -o pcre2demo++If PCRE2 is not installed in a standard place, it is likely to be installed+with support for the pkg-config mechanism. If you have pkg-config, you can+compile this program using this command:++cc -Wall pcre2demo.c `pkg-config --cflags --libs libpcre2-8` -o pcre2demo++If you do not have pkg-config, you may have to use something like this:++cc -Wall pcre2demo.c -I/usr/local/include -L/usr/local/lib \+  -R/usr/local/lib -lpcre2-8 -o pcre2demo++Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and+library files for PCRE2 are installed on your system. Only some operating+systems (Solaris is one) use the -R option.++Building under Windows:++If you want to statically link this program against a non-dll .a file, you must+define PCRE2_STATIC before including pcre2.h, so in this environment, uncomment+the following line. */++/* #define PCRE2_STATIC */++/* The PCRE2_CODE_UNIT_WIDTH macro must be defined before including pcre2.h.+For a program that uses only one code unit width, setting it to 8, 16, or 32+makes it possible to use generic function names such as pcre2_compile(). Note+that just changing 8 to 16 (for example) is not sufficient to convert this+program to process 16-bit characters. Even in a fully 16-bit environment, where+string-handling functions such as strcmp() and printf() work with 16-bit+characters, the code for handling the table of named substrings will still need+to be modified. */++#define PCRE2_CODE_UNIT_WIDTH 8++#include <stdio.h>+#include <string.h>+#include <pcre2.h>+++/**************************************************************************+* Here is the program. The API includes the concept of "contexts" for     *+* setting up unusual interface requirements for compiling and matching,   *+* such as custom memory managers and non-standard newline definitions.    *+* This program does not do any of this, so it makes no use of contexts,   *+* always passing NULL where a context could be given.                     *+**************************************************************************/++int main(int argc, char **argv)+{+pcre2_code *re;+PCRE2_SPTR pattern;     /* PCRE2_SPTR is a pointer to unsigned code units of */+PCRE2_SPTR subject;     /* the appropriate width (in this case, 8 bits). */+PCRE2_SPTR name_table;++int crlf_is_newline;+int errornumber;+int find_all;+int i;+int rc;+int utf8;++uint32_t option_bits;+uint32_t namecount;+uint32_t name_entry_size;+uint32_t newline;++PCRE2_SIZE erroroffset;+PCRE2_SIZE *ovector;+PCRE2_SIZE subject_length;++pcre2_match_data *match_data;+++/**************************************************************************+* First, sort out the command line. There is only one possible option at  *+* the moment, "-g" to request repeated matching to find all occurrences,  *+* like Perl's /g option. We set the variable find_all to a non-zero value *+* if the -g option is present.                                            *+**************************************************************************/++find_all = 0;+for (i = 1; i < argc; i++)+  {+  if (strcmp(argv[i], "-g") == 0) find_all = 1;+  else if (argv[i][0] == '-')+    {+    printf("Unrecognised option %s\n", argv[i]);+    return 1;+    }+  else break;+  }++/* After the options, we require exactly two arguments, which are the pattern,+and the subject string. */++if (argc - i != 2)+  {+  printf("Exactly two arguments required: a regex and a subject string\n");+  return 1;+  }++/* Pattern and subject are char arguments, so they can be straightforwardly+cast to PCRE2_SPTR because we are working in 8-bit code units. The subject+length is cast to PCRE2_SIZE for completeness, though PCRE2_SIZE is in fact+defined to be size_t. */++pattern = (PCRE2_SPTR)argv[i];+subject = (PCRE2_SPTR)argv[i+1];+subject_length = (PCRE2_SIZE)strlen((char *)subject);+++/*************************************************************************+* Now we are going to compile the regular expression pattern, and handle *+* any errors that are detected.                                          *+*************************************************************************/++re = pcre2_compile(+  pattern,               /* the pattern */+  PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */+  0,                     /* default options */+  &errornumber,          /* for error number */+  &erroroffset,          /* for error offset */+  NULL);                 /* use default compile context */++/* Compilation failed: print the error message and exit. */++if (re == NULL)+  {+  PCRE2_UCHAR buffer[256];+  pcre2_get_error_message(errornumber, buffer, sizeof(buffer));+  printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset,+    buffer);+  return 1;+  }+++/*************************************************************************+* If the compilation succeeded, we call PCRE2 again, in order to do a    *+* pattern match against the subject string. This does just ONE match. If *+* further matching is needed, it will be done below. Before running the  *+* match we must set up a match_data block for holding the result. Using  *+* pcre2_match_data_create_from_pattern() ensures that the block is       *+* exactly the right size for the number of capturing parentheses in the  *+* pattern. If you need to know the actual size of a match_data block as  *+* a number of bytes, you can find it like this:                          *+*                                                                        *+* PCRE2_SIZE match_data_size = pcre2_get_match_data_size(match_data);    *+*************************************************************************/++match_data = pcre2_match_data_create_from_pattern(re, NULL);++/* Now run the match. */++rc = pcre2_match(+  re,                   /* the compiled pattern */+  subject,              /* the subject string */+  subject_length,       /* the length of the subject */+  0,                    /* start at offset 0 in the subject */+  0,                    /* default options */+  match_data,           /* block for storing the result */+  NULL);                /* use default match context */++/* Matching failed: handle error cases */++if (rc < 0)+  {+  switch(rc)+    {+    case PCRE2_ERROR_NOMATCH: printf("No match\n"); break;+    /*+    Handle other special cases if you like+    */+    default: printf("Matching error %d\n", rc); break;+    }+  pcre2_match_data_free(match_data);   /* Release memory used for the match */+  pcre2_code_free(re);                 /*   data and the compiled pattern. */+  return 1;+  }++/* Match succeded. Get a pointer to the output vector, where string offsets are+stored. */++ovector = pcre2_get_ovector_pointer(match_data);+printf("Match succeeded at offset %d\n", (int)ovector[0]);+++/*************************************************************************+* We have found the first match within the subject string. If the output *+* vector wasn't big enough, say so. Then output any substrings that were *+* captured.                                                              *+*************************************************************************/++/* The output vector wasn't big enough. This should not happen, because we used+pcre2_match_data_create_from_pattern() above. */++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. */++for (i = 0; i < rc; i++)+  {+  PCRE2_SPTR substring_start = subject + ovector[2*i];+  PCRE2_SIZE substring_length = ovector[2*i+1] - ovector[2*i];+  printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start);+  }+++/**************************************************************************+* That concludes the basic part of this demonstration program. We have    *+* compiled a pattern, and performed a single match. The code that follows *+* shows first how to access named substrings, and then how to code for    *+* repeated matches on the same subject.                                   *+**************************************************************************/++/* See if there are any named substrings, and if so, show them by name. First+we have to extract the count of named parentheses from the pattern. */++(void)pcre2_pattern_info(+  re,                   /* the compiled pattern */+  PCRE2_INFO_NAMECOUNT, /* get the number of named substrings */+  &namecount);          /* where to put the answer */++if (namecount == 0) printf("No named substrings\n"); else+  {+  PCRE2_SPTR tabptr;+  printf("Named substrings\n");++  /* Before we can access the substrings, we must extract the table for+  translating names to numbers, and the size of each entry in the table. */++  (void)pcre2_pattern_info(+    re,                       /* the compiled pattern */+    PCRE2_INFO_NAMETABLE,     /* address of the table */+    &name_table);             /* where to put the answer */++  (void)pcre2_pattern_info(+    re,                       /* the compiled pattern */+    PCRE2_INFO_NAMEENTRYSIZE, /* size of each entry in the table */+    &name_entry_size);        /* where to put the answer */++  /* Now we can scan the table and, for each entry, print the number, the name,+  and the substring itself. In the 8-bit library the number is held in two+  bytes, most significant first. */++  tabptr = name_table;+  for (i = 0; i < namecount; i++)+    {+    int n = (tabptr[0] << 8) | tabptr[1];+    printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,+      (int)(ovector[2*n+1] - ovector[2*n]), subject + ovector[2*n]);+    tabptr += name_entry_size;+    }+  }+++/*************************************************************************+* If the "-g" option was given on the command line, we want to continue  *+* to search for additional matches in the subject string, in a similar   *+* way to the /g option in Perl. This turns out to be trickier than you   *+* might think because of the possibility of matching an empty string.    *+* What happens is as follows:                                            *+*                                                                        *+* If the previous match was NOT for an empty string, we can just start   *+* the next match at the end of the previous one.                         *+*                                                                        *+* If the previous match WAS for an empty string, we can't do that, as it *+* would lead to an infinite loop. Instead, a call of pcre2_match() is    *+* made with the PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED flags set. The *+* first of these tells PCRE2 that an empty string at the start of the    *+* subject is not a valid match; other possibilities must be tried. The   *+* second flag restricts PCRE2 to one match attempt at the initial string *+* position. If this match succeeds, an alternative to the empty string   *+* match has been found, and we can print it and proceed round the loop,  *+* advancing by the length of whatever was found. If this match does not  *+* succeed, we still stay in the loop, advancing by just one character.   *+* In UTF-8 mode, which can be set by (*UTF) in the pattern, this may be  *+* more than one byte.                                                    *+*                                                                        *+* However, there is a complication concerned with newlines. When the     *+* newline convention is such that CRLF is a valid newline, we must       *+* advance by two characters rather than one. The newline convention can  *+* be set in the regex by (*CR), etc.; if not, we must find the default.  *+*************************************************************************/++if (!find_all)     /* Check for -g */+  {+  pcre2_match_data_free(match_data);  /* Release the memory that was used */+  pcre2_code_free(re);                /* for the match data and the pattern. */+  return 0;                           /* Exit the program. */+  }++/* Before running the loop, check for UTF-8 and whether CRLF is a valid newline+sequence. First, find the options with which the regex was compiled and extract+the UTF state. */++(void)pcre2_pattern_info(re, PCRE2_INFO_ALLOPTIONS, &option_bits);+utf8 = (option_bits & PCRE2_UTF) != 0;++/* Now find the newline convention and see whether CRLF is a valid newline+sequence. */++(void)pcre2_pattern_info(re, PCRE2_INFO_NEWLINE, &newline);+crlf_is_newline = newline == PCRE2_NEWLINE_ANY ||+                  newline == PCRE2_NEWLINE_CRLF ||+                  newline == PCRE2_NEWLINE_ANYCRLF;++/* Loop for second and subsequent matches */++for (;;)+  {+  uint32_t options = 0;                   /* Normally no options */+  PCRE2_SIZE start_offset = ovector[1];   /* Start at end of previous match */++  /* If the previous match was for an empty string, we are finished if we are+  at the end of the subject. Otherwise, arrange to run another match at the+  same point to see if a non-empty match can be found. */++  if (ovector[0] == ovector[1])+    {+    if (ovector[0] == subject_length) break;+    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(+    re,                   /* the compiled pattern */+    subject,              /* the subject string */+    subject_length,       /* the length of the subject */+    start_offset,         /* starting offset in the subject */+    options,              /* options */+    match_data,           /* block for storing the result */+    NULL);                /* use default match context */++  /* This time, a result of NOMATCH isn't an error. If the value in "options"+  is zero, it just means we have found all possible matches, so the loop ends.+  Otherwise, it means we have failed to find a non-empty-string match at a+  point where there was a previous empty-string match. In this case, we do what+  Perl does: advance the matching position by one character, and continue. We+  do this by setting the "end of previous match" offset, because that is picked+  up at the top of the loop as the point at which to start again.++  There are two complications: (a) When CRLF is a valid newline sequence, and+  the current position is just before it, advance by an extra byte. (b)+  Otherwise we must ensure that we skip an entire UTF character if we are in+  UTF mode. */++  if (rc == PCRE2_ERROR_NOMATCH)+    {+    if (options == 0) break;                    /* All matches found */+    ovector[1] = start_offset + 1;              /* Advance one code unit */+    if (crlf_is_newline &&                      /* If CRLF is a newline & */+        start_offset < subject_length - 1 &&    /* we are at CRLF, */+        subject[start_offset] == '\r' &&+        subject[start_offset + 1] == '\n')+      ovector[1] += 1;                          /* Advance by one more. */+    else if (utf8)                              /* Otherwise, ensure we */+      {                                         /* advance a whole UTF-8 */+      while (ovector[1] < subject_length)       /* character. */+        {+        if ((subject[ovector[1]] & 0xc0) != 0x80) break;+        ovector[1] += 1;+        }+      }+    continue;    /* Go round the loop again */+    }++  /* Other matching errors are not recoverable. */++  if (rc < 0)+    {+    printf("Matching error %d\n", rc);+    pcre2_match_data_free(match_data);+    pcre2_code_free(re);+    return 1;+    }++  /* Match succeded */++  printf("\nMatch succeeded again at offset %d\n", (int)ovector[0]);++  /* The match succeeded, but the output vector wasn't big enough. This+  should not happen. */++  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. */++  for (i = 0; i < rc; i++)+    {+    PCRE2_SPTR substring_start = subject + ovector[2*i];+    size_t substring_length = ovector[2*i+1] - ovector[2*i];+    printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start);+    }++  if (namecount == 0) printf("No named substrings\n"); else+    {+    PCRE2_SPTR tabptr = name_table;+    printf("Named substrings\n");+    for (i = 0; i < namecount; i++)+      {+      int n = (tabptr[0] << 8) | tabptr[1];+      printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,+        (int)(ovector[2*n+1] - ovector[2*n]), subject + ovector[2*n]);+      tabptr += name_entry_size;+      }+    }+  }      /* End of loop to find second and subsequent matches */++printf("\n");+pcre2_match_data_free(match_data);+pcre2_code_free(re);+return 0;+}++/* End of pcre2demo.c */
+ src/c/pcre2/src/pcre2grep.c view
@@ -0,0 +1,4553 @@+/*************************************************+*               pcre2grep program                *+*************************************************/++/* This is a grep program that uses the 8-bit PCRE regular expression library+via the PCRE2 updated API to do its pattern matching. On Unix-like, Windows,+and native z/OS systems it can recurse into directories, and in z/OS it can+handle PDS files.++Note that for native z/OS, in addition to defining the NATIVE_ZOS macro, an+additional header is required. That header is not included in the main PCRE2+distribution because other apparatus is needed to compile pcre2grep for z/OS.+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-2020 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 <ctype.h>+#include <locale.h>+#include <stdio.h>+#include <string.h>+#include <stdlib.h>+#include <errno.h>++#include <sys/types.h>+#include <sys/stat.h>++#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)+#undef WIN32+#endif++#ifdef __VMS+#include clidef+#include descrip+#include lib$routines+#endif++#ifdef WIN32+#include <io.h>                /* For _setmode() */+#include <fcntl.h>             /* For _O_BINARY */+#endif++#if defined(SUPPORT_PCRE2GREP_CALLOUT) && defined(SUPPORT_PCRE2GREP_CALLOUT_FORK)+#ifdef WIN32+#include <process.h>+#else+#include <sys/wait.h>+#endif+#endif++#ifdef HAVE_UNISTD_H+#include <unistd.h>+#endif++#ifdef SUPPORT_LIBZ+#include <zlib.h>+#endif++#ifdef SUPPORT_LIBBZ2+#include <bzlib.h>+#endif++#define PCRE2_CODE_UNIT_WIDTH 8+#include "pcre2.h"++/* Older versions of MSVC lack snprintf(). This define allows for+warning/error-free compilation and testing with MSVC compilers back to at least+MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */++#if defined(_MSC_VER) && (_MSC_VER < 1900)+#define snprintf _snprintf+#endif++/* VC and older compilers don't support %td or %zu, and even some that claim to+be C99 don't support it (hence DISABLE_PERCENT_ZT). */++#if defined(_MSC_VER) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || defined(DISABLE_PERCENT_ZT)+#define PTR_FORM "lu"+#define SIZ_FORM "lu"+#define SIZ_CAST (unsigned long int)+#else+#define PTR_FORM "td"+#define SIZ_FORM "zu"+#define SIZ_CAST+#endif++#define FALSE 0+#define TRUE 1++typedef int BOOL;++#define DEFAULT_CAPTURE_MAX 50++#if BUFSIZ > 8192+#define MAXPATLEN BUFSIZ+#else+#define MAXPATLEN 8192+#endif++#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+all values greater than FN_DEFAULT. */++enum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE };++/* File reading styles */++enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 };++/* Actions for the -d and -D options */++enum { dee_READ, dee_SKIP, dee_RECURSE };+enum { DEE_READ, DEE_SKIP };++/* Actions for special processing options (flag bits) */++#define PO_WORD_MATCH     0x0001+#define PO_LINE_MATCH     0x0002+#define PO_FIXED_STRINGS  0x0004++/* Binary file options */++enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT };++/* Return values from decode_dollar_escape() */++enum { DDE_ERROR, DDE_CAPTURE, DDE_CHAR };++/* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some+environments), a warning is issued if the value of fwrite() is ignored.+Unfortunately, casting to (void) does not suppress the warning. To get round+this, we use a macro that compiles a fudge. Oddly, this does not also seem to+apply to fprintf(). */++#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. We also use a normal double+quote for the example, as single quotes aren't usually available. */++#ifdef WIN32+#define STDOUT_NL     "\r\n"+#define STDOUT_NL_LEN  2+#define QUOT          "\""+#else+#define STDOUT_NL      "\n"+#define STDOUT_NL_LEN  1+#define QUOT           "'"+#endif++/* This code is returned from decode_dollar_escape() when $n is encountered,+and used to mean "output STDOUT_NL". It is, of course, not a valid Unicode code+point. */++#define STDOUT_NL_CODE 0x7fffffffu++++/*************************************************+*               Global variables                 *+*************************************************/++/* Jeffrey Friedl has some debugging requirements that are not part of the+regular code. */++#ifdef JFRIEDL_DEBUG+static int S_arg = -1;+static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */+static unsigned int jfriedl_XT = 0; /* replicate text this many times */+static const char *jfriedl_prefix = "";+static const char *jfriedl_postfix = "";+#endif++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 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;++static int count_limit = -1;  /* Not long, so that it works with OP_NUMBER */+static unsigned long int counts_printed = 0;+static unsigned long int total_count = 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;++#ifdef SUPPORT_PCRE2GREP_JIT+static BOOL use_jit = TRUE;+#else+static BOOL use_jit = FALSE;+#endif++static const uint8_t *character_tables = NULL;++static uint32_t pcre2_options = 0;+static uint32_t extra_options = 0;+static PCRE2_SIZE heap_limit = PCRE2_UNSET;+static uint32_t match_limit = 0;+static uint32_t depth_limit = 0;++static pcre2_compile_context *compile_context;+static pcre2_match_context *match_context;+static pcre2_match_data *match_data;+static PCRE2_SIZE *offsets;+static uint32_t offset_size;+static uint32_t capture_max = DEFAULT_CAPTURE_MAX;++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;+static BOOL line_buffered = FALSE;+static BOOL line_offsets = FALSE;+static BOOL multiline = FALSE;+static BOOL number = FALSE;+static BOOL omit_zero_count = FALSE;+static BOOL resource_error = FALSE;+static BOOL quiet = FALSE;+static BOOL show_total_count = FALSE;+static BOOL silent = FALSE;+static BOOL utf = FALSE;++static uint8_t utf8_buffer[8];+++/* Structure for list of --only-matching capturing numbers. */++typedef struct omstr {+  struct omstr *next;+  int groupnum;+} omstr;++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. */++typedef struct omdatastr {+  omstr **anchor;+  omstr **lastptr;+} omdatastr;++static omdatastr only_matching_data = { &only_matching, &only_matching_last };++/* Structure for list of file names (for -f and --{in,ex}clude-from) */++typedef struct fnstr {+  struct fnstr *next;+  char *name;+} fnstr;++static fnstr *exclude_from = NULL;+static fnstr *exclude_from_last = NULL;+static fnstr *include_from = NULL;+static fnstr *include_from_last = NULL;++static fnstr *file_lists = NULL;+static fnstr *file_lists_last = NULL;+static fnstr *pattern_files = NULL;+static fnstr *pattern_files_last = NULL;++/* Structure for holding the two variables that describe a file name chain. */++typedef struct fndatastr {+  fnstr **anchor;+  fnstr **lastptr;+} fndatastr;++static fndatastr exclude_from_data = { &exclude_from, &exclude_from_last };+static fndatastr include_from_data = { &include_from, &include_from_last };+static fndatastr file_lists_data = { &file_lists, &file_lists_last };+static fndatastr pattern_files_data = { &pattern_files, &pattern_files_last };++/* Structure for pattern and its compiled form; used for matching patterns and+also for include/exclude patterns. */++typedef struct patstr {+  struct patstr *next;+  char *string;+  PCRE2_SIZE length;+  pcre2_code *compiled;+} patstr;++static patstr *patterns = NULL;+static patstr *patterns_last = NULL;+static patstr *include_patterns = NULL;+static patstr *include_patterns_last = NULL;+static patstr *exclude_patterns = NULL;+static patstr *exclude_patterns_last = NULL;+static patstr *include_dir_patterns = NULL;+static patstr *include_dir_patterns_last = NULL;+static patstr *exclude_dir_patterns = NULL;+static patstr *exclude_dir_patterns_last = NULL;++/* Structure holding the two variables that describe a pattern chain. A pointer+to such structures is used for each appropriate option. */++typedef struct patdatastr {+  patstr **anchor;+  patstr **lastptr;+} patdatastr;++static patdatastr match_patdata = { &patterns, &patterns_last };+static patdatastr include_patdata = { &include_patterns, &include_patterns_last };+static patdatastr exclude_patdata = { &exclude_patterns, &exclude_patterns_last };+static patdatastr include_dir_patdata = { &include_dir_patterns, &include_dir_patterns_last };+static patdatastr exclude_dir_patdata = { &exclude_dir_patterns, &exclude_dir_patterns_last };++static patstr **incexlist[4] = { &include_patterns, &exclude_patterns,+                                 &include_dir_patterns, &exclude_dir_patterns };++static const char *incexname[4] = { "--include", "--exclude",+                                    "--include-dir", "--exclude-dir" };++/* Structure for options and list of them */++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 {+  int type;+  int one_char;+  void *dataptr;+  const char *long_name;+  const char *help_text;+} option_item;++/* Options without a single-letter equivalent get a negative value. This can be+used to identify them. */++#define N_COLOUR       (-1)+#define N_EXCLUDE      (-2)+#define N_EXCLUDE_DIR  (-3)+#define N_HELP         (-4)+#define N_INCLUDE      (-5)+#define N_INCLUDE_DIR  (-6)+#define N_LABEL        (-7)+#define N_LOCALE       (-8)+#define N_NULL         (-9)+#define N_LOFFSETS     (-10)+#define N_FOFFSETS     (-11)+#define N_LBUFFER      (-12)+#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)+#define N_OM_CAPTURE   (-24)++static option_item optionlist[] = {+  { OP_NODATA,     N_NULL,   NULL,              "",              "terminate options" },+  { OP_NODATA,     N_HELP,   NULL,              "help",          "display this help and exit" },+  { OP_NUMBER,     'A',      &after_context,    "after-context=number", "set number of following context lines" },+  { 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 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" },+  { OP_NODATA,     'c',      NULL,              "count",         "print only a count of matching lines per FILE" },+  { OP_STRING,     'D',      &DEE_option,       "devices=action","how to handle devices, FIFOs, and sockets" },+  { OP_STRING,     'd',      &dee_option,       "directories=action", "how to handle directories" },+  { OP_PATLIST,    'e',      &match_patdata,    "regex(p)=pattern", "specify pattern (may be used more than once)" },+  { OP_NODATA,     'F',      NULL,              "fixed-strings", "patterns are sets of newline-separated strings" },+  { OP_FILELIST,   'f',      &pattern_files_data, "file=path",   "read patterns from file" },+  { OP_FILELIST,   N_FILE_LIST, &file_lists_data, "file-list=path","read files to search from file" },+  { OP_NODATA,     N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },+  { OP_NODATA,     'H',      NULL,              "with-filename", "force the prefixing filename on output" },+  { 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" },+  { 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_SIZE,       N_H_LIMIT, &heap_limit,      "heap-limit=number",  "set PCRE2 heap limit option (kibibytes)" },+  { 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_NUMBER,     'm',      &count_limit,      "max-count=number", "stop after <number> matched lines" },+  { 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_U32NUMBER,  N_OM_CAPTURE, &capture_max,  "om-capture=n",  "set capture count for --only-matching" },+  { OP_NODATA,     'q',      NULL,              "quiet",         "suppress output, just set return code" },+  { OP_NODATA,     'r',      NULL,              "recursive",     "recursively scan sub-directories" },+  { OP_PATLIST,    N_EXCLUDE,&exclude_patdata,  "exclude=pattern","exclude matching files when recursing" },+  { OP_PATLIST,    N_INCLUDE,&include_patdata,  "include=pattern","include matching files when recursing" },+  { OP_PATLIST,    N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude-dir=pattern","exclude matching directories when recursing" },+  { OP_PATLIST,    N_INCLUDE_DIR,&include_dir_patdata, "include-dir=pattern","include matching directories when recursing" },+  { OP_FILELIST,   N_EXCLUDE_FROM,&exclude_from_data, "exclude-from=path", "read exclude list from file" },+  { OP_FILELIST,   N_INCLUDE_FROM,&include_from_data, "include-from=path", "read include list from file" },+#ifdef JFRIEDL_DEBUG+  { 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,    'U',      NULL,              "utf-allow-invalid", "use UTF mode, allow for invalid code units" },+  { OP_NODATA,    'V',      NULL,              "version",       "print version information and exit" },+  { OP_NODATA,    'v',      NULL,              "invert-match",  "select non-matching lines" },+  { OP_NODATA,    'w',      NULL,              "word-regex(p)", "force patterns to match only as words"  },+  { OP_NODATA,    'x',      NULL,              "line-regex(p)", "force patterns to match only whole lines" },+  { OP_NODATA,    0,        NULL,               NULL,            NULL }+};++/* Table of names for newline types. Must be kept in step with the definitions+of PCRE2_NEWLINE_xx in pcre2.h. */++static const char *newlines[] = {+  "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF", "NUL" };++/* UTF-8 tables  */++const int utf8_table1[] =+  { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};+const int utf8_table1_size = sizeof(utf8_table1) / sizeof(int);++const int utf8_table2[] = { 0,    0xc0, 0xe0, 0xf0, 0xf8, 0xfc};+const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};++const char utf8_table4[] = {+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,+  3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };+++#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)+/*************************************************+*    Emulated memmove() for systems without it   *+*************************************************/++/* This function can make use of bcopy() if it is available. Otherwise do it by+steam, as there are some non-Unix environments that lack both memmove() and+bcopy(). */++static void *+emulated_memmove(void *d, const void *s, size_t n)+{+#ifdef HAVE_BCOPY+bcopy(s, d, n);+return d;+#else+size_t i;+unsigned char *dest = (unsigned char *)d;+const unsigned char *src = (const unsigned char *)s;+if (dest > src)+  {+  dest += n;+  src += n;+  for (i = 0; i < n; ++i) *(--dest) = *(--src);+  return (void *)dest;+  }+else+  {+  for (i = 0; i < n; ++i) *dest++ = *src++;+  return (void *)(dest - n);+  }+#endif   /* not HAVE_BCOPY */+}+#undef memmove+#define memmove(d,s,n) emulated_memmove(d,s,n)+#endif   /* not VPCOMPAT && not HAVE_MEMMOVE */++++/*************************************************+*           Convert code point to UTF-8          *+*************************************************/++/* A static buffer is used. Returns the number of bytes. */++static int+ord2utf8(uint32_t value)+{+int i, j;+uint8_t *utf8bytes = utf8_buffer;+for (i = 0; i < utf8_table1_size; i++)+  if (value <= (uint32_t)utf8_table1[i]) break;+utf8bytes += i;+for (j = i; j > 0; j--)+  {+  *utf8bytes-- = 0x80 | (value & 0x3f);+  value >>= 6;+  }+*utf8bytes = utf8_table2[i] | value;+return i + 1;+}++++/*************************************************+*         Case-independent string compare        *+*************************************************/++static int+strcmpic(const char *str1, const char *str2)+{+unsigned int c1, c2;+while (*str1 != '\0' || *str2 != '\0')+  {+  c1 = tolower(*str1++);+  c2 = tolower(*str2++);+  if (c1 != c2) return ((c1 > c2) << 1) - 1;+  }+return 0;+}+++/*************************************************+*         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                  *+*************************************************/++/* If there has been a resource error, give a suitable message.++Argument:  the return code+Returns:   does not return+*/++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+  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, %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);+}+++/*************************************************+*          Add item to chain of patterns         *+*************************************************/++/* Used to add an item onto a chain, or just return an unconnected item if the+"after" argument is NULL.++Arguments:+  s          pattern string to add+  patlen     length of pattern+  after      if not NULL points to item to insert after++Returns:     new pattern block or NULL on error+*/++static patstr *+add_pattern(char *s, PCRE2_SIZE patlen, patstr *after)+{+patstr *p = (patstr *)malloc(sizeof(patstr));+if (p == NULL)+  {+  fprintf(stderr, "pcre2grep: malloc failed\n");+  pcre2grep_exit(2);+  }+if (patlen > MAXPATLEN)+  {+  fprintf(stderr, "pcre2grep: pattern is too long (limit is %d bytes)\n",+    MAXPATLEN);+  free(p);+  return NULL;+  }+p->next = NULL;+p->string = s;+p->length = patlen;+p->compiled = NULL;++if (after != NULL)+  {+  p->next = after->next;+  after->next = p;+  }+return p;+}+++/*************************************************+*           Free chain of patterns               *+*************************************************/++/* Used for several chains of patterns.++Argument: pointer to start of chain+Returns:  nothing+*/++static void+free_pattern_chain(patstr *pc)+{+while (pc != NULL)+  {+  patstr *p = pc;+  pc = p->next;+  if (p->compiled != NULL) pcre2_code_free(p->compiled);+  free(p);+  }+}+++/*************************************************+*           Free chain of file names             *+*************************************************/++/*+Argument: pointer to start of chain+Returns:  nothing+*/++static void+free_file_chain(fnstr *fn)+{+while (fn != NULL)+  {+  fnstr *f = fn;+  fn = f->next;+  free(f);+  }+}+++/*************************************************+*            OS-specific functions               *+*************************************************/++/* 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 ***********/++#if (defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H) || defined NATIVE_ZOS+#include <sys/types.h>+#include <sys/stat.h>+#include <dirent.h>++#if defined NATIVE_ZOS+/************* Directory and PDS/E scanning for z/OS ***********/+/************* z/OS looks mostly like Unix with USS ************/+/* However, z/OS needs the #include statements in this header */+#include "pcrzosfs.h"+/* That header is not included in the main PCRE distribution because+   other apparatus is needed to compile pcre2grep for z/OS. The header+   can be found in the special z/OS distribution, which is available+   from www.zaconsultants.net or from www.cbttape.org. */+#endif++typedef DIR directory_type;+#define FILESEP '/'++static int+isdirectory(char *filename)+{+struct stat statbuf;+if (stat(filename, &statbuf) < 0)+  return 0;        /* In the expectation that opening as a file will fail */+return S_ISDIR(statbuf.st_mode);+}++static directory_type *+opendirectory(char *filename)+{+return opendir(filename);+}++static char *+readdirectory(directory_type *dir)+{+for (;;)+  {+  struct dirent *dent = readdir(dir);+  if (dent == NULL) return NULL;+  if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0)+    return dent->d_name;+  }+/* Control never reaches here */+}++static void+closedirectory(directory_type *dir)+{+closedir(dir);+}+++/************* Test for regular file, Unix-style **********/++static int+isregfile(char *filename)+{+struct stat statbuf;+if (stat(filename, &statbuf) < 0)+  return 1;        /* In the expectation that opening as a file will fail */+return S_ISREG(statbuf.st_mode);+}+++#if defined NATIVE_ZOS+/************* Test for a terminal in z/OS **********/+/* isatty() does not work in a TSO environment, so always give FALSE.*/++static BOOL+is_stdout_tty(void)+{+return FALSE;+}++static BOOL+is_file_tty(FILE *f)+{+return FALSE;+}+++/************* Test for a terminal, Unix-style **********/++#else+static BOOL+is_stdout_tty(void)+{+return isatty(fileno(stdout));+}++static BOOL+is_file_tty(FILE *f)+{+return isatty(fileno(f));+}+#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. */+++/************* Directory scanning in Windows ***********/++/* I (Philip Hazel) have no means of testing this code. It was contributed by+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.+*/++#elif defined WIN32++#ifndef INVALID_FILE_ATTRIBUTES+#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF+#endif++typedef struct directory_type+{+HANDLE handle;+BOOL first;+WIN32_FIND_DATA data;+} directory_type;++#define FILESEP '/'++int+isdirectory(char *filename)+{+DWORD attr = GetFileAttributes(filename);+if (attr == INVALID_FILE_ATTRIBUTES)+  return 0;+return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;+}++directory_type *+opendirectory(char *filename)+{+size_t len;+char *pattern;+directory_type *dir;+DWORD err;+len = strlen(filename);+pattern = (char *)malloc(len + 3);+dir = (directory_type *)malloc(sizeof(*dir));+if ((pattern == NULL) || (dir == NULL))+  {+  fprintf(stderr, "pcre2grep: malloc failed\n");+  pcre2grep_exit(2);+  }+memcpy(pattern, filename, len);+if (iswild(filename))+  pattern[len] = 0;+else+  memcpy(&(pattern[len]), "\\*", 3);+dir->handle = FindFirstFile(pattern, &(dir->data));+if (dir->handle != INVALID_HANDLE_VALUE)+  {+  free(pattern);+  dir->first = TRUE;+  return dir;+  }+err = GetLastError();+free(pattern);+free(dir);+errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT;+return NULL;+}++char *+readdirectory(directory_type *dir)+{+for (;;)+  {+  if (!dir->first)+    {+    if (!FindNextFile(dir->handle, &(dir->data)))+      return NULL;+    }+  else+    {+    dir->first = FALSE;+    }+  if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0)+    return dir->data.cFileName;+  }+#ifndef _MSC_VER+return NULL;   /* Keep compiler happy; never executed */+#endif+}++void+closedirectory(directory_type *dir)+{+FindClose(dir->handle);+free(dir);+}+++/************* Test for regular file in Windows **********/++/* I don't know how to do this, or if it can be done; assume all paths are+regular if they are not directories. */++int isregfile(char *filename)+{+return !isdirectory(filename);+}+++/************* Test for a terminal in Windows **********/++static BOOL+is_stdout_tty(void)+{+return _isatty(_fileno(stdout));+}++static BOOL+is_file_tty(FILE *f)+{+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 */+++/************* Directory scanning when we can't do it ***********/++/* The type is void, and apart from isdirectory(), the functions do nothing. */++#else++#define FILESEP 0+typedef void directory_type;++int isdirectory(char *filename) { return 0; }+directory_type * opendirectory(char *filename) { return (directory_type*)0;}+char *readdirectory(directory_type *dir) { return (char*)0;}+void closedirectory(directory_type *dir) {}+++/************* Test for regular file when we can't do it **********/++/* Assume all files are regular. */++int isregfile(char *filename) { return 1; }+++/************* Test for a terminal when we can't do it **********/++static BOOL+is_stdout_tty(void)+{+return FALSE;+}++static BOOL+is_file_tty(FILE *f)+{+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 */++++#ifndef HAVE_STRERROR+/*************************************************+*     Provide strerror() for non-ANSI libraries  *+*************************************************/++/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()+in their libraries, but can 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 */++++/*************************************************+*                Usage function                  *+*************************************************/++static int+usage(int rc)+{+option_item *op;+fprintf(stderr, "Usage: pcre2grep [-");+for (op = optionlist; op->one_char != 0; op++)+  {+  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 "+  "options.\n");+return rc;+}++++/*************************************************+*                Help function                   *+*************************************************/++static void+help(void)+{+option_item *op;++printf("Usage: pcre2grep [OPTION]... [PATTERN] [FILE1 FILE2 ...]" STDOUT_NL);+printf("Search for PATTERN in each FILE or standard input." STDOUT_NL);+printf("PATTERN must be present if neither -e nor -f is used." STDOUT_NL);++#ifdef SUPPORT_PCRE2GREP_CALLOUT+#ifdef SUPPORT_PCRE2GREP_CALLOUT_FORK+printf("All callout scripts in patterns are supported." STDOUT_NL);+#else+printf("Non-fork callout scripts in patterns are supported." STDOUT_NL);+#endif+#else+printf("Callout scripts are not supported in this pcre2grep." STDOUT_NL);+#endif++printf("\"-\" can be used as a file name to mean STDIN." STDOUT_NL);++#ifdef SUPPORT_LIBZ+printf("Files whose names end in .gz are read using zlib." STDOUT_NL);+#endif++#ifdef SUPPORT_LIBBZ2+printf("Files whose names end in .bz2 are read using bzlib2." STDOUT_NL);+#endif++#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2+printf("Other files and the standard input are read as plain files." STDOUT_NL STDOUT_NL);+#else+printf("All files are read as plain files, without any interpretation." STDOUT_NL STDOUT_NL);+#endif++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++)+  {+  int n;+  char s[4];++  if (op->one_char > 0 && (op->long_name)[0] == 0)+    n = 31 - printf("  -%c", op->one_char);+  else+    {+    if (op->one_char > 0) sprintf(s, "-%c,", op->one_char);+      else strcpy(s, "   ");+    n = 31 - printf("  %s --%s", s, op->long_name);+    }++  if (n < 1) n = 1;+  printf("%.*s%s" STDOUT_NL, n, "                           ", op->help_text);+  }++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);++printf(STDOUT_NL "With no FILEs, read standard input. If fewer than two FILEs given, assume -h." STDOUT_NL);+printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble." STDOUT_NL);+}++++/*************************************************+*            Test exclude/includes               *+*************************************************/++/* If any exclude pattern matches, the path is excluded. Otherwise, unless+there are no includes, the path must match an include pattern.++Arguments:+  path      the path to be matched+  ip        the chain of include patterns+  ep        the chain of exclude patterns++Returns:    TRUE if the path is not excluded+*/++static BOOL+test_incexc(char *path, patstr *ip, patstr *ep)+{+int plen = strlen((const char *)path);++for (; ep != NULL; ep = ep->next)+  {+  if (pcre2_match(ep->compiled, (PCRE2_SPTR)path, plen, 0, 0, match_data, NULL) >= 0)+    return FALSE;+  }++if (ip == NULL) return TRUE;++for (; ip != NULL; ip = ip->next)+  {+  if (pcre2_match(ip->compiled, (PCRE2_SPTR)path, plen, 0, 0, match_data, NULL) >= 0)+    return TRUE;+  }++return FALSE;+}++++/*************************************************+*         Decode integer argument value          *+*************************************************/++/* Integer arguments can be followed by K or M. Avoid the use of strtoul()+because SunOS4 doesn't have it. This is used only for unpicking arguments, so+just keep it simple.++Arguments:+  option_data   the option data string+  op            the option item (for error messages)+  longop        TRUE if option given in long form++Returns:        a long integer+*/++static long int+decode_number(char *option_data, option_item *op, BOOL longop)+{+unsigned long int n = 0;+char *endptr = option_data;+while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;+while (isdigit((unsigned char)(*endptr)))+  n = n * 10 + (int)(*endptr++ - '0');+if (toupper(*endptr) == 'K')+  {+  n *= 1024;+  endptr++;+  }+else if (toupper(*endptr) == 'M')+  {+  n *= 1024*1024;+  endptr++;+  }++if (*endptr != 0)   /* Error */+  {+  if (longop)+    {+    char *equals = strchr(op->long_name, '=');+    int nlen = (equals == NULL)? (int)strlen(op->long_name) :+      (int)(equals - op->long_name);+    fprintf(stderr, "pcre2grep: Malformed number \"%s\" after --%.*s\n",+      option_data, nlen, op->long_name);+    }+  else+    fprintf(stderr, "pcre2grep: Malformed number \"%s\" after -%c\n",+      option_data, op->one_char);+  pcre2grep_exit(usage(2));+  }++return n;+}++++/*************************************************+*       Add item to a chain of numbers           *+*************************************************/++/* Used to add an item onto a chain, or just return an unconnected item if the+"after" argument is NULL.++Arguments:+  n          the number to add+  after      if not NULL points to item to insert after++Returns:     new number block+*/++static omstr *+add_number(int n, omstr *after)+{+omstr *om = (omstr *)malloc(sizeof(omstr));++if (om == NULL)+  {+  fprintf(stderr, "pcre2grep: malloc failed\n");+  pcre2grep_exit(2);+  }+om->next = NULL;+om->groupnum = n;++if (after != NULL)+  {+  om->next = after->next;+  after->next = om;+  }+return om;+}++++/*************************************************+*            Read one line of input              *+*************************************************/++/* Normally, input that is to be scanned 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. This function is also used for reading patterns+from files (the -f option).++Arguments:+  buffer     the buffer to read into+  length     the maximum number of characters to read+  f          the file++Returns:     the number of characters read, zero at end of file+*/++static PCRE2_SIZE+read_one_line(char *buffer, int length, FILE *f)+{+int c;+int yield = 0;+while ((c = fgetc(f)) != EOF)+  {+  buffer[yield++] = c;+  if (c == '\n' || yield >= length) break;+  }+return yield;+}++++/*************************************************+*             Find end of line                   *+*************************************************/++/* The length of the endline sequence that is found is set via lenptr. This may+be zero at the very end of the file if there is no line-ending sequence there.++Arguments:+  p         current position in line+  endptr    end of available data+  lenptr    where to put the length of the eol sequence++Returns:    pointer after the last byte of the line,+            including the newline byte(s)+*/++static char *+end_of_line(char *p, char *endptr, int *lenptr)+{+switch(endlinetype)+  {+  default:      /* Just in case */+  case PCRE2_NEWLINE_LF:+  while (p < endptr && *p != '\n') p++;+  if (p < endptr)+    {+    *lenptr = 1;+    return p + 1;+    }+  *lenptr = 0;+  return endptr;++  case PCRE2_NEWLINE_CR:+  while (p < endptr && *p != '\r') p++;+  if (p < endptr)+    {+    *lenptr = 1;+    return p + 1;+    }+  *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 (;;)+    {+    while (p < endptr && *p != '\r') p++;+    if (++p >= endptr)+      {+      *lenptr = 0;+      return endptr;+      }+    if (*p == '\n')+      {+      *lenptr = 2;+      return p + 1;+      }+    }+  break;++  case PCRE2_NEWLINE_ANYCRLF:+  while (p < endptr)+    {+    int extra = 0;+    int c = *((unsigned char *)p);++    if (utf && c >= 0xc0)+      {+      int gcii, gcss;+      extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */+      gcss = 6*extra;+      c = (c & utf8_table3[extra]) << gcss;+      for (gcii = 1; gcii <= extra; gcii++)+        {+        gcss -= 6;+        c |= (p[gcii] & 0x3f) << gcss;+        }+      }++    p += 1 + extra;++    switch (c)+      {+      case '\n':+      *lenptr = 1;+      return p;++      case '\r':+      if (p < endptr && *p == '\n')+        {+        *lenptr = 2;+        p++;+        }+      else *lenptr = 1;+      return p;++      default:+      break;+      }+    }   /* End of loop for ANYCRLF case */++  *lenptr = 0;  /* Must have hit the end */+  return endptr;++  case PCRE2_NEWLINE_ANY:+  while (p < endptr)+    {+    int extra = 0;+    int c = *((unsigned char *)p);++    if (utf && c >= 0xc0)+      {+      int gcii, gcss;+      extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */+      gcss = 6*extra;+      c = (c & utf8_table3[extra]) << gcss;+      for (gcii = 1; gcii <= extra; gcii++)+        {+        gcss -= 6;+        c |= (p[gcii] & 0x3f) << gcss;+        }+      }++    p += 1 + extra;++    switch (c)+      {+      case '\n':    /* LF */+      case '\v':    /* VT */+      case '\f':    /* FF */+      *lenptr = 1;+      return p;++      case '\r':    /* CR */+      if (p < endptr && *p == '\n')+        {+        *lenptr = 2;+        p++;+        }+      else *lenptr = 1;+      return p;++#ifndef EBCDIC+      case 0x85:    /* Unicode NEL */+      *lenptr = utf? 2 : 1;+      return p;++      case 0x2028:  /* Unicode LS */+      case 0x2029:  /* Unicode PS */+      *lenptr = 3;+      return p;+#endif  /* Not EBCDIC */++      default:+      break;+      }+    }   /* End of loop for ANY case */++  *lenptr = 0;  /* Must have hit the end */+  return endptr;+  }     /* End of overall switch */+}++++/*************************************************+*         Find start of previous line            *+*************************************************/++/* This is called when looking back for before lines to print.++Arguments:+  p         start of the subsequent line+  startptr  start of available data++Returns:    pointer to the start of the previous line+*/++static char *+previous_line(char *p, char *startptr)+{+switch(endlinetype)+  {+  default:      /* Just in case */+  case PCRE2_NEWLINE_LF:+  p--;+  while (p > startptr && p[-1] != '\n') p--;+  return p;++  case PCRE2_NEWLINE_CR:+  p--;+  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 (;;)+    {+    p -= 2;+    while (p > startptr && p[-1] != '\n') p--;+    if (p <= startptr + 1 || p[-2] == '\r') return p;+    }+  /* Control can never get here */++  case PCRE2_NEWLINE_ANY:+  case PCRE2_NEWLINE_ANYCRLF:+  if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--;+  if (utf) while ((*p & 0xc0) == 0x80) p--;++  while (p > startptr)+    {+    unsigned int c;+    char *pp = p - 1;++    if (utf)+      {+      int extra = 0;+      while ((*pp & 0xc0) == 0x80) pp--;+      c = *((unsigned char *)pp);+      if (c >= 0xc0)+        {+        int gcii, gcss;+        extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */+        gcss = 6*extra;+        c = (c & utf8_table3[extra]) << gcss;+        for (gcii = 1; gcii <= extra; gcii++)+          {+          gcss -= 6;+          c |= (pp[gcii] & 0x3f) << gcss;+          }+        }+      }+    else c = *((unsigned char *)pp);++    if (endlinetype == PCRE2_NEWLINE_ANYCRLF) switch (c)+      {+      case '\n':    /* LF */+      case '\r':    /* CR */+      return p;++      default:+      break;+      }++    else switch (c)+      {+      case '\n':    /* LF */+      case '\v':    /* VT */+      case '\f':    /* FF */+      case '\r':    /* CR */+#ifndef EBCDIC+      case 0x85:    /* Unicode NEL */+      case 0x2028:  /* Unicode LS */+      case 0x2029:  /* Unicode PS */+#endif  /* Not EBCDIC */+      return p;++      default:+      break;+      }++    p = pp;  /* Back one character */+    }        /* End of loop for ANY case */++  return startptr;  /* Hit start of data */+  }     /* End of overall switch */+}++++/*************************************************+*              Output newline at end             *+*************************************************/++/* This function is called if the final line of a file has been written to+stdout, but it does not have a terminating newline.++Arguments:  none+Returns:    nothing+*/++static void+write_final_newline(void)+{+switch(endlinetype)+  {+  default:      /* Just in case */+  case PCRE2_NEWLINE_LF:+  case PCRE2_NEWLINE_ANY:+  case PCRE2_NEWLINE_ANYCRLF:+  fprintf(stdout, "\n");+  break;++  case PCRE2_NEWLINE_CR:+  fprintf(stdout, "\r");+  break;++  case PCRE2_NEWLINE_CRLF:+  fprintf(stdout, "\r\n");+  break;++  case PCRE2_NEWLINE_NUL:+  fprintf(stdout, "%c", 0);+  break;+  }+}+++/*************************************************+*       Print the previous "after" lines         *+*************************************************/++/* This is called if we are about to lose said lines because of buffer filling,+and at the end of the file. The data in the line is written using fwrite() so+that a binary zero does not terminate it.++Arguments:+  lastmatchnumber   the number of the last matching line, plus one+  lastmatchrestart  where we restarted after the last match+  endptr            end of available data+  printname         filename for printing++Returns:            nothing+*/++static void+do_after_lines(unsigned long int lastmatchnumber, char *lastmatchrestart,+  char *endptr, const char *printname)+{+if (after_context > 0 && lastmatchnumber > 0)+  {+  int count = 0;+  int ellength = 0;+  while (lastmatchrestart < endptr && count < after_context)+    {+    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, "%lu-", lastmatchnumber++);+    FWRITE_IGNORE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);+    lastmatchrestart = pp;+    count++;+    }++  /* If we have printed any lines, arrange for a hyphen separator if anything+  else follows. Also, if the last line is the final line in the file and it had+  no newline, add one. */++  if (count > 0)+    {+    hyphenpending = TRUE;+    if (ellength == 0 && lastmatchrestart >= endptr)+      write_final_newline();+    }+  }+}++++/*************************************************+*   Apply patterns to subject till one matches   *+*************************************************/++/* This function is called to run through all patterns, looking for a match. It+is used multiple times for the same subject when colouring is enabled, in order+to find all possible matches.++Arguments:+  matchptr     the start of the subject+  length       the length of the subject to match+  options      options for pcre_exec+  startoffset  where to start matching+  mrc          address of where to put the result of pcre2_match()++Returns:      TRUE if there was a match+              FALSE if there was no match+              invert if there was a non-fatal error+*/++static BOOL+match_patterns(char *matchptr, PCRE2_SIZE length, unsigned int options,+  PCRE2_SIZE startoffset, int *mrc)+{+int i;+PCRE2_SIZE slen = length;+patstr *p = patterns;+const char *msg = "this text:\n\n";++if (slen > 200)+  {+  slen = 200;+  msg = "text that starts:\n\n";+  }++for (i = 1; p != NULL; p = p->next, i++)+  {+  *mrc = pcre2_match(p->compiled, (PCRE2_SPTR)matchptr, (int)length,+    startoffset, options, match_data, match_context);+  if (*mrc >= 0) return TRUE;+  if (*mrc == PCRE2_ERROR_NOMATCH) continue;+  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_IGNORE(matchptr, 1, slen, stderr);   /* In case binary zero included */+  fprintf(stderr, "\n\n");+  if (*mrc <= PCRE2_ERROR_UTF8_ERR1 &&+      *mrc >= PCRE2_ERROR_UTF8_ERR21)+    {+    unsigned char mbuffer[256];+    PCRE2_SIZE startchar = pcre2_get_startchar(match_data);+    (void)pcre2_get_error_message(*mrc, mbuffer, sizeof(mbuffer));+    fprintf(stderr, "%s at offset %" SIZ_FORM "\n\n", mbuffer,+      SIZ_CAST startchar);+    }+  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)+    {+    fprintf(stderr, "pcre2grep: Too many errors - abandoned.\n");+    pcre2grep_exit(2);+    }+  return invert;    /* No more matching; don't show the line again */+  }++return FALSE;  /* No match, no errors */+}++++/*************************************************+*          Decode dollar escape sequence         *+*************************************************/++/* Called from various places to decode $ escapes in output strings. The escape+sequences are as follows:++$<digits> or ${<digits>} returns a capture number. However, if callout is TRUE,+zero is never returned; '0' is substituted.++$a returns bell.+$b returns backspace.+$e returns escape.+$f returns form feed.+$n returns newline.+$r returns carriage return.+$t returns tab.+$v returns vertical tab.+$o<digits> returns the character represented by the given octal+  number; up to three digits are processed.+$o{<digits>} does the same, up to 7 digits, but gives an error for mode-invalid+  code points.+$x<digits> returns the character represented by the given hexadecimal+  number; up to two digits are processed.+$x{<digits} does the same, up to 6 digits, but gives an error for mode-invalid+  code points.+Any other character is substituted by itself. E.g: $$ is replaced by a single+dollar.++Arguments:+  begin      the start of the whole string+  string     points to the $+  callout    TRUE if in a callout (inhibits error messages)+  value      where to return a value+  last       where to return pointer to the last used character++Returns:     DDE_ERROR    after a syntax error+             DDE_CAPTURE  if *value is a capture number+             DDE_CHAR     if *value is a character code+*/++static int+decode_dollar_escape(PCRE2_SPTR begin, PCRE2_SPTR string, BOOL callout,+  uint32_t *value, PCRE2_SPTR *last)+{+uint32_t c = 0;+int base = 10;+int dcount;+int rc = DDE_CHAR;+BOOL brace = FALSE;++switch (*(++string))+  {+  case 0:   /* Syntax error: a character must be present after $. */+  if (!callout)+    fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",+      (int)(string - begin), "no character after $");+  *last = string;+  return DDE_ERROR;++  case '{':+  brace = TRUE;+  string++;+  if (!isdigit(*string))  /* 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");+    rc = DDE_ERROR;+    break;+    }++  /* Fall through */++  /* The maximum capture number is 65535, so any number greater than that will+  always be an unknown capture number. We just stop incrementing, in order to+  avoid overflow. */++  case '0': case '1': case '2': case '3': case '4':+  case '5': case '6': case '7': case '8': case '9':+  do+    {+    if (c <= 65535) c = c * 10 + (*string - '0');+    string++;+    }+  while (*string >= '0' && *string <= '9');+  string--;  /* Point to last digit */++  /* In a callout, capture number 0 is not available. No error can be given,+  so just return the character '0'. */++  if (callout && c == 0)+    {+    *value = '0';+    }+  else+    {+    *value = c;+    rc = DDE_CAPTURE;+    }+  break;++  /* Limit octal numbers to 3 digits without braces, or up to 7 with braces,+  for valid Unicode code points. */++  case 'o':+  base = 8;+  string++;+  if (*string == '{')+    {+    brace = TRUE;+    string++;+    dcount = 7;+    }+  else dcount = 3;+  for (; dcount > 0; dcount--)+    {+    if (*string < '0' || *string > '7') break;+    c = c * 8 + (*string++ - '0');+    }+  *value = c;+  string--;  /* Point to last digit */+  break;++  /* Limit hex numbers to 2 digits without braces, or up to 6 with braces,+  for valid Unicode code points. */++  case 'x':+  base = 16;+  string++;+  if (*string == '{')+    {+    brace = TRUE;+    string++;+    dcount = 6;+    }+  else dcount = 2;+  for (; dcount > 0; dcount--)+    {+    if (!isxdigit(*string)) break;+    if (*string >= '0' && *string <= '9')+      c = c *16 + *string++ - '0';+    else+      c = c * 16 + (*string++ | 0x20) - 'a' + 10;+    }+  *value = c;+  string--;  /* Point to last digit */+  break;++  case 'a': *value = '\a'; break;+  case 'b': *value = '\b'; break;+#ifndef EBCDIC+  case 'e': *value = '\033'; break;+#else+  case 'e': *value = '\047'; break;+#endif+  case 'f': *value = '\f'; break;+  case 'n': *value = STDOUT_NL_CODE; break;+  case 'r': *value = '\r'; break;+  case 't': *value = '\t'; break;+  case 'v': *value = '\v'; break;++  default: *value = *string; break;+  }++if (brace)+  {+  c = string[1];+  if (c != '}')+    {+    rc = DDE_ERROR;+    if (!callout)+      {+      if ((base == 8 && c >= '0' && c <= '7') ||+          (base == 16 && isxdigit(c)))+        {+        fprintf(stderr, "pcre2grep: Error in output text at offset %d: "+          "too many %s digits\n", (int)(string - begin),+          (base == 8)? "octal" : "hex");+        }+      else+        {+        fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",+          (int)(string - begin), "missing closing brace");+        }+      }+    }+  else string++;+  }++/* Check maximum code point values, but take note of STDOUT_NL_CODE. */++if (rc == DDE_CHAR && *value != STDOUT_NL_CODE)+  {+  uint32_t max = utf? 0x0010ffffu : 0xffu;+  if (*value > max)+    {+    if (!callout) +      fprintf(stderr, "pcre2grep: Error in output text at offset %d: "+        "code point greater than 0x%x is invalid\n", (int)(string - begin), max);+    rc = DDE_ERROR;+    }+  }++*last = string;+return rc;+}++++/*************************************************+*          Check output text for errors          *+*************************************************/++/* Called early, to get errors before doing anything for -O text; also called+from callouts to check before outputting.++Arguments:+  string    an --output text string+  callout   TRUE if in a callout (stops printing errors)++Returns:    TRUE if OK, FALSE on error+*/++static BOOL+syntax_check_output_text(PCRE2_SPTR string, BOOL callout)+{+uint32_t value;+PCRE2_SPTR begin = string;++for (; *string != 0; string++)+  {+  if (*string == '$' &&+    decode_dollar_escape(begin, string, callout, &value, &string) == DDE_ERROR)+      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.++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)+{+uint32_t value;+BOOL printed = FALSE;+PCRE2_SPTR begin = string;++for (; *string != 0; string++)+  {+  if (*string == '$')+    {+    switch(decode_dollar_escape(begin, string, callout, &value, &string))+      {+      case DDE_CHAR:+      if (value == STDOUT_NL_CODE)+        {+        fprintf(stdout, STDOUT_NL);+        printed = FALSE;+        continue;+        }+      break;  /* Will print value */++      case DDE_CAPTURE:+      if (value < capture_top)+        {+        PCRE2_SIZE capturesize;+        value *= 2;+        capturesize = ovector[value + 1] - ovector[value];+        if (capturesize > 0)+          {+          print_match(subject + ovector[value], capturesize);+          printed = TRUE;+          }+        }+      continue;++      default:  /* Should not occur */+      break;+      }+    }++  else value = *string;  /* Not a $ escape */++  if (utf && value <= 127) fprintf(stdout, "%c", *string); else+    {+    int i;+    int n = ord2utf8(value);+    for (i = 0; i < n; i++) fputc(utf8_buffer[i], stdout);+    }++  printed = TRUE;+  }++return printed;+}+++#ifdef SUPPORT_PCRE2GREP_CALLOUT++/*************************************************+*        Parse and execute callout scripts       *+*************************************************/++/* If SUPPORT_PCRE2GREP_CALLOUT_FORK is defined, this function parses a callout+string block and executes the program specified by the string. The string is a+list of substrings separated by pipe characters. The first substring represents+the executable name, and the following substrings specify the arguments:++  program_name|param1|param2|...++Any substring (including the program name) can contain escape sequences+started by the dollar character. The escape sequences are substituted as+follows:++  $<digits> or ${<digits>} is replaced by the captured substring of the given+  decimal number, which must be greater than zero. If the number is greater+  than the number of capturing substrings, or if the capture is unset, the+  replacement is empty.++  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. This is the only form that is supported if+SUPPORT_PCRE2GREP_FORK is not defined. In this case, --om-separator is used to+separate each callout, defaulting to newline.++Example:++  echo -e "abcde\n12345" | pcre2grep \+    '(.)(..(.))(?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4)")()' -++  Output:++    Arg1: [a] [bcd] [d] Arg2: |a| ()+    abcde+    Arg1: [1] [234] [4] Arg2: |1| ()+    12345++Arguments:+  blockptr     the callout block++Returns:       currently it always returns with 0+*/++static int+pcre2grep_callout(pcre2_callout_block *calloutptr, void *unused)+{+PCRE2_SIZE length = calloutptr->callout_string_length;+PCRE2_SPTR string = calloutptr->callout_string;+PCRE2_SPTR subject = calloutptr->subject;+PCRE2_SIZE *ovector = calloutptr->offset_vector;+PCRE2_SIZE capture_top = calloutptr->capture_top;++#ifdef SUPPORT_PCRE2GREP_CALLOUT_FORK+PCRE2_SIZE argsvectorlen = 2;+PCRE2_SIZE argslen = 1;+char *args;+char *argsptr;+char **argsvector;+char **argsvectorptr;+#ifndef WIN32+pid_t pid;+#endif+int result = 0;+#endif  /* SUPPORT_PCRE2GREP_CALLOUT_FORK */++(void)unused;   /* Avoid compiler warning */++/* Only callouts 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;+  }++#ifndef SUPPORT_PCRE2GREP_CALLOUT_FORK+return 0;+#else++/* Checking syntax and compute the number of string fragments. Callout strings+are silently ignored in the event of a syntax error. */++while (length > 0)+  {+  if (*string == '|')+    {+    argsvectorlen++;+    if (argsvectorlen > 10000) return 0;  /* Too many args */+    }++  else if (*string == '$')+    {+    uint32_t value;+    PCRE2_SPTR begin = string;++    switch (decode_dollar_escape(begin, string, TRUE, &value, &string))+      {+      case DDE_CAPTURE:+      if (value < capture_top)+        {+        value *= 2;+        argslen += ovector[value + 1] - ovector[value];+        }+      argslen--;   /* Negate the effect of argslen++ below. */+      break;++      case DDE_CHAR:+      if (value == STDOUT_NL_CODE) argslen += STDOUT_NL_LEN - 1;+        else if (utf && value > 127) argslen += ord2utf8(value) - 1;+      break;++      default:         /* Should not occur */+      case DDE_ERROR:+      return 0;+      }++    length -= (string - begin);+    }++  string++;+  length--;+  argslen++;+  }++/* Get memory for the argument vector and its strings. */++args = (char*)malloc(argslen);+if (args == NULL) return 0;++argsvector = (char**)malloc(argsvectorlen * sizeof(char*));+if (argsvector == NULL)+  {+  free(args);+  return 0;+  }++/* Now reprocess the string and set up the arguments. */++argsptr = args;+argsvectorptr = argsvector;+*argsvectorptr++ = argsptr;++length = calloutptr->callout_string_length;+string = calloutptr->callout_string;++while (length > 0)+  {+  if (*string == '|')+    {+    *argsptr++ = '\0';+    *argsvectorptr++ = argsptr;+    }++  else if (*string == '$')+    {+    uint32_t value;+    PCRE2_SPTR begin = string;++    switch (decode_dollar_escape(begin, string, TRUE, &value, &string))+      {+      case DDE_CAPTURE:+      if (value < capture_top)+        {+        PCRE2_SIZE capturesize;+        value *= 2;+        capturesize = ovector[value + 1] - ovector[value];+        memcpy(argsptr, subject + ovector[value], capturesize);+        argsptr += capturesize;+        }+      break;++      case DDE_CHAR:+      if (value == STDOUT_NL_CODE)+        {+        memcpy(argsptr, STDOUT_NL, STDOUT_NL_LEN);+        argsptr += STDOUT_NL_LEN;  +        }   +      else if (utf && value > 127)+        {+        int n = ord2utf8(value);+        memcpy(argsptr, utf8_buffer, n);+        argsptr += n;+        }+      else+        {+        *argsptr++ = value;+        }+      break;++      default:         /* Even though this should not occur, the string having */+      case DDE_ERROR:  /* been checked above, we need to include the free() */+      free(args);      /* calls so that source checkers do not complain. */+      free(argsvector);+      return 0;+      }++    length -= (string - begin);+    }++  else *argsptr++ = *string;++  /* Advance along the string */++  string++;+  length--;+  }++*argsptr++ = '\0';+*argsvectorptr = NULL;++/* Running an external command is system-dependent. Handle Windows and VMS as+necessary, otherwise assume fork(). */++#ifdef WIN32+result = _spawnvp(_P_WAIT, argsvector[0], (const char * const *)argsvector);++#elif defined __VMS+  {+  char cmdbuf[500];+  short i = 0;+  int flags = CLI$M_NOCLISYM|CLI$M_NOLOGNAM|CLI$M_NOKEYPAD, status, retstat;+  $DESCRIPTOR(cmd, cmdbuf);++  cmdbuf[0] = 0;+  while (argsvector[i])+  {+    strcat(cmdbuf, argsvector[i]);+    strcat(cmdbuf, " ");+    i++;+  }+  cmd.dsc$w_length = strlen(cmdbuf) - 1;+  status = lib$spawn(&cmd, 0,0, &flags, 0,0, &retstat);+  if (!(status & 1)) result = 0;+  else result = retstat & 1 ? 0 : 1;+  }++#else  /* Neither Windows nor VMS */+pid = fork();+if (pid == 0)+  {+  (void)execv(argsvector[0], argsvector);+  /* Control gets here if there is an error, e.g. a non-existent program */+  exit(1);+  }+else if (pid > 0)+  (void)waitpid(pid, &result, 0);+#endif  /* End Windows/VMS/other handling */++free(args);+free(argsvector);++/* Currently negative return values are not supported, only zero (match+continues) or non-zero (match fails). */++return result != 0;+#endif  /* SUPPORT_PCRE2GREP_CALLOUT_FORK */+}+#endif  /* SUPPORT_PCRE2GREP_CALLOUT */++++/*************************************************+*     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             *+*************************************************/++/* This is called from grep_or_recurse() below. It uses a buffer that is three+times the value of bufthird. The matching point is never allowed to stray into+the top third of the buffer, thus keeping more of the file available for+context printing or for multiline scanning. For large files, the pointer will+be in the middle third most of the time, so the bottom third is available for+"before" context printing.++Arguments:+  handle       the fopened FILE stream for a normal file+               the gzFile pointer when reading is via libz+               the BZFILE pointer when reading is via libbz2+  frtype       FR_PLAIN, FR_LIBZ, or FR_LIBBZ2+  filename     the file name or NULL (for errors)+  printname    the file name if it is to be printed for each match+               or NULL if the file name is not to be printed+               it cannot be NULL if filenames[_nomatch]_only is set++Returns:       0 if there was at least one match+               1 otherwise (no matches)+               2 if an overlong line is encountered+               3 if there is a read error on a .bz2 file+*/++static int+pcre2grep(void *handle, int frtype, const char *filename, const char *printname)+{+int rc = 1;+int filepos = 0;+unsigned long int linenumber = 1;+unsigned long int lastmatchnumber = 0;+unsigned long int count = 0;+long int count_matched_lines = 0;+char *lastmatchrestart = main_buffer;+char *ptr = main_buffer;+char *endptr;+PCRE2_SIZE bufflength;+BOOL binary = FALSE;+BOOL endhyphenpending = FALSE;+BOOL lines_printed = FALSE;+BOOL input_line_buffered = line_buffered;+FILE *in = NULL;                    /* Ensure initialized */++/* 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. */++if (frtype != FR_LIBZ && frtype != FR_LIBBZ2)+  {+  in = (FILE *)handle;+  if (is_file_tty(in)) input_line_buffered = TRUE;+  }+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 PCRE2_SIZE */+#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. However, when the newline convention is binary zero, we can't do this. */++if (binary_files != BIN_TEXT)+  {+  if (endlinetype != PCRE2_NEWLINE_NUL)+    binary = memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength)+      != NULL;+  if (binary && binary_files == BIN_NOMATCH) return 1;+  }++/* Loop while the current pointer is not at the end of the file. For large+files, endptr will be at the end of the buffer when we are in the middle of the+file, but ptr will never get there, because as soon as it gets over 2/3 of the+way, the buffer is shifted left and re-filled. */++while (ptr < endptr)+  {+  int endlinelength;+  int mrc = 0;+  unsigned int options = 0;+  BOOL match;+  BOOL line_matched = FALSE;+  char *t = ptr;+  PCRE2_SIZE length, linelength;+  PCRE2_SIZE startoffset = 0;++  /* If the -m option set a limit for the number of matched or non-matched+  lines, check it here. A limit of zero means that no matching is ever done.+  For stdin from a file, set the file position. */++  if (count_limit >= 0 && count_matched_lines >= count_limit)+    {+    if (frtype == FR_PLAIN && filename == stdin_name && !is_file_tty(handle))+      (void)fseek(handle, (long int)filepos, SEEK_SET);+    rc = (count_limit == 0)? 1 : 0;+    break;+    }++  /* At this point, ptr is at the start of a line. We need to find the length+  of the subject string to pass to pcre2_match(). In multiline mode, it is the+  length remainder of the data in the buffer. Otherwise, it is the length of+  the next line, excluding the terminating newline. After matching, we always+  advance by the length of the next line. In multiline mode the PCRE2_FIRSTLINE+  option is used for compiling, so that any match is constrained to be in the+  first line. */++  t = end_of_line(t, endptr, &endlinelength);+  linelength = t - ptr - endlinelength;+  length = multiline? (PCRE2_SIZE)(endptr - ptr) : linelength;++  /* 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 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)+    {+    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. */++#ifdef JFRIEDL_DEBUG+  if (jfriedl_XT || jfriedl_XR)+  {+#     include <sys/time.h>+#     include <time.h>+      struct timeval start_time, end_time;+      struct timezone dummy;+      int i;++      if (jfriedl_XT)+      {+          unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix);+          const char *orig = ptr;+          ptr = malloc(newlen + 1);+          if (!ptr) {+                  printf("out of memory");+                  pcre2grep_exit(2);+          }+          endptr = ptr;+          strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix);+          for (i = 0; i < jfriedl_XT; i++) {+                  strncpy(endptr, orig,  length);+                  endptr += length;+          }+          strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix);+          length = newlen;+      }++      if (gettimeofday(&start_time, &dummy) != 0)+              perror("bad gettimeofday");+++      for (i = 0; i < jfriedl_XR; i++)+          match = (pcre_exec(patterns->compiled, patterns->hint, ptr, length, 0,+              PCRE2_NOTEMPTY, offsets, offset_size) >= 0);++      if (gettimeofday(&end_time, &dummy) != 0)+              perror("bad gettimeofday");++      double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0))+                      -+                      (start_time.tv_sec + (start_time.tv_usec / 1000000.0)));++      printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta);+      return 0;+  }+#endif++  /* 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:++  /* Run through all the patterns until one matches or there is an error other+  than NOMATCH. This code is in a subroutine so that it can be re-used for+  finding subsequent matches when colouring matched lines. After finding one+  match, set PCRE2_NOTEMPTY to disable any further matches of null strings in+  this line. */++  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. 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)+    {+    BOOL hyphenprinted = FALSE;++    /* We've failed if we want a file that doesn't have any matches. */++    if (filenames == FN_NOMATCH_ONLY) return 1;++    /* Remember that this line matched (for counting matched lines) */++    line_matched = TRUE;++    /* If all we want is a yes/no answer, we can return immediately. */++    if (quiet) return 0;++    /* Just count if just counting is wanted. */++    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+    situation we just want to output the file name. No need to scan further. */++    else if (binary)+      {+      fprintf(stdout, "Binary file %s matches" STDOUT_NL, filename);+      return 0;+      }++    /* Likewise, if all we want is a file name, there is no need to scan any+    more lines in the file. */++    else if (filenames == FN_MATCH_ONLY)+      {+      fprintf(stdout, "%s" STDOUT_NL, printname);+      return 0;+      }++    /* 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 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 (only_matching_count != 0)+      {+      if (!invert)+        {+        PCRE2_SIZE oldstartoffset;++        if (printname != NULL) fprintf(stdout, "%s:", printname);+        if (number) fprintf(stdout, "%lu:", linenumber);++        /* Handle --line-offsets */++        if (line_offsets)+          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 + 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+          {+          BOOL printed = FALSE;+          omstr *om;++          for (om = only_matching; om != NULL; om = om->next)+            {+            int n = om->groupnum;+            if (n == 0 || n < mrc)+              {+              int plen = offsets[2*n + 1] - offsets[2*n];+              if (plen > 0)+                {+                if (printed && om_separator != NULL)+                  fprintf(stdout, "%s", om_separator);+                print_match(ptr + offsets[n*2], plen);+                printed = TRUE;+                }+              }+            }++          if (printed || printname != NULL || number)+            fprintf(stdout, STDOUT_NL);+          }++        /* Prepare to repeat to find the next match in the line. */++        match = FALSE;+        if (line_buffered) fflush(stdout);+        rc = 0;                      /* Had some success */++        /* 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. */++        startoffset = offsets[1];    /* Restart after the match */+        oldstartoffset = pcre2_get_startchar(match_data);+        if (startoffset <= oldstartoffset)+          {+          if (startoffset >= length) goto END_ONE_MATCH;  /* Were at end */+          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. */++        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 = (PCRE2_SIZE)(endptr - ptr);+          }++        goto ONLY_MATCHING_RESTART;+        }+      }++    /* This is the default case when none of the above options is set. We print+    the matching lines(s), possibly preceded and/or followed by other lines of+    context. */++    else+      {+      lines_printed = TRUE;++      /* See if there is a requirement to print some "after" lines from a+      previous match. We never print any overlaps. */++      if (after_context > 0 && lastmatchnumber > 0)+        {+        int ellength;+        int linecount = 0;+        char *p = lastmatchrestart;++        while (p < ptr && linecount < after_context)+          {+          p = end_of_line(p, ptr, &ellength);+          linecount++;+          }++        /* It is important to advance lastmatchrestart during this printing so+        that it interacts correctly with any "before" printing below. Print+        each line's data using fwrite() in case there are binary zeroes. */++        while (lastmatchrestart < p)+          {+          char *pp = lastmatchrestart;+          if (printname != NULL) fprintf(stdout, "%s-", printname);+          if (number) fprintf(stdout, "%lu-", lastmatchnumber++);+          pp = end_of_line(pp, endptr, &ellength);+          FWRITE_IGNORE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);+          lastmatchrestart = pp;+          }+        if (lastmatchrestart != ptr) hyphenpending = TRUE;+        }++      /* If there were non-contiguous lines printed above, insert hyphens. */++      if (hyphenpending)+        {+        fprintf(stdout, "--" STDOUT_NL);+        hyphenpending = FALSE;+        hyphenprinted = TRUE;+        }++      /* See if there is a requirement to print some "before" lines for this+      match. Again, don't print overlaps. */++      if (before_context > 0)+        {+        int linecount = 0;+        char *p = ptr;++        while (p > main_buffer &&+               (lastmatchnumber == 0 || p > lastmatchrestart) &&+               linecount < before_context)+          {+          linecount++;+          p = previous_line(p, main_buffer);+          }++        if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)+          fprintf(stdout, "--" STDOUT_NL);++        while (p < ptr)+          {+          int ellength;+          char *pp = p;+          if (printname != NULL) fprintf(stdout, "%s-", printname);+          if (number) fprintf(stdout, "%lu-", linenumber - linecount--);+          pp = end_of_line(pp, endptr, &ellength);+          FWRITE_IGNORE(p, 1, pp - p, stdout);+          p = pp;+          }+        }++      /* Now print the matching line(s); ensure we set hyphenpending at the end+      of the file if any context lines are being output. */++      if (after_context > 0 || before_context > 0)+        endhyphenpending = TRUE;++      if (printname != NULL) fprintf(stdout, "%s:", printname);+      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,+      with X. When this happens, colouring is ignored. */++#ifdef JFRIEDL_DEBUG+      if (S_arg >= 0 && S_arg < mrc)+        {+        int first = S_arg * 2;+        int last  = first + 1;+        FWRITE_IGNORE(ptr, 1, offsets[first], stdout);+        fprintf(stdout, "X");+        FWRITE_IGNORE(ptr + offsets[last], 1, linelength - offsets[last], stdout);+        }+      else+#endif++      /* 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 ((multiline || do_colour) && !invert)+        {+        int plength;+        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 (;;)+          {+          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 = (PCRE2_SIZE)(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) - endprevious);+        if (plength > 0) FWRITE_IGNORE(ptr + endprevious, 1, plength, stdout);+        }++      /* Not colouring or multiline; no need to search for further matches. */++      else FWRITE_IGNORE(ptr, 1, linelength + endlinelength, stdout);+      }++    /* End of doing what has to be done for a match. If --line-buffered was+    given, flush the output. */++    if (line_buffered) fflush(stdout);+    rc = 0;    /* Had some success */++    /* Remember where the last match happened for after_context. We remember+    where we are about to restart, and that line's number. */++    lastmatchrestart = ptr + linelength + endlinelength;+    lastmatchnumber = linenumber + 1;++    /* If a line was printed and we are now at the end of the file and the last+    line had no newline, output one. */++    if (lines_printed && lastmatchrestart >= endptr && endlinelength == 0)+      write_final_newline();+    }++  /* For a match in multiline inverted mode (which of course did not cause+  anything to be printed), we have to move on to the end of the match before+  proceeding. */++  if (multiline && invert && match)+    {+    int ellength;+    char *endmatch = ptr + offsets[1];+    t = ptr;+    while (t < endmatch)+      {+      t = end_of_line(t, endptr, &ellength);+      if (t <= endmatch) linenumber++; else break;+      }+    endmatch = end_of_line(endmatch, endptr, &ellength);+    linelength = endmatch - ptr - ellength;+    }++  /* Advance to after the newline and increment the line number. The file+  offset to the current line is maintained in filepos. */++  END_ONE_MATCH:+  ptr += linelength + endlinelength;+  filepos += (int)(linelength + endlinelength);+  linenumber++;++  /* If there was at least one match (or a non-match, as required) in the line,+  increment the count for the -m option. */++  if (line_matched) count_matched_lines++;++  /* If input is line buffered, and the buffer is not yet full, read another+  line and add it into the buffer. */++  if (input_line_buffered && bufflength < (PCRE2_SIZE)bufsize)+    {+    int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in);+    bufflength += add;+    endptr += add;+    }++  /* If we haven't yet reached the end of the file (the buffer is full), and+  the current point is in the top 1/3 of the buffer, slide the buffer down by+  1/3 and refill it. Before we do this, if some unprinted "after" lines are+  about to be lost, print them. */++  if (bufflength >= (PCRE2_SIZE)bufsize && ptr > main_buffer + 2*bufthird)+    {+    if (after_context > 0 &&+        lastmatchnumber > 0 &&+        lastmatchrestart < main_buffer + bufthird)+      {+      do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);+      lastmatchnumber = 0;  /* Indicates no after lines pending */+      }++    /* Now do the shuffle */++    (void)memmove(main_buffer, main_buffer + bufthird, 2*bufthird);+    ptr -= bufthird;++    bufflength = 2*bufthird + fill_buffer(handle, frtype,+      main_buffer + 2*bufthird, bufthird, input_line_buffered);+    endptr = main_buffer + bufflength;++    /* Adjust any last match point */++    if (lastmatchnumber > 0) lastmatchrestart -= bufthird;+    }+  }     /* Loop through the whole file */++/* End of file; print final "after" lines if wanted; do_after_lines sets+hyphenpending if it prints something. */++if (only_matching_count == 0 && !(count_only|show_total_count))+  {+  do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);+  hyphenpending |= endhyphenpending;+  }++/* Print the file name if we are looking for those without matches and there+were none. If we found a match, we won't have got this far. */++if (filenames == FN_NOMATCH_ONLY)+  {+  fprintf(stdout, "%s" STDOUT_NL, printname);+  return 0;+  }++/* Print the match count if wanted */++if (count_only && !quiet)+  {+  if (count > 0 || !omit_zero_count)+    {+    if (printname != NULL && filenames != FN_NONE)+      fprintf(stdout, "%s:", printname);+    fprintf(stdout, "%lu" STDOUT_NL, count);+    counts_printed++;+    }+  }++total_count += count;   /* Can be set without count_only */+return rc;+}++++/*************************************************+*     Grep a file or recurse into a directory    *+*************************************************/++/* Given a path name, if it's a directory, scan all the files if we are+recursing; if it's a file, grep it.++Arguments:+  pathname          the path to investigate+  dir_recurse       TRUE if recursing is wanted (-r or -drecurse)+  only_one_at_top   TRUE if the path is the only one at toplevel++Returns:  -1 the file/directory was skipped+           0 if there was at least one match+           1 if there were no matches+           2 there was some kind of error++However, file opening failures are suppressed if "silent" is set.+*/++static int+grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top)+{+int rc = 1;+int frtype;+void *handle;+char *lastcomp;+FILE *in = NULL;           /* Ensure initialized */++#ifdef SUPPORT_LIBZ+gzFile ingz = NULL;+#endif++#ifdef SUPPORT_LIBBZ2+BZFILE *inbz2 = NULL;+#endif++#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2+int pathlen;+#endif++#if defined NATIVE_ZOS+int zos_type;+FILE *zos_test_file;+#endif++/* If the file name is "-" we scan stdin */++if (strcmp(pathname, "-") == 0)+  {+  return pcre2grep(stdin, FR_PLAIN, stdin_name,+    (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?+      stdin_name : NULL);+  }++/* Inclusion and exclusion: --include-dir and --exclude-dir apply only to+directories, whereas --include and --exclude apply to everything else. The test+is against the final component of the path. */++lastcomp = strrchr(pathname, FILESEP);+lastcomp = (lastcomp == NULL)? pathname : lastcomp + 1;++/* If the file is a directory, skip if not recursing or if explicitly excluded.+Otherwise, scan the directory and recurse for each path within it. The scanning+code is localized so it can be made system-specific. */+++/* For z/OS, determine the file type. */++#if defined NATIVE_ZOS+zos_test_file =  fopen(pathname,"rb");++if (zos_test_file == NULL)+   {+   if (!silent) fprintf(stderr, "pcre2grep: failed to test next file %s\n",+     pathname, strerror(errno));+   return -1;+   }+zos_type = identifyzosfiletype (zos_test_file);+fclose (zos_test_file);++/* Handle a PDS in separate code */++if (zos_type == __ZOS_PDS || zos_type == __ZOS_PDSE)+   {+   return travelonpdsdir (pathname, only_one_at_top);+   }++/* Deal with regular files in the normal way below. These types are:+   zos_type == __ZOS_PDS_MEMBER+   zos_type == __ZOS_PS+   zos_type == __ZOS_VSAM_KSDS+   zos_type == __ZOS_VSAM_ESDS+   zos_type == __ZOS_VSAM_RRDS+*/++/* Handle a z/OS directory using common code. */++else if (zos_type == __ZOS_HFS)+ {+#endif  /* NATIVE_ZOS */+++/* Handle directories: common code for all OS */++if (isdirectory(pathname))+  {+  if (dee_action == dee_SKIP ||+      !test_incexc(lastcomp, include_dir_patterns, exclude_dir_patterns))+    return -1;++  if (dee_action == dee_RECURSE)+    {+    char buffer[FNBUFSIZ];+    char *nextfile;+    directory_type *dir = opendirectory(pathname);++    if (dir == NULL)+      {+      if (!silent)+        fprintf(stderr, "pcre2grep: Failed to open directory %s: %s\n", pathname,+          strerror(errno));+      return 2;+      }++    while ((nextfile = readdirectory(dir)) != NULL)+      {+      int frc;+      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;+      }++    closedirectory(dir);+    return rc;+    }+  }++#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++/* If the file is not a directory, check for a regular file, and if it is not,+skip it if that's been requested. Otherwise, check for an explicit inclusion or+exclusion. */++else if (+#if defined NATIVE_ZOS+        (zos_type == __ZOS_NOFILE && DEE_action == DEE_SKIP) ||+#else  /* all other OS */+        (!isregfile(pathname) && DEE_action == DEE_SKIP) ||+#endif+        !test_incexc(lastcomp, include_patterns, exclude_patterns))+  return -1;  /* File skipped */++/* Control reaches here if we have a regular file, or if we have a directory+and recursion or skipping was not requested, or if we have anything else and+skipping was not requested. The scan proceeds. If this is the first and only+argument at top level, we don't show the file name, unless we are only showing+the file name, or the filename was forced (-H). */++#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2+pathlen = (int)(strlen(pathname));+#endif++/* Open using zlib if it is supported and the file name ends with .gz. */++#ifdef SUPPORT_LIBZ+if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0)+  {+  ingz = gzopen(pathname, "rb");+  if (ingz == NULL)+    {+    if (!silent)+      fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", pathname,+        strerror(errno));+    return 2;+    }+  handle = (void *)ingz;+  frtype = FR_LIBZ;+  }+else+#endif++/* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */++#ifdef SUPPORT_LIBBZ2+if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0)+  {+  inbz2 = BZ2_bzopen(pathname, "rb");+  handle = (void *)inbz2;+  frtype = FR_LIBBZ2;+  }+else+#endif++/* Otherwise use plain fopen(). The label is so that we can come back here if+an attempt to read a .bz2 file indicates that it really is a plain file. */++#ifdef SUPPORT_LIBBZ2+PLAIN_FILE:+#endif+  {+  in = fopen(pathname, "rb");+  handle = (void *)in;+  frtype = FR_PLAIN;+  }++/* All the opening methods return errno when they fail. */++if (handle == NULL)+  {+  if (!silent)+    fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", pathname,+      strerror(errno));+  return 2;+  }++/* Now grep the file */++rc = pcre2grep(handle, frtype, pathname, (filenames > FN_DEFAULT ||+  (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);++/* Close in an appropriate manner. */++#ifdef SUPPORT_LIBZ+if (frtype == FR_LIBZ)+  gzclose(ingz);+else+#endif++/* If it is a .bz2 file and the result is 3, it means that the first attempt to+read failed. If the error indicates that the file isn't in fact bzipped, try+again as a normal file. */++#ifdef SUPPORT_LIBBZ2+if (frtype == FR_LIBBZ2)+  {+  if (rc == 3)+    {+    int errnum;+    const char *err = BZ2_bzerror(inbz2, &errnum);+    if (errnum == BZ_DATA_ERROR_MAGIC)+      {+      BZ2_bzclose(inbz2);+      goto PLAIN_FILE;+      }+    else if (!silent)+      fprintf(stderr, "pcre2grep: Failed to read %s using bzlib: %s\n",+        pathname, err);+    rc = 2;    /* The normal "something went wrong" code */+    }+  BZ2_bzclose(inbz2);+  }+else+#endif++/* Normal file close */++fclose(in);++/* Pass back the yield from pcre2grep(). */++return rc;+}++++/*************************************************+*    Handle a single-letter, no data option      *+*************************************************/++static int+handle_option(int letter, int options)+{+switch(letter)+  {+  case N_FOFFSETS: file_offsets = TRUE; break;+  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': options |= PCRE2_LITERAL; break;+  case 'H': filenames = FN_FORCE; break;+  case 'I': binary_files = BIN_NOMATCH; break;+  case 'h': filenames = FN_NONE; break;+  case 'i': options |= PCRE2_CASELESS; break;+  case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;+  case 'L': filenames = FN_NOMATCH_ONLY; break;+  case 'M': multiline = TRUE; options |= PCRE2_MULTILINE|PCRE2_FIRSTLINE; break;+  case 'n': number = TRUE; break;++  case 'o':+  only_matching_last = add_number(0, only_matching_last);+  if (only_matching == NULL) only_matching = only_matching_last;+  break;++  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 'U': options |= PCRE2_UTF|PCRE2_MATCH_INVALID_UTF; utf = TRUE; break;+  case 'v': invert = TRUE; break;+  case 'w': extra_options |= PCRE2_EXTRA_MATCH_WORD; break;+  case 'x': extra_options |= PCRE2_EXTRA_MATCH_LINE; break;++  case 'V':+    {+    unsigned char buffer[128];+    (void)pcre2_config(PCRE2_CONFIG_VERSION, buffer);+    fprintf(stdout, "pcre2grep version %s" STDOUT_NL, buffer);+    }+  pcre2grep_exit(0);+  break;++  default:+  fprintf(stderr, "pcre2grep: Unknown option -%c\n", letter);+  pcre2grep_exit(usage(2));+  }++return options;+}++++/*************************************************+*          Construct printed ordinal             *+*************************************************/++/* This turns a number into "1st", "3rd", etc. */++static char *+ordin(int n)+{+static char buffer[14];+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;+  case 2: strcpy(p, "nd"); break;+  case 3: strcpy(p, "rd"); break;+  default: strcpy(p, "th"); break;+  }+return buffer;+}++++/*************************************************+*          Compile a single pattern              *+*************************************************/++/* Do nothing if the pattern has already been compiled. This is the case for+include/exclude patterns read from a file.++When the -F option has been used, each "pattern" may be a list of strings,+separated by line breaks. They will be matched literally. We split such a+string and compile the first substring, inserting an additional block into the+pattern chain.++Arguments:+  p              points to the pattern block+  options        the PCRE 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+                 number of the command line pattern, or+                 linenumber for a pattern from a file++Returns:         TRUE on success, FALSE after an error+*/++static BOOL+compile_pattern(patstr *p, int options, int fromfile, const char *fromtext,+  int count)+{+char *ps;+int errcode;+PCRE2_SIZE patlen, erroffset;+PCRE2_UCHAR errmessbuffer[ERRBUFSIZ];++if (p->compiled != NULL) return TRUE;+ps = p->string;+patlen = p->length;++if ((options & PCRE2_LITERAL) != 0)+  {+  int ellength;+  char *eop = ps + patlen;+  char *pe = end_of_line(ps, eop, &ellength);++  if (ellength != 0)+    {+    patlen = pe - ps - ellength;+    if (add_pattern(pe, p->length-patlen-ellength, p) == NULL) return FALSE;+    }+  }++p->compiled = pcre2_compile((PCRE2_SPTR)ps, patlen, options, &errcode,+  &erroffset, compile_context);++/* 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) (void)pcre2_jit_compile(p->compiled, PCRE2_JIT_COMPLETE);+#endif+  return TRUE;+  }++/* Handle compile errors */++if (erroffset > patlen) erroffset = patlen;+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, errmessbuffer);+  }+else+  {+  if (count == 0)+    fprintf(stderr, "pcre2grep: Error in %s regex at offset %d: %s\n",+      fromtext, (int)erroffset, errmessbuffer);+  else+    fprintf(stderr, "pcre2grep: Error in %s %s regex at offset %d: %s\n",+      ordin(count), fromtext, (int)erroffset, errmessbuffer);+  }++return FALSE;+}++++/*************************************************+*     Read and compile a file of patterns        *+*************************************************/++/* This is used for --filelist, --include-from, and --exclude-from.++Arguments:+  name         the name of the file; "-" is stdin+  patptr       pointer to the pattern chain anchor+  patlastptr   pointer to the last pattern pointer++Returns:       TRUE if all went well+*/++static BOOL+read_pattern_file(char *name, patstr **patptr, patstr **patlastptr)+{+int linenumber = 0;+PCRE2_SIZE patlen;+FILE *f;+const char *filename;+char buffer[MAXPATLEN+20];++if (strcmp(name, "-") == 0)+  {+  f = stdin;+  filename = stdin_name;+  }+else+  {+  f = fopen(name, "r");+  if (f == NULL)+    {+    fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", name, strerror(errno));+    return FALSE;+    }+  filename = name;+  }++while ((patlen = read_one_line(buffer, sizeof(buffer), f)) > 0)+  {+  while (patlen > 0 && isspace((unsigned char)(buffer[patlen-1]))) patlen--;+  linenumber++;+  if (patlen == 0) continue;   /* Skip blank lines */++  /* Note: this call to add_pattern() puts a pointer to the local variable+  "buffer" into the pattern chain. However, that pointer is used only when+  compiling the pattern, which happens immediately below, so we flatten it+  afterwards, as a precaution against any later code trying to use it. */++  *patlastptr = add_pattern(buffer, patlen, *patlastptr);+  if (*patlastptr == NULL)+    {+    if (f != stdin) fclose(f);+    return FALSE;+    }+  if (*patptr == NULL) *patptr = *patlastptr;++  /* This loop is needed because compiling a "pattern" when -F is set may add+  on additional literal patterns if the original contains a newline. In the+  common case, it never will, because read_one_line() stops at a newline.+  However, the -N option can be used to give pcre2grep a different newline+  setting. */++  for(;;)+    {+    if (!compile_pattern(*patlastptr, pcre2_options, TRUE, filename,+        linenumber))+      {+      if (f != stdin) fclose(f);+      return FALSE;+      }+    (*patlastptr)->string = NULL;            /* Insurance */+    if ((*patlastptr)->next == NULL) break;+    *patlastptr = (*patlastptr)->next;+    }+  }++if (f != stdin) fclose(f);+return TRUE;+}++++/*************************************************+*                Main program                    *+*************************************************/++/* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */++int+main(int argc, char **argv)+{+int i, j;+int rc = 1;+BOOL only_one_at_top;+patstr *cp;+fnstr *fn;+omstr *om;+const char *locale_from = "--locale";++#ifdef SUPPORT_PCRE2GREP_JIT+pcre2_jit_stack *jit_stack = NULL;+#endif++/* In Windows, stdout is set up as a text stream, which means that \n is+converted to \r\n. This causes output lines that are copied from the input to+change from ....\r\n to ....\r\r\n, which is not right. We therefore ensure+that stdout is a binary stream. Note that this means all other output to stdout+must use STDOUT_NL to terminate lines. */++#ifdef WIN32+_setmode(_fileno(stdout), _O_BINARY);+#endif++/* Process the options */++for (i = 1; i < argc; i++)+  {+  option_item *op = NULL;+  char *option_data = (char *)"";    /* default to keep compiler happy */+  BOOL longop;+  BOOL longopwasequals = FALSE;++  if (argv[i][0] != '-') break;++  /* If we hit an argument that is just "-", it may be a reference to STDIN,+  but only if we have previously had -e or -f to define the patterns. */++  if (argv[i][1] == 0)+    {+    if (pattern_files != NULL || patterns != NULL) break;+      else pcre2grep_exit(usage(2));+    }++  /* Handle a long name option, or -- to terminate the options */++  if (argv[i][1] == '-')+    {+    char *arg = argv[i] + 2;+    char *argequals = strchr(arg, '=');++    if (*arg == 0)    /* -- terminates options */+      {+      i++;+      break;                /* out of the options-handling loop */+      }++    longop = TRUE;++    /* Some long options have data that follows after =, for example file=name.+    Some options have variations in the long name spelling: specifically, we+    allow "regexp" because GNU grep allows it, though I personally go along+    with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".+    These options are entered in the table as "regex(p)". Options can be in+    both these categories. */++    for (op = optionlist; op->one_char != 0; op++)+      {+      char *opbra = strchr(op->long_name, '(');+      char *equals = strchr(op->long_name, '=');++      /* Handle options with only one spelling of the name */++      if (opbra == NULL)     /* Does not contain '(' */+        {+        if (equals == NULL)  /* Not thing=data case */+          {+          if (strcmp(arg, op->long_name) == 0) break;+          }+        else                 /* Special case xxx=data */+          {+          int oplen = (int)(equals - op->long_name);+          int arglen = (argequals == NULL)?+            (int)strlen(arg) : (int)(argequals - arg);+          if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0)+            {+            option_data = arg + arglen;+            if (*option_data == '=')+              {+              option_data++;+              longopwasequals = TRUE;+              }+            break;+            }+          }+        }++      /* Handle options with an alternate spelling of the name */++      else+        {+        char buff1[24];+        char buff2[24];+        int ret;++        int baselen = (int)(opbra - op->long_name);+        int fulllen = (int)(strchr(op->long_name, ')') - op->long_name + 1);+        int arglen = (argequals == NULL || equals == NULL)?+          (int)strlen(arg) : (int)(argequals - arg);++        if ((ret = snprintf(buff1, sizeof(buff1), "%.*s", baselen, op->long_name),+             ret < 0 || ret > (int)sizeof(buff1)) ||+            (ret = snprintf(buff2, sizeof(buff2), "%s%.*s", buff1,+                     fulllen - baselen - 2, opbra + 1),+             ret < 0 || ret > (int)sizeof(buff2)))+          {+          fprintf(stderr, "pcre2grep: Buffer overflow when parsing %s option\n",+            op->long_name);+          pcre2grep_exit(2);+          }++        if (strncmp(arg, buff1, arglen) == 0 ||+           strncmp(arg, buff2, arglen) == 0)+          {+          if (equals != NULL && argequals != NULL)+            {+            option_data = argequals;+            if (*option_data == '=')+              {+              option_data++;+              longopwasequals = TRUE;+              }+            }+          break;+          }+        }+      }++    if (op->one_char == 0)+      {+      fprintf(stderr, "pcre2grep: Unknown option %s\n", argv[i]);+      pcre2grep_exit(usage(2));+      }+    }++  /* Jeffrey Friedl's debugging harness uses these additional options which+  are not in the right form for putting in the option table because they use+  only one hyphen, yet are more than one character long. By putting them+  separately here, they will not get displayed as part of the help() output,+  but I don't think Jeffrey will care about that. */++#ifdef JFRIEDL_DEBUG+  else if (strcmp(argv[i], "-pre") == 0) {+          jfriedl_prefix = argv[++i];+          continue;+  } else if (strcmp(argv[i], "-post") == 0) {+          jfriedl_postfix = argv[++i];+          continue;+  } else if (strcmp(argv[i], "-XT") == 0) {+          sscanf(argv[++i], "%d", &jfriedl_XT);+          continue;+  } else if (strcmp(argv[i], "-XR") == 0) {+          sscanf(argv[++i], "%d", &jfriedl_XR);+          continue;+  }+#endif+++  /* One-char options; many that have no data may be in a single argument; we+  continue till we hit the last one or one that needs data. */++  else+    {+    char *s = argv[i] + 1;+    longop = FALSE;++    while (*s != 0)+      {+      for (op = optionlist; op->one_char != 0; op++)+        {+        if (*s == op->one_char) break;+        }+      if (op->one_char == 0)+        {+        fprintf(stderr, "pcre2grep: Unknown option letter '%c' in \"%s\"\n",+          *s, argv[i]);+        pcre2grep_exit(usage(2));+        }++      option_data = s+1;++      /* Break out if this is the last character in the string; it's handled+      below like a single multi-char option. */++      if (*option_data == 0) break;++      /* Check for a single-character option that has data: OP_OP_NUMBER(S)+      are used for ones that either have a numerical number or defaults, i.e.+      the data is optional. If a digit follows, there is data; if not, carry on+      with other single-character options in the same string. */++      if (op->type == OP_OP_NUMBER || op->type == OP_OP_NUMBERS)+        {+        if (isdigit((unsigned char)s[1])) break;+        }+      else   /* Check for an option with data */+        {+        if (op->type != OP_NODATA) break;+        }++      /* Handle a single-character option with no data, then loop for the+      next character in the string. */++      pcre2_options = handle_option(*s++, pcre2_options);+      }+    }++  /* At this point we should have op pointing to a matched option. If the type+  is NO_DATA, it means that there is no data, and the option might set+  something in the PCRE options. */++  if (op->type == OP_NODATA)+    {+    pcre2_options = handle_option(op->one_char, pcre2_options);+    continue;+    }++  /* If the option type is OP_OP_STRING or OP_OP_NUMBER(S), it's an option that+  either has a value or defaults to something. It cannot have data in a+  separate item. At the moment, the only such options are "colo(u)r",+  "only-matching", and Jeffrey Friedl's special -S debugging option. */++  if (*option_data == 0 &&+      (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER ||+       op->type == OP_OP_NUMBERS))+    {+    switch (op->one_char)+      {+      case N_COLOUR:+      colour_option = "auto";+      break;++      case 'o':+      only_matching_last = add_number(0, only_matching_last);+      if (only_matching == NULL) only_matching = only_matching_last;+      break;++#ifdef JFRIEDL_DEBUG+      case 'S':+      S_arg = 0;+      break;+#endif+      }+    continue;+    }++  /* Otherwise, find the data string for the option. */++  if (*option_data == 0)+    {+    if (i >= argc - 1 || longopwasequals)+      {+      fprintf(stderr, "pcre2grep: Data missing after %s\n", argv[i]);+      pcre2grep_exit(usage(2));+      }+    option_data = argv[++i];+    }++  /* If the option type is OP_OP_NUMBERS, the value is a number that is to be+  added to a chain of numbers. */++  if (op->type == OP_OP_NUMBERS)+    {+    unsigned long int n = decode_number(option_data, op, longop);+    omdatastr *omd = (omdatastr *)op->dataptr;+    *(omd->lastptr) = add_number((int)n, *(omd->lastptr));+    if (*(omd->anchor) == NULL) *(omd->anchor) = *(omd->lastptr);+    }++  /* If the option type is OP_PATLIST, it's the -e option, or one of the+  include/exclude options, which can be called multiple times to create lists+  of patterns. */++  else if (op->type == OP_PATLIST)+    {+    patdatastr *pd = (patdatastr *)op->dataptr;+    *(pd->lastptr) = add_pattern(option_data, (PCRE2_SIZE)strlen(option_data),+      *(pd->lastptr));+    if (*(pd->lastptr) == NULL) goto EXIT2;+    if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr);+    }++  /* If the option type is OP_FILELIST, it's one of the options that names a+  file. */++  else if (op->type == OP_FILELIST)+    {+    fndatastr *fd = (fndatastr *)op->dataptr;+    fn = (fnstr *)malloc(sizeof(fnstr));+    if (fn == NULL)+      {+      fprintf(stderr, "pcre2grep: malloc failed\n");+      goto EXIT2;+      }+    fn->next = NULL;+    fn->name = option_data;+    if (*(fd->anchor) == NULL)+      *(fd->anchor) = fn;+    else+      (*(fd->lastptr))->next = fn;+    *(fd->lastptr) = fn;+    }++  /* Handle OP_BINARY_FILES */++  else if (op->type == OP_BINFILES)+    {+    if (strcmp(option_data, "binary") == 0)+      binary_files = BIN_BINARY;+    else if (strcmp(option_data, "without-match") == 0)+      binary_files = BIN_NOMATCH;+    else if (strcmp(option_data, "text") == 0)+      binary_files = BIN_TEXT;+    else+      {+      fprintf(stderr, "pcre2grep: unknown value \"%s\" for binary-files\n",+        option_data);+      pcre2grep_exit(usage(2));+      }+    }++  /* 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_SIZE)+    {+    *((char **)op->dataptr) = option_data;+    }+  else+    {+    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;+    }+  }++/* Options have been decoded. If -C was used, its value is used as a default+for -A and -B. */++if (both_context > 0)+  {+  if (after_context == 0) after_context = both_context;+  if (before_context == 0) before_context = both_context;+  }++/* 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.+*/++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, --output, "+    "--file-offsets and/or --line-offsets\n");+  pcre2grep_exit(usage(2));+  }+++/* Check that there is a big enough ovector for all -o settings. */++for (om = only_matching; om != NULL; om = om->next)+  {+  int n = om->groupnum;+  if (n > (int)capture_max)+    {+    fprintf(stderr, "pcre2grep: Requested group %d cannot be captured.\n", n);+    fprintf(stderr, "pcre2grep: Use --om-capture to increase the size of the capture vector.\n");+    goto EXIT2;+    }+  }++/* Check the text supplied to --output for errors. */++if (output_text != NULL &&+    !syntax_check_output_text((PCRE2_SPTR)output_text, FALSE))+  goto EXIT2;++/* Set up default compile and match contexts and a match data block. */++offset_size = capture_max + 1;+compile_context = pcre2_compile_context_create(NULL);+match_context = pcre2_match_context_create(NULL);+match_data = pcre2_match_data_create(offset_size, NULL);+offsets = pcre2_get_ovector_pointer(match_data);++/* If string (script) callouts are supported, set up the callout processing+function. */++#ifdef SUPPORT_PCRE2GREP_CALLOUT+pcre2_set_callout(match_context, pcre2grep_callout, NULL);+#endif++/* 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 (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. */++if (locale == NULL)+  {+  locale = getenv("LC_ALL");+  locale_from = "LC_ALL";+  }++if (locale == NULL)+  {+  locale = getenv("LC_CTYPE");+  locale_from = "LC_CTYPE";+  }++/* If a locale is set, use it to generate the tables the PCRE needs. Passing+NULL to pcre2_maketables() means that malloc() is used to get the memory. */++if (locale != NULL)+  {+  if (setlocale(LC_CTYPE, locale) == NULL)+    {+    fprintf(stderr, "pcre2grep: Failed to set locale %s (obtained from %s)\n",+      locale, locale_from);+    goto EXIT2;+    }+  character_tables = pcre2_maketables(NULL);+  pcre2_set_character_tables(compile_context, character_tables);+  }++/* Sort out colouring */++if (colour_option != NULL && strcmp(colour_option, "never") != 0)+  {+  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+    {+    fprintf(stderr, "pcre2grep: Unknown colour setting \"%s\"\n",+      colour_option);+    goto EXIT2;+    }+  if (do_colour)+    {+    char *cs = getenv("PCRE2GREP_COLOUR");+    if (cs == NULL) cs = getenv("PCRE2GREP_COLOR");+    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+    }+  }++/* Sort out a newline setting. */++if (newline_arg != NULL)+  {+  for (endlinetype = 1; endlinetype < (int)(sizeof(newlines)/sizeof(char *));+       endlinetype++)+    {+    if (strcmpic(newline_arg, newlines[endlinetype]) == 0) break;+    }+  if (endlinetype < (int)(sizeof(newlines)/sizeof(char *)))+    pcre2_set_newline(compile_context, endlinetype);+  else+    {+    fprintf(stderr, "pcre2grep: Invalid newline specifier \"%s\"\n",+      newline_arg);+    goto EXIT2;+    }+  }++/* Find default newline convention */++else+  {+  (void)pcre2_config(PCRE2_CONFIG_NEWLINE, &endlinetype);+  }++/* Interpret the text values for -d and -D */++if (dee_option != NULL)+  {+  if (strcmp(dee_option, "read") == 0) dee_action = dee_READ;+  else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE;+  else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP;+  else+    {+    fprintf(stderr, "pcre2grep: Invalid value \"%s\" for -d\n", dee_option);+    goto EXIT2;+    }+  }++if (DEE_option != NULL)+  {+  if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ;+  else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP;+  else+    {+    fprintf(stderr, "pcre2grep: Invalid value \"%s\" for -D\n", DEE_option);+    goto EXIT2;+    }+  }++/* 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+if (S_arg > 9)+  {+  fprintf(stderr, "pcre2grep: bad value for -S option\n");+  return 2;+  }+if (jfriedl_XT != 0 || jfriedl_XR != 0)+  {+  if (jfriedl_XT == 0) jfriedl_XT = 1;+  if (jfriedl_XR == 0) jfriedl_XR = 1;+  }+#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);++if (main_buffer == NULL)+  {+  fprintf(stderr, "pcre2grep: malloc failed\n");+  goto EXIT2;+  }++/* If no patterns were provided by -e, and there are no files provided by -f,+the first argument is the one and only pattern, and it must exist. */++if (patterns == NULL && pattern_files == NULL)+  {+  if (i >= argc) return usage(2);+  patterns = patterns_last = add_pattern(argv[i], (PCRE2_SIZE)strlen(argv[i]),+    NULL);+  i++;+  if (patterns == NULL) goto EXIT2;+  }++/* Compile the patterns that were provided on the command line, either by+multiple uses of -e or as a single unkeyed pattern. We cannot do this until+after all the command-line options are read so that we know which PCRE options+to use. When -F is used, compile_pattern() may add another block into the+chain, so we must not access the next pointer till after the compile. */++for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next)+  {+  if (!compile_pattern(cp, pcre2_options, FALSE, "command-line",+       (j == 1 && patterns->next == NULL)? 0 : j))+    goto EXIT2;+  }++/* Read and compile the regular expressions that are provided in files. */++for (fn = pattern_files; fn != NULL; fn = fn->next)+  {+  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++/* -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. */++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, FALSE, incexname[j],+         (k == 1 && cp->next == NULL)? 0 : k))+      goto EXIT2;+    }+  }++/* Read and compile include/exclude patterns from files. */++for (fn = include_from; fn != NULL; fn = fn->next)+  {+  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))+    goto EXIT2;+  }++/* If there are no files that contain lists of files to search, and there are+no file arguments, search stdin, and then exit. */++if (file_lists == NULL && i >= argc)+  {+  rc = pcre2grep(stdin, FR_PLAIN, stdin_name,+    (filenames > FN_DEFAULT)? stdin_name : NULL);+  goto EXIT;+  }++/* If any files that contains a list of files to search have been specified,+read them line by line and search the given files. */++for (fn = file_lists; fn != NULL; fn = fn->next)+  {+  char buffer[FNBUFSIZ];+  FILE *fl;+  if (strcmp(fn->name, "-") == 0) fl = stdin; else+    {+    fl = fopen(fn->name, "rb");+    if (fl == NULL)+      {+      fprintf(stderr, "pcre2grep: Failed to open %s: %s\n", fn->name,+        strerror(errno));+      goto EXIT2;+      }+    }+  while (fgets(buffer, sizeof(buffer), fl) != NULL)+    {+    int frc;+    char *end = buffer + (int)strlen(buffer);+    while (end > buffer && isspace(end[-1])) end--;+    *end = 0;+    if (*buffer != 0)+      {+      frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE);+      if (frc > 1) rc = frc;+        else if (frc == 0 && rc == 1) rc = 0;+      }+    }+  if (fl != stdin) fclose(fl);+  }++/* After handling file-list, work through remaining arguments. Pass in the fact+that there is only one argument at top level - this suppresses the file name if+the argument is not a directory and filenames are not otherwise forced. */++only_one_at_top = i == argc - 1 && file_lists == NULL;++for (; i < argc; i++)+  {+  int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE,+    only_one_at_top);+  if (frc > 1) rc = frc;+    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+pcre2_jit_free_unused_memory(NULL);+if (jit_stack != NULL) pcre2_jit_stack_free(jit_stack);+#endif++free(main_buffer);+if (character_tables != NULL) pcre2_maketables_free(NULL, character_tables);++pcre2_compile_context_free(compile_context);+pcre2_match_context_free(match_context);+pcre2_match_data_free(match_data);++free_pattern_chain(patterns);+free_pattern_chain(include_patterns);+free_pattern_chain(include_dir_patterns);+free_pattern_chain(exclude_patterns);+free_pattern_chain(exclude_dir_patterns);++free_file_chain(exclude_from);+free_file_chain(include_from);+free_file_chain(pattern_files);+free_file_chain(file_lists);++while (only_matching != NULL)+  {+  omstr *this = only_matching;+  only_matching = this->next;+  free(this);+  }++pcre2grep_exit(rc);++EXIT2:+rc = 2;+goto EXIT;+}++/* End of pcre2grep */
+ src/c/pcre2/src/pcre2posix.c view
@@ -0,0 +1,423 @@+/*************************************************+*      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-2019 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 is a wrapper that provides a POSIX API to the underlying PCRE2+functions. The operative functions are called pcre2_regcomp(), etc., with+wrappers that use the plain POSIX names. In addition, pcre2posix.h defines the+POSIX names as macros for the pcre2_xxx functions, so any program that includes+it and uses the POSIX names will call the base functions directly. This makes+it easier for an application to be sure it gets the PCRE2 versions in the+presence of other POSIX regex libraries. */+++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif+++/* Ensure that the PCRE2POSIX_EXP_xxx macros are set appropriately for+compiling these functions. This must come before including pcre2posix.h, where+they are set for an application (using these functions) if they have not+previously been set. */++#if defined(_WIN32) && !defined(PCRE2_STATIC)+#  define PCRE2POSIX_EXP_DECL extern __declspec(dllexport)+#  define PCRE2POSIX_EXP_DEFN __declspec(dllexport)+#endif++/* Older versions of MSVC lack snprintf(). This define allows for+warning/error-free compilation and testing with MSVC compilers back to at least+MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */++#if defined(_MSC_VER) && (_MSC_VER < 1900)+#define snprintf _snprintf+#endif+++/* Compile-time error numbers start at this value. It should probably never be+changed. This #define is a copy of the one in pcre2_internal.h. */++#define COMPILE_ERROR_BASE 100+++/* Standard C headers */++#include <ctype.h>+#include <limits.h>+#include <stddef.h>+#include <stdio.h>+#include <stdlib.h>+#include <string.h>++/* PCRE2 headers */++#include "pcre2.h"+#include "pcre2posix.h"++/* 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 to 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++/* Table to translate PCRE2 compile time error codes into POSIX error codes.+Only a few PCRE2 errors with a value greater than 23 turn into special POSIX+codes: most go to REG_BADPAT. The second table lists, in pairs, those that+don't. */++static const int eint1[] = {+  0,           /* No error */+  REG_EESCAPE, /* \ at end of pattern */+  REG_EESCAPE, /* \c at end of pattern */+  REG_EESCAPE, /* unrecognized character follows \ */+  REG_BADBR,   /* numbers out of order in {} quantifier */+  /* 5 */+  REG_BADBR,   /* number too big in {} quantifier */+  REG_EBRACK,  /* missing terminating ] for character class */+  REG_ECTYPE,  /* invalid escape sequence in character class */+  REG_ERANGE,  /* range out of order in character class */+  REG_BADRPT,  /* nothing to repeat */+  /* 10 */+  REG_ASSERT,  /* internal error: unexpected repeat */+  REG_BADPAT,  /* unrecognized character after (? or (?- */+  REG_BADPAT,  /* POSIX named classes are supported only within a class */+  REG_BADPAT,  /* POSIX collating elements are not supported */+  REG_EPAREN,  /* missing ) */+  /* 15 */+  REG_ESUBREG, /* reference to non-existent subpattern */+  REG_INVARG,  /* pattern passed as NULL */+  REG_INVARG,  /* unknown compile-time option bit(s) */+  REG_EPAREN,  /* missing ) after (?# comment */+  REG_ESIZE,   /* parentheses nested too deeply */+  /* 20 */+  REG_ESIZE,   /* regular expression too large */+  REG_ESPACE,  /* failed to get memory */+  REG_EPAREN,  /* unmatched closing parenthesis */+  REG_ASSERT   /* internal error: code overflow */+  };++static const int eint2[] = {+  30, REG_ECTYPE,  /* unknown POSIX class name */+  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 */++static const char *const pstring[] = {+  "",                                /* Dummy for value 0 */+  "internal error",                  /* REG_ASSERT */+  "invalid repeat counts in {}",     /* BADBR      */+  "pattern error",                   /* BADPAT     */+  "? * + invalid",                   /* BADRPT     */+  "unbalanced {}",                   /* EBRACE     */+  "unbalanced []",                   /* EBRACK     */+  "collation error - not relevant",  /* ECOLLATE   */+  "bad class",                       /* ECTYPE     */+  "bad escape sequence",             /* EESCAPE    */+  "empty expression",                /* EMPTY      */+  "unbalanced ()",                   /* EPAREN     */+  "bad range inside []",             /* ERANGE     */+  "expression too big",              /* ESIZE      */+  "failed to get memory",            /* ESPACE     */+  "bad back reference",              /* ESUBREG    */+  "bad argument",                    /* INVARG     */+  "match failed"                     /* NOMATCH    */+};++++/*************************************************+*      Wrappers with traditional POSIX names     *+*************************************************/++/* Keep defining them to preseve the ABI for applications linked to the pcre2+POSIX library before these names were changed into macros in pcre2posix.h.+This also ensures that the POSIX names are callable from languages that do not+include pcre2posix.h. It is vital to #undef the macro definitions from+pcre2posix.h! */++#undef regerror+PCRE2POSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);+PCRE2POSIX_EXP_DEFN size_t PCRE2_CALL_CONVENTION+regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)+{+return pcre2_regerror(errcode, preg, errbuf, errbuf_size);+}++#undef regfree+PCRE2POSIX_EXP_DECL void regfree(regex_t *);+PCRE2POSIX_EXP_DEFN void PCRE2_CALL_CONVENTION+regfree(regex_t *preg)+{+pcre2_regfree(preg);+}++#undef regcomp+PCRE2POSIX_EXP_DECL int regcomp(regex_t *, const char *, int);+PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION+regcomp(regex_t *preg, const char *pattern, int cflags)+{+return pcre2_regcomp(preg, pattern, cflags);+}++#undef regexec+PCRE2POSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,+  regmatch_t *, int);+PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION+regexec(const regex_t *preg, const char *string, size_t nmatch,+  regmatch_t pmatch[], int eflags)+{+return pcre2_regexec(preg, string, nmatch, pmatch, eflags);+}++++/*************************************************+*          Translate error code to string        *+*************************************************/++PCRE2POSIX_EXP_DEFN size_t PCRE2_CALL_CONVENTION+pcre2_regerror(int errcode, const regex_t *preg, char *errbuf,+  size_t errbuf_size)+{+int used;+const char *message;++message = (errcode <= 0 || errcode >= (int)(sizeof(pstring)/sizeof(char *)))?+  "unknown error code" : pstring[errcode];++if (preg != NULL && (int)preg->re_erroffset != -1)+  {+  used = snprintf(errbuf, errbuf_size, "%s at offset %-6d", message,+    (int)preg->re_erroffset);+  }+else+  {+  used = snprintf(errbuf, errbuf_size, "%s", message);+  }++return used + 1;+}++++/*************************************************+*           Free store held by a regex           *+*************************************************/++PCRE2POSIX_EXP_DEFN void PCRE2_CALL_CONVENTION+pcre2_regfree(regex_t *preg)+{+pcre2_match_data_free(preg->re_match_data);+pcre2_code_free(preg->re_pcre2_code);+}++++/*************************************************+*            Compile a regular expression        *+*************************************************/++/*+Arguments:+  preg        points to a structure for recording the compiled expression+  pattern     the pattern to compile+  cflags      compilation flags++Returns:      0 on success+              various non-zero codes on failure+*/++PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_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, patlen, options,+  &errorcode, &erroffset, NULL);+preg->re_erroffset = erroffset;++if (preg->re_pcre2_code == NULL)+  {+  unsigned int i;++  /* A negative value is a UTF error; otherwise all error codes are greater+  than COMPILE_ERROR_BASE, but check, just in case. */++  if (errorcode < COMPILE_ERROR_BASE) return REG_BADPAT;+  errorcode -= COMPILE_ERROR_BASE;++  if (errorcode < (int)(sizeof(eint1)/sizeof(const int)))+    return eint1[errorcode];+  for (i = 0; i < sizeof(eint2)/sizeof(const int); i += 2)+    if (errorcode == eint2[i]) return eint2[i+1];+  return REG_BADPAT;+  }++(void)pcre2_pattern_info((const pcre2_code *)preg->re_pcre2_code,+  PCRE2_INFO_CAPTURECOUNT, &re_nsub);+preg->re_nsub = (size_t)re_nsub;+preg->re_match_data = pcre2_match_data_create(re_nsub + 1, NULL);+preg->re_erroffset = (size_t)(-1);  /* No meaning after successful compile */++if (preg->re_match_data == NULL)+  {+  pcre2_code_free(preg->re_pcre2_code);+  return REG_ESPACE;+  }++return 0;+}++++/*************************************************+*              Match a regular expression        *+*************************************************/++/* 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 nmatch and+pmatch arguments are ignored, and the only result is yes/no/error. */++PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION+pcre2_regexec(const regex_t *preg, const char *string, size_t nmatch,+  regmatch_t pmatch[], int eflags)+{+int rc, so, eo;+int options = 0;+pcre2_match_data *md = (pcre2_match_data *)preg->re_match_data;++if ((eflags & REG_NOTBOL) != 0) options |= PCRE2_NOTBOL;+if ((eflags & REG_NOTEOL) != 0) options |= PCRE2_NOTEOL;+if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE2_NOTEMPTY;++/* When REG_NOSUB was specified, or if no vector has been passed in which to+put captured strings, ensure that nmatch is zero. This will stop any attempt to+write to pmatch. */++if ((preg->re_cflags & REG_NOSUB) != 0 || pmatch == NULL) nmatch = 0;++/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings.+The man page from OS X says "REG_STARTEND affects only the location of the+string, not how it is matched". That is why the "so" value is used to bump the+start location rather than being passed as a PCRE2 "starting offset". */++if ((eflags & REG_STARTEND) != 0)+  {+  if (pmatch == NULL) return REG_INVARG;+  so = pmatch[0].rm_so;+  eo = pmatch[0].rm_eo;+  }+else+  {+  so = 0;+  eo = (int)strlen(string);+  }++rc = pcre2_match((const pcre2_code *)preg->re_pcre2_code,+  (PCRE2_SPTR)string + so, (eo - so), 0, options, md, NULL);++/* Successful match */++if (rc >= 0)+  {+  size_t i;+  PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md);+  if ((size_t)rc > nmatch) rc = (int)nmatch;+  for (i = 0; i < (size_t)rc; i++)+    {+    pmatch[i].rm_so = (ovector[i*2] == PCRE2_UNSET)? -1 :+      (int)(ovector[i*2] + so);+    pmatch[i].rm_eo = (ovector[i*2+1] == PCRE2_UNSET)? -1 :+      (int)(ovector[i*2+1] + so);+    }+  for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;+  return 0;+  }++/* Unsuccessful match */++if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21)+  return REG_INVARG;++switch(rc)+  {+  default: return REG_ASSERT;+  case PCRE2_ERROR_BADMODE: return REG_INVARG;+  case PCRE2_ERROR_BADMAGIC: return REG_INVARG;+  case PCRE2_ERROR_BADOPTION: return REG_INVARG;+  case PCRE2_ERROR_BADUTFOFFSET: return REG_INVARG;+  case PCRE2_ERROR_MATCHLIMIT: return REG_ESPACE;+  case PCRE2_ERROR_NOMATCH: return REG_NOMATCH;+  case PCRE2_ERROR_NOMEMORY: return REG_ESPACE;+  case PCRE2_ERROR_NULL: return REG_INVARG;+  }+}++/* End of pcre2posix.c */
+ src/c/pcre2/src/pcre2posix.h view
@@ -0,0 +1,170 @@+/*************************************************+*      Perl-Compatible Regular Expressions       *+*************************************************/++/* PCRE2 is a library of functions to support regular expressions whose syntax+and semantics are as close as possible to those of the Perl 5 language. This is+the public header file to be #included by applications that call PCRE2 via the+POSIX wrapper interface.++                       Written by Philip Hazel+     Original API code Copyright (c) 1997-2012 University of Cambridge+          New API code Copyright (c) 2016-2019 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.+-----------------------------------------------------------------------------+*/+++/* Have to include stdlib.h in order to ensure that size_t is defined. */++#include <stdlib.h>++/* Allow for C++ users */++#ifdef __cplusplus+extern "C" {+#endif++/* Options, mostly defined by POSIX, but with some extras. */++#define REG_ICASE     0x0001  /* Maps to PCRE2_CASELESS */+#define REG_NEWLINE   0x0002  /* Maps to PCRE2_MULTILINE */+#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  /* 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. */++#define REG_EXTENDED  0++/* Error values. Not all these are relevant or used by the wrapper. */++enum {+  REG_ASSERT = 1,  /* internal error ? */+  REG_BADBR,       /* invalid repeat counts in {} */+  REG_BADPAT,      /* pattern error */+  REG_BADRPT,      /* ? * + invalid */+  REG_EBRACE,      /* unbalanced {} */+  REG_EBRACK,      /* unbalanced [] */+  REG_ECOLLATE,    /* collation error - not relevant */+  REG_ECTYPE,      /* bad class */+  REG_EESCAPE,     /* bad escape sequence */+  REG_EMPTY,       /* empty expression */+  REG_EPAREN,      /* unbalanced () */+  REG_ERANGE,      /* bad range inside [] */+  REG_ESIZE,       /* expression too big */+  REG_ESPACE,      /* failed to get memory */+  REG_ESUBREG,     /* bad back reference */+  REG_INVARG,      /* bad argument */+  REG_NOMATCH      /* match failed */+};+++/* 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;+} regex_t;++/* The structure in which a captured offset is returned. */++typedef int regoff_t;++typedef struct {+  regoff_t rm_so;+  regoff_t rm_eo;+} regmatch_t;++/* When an application links to a PCRE2 DLL in Windows, the symbols that are+imported have to be identified as such. When building PCRE2, the appropriate+export settings are needed, and are set in pcre2posix.c before including this+file. */++#if defined(_WIN32) && !defined(PCRE2_STATIC) && !defined(PCRE2POSIX_EXP_DECL)+#  define PCRE2POSIX_EXP_DECL  extern __declspec(dllimport)+#  define PCRE2POSIX_EXP_DEFN  __declspec(dllimport)+#endif++/* By default, we use the standard "extern" declarations. */++#ifndef PCRE2POSIX_EXP_DECL+#  ifdef __cplusplus+#    define PCRE2POSIX_EXP_DECL  extern "C"+#    define PCRE2POSIX_EXP_DEFN  extern "C"+#  else+#    define PCRE2POSIX_EXP_DECL  extern+#    define PCRE2POSIX_EXP_DEFN  extern+#  endif+#endif++/* The functions. The actual code is in functions with pcre2_xxx names for+uniqueness. POSIX names are provided as macros for API compatibility with POSIX+regex functions. It's done this way to ensure to they are always linked from+the PCRE2 library and not by accident from elsewhere (regex_t differs in size+elsewhere). */++PCRE2POSIX_EXP_DECL int pcre2_regcomp(regex_t *, const char *, int);+PCRE2POSIX_EXP_DECL int pcre2_regexec(const regex_t *, const char *, size_t,+                     regmatch_t *, int);+PCRE2POSIX_EXP_DECL size_t pcre2_regerror(int, const regex_t *, char *, size_t);+PCRE2POSIX_EXP_DECL void pcre2_regfree(regex_t *);++#define regcomp  pcre2_regcomp+#define regexec  pcre2_regexec+#define regerror pcre2_regerror+#define regfree  pcre2_regfree++/* Debian had a patch that used different names. These are now here to save+them having to maintain their own patch, but are not documented by PCRE2. */++#define PCRE2regcomp  pcre2_regcomp+#define PCRE2regexec  pcre2_regexec+#define PCRE2regerror pcre2_regerror+#define PCRE2regfree  pcre2_regfree++#ifdef __cplusplus+}   /* extern "C" */+#endif++/* End of pcre2posix.h */
+ src/c/pcre2/src/pcre2test.c view
@@ -0,0 +1,9220 @@+/*************************************************+*             PCRE2 testing program              *+*************************************************/++/* PCRE2 is a library of functions to support regular expressions whose syntax+and semantics are as close as possible to those of the Perl 5 language. In 2014+the API was completely revised and '2' was added to the name, because the old+API, which had lasted for 16 years, could not accommodate new requirements. At+the same time, this testing program was re-designed because its original+hacked-up (non-) design had also run out of steam.++                       Written by Philip Hazel+     Original code Copyright (c) 1997-2012 University of Cambridge+    Rewritten code Copyright (c) 2016-2020 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 program supports testing of the 8-bit, 16-bit, and 32-bit PCRE2+libraries in a single program, though its input and output are always 8-bit.+It is different from modules such as pcre2_compile.c in the library itself,+which are compiled separately for each code unit width. If two widths are+enabled, for example, pcre2_compile.c is compiled twice. In contrast,+pcre2test.c is compiled only once, and linked with all the enabled libraries.+Therefore, it must not make use of any of the macros from pcre2.h or+pcre2_internal.h that depend on PCRE2_CODE_UNIT_WIDTH. It does, however, make+use of SUPPORT_PCRE2_8, SUPPORT_PCRE2_16, and SUPPORT_PCRE2_32, to ensure that+it references only the enabled library functions. */++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include <ctype.h>+#include <stdio.h>+#include <string.h>+#include <stdlib.h>+#include <time.h>+#include <locale.h>+#include <errno.h>++#if defined NATIVE_ZOS+#include "pcrzoscs.h"+/* That header is not included in the main PCRE2 distribution because other+apparatus is needed to compile pcre2test for z/OS. The header can be found in+the special z/OS distribution, which is available from www.zaconsultants.net or+from www.cbttape.org. */+#endif++#ifdef HAVE_UNISTD_H+#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+that first, falling back to readline/readline.h. */++#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+#if defined(SUPPORT_LIBREADLINE)+#include <readline/readline.h>+#include <readline/history.h>+#else+#if defined(HAVE_EDITLINE_READLINE_H)+#include <editline/readline.h>+#else+#include <readline/readline.h>+#endif+#endif+#endif++/* Put the test for interactive input into a macro so that it can be changed if+required for different environments. */++#define INTERACTIVE(f) isatty(fileno(f))+++/* ---------------------- System-specific definitions ---------------------- */++/* A number of things vary for Windows builds. Originally, pcretest opened its+input and output without "b"; then I was told that "b" was needed in some+environments, so it was added for release 5.0 to both the input and output. (It+makes no difference on Unix-like systems.) Later I was told that it is wrong+for the input on Windows. I've now abstracted the modes into macros that are+set here, to make it easier to fiddle with them, and removed "b" from the input+mode under Windows. The BINARY versions are used when saving/restoring compiled+patterns. */++#if defined(_WIN32) || defined(WIN32)+#include <io.h>                /* For _setmode() */+#include <fcntl.h>             /* For _O_BINARY */+#define INPUT_MODE          "r"+#define OUTPUT_MODE         "wb"+#define BINARY_INPUT_MODE   "rb"+#define BINARY_OUTPUT_MODE  "wb"++#ifndef isatty+#define isatty _isatty         /* This is what Windows calls them, I'm told, */+#endif                         /* though in some environments they seem to   */+                               /* be already defined, hence the #ifndefs.    */+#ifndef fileno+#define fileno _fileno+#endif++/* A user sent this fix for Borland Builder 5 under Windows. */++#ifdef __BORLANDC__+#define _setmode(handle, mode) setmode(handle, mode)+#endif++/* Not Windows */++#else+#include <sys/time.h>          /* These two includes are needed */+#include <sys/resource.h>      /* for setrlimit(). */+#if defined NATIVE_ZOS         /* z/OS uses non-binary I/O */+#define INPUT_MODE   "r"+#define OUTPUT_MODE  "w"+#define BINARY_INPUT_MODE   "rb"+#define BINARY_OUTPUT_MODE  "wb"+#else+#define INPUT_MODE          "rb"+#define OUTPUT_MODE         "wb"+#define BINARY_INPUT_MODE   "rb"+#define BINARY_OUTPUT_MODE  "wb"+#endif+#endif++/* VMS-specific code was included as suggested by a VMS user [1]. Another VMS+user [2] provided alternative code which worked better for him. I have+commented out the original, but kept it around just in case. */++#ifdef __VMS+#include <ssdef.h>+/* These two includes came from [2]. */+#include descrip+#include lib$routines+/* void vms_setsymbol( char *, char *, int ); Original code from [1]. */+#endif++/* VC and older compilers don't support %td or %zu, and even some that claim to+be C99 don't support it (hence DISABLE_PERCENT_ZT). There are some non-C99+environments where %lu gives a warning with 32-bit pointers. As there doesn't+seem to be an easy way round this, just live with it (the cases are rare). */++#if defined(_MSC_VER) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || defined(DISABLE_PERCENT_ZT)+#define PTR_FORM "lu"+#define SIZ_FORM "lu"+#define SIZ_CAST (unsigned long int)+#else+#define PTR_FORM "td"+#define SIZ_FORM "zu"+#define SIZ_CAST+#endif++/* ------------------End of system-specific definitions -------------------- */++/* Glueing macros that are used in several places below. */++#define glue(a,b) a##b+#define G(a,b) glue(a,b)++/* Miscellaneous parameters and manifests */++#ifndef CLOCKS_PER_SEC+#ifdef CLK_TCK+#define CLOCKS_PER_SEC CLK_TCK+#else+#define CLOCKS_PER_SEC 100+#endif+#endif++#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 */++/* Default JIT compile options */++#define JIT_DEFAULT (PCRE2_JIT_COMPLETE|\+                     PCRE2_JIT_PARTIAL_SOFT|\+                     PCRE2_JIT_PARTIAL_HARD)++/* Make sure the buffer into which replacement strings are copied is big enough+to hold them as 32-bit code units. */++#define REPLACE_BUFFSIZE 1024   /* This is a byte value */++/* Execution modes */++#define PCRE8_MODE   8+#define PCRE16_MODE 16+#define PCRE32_MODE 32++/* Processing returns */++enum { PR_OK, PR_SKIP, PR_ABEND };++/* The macro PRINTABLE determines whether to print an output character as-is or+as a hex value when showing compiled patterns. is We use it in cases when the+locale has not been explicitly changed, so as to get consistent output from+systems that differ in their output from isprint() even in the "C" locale. */++#ifdef EBCDIC+#define PRINTABLE(c) ((c) >= 64 && (c) < 255)+#else+#define PRINTABLE(c) ((c) >= 32 && (c) < 127)+#endif++#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+values - pcre2test has "inside information" compared to an application program+that strictly follows the PCRE2 API.++Before including pcre2_internal.h we define PRIV so that it does not get+defined therein. This ensures that PRIV names in the included files do not+clash with those in the libraries. Also, although pcre2_internal.h does itself+include pcre2.h, we explicitly include it beforehand, along with pcre2posix.h,+so that the PCRE2_EXP_xxx macros get set appropriately for an application, not+for building the library. */++#define PRIV(name) name+#define PCRE2_CODE_UNIT_WIDTH 0+#include "pcre2.h"+#include "pcre2posix.h"+#include "pcre2_internal.h"++/* We need access to some of the data tables that PCRE2 uses. Defining+PCRE2_PCRETEST makes some minor changes in the files. The previous definition+of PRIV avoids name clashes. */++#define PCRE2_PCRE2TEST+#include "pcre2_tables.c"+#include "pcre2_ucd.c"++/* 32-bit integer values in the input are read by strtoul() or strtol(). The+check needed for overflow depends on whether long ints are in fact longer than+ints. They are defined not to be shorter. */++#if ULONG_MAX > UINT32_MAX+#define U32OVERFLOW(x) (x > UINT32_MAX)+#else+#define U32OVERFLOW(x) (x == UINT32_MAX)+#endif++#if LONG_MAX > INT32_MAX+#define S32OVERFLOW(x) (x > INT32_MAX || x < INT32_MIN)+#else+#define S32OVERFLOW(x) (x == INT32_MAX || x == INT32_MIN)+#endif++/* When PCRE2_CODE_UNIT_WIDTH is zero, pcre2_internal.h does not include+pcre2_intmodedep.h, which is where mode-dependent macros and structures are+defined. We can now include it for each supported code unit width. Because+PCRE2_CODE_UNIT_WIDTH was defined as zero before including pcre2.h, it will+have left PCRE2_SUFFIX defined as a no-op. We must re-define it appropriately+while including these files, and then restore it to a no-op. Because LINK_SIZE+may be changed in 16-bit mode and forced to 1 in 32-bit mode, the order of+these inclusions should not be changed. */++#undef PCRE2_SUFFIX+#undef PCRE2_CODE_UNIT_WIDTH++#ifdef   SUPPORT_PCRE2_8+#define  PCRE2_CODE_UNIT_WIDTH 8+#define  PCRE2_SUFFIX(a) G(a,8)+#include "pcre2_intmodedep.h"+#include "pcre2_printint.c"+#undef   PCRE2_CODE_UNIT_WIDTH+#undef   PCRE2_SUFFIX+#endif   /* SUPPORT_PCRE2_8 */++#ifdef   SUPPORT_PCRE2_16+#define  PCRE2_CODE_UNIT_WIDTH 16+#define  PCRE2_SUFFIX(a) G(a,16)+#include "pcre2_intmodedep.h"+#include "pcre2_printint.c"+#undef   PCRE2_CODE_UNIT_WIDTH+#undef   PCRE2_SUFFIX+#endif   /* SUPPORT_PCRE2_16 */++#ifdef   SUPPORT_PCRE2_32+#define  PCRE2_CODE_UNIT_WIDTH 32+#define  PCRE2_SUFFIX(a) G(a,32)+#include "pcre2_intmodedep.h"+#include "pcre2_printint.c"+#undef   PCRE2_CODE_UNIT_WIDTH+#undef   PCRE2_SUFFIX+#endif   /* SUPPORT_PCRE2_32 */++#define PCRE2_SUFFIX(a) a++/* We need to be able to check input text for UTF-8 validity, whatever code+widths are actually available, because the input to pcre2test is always in+8-bit code units. So we include the UTF validity checking function for 8-bit+code units. */++extern int valid_utf(PCRE2_SPTR8, PCRE2_SIZE, PCRE2_SIZE *);++#define  PCRE2_CODE_UNIT_WIDTH 8+#undef   PCRE2_SPTR+#define  PCRE2_SPTR PCRE2_SPTR8+#include "pcre2_valid_utf.c"+#undef   PCRE2_CODE_UNIT_WIDTH+#undef   PCRE2_SPTR++/* 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-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. */++#if defined SUPPORT_PCRE2_8+#define DEFAULT_TEST_MODE PCRE8_MODE+#define VERSION_TYPE PCRE2_UCHAR8+#define PCRE2_CONFIG pcre2_config_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++#elif defined SUPPORT_PCRE2_16+#define DEFAULT_TEST_MODE PCRE16_MODE+#define VERSION_TYPE PCRE2_UCHAR16+#define PCRE2_CONFIG pcre2_config_16+#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+#define DEFAULT_TEST_MODE PCRE32_MODE+#define VERSION_TYPE PCRE2_UCHAR32+#define PCRE2_CONFIG pcre2_config_32+#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++/* ------------- Structure and table for handling #-commands ------------- */++typedef struct cmdstruct {+  const char *name;+  int  value;+} cmdstruct;++enum { CMD_FORBID_UTF, CMD_LOAD, CMD_LOADTABLES, CMD_NEWLINE_DEFAULT,+  CMD_PATTERN, CMD_PERLTEST, CMD_POP, CMD_POPCOPY, CMD_SAVE, CMD_SUBJECT,+  CMD_UNKNOWN };++static cmdstruct cmdlist[] = {+  { "forbid_utf",      CMD_FORBID_UTF },+  { "load",            CMD_LOAD },+  { "loadtables",      CMD_LOADTABLES },+  { "newline_default", CMD_NEWLINE_DEFAULT },+  { "pattern",         CMD_PATTERN },+  { "perltest",        CMD_PERLTEST },+  { "pop",             CMD_POP },+  { "popcopy",         CMD_POPCOPY },+  { "save",            CMD_SAVE },+  { "subject",         CMD_SUBJECT }};++#define cmdlistcount (sizeof(cmdlist)/sizeof(cmdstruct))++/* ------------- Structures and tables for handling modifiers -------------- */++/* Table of names for newline types. Must be kept in step with the definitions+of PCRE2_NEWLINE_xx in pcre2.h. */++static const char *newlines[] = {+  "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 */++enum { MOD_CTC,    /* Applies to a compile context */+       MOD_CTM,    /* Applies to a match context */+       MOD_PAT,    /* Applies to a pattern */+       MOD_PATP,   /* Ditto, OK for Perl test */+       MOD_DAT,    /* Applies to a data line */+       MOD_PD,     /* Applies to a pattern or a data line */+       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 */+       MOD_INS,    /* Is a signed integer */+       MOD_INT,    /* Is an unsigned integer */+       MOD_IND,    /* Is an unsigned integer, but no value => default */+       MOD_NL,     /* Is a newline value */+       MOD_NN,     /* Is a number or a name; more than one may occur */+       MOD_OPT,    /* Is an option bit */+       MOD_SIZ,    /* Is a PCRE2_SIZE value */+       MOD_STR };  /* Is a string */++/* Control bits. Some apply to compiling, some to matching, but some can be set+either on a pattern or a data line, so they must all be distinct. There are now+so many of them that they are split into two fields. */++#define CTL_AFTERTEXT                    0x00000001u+#define CTL_ALLAFTERTEXT                 0x00000002u+#define CTL_ALLCAPTURES                  0x00000004u+#define CTL_ALLUSEDTEXT                  0x00000008u+#define CTL_ALTGLOBAL                    0x00000010u+#define CTL_BINCODE                      0x00000020u+#define CTL_CALLOUT_CAPTURE              0x00000040u+#define CTL_CALLOUT_INFO                 0x00000080u+#define CTL_CALLOUT_NONE                 0x00000100u+#define CTL_DFA                          0x00000200u+#define CTL_EXPAND                       0x00000400u+#define CTL_FINDLIMITS                   0x00000800u+#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 */++#define CTL_DEBUG            (CTL_FULLBINCODE|CTL_INFO)  /* For setting */+#define CTL_ANYINFO          (CTL_DEBUG|CTL_BINCODE|CTL_CALLOUT_INFO)+#define CTL_ANYGLOB          (CTL_ALTGLOBAL|CTL_GLOBAL)++/* Second control word */++#define CTL2_SUBSTITUTE_CALLOUT          0x00000001u+#define CTL2_SUBSTITUTE_EXTENDED         0x00000002u+#define CTL2_SUBSTITUTE_LITERAL          0x00000004u+#define CTL2_SUBSTITUTE_MATCHED          0x00000008u+#define CTL2_SUBSTITUTE_OVERFLOW_LENGTH  0x00000010u+#define CTL2_SUBSTITUTE_REPLACEMENT_ONLY 0x00000020u+#define CTL2_SUBSTITUTE_UNKNOWN_UNSET    0x00000040u+#define CTL2_SUBSTITUTE_UNSET_EMPTY      0x00000080u+#define CTL2_SUBJECT_LITERAL             0x00000100u+#define CTL2_CALLOUT_NO_WHERE            0x00000200u+#define CTL2_CALLOUT_EXTRA               0x00000400u+#define CTL2_ALLVECTOR                   0x00000800u++#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|\+                    CTL_ALLCAPTURES|\+                    CTL_ALLUSEDTEXT|\+                    CTL_ALTGLOBAL|\+                    CTL_GLOBAL|\+                    CTL_MARK|\+                    CTL_STARTCHAR|\+                    CTL_UTF8_INPUT)++#define CTL2_ALLPD (CTL2_SUBSTITUTE_CALLOUT|\+                    CTL2_SUBSTITUTE_EXTENDED|\+                    CTL2_SUBSTITUTE_LITERAL|\+                    CTL2_SUBSTITUTE_MATCHED|\+                    CTL2_SUBSTITUTE_OVERFLOW_LENGTH|\+                    CTL2_SUBSTITUTE_REPLACEMENT_ONLY|\+                    CTL2_SUBSTITUTE_UNKNOWN_UNSET|\+                    CTL2_SUBSTITUTE_UNSET_EMPTY|\+                    CTL2_ALLVECTOR)++/* Structures for holding modifier information for patterns and subject strings+(data). Fields containing modifiers that can be set either for a pattern or a+subject must be at the start and in the same order in both cases so that the+same offset in the big table below works for both. */++typedef struct patctl {       /* Structure for pattern modifiers. */+  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  substitute_skip;  /* Must be in same position as patctl */+  uint32_t  substitute_stop;  /* Must be in same position as patctl */+  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;++#define MAXCPYGET 10+#define LENCPYGET 64++typedef struct datctl {       /* Structure for data line modifiers. */+  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  substitute_skip;  /* Must be in same position as patctl */+  uint32_t  substitute_stop;  /* Must be in same position as patctl */+  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  oveccount;+  uint32_t  offset;+  uint8_t   copy_names[LENCPYGET];+  uint8_t   get_names[LENCPYGET];+} datctl;++/* Ids for which context to modify. */++enum { CTX_PAT,            /* Active pattern context */+       CTX_POPPAT,         /* Ditto, for a popped pattern */+       CTX_DEFPAT,         /* Default pattern context */+       CTX_DAT,            /* Active data (match) context */+       CTX_DEFDAT };       /* Default data (match) context */++/* Macros to simplify the big table below. */++#define CO(name) offsetof(PCRE2_REAL_COMPILE_CONTEXT, name)+#define MO(name) offsetof(PCRE2_REAL_MATCH_CONTEXT, name)+#define PO(name) offsetof(patctl, name)+#define PD(name) PO(name)+#define DO(name) offsetof(datctl, name)++/* Table of all long-form modifiers. Must be in collating sequence of modifier+name because it is searched by binary chop. */++typedef struct modstruct {+  const char   *name;+  uint16_t      which;+  uint16_t      type;+  uint32_t      value;+  PCRE2_SIZE    offset;+} modstruct;++static modstruct modlist[] = {+  { "aftertext",                   MOD_PNDP, MOD_CTL, CTL_AFTERTEXT,              PO(control) },+  { "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) },+  { "allvector",                   MOD_PND,  MOD_CTL, CTL2_ALLVECTOR,             PO(control2) },+  { "alt_bsux",                    MOD_PAT,  MOD_OPT, PCRE2_ALT_BSUX,             PO(options) },+  { "alt_circumflex",              MOD_PAT,  MOD_OPT, PCRE2_ALT_CIRCUMFLEX,       PO(options) },+  { "alt_verbnames",               MOD_PAT,  MOD_OPT, PCRE2_ALT_VERBNAMES,        PO(options) },+  { "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) },+  { "copy_matched_subject",        MOD_DAT,  MOD_OPT, PCRE2_COPY_MATCHED_SUBJECT, DO(options) },+  { "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) },+  { "escaped_cr_is_lf",            MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ESCAPED_CR_IS_LF, CO(extra_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) },+  { "extra_alt_bsux",              MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ALT_BSUX,       CO(extra_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_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_invalid_utf",           MOD_PAT,  MOD_OPT, PCRE2_MATCH_INVALID_UTF,    PO(options) },+  { "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) },+  { "never_backslash_c",           MOD_PAT,  MOD_OPT, PCRE2_NEVER_BACKSLASH_C,    PO(options) },+  { "never_ucp",                   MOD_PAT,  MOD_OPT, PCRE2_NEVER_UCP,            PO(options) },+  { "never_utf",                   MOD_PAT,  MOD_OPT, PCRE2_NEVER_UTF,            PO(options) },+  { "newline",                     MOD_CTC,  MOD_NL,  0,                          CO(newline_convention) },+  { "no_auto_capture",             MOD_PAT,  MOD_OPT, PCRE2_NO_AUTO_CAPTURE,      PO(options) },+  { "no_auto_possess",             MOD_PATP, MOD_OPT, PCRE2_NO_AUTO_POSSESS,      PO(options) },+  { "no_dotstar_anchor",           MOD_PAT,  MOD_OPT, PCRE2_NO_DOTSTAR_ANCHOR,    PO(options) },+  { "no_jit",                      MOD_DAT,  MOD_OPT, PCRE2_NO_JIT,               DO(options) },+  { "no_start_optimize",           MOD_PATP, MOD_OPT, PCRE2_NO_START_OPTIMIZE,    PO(options) },+  { "no_utf_check",                MOD_PD,   MOD_OPT, PCRE2_NO_UTF_CHECK,         PD(options) },+  { "notbol",                      MOD_DAT,  MOD_OPT, PCRE2_NOTBOL,               DO(options) },+  { "notempty",                    MOD_DAT,  MOD_OPT, PCRE2_NOTEMPTY,             DO(options) },+  { "notempty_atstart",            MOD_DAT,  MOD_OPT, PCRE2_NOTEMPTY_ATSTART,     DO(options) },+  { "noteol",                      MOD_DAT,  MOD_OPT, PCRE2_NOTEOL,               DO(options) },+  { "null_context",                MOD_PD,   MOD_CTL, CTL_NULLCONTEXT,            PO(control) },+  { "offset",                      MOD_DAT,  MOD_INT, 0,                          DO(offset) },+  { "offset_limit",                MOD_CTM,  MOD_SIZ, 0,                          MO(offset_limit)},+  { "ovector",                     MOD_DAT,  MOD_INT, 0,                          DO(oveccount) },+  { "parens_nest_limit",           MOD_CTC,  MOD_INT, 0,                          CO(parens_nest_limit) },+  { "partial_hard",                MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_HARD,         DO(options) },+  { "partial_soft",                MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_SOFT,         DO(options) },+  { "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) },+  { "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_callout",          MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_CALLOUT,    PO(control2) },+  { "substitute_extended",         MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_EXTENDED,   PO(control2) },+  { "substitute_literal",          MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_LITERAL,    PO(control2) },+  { "substitute_matched",          MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_MATCHED,    PO(control2) },+  { "substitute_overflow_length",  MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_OVERFLOW_LENGTH, PO(control2) },+  { "substitute_replacement_only", MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_REPLACEMENT_ONLY, PO(control2) },+  { "substitute_skip",             MOD_PND,  MOD_INT, 0,                          PO(substitute_skip) },+  { "substitute_stop",             MOD_PND,  MOD_INT, 0,                          PO(substitute_stop) },+  { "substitute_unknown_unset",    MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_UNKNOWN_UNSET, PO(control2) },+  { "substitute_unset_empty",      MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_UNSET_EMPTY, PO(control2) },+  { "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) }+};++#define MODLISTCOUNT sizeof(modlist)/sizeof(modstruct)++/* Controls and options that are supported for use with the POSIX interface. */++#define POSIX_SUPPORTED_COMPILE_OPTIONS ( \+  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_HEXPAT|CTL_POSIX| \+  CTL_POSIX_NOSUB|CTL_USE_LENGTH)++#define POSIX_SUPPORTED_COMPILE_CONTROLS2 (0)++#define POSIX_SUPPORTED_MATCH_OPTIONS ( \+  PCRE2_NOTBOL|PCRE2_NOTEMPTY|PCRE2_NOTEOL)++#define POSIX_SUPPORTED_MATCH_CONTROLS  (CTL_AFTERTEXT|CTL_ALLAFTERTEXT)+#define POSIX_SUPPORTED_MATCH_CONTROLS2 (0)++/* Control bits that are not ignored with 'push'. */++#define PUSH_SUPPORTED_COMPILE_CONTROLS ( \+  CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \+  CTL_JITVERIFY|CTL_MEMORY|CTL_FRAMESIZE|CTL_PUSH|CTL_PUSHCOPY| \+  CTL_PUSHTABLESCOPY|CTL_USE_LENGTH)++#define PUSH_SUPPORTED_COMPILE_CONTROLS2 (CTL2_BSR_SET|CTL2_NL_SET)++/* Controls that apply only at compile time with 'push'. */++#define PUSH_COMPILE_ONLY_CONTROLS   CTL_JITVERIFY+#define PUSH_COMPILE_ONLY_CONTROLS2  (0)++/* Controls that are forbidden with #pop or #popcopy. */++#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_POSIX_NOSUB|CTL_PUSH| \+  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_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 };++/* Table of single-character abbreviated modifiers. The index field is+initialized to -1, but the first time the modifier is encountered, it is filled+in with the index of the full entry in modlist, to save repeated searching when+processing multiple test items. This short list is searched serially, so its+order does not matter. */++typedef struct c1modstruct {+  const char *fullname;+  uint32_t    onechar;+  int         index;+} c1modstruct;++static c1modstruct c1modlist[] = {+  { "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)++/* Table of arguments for the -C command line option. Use macros to make the+table itself easier to read. */++#if defined SUPPORT_PCRE2_8+#define SUPPORT_8 1+#endif+#if defined SUPPORT_PCRE2_16+#define SUPPORT_16 1+#endif+#if defined SUPPORT_PCRE2_32+#define SUPPORT_32 1+#endif++#ifndef SUPPORT_8+#define SUPPORT_8 0+#endif+#ifndef SUPPORT_16+#define SUPPORT_16 0+#endif+#ifndef SUPPORT_32+#define SUPPORT_32 0+#endif++#ifdef EBCDIC+#define SUPPORT_EBCDIC 1+#define EBCDIC_NL CHAR_LF+#else+#define SUPPORT_EBCDIC 0+#define EBCDIC_NL 0+#endif++#ifdef NEVER_BACKSLASH_C+#define BACKSLASH_C 0+#else+#define BACKSLASH_C 1+#endif++typedef struct coptstruct {+  const char *name;+  uint32_t    type;+  uint32_t    value;+} coptstruct;++enum { CONF_BSR,+       CONF_FIX,+       CONF_FIZ,+       CONF_INT,+       CONF_NL+};++static coptstruct coptlist[] = {+  { "backslash-C", CONF_FIX, BACKSLASH_C },+  { "bsr",         CONF_BSR, PCRE2_CONFIG_BSR },+  { "ebcdic",      CONF_FIX, SUPPORT_EBCDIC },+  { "ebcdic-nl",   CONF_FIZ, EBCDIC_NL },+  { "jit",         CONF_INT, PCRE2_CONFIG_JIT },+  { "linksize",    CONF_INT, PCRE2_CONFIG_LINKSIZE },+  { "newline",     CONF_NL,  PCRE2_CONFIG_NEWLINE },+  { "pcre2-16",    CONF_FIX, SUPPORT_16 },+  { "pcre2-32",    CONF_FIX, SUPPORT_32 },+  { "pcre2-8",     CONF_FIX, SUPPORT_8 },+  { "unicode",     CONF_INT, PCRE2_CONFIG_UNICODE }+};++#define COPTLISTCOUNT sizeof(coptlist)/sizeof(coptstruct)++#undef SUPPORT_8+#undef SUPPORT_16+#undef SUPPORT_32+#undef SUPPORT_EBCDIC+++/* ----------------------- Static variables ------------------------ */++static FILE *infile;+static FILE *outfile;++static const void *last_callout_mark;+static PCRE2_JIT_STACK *jit_stack = NULL;+static size_t jit_stack_size = 0;++static BOOL first_callout;+static BOOL jit_was_used;+static BOOL restrict_for_perl_test = FALSE;+static BOOL show_memory = FALSE;++static int code_unit_size;                    /* Bytes */+static int jitrc;                             /* Return from JIT compile */+static int test_mode = DEFAULT_TEST_MODE;+static int timeit = 0;+static int timeitm = 0;++clock_t total_compile_time = 0;+clock_t total_jit_compile_time = 0;+clock_t total_match_time = 0;++static uint32_t dfa_matched;+static uint32_t forbid_utf = 0;+static uint32_t maxlookbehind;+static uint32_t max_oveccount;+static uint32_t callout_count;+static uint32_t maxcapcount;++static uint16_t local_newline_default = 0;++static VERSION_TYPE jittarget[VERSION_SIZE];+static VERSION_TYPE version[VERSION_SIZE];+static VERSION_TYPE uversion[VERSION_SIZE];++static patctl def_patctl;+static patctl pat_patctl;+static datctl def_datctl;+static datctl dat_datctl;++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, 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];+static uint8_t *tables3 = NULL;         /* For binary-loaded tables */+static uint32_t loadtables_length = 0;++/* We need buffers for building 16/32-bit strings; 8-bit strings don't need+rebuilding, but set up the same naming scheme for use in macros. The "buffer"+buffer is where all input lines are read. Its size is the same as pbuffer8.+Pattern lines are always copied to pbuffer8 for use in callouts, even if they+are actually compiled from pbuffer16 or pbuffer32. */++static size_t    pbuffer8_size  = 50000;        /* Initial size, bytes */+static uint8_t  *pbuffer8 = NULL;+static uint8_t  *buffer = NULL;++/* The dbuffer is where all processed data lines are put. In non-8-bit modes it+is cast as needed. For long data lines it grows as necessary. */++static size_t dbuffer_size = 1u << 14;    /* Initial size, bytes */+static uint8_t *dbuffer = NULL;+++/* ---------------- Mode-dependent variables -------------------*/++#ifdef SUPPORT_PCRE2_8+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++#ifdef SUPPORT_PCRE2_16+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 */+static uint16_t *pbuffer16 = NULL;+#endif++#ifdef SUPPORT_PCRE2_32+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 */+static uint32_t *pbuffer32 = NULL;+#endif+++/* ---------------- Macros that work in all modes ----------------- */++#define CAST8VAR(x) CASTVAR(uint8_t *, x)+#define SET(x,y) SETOP(x,y,=)+#define SETPLUS(x,y) SETOP(x,y,+=)+#define strlen8(x) strlen((char *)x)+++/* ---------------- Mode-dependent, runtime-testing macros ------------------*/++/* Define macros for variables and functions that must be selected dynamically+depending on the mode setting (8, 16, 32). These are dependent on which modes+are supported. */++#if (defined (SUPPORT_PCRE2_8) + defined (SUPPORT_PCRE2_16) + \+     defined (SUPPORT_PCRE2_32)) >= 2++/* ----- All three modes supported ----- */++#if defined(SUPPORT_PCRE2_8) && defined(SUPPORT_PCRE2_16) && defined(SUPPORT_PCRE2_32)++#define CASTFLD(t,a,b) ((test_mode == PCRE8_MODE)? (t)(G(a,8)->b) : \+  (test_mode == PCRE16_MODE)? (t)(G(a,16)->b) : (t)(G(a,32)->b))++#define CASTVAR(t,x) ( \+  (test_mode == PCRE8_MODE)? (t)G(x,8) : \+  (test_mode == PCRE16_MODE)? (t)G(x,16) : (t)G(x,32))++#define CODE_UNIT(a,b) ( \+  (test_mode == PCRE8_MODE)? (uint32_t)(((PCRE2_SPTR8)(a))[b]) : \+  (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)); \+  else if (test_mode == PCRE16_MODE) \+    memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16)); \+  else memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32))++#define FLD(a,b) ((test_mode == PCRE8_MODE)? G(a,8)->b : \+  (test_mode == PCRE16_MODE)? G(a,16)->b : G(a,32)->b)++#define PATCTXCPY(a,b) \+  if (test_mode == PCRE8_MODE) \+    memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8)); \+  else if (test_mode == PCRE16_MODE) \+    memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16)); \+  else memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32))++#define PCHARS(lv, p, offset, len, utf, f) \+  if (test_mode == PCRE32_MODE) \+    lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \+  else if (test_mode == PCRE16_MODE) \+    lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \+  else \+    lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)++#define PCHARSV(p, offset, len, utf, f) \+  if (test_mode == PCRE32_MODE) \+    (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f); \+  else if (test_mode == PCRE16_MODE) \+    (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f); \+  else \+    (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)++#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \+  if (test_mode == PCRE8_MODE) \+     a = pcre2_callout_enumerate_8(compiled_code8, \+       (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c); \+  else if (test_mode == PCRE16_MODE) \+     a = pcre2_callout_enumerate_16(compiled_code16, \+       (int(*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c); \+  else \+     a = pcre2_callout_enumerate_32(compiled_code32, \+       (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c)++#define PCRE2_CODE_COPY_FROM_VOID(a,b) \+  if (test_mode == PCRE8_MODE) \+    G(a,8) = pcre2_code_copy_8(b); \+  else if (test_mode == PCRE16_MODE) \+    G(a,16) = pcre2_code_copy_16(b); \+  else \+    G(a,32) = pcre2_code_copy_32(b)++#define PCRE2_CODE_COPY_TO_VOID(a,b) \+  if (test_mode == PCRE8_MODE) \+    a = (void *)pcre2_code_copy_8(G(b,8)); \+  else if (test_mode == PCRE16_MODE) \+    a = (void *)pcre2_code_copy_16(G(b,16)); \+  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); \+  else if (test_mode == PCRE16_MODE) \+    G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g); \+  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); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j); \+  else \+    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) \+  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/2)); \+  else \+    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) \+    a = pcre2_get_ovector_count_8(G(b,8)); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_get_ovector_count_16(G(b,16)); \+  else \+    a = pcre2_get_ovector_count_32(G(b,32))++#define PCRE2_GET_STARTCHAR(a,b) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_get_startchar_8(G(b,8)); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_get_startchar_16(G(b,16)); \+  else \+    a = pcre2_get_startchar_32(G(b,32))++#define PCRE2_JIT_COMPILE(r,a,b) \+  if (test_mode == PCRE8_MODE) r = pcre2_jit_compile_8(G(a,8),b); \+  else if (test_mode == PCRE16_MODE) r = pcre2_jit_compile_16(G(a,16),b); \+  else r = pcre2_jit_compile_32(G(a,32),b)++#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \+  if (test_mode == PCRE8_MODE) pcre2_jit_free_unused_memory_8(G(a,8)); \+  else if (test_mode == PCRE16_MODE) pcre2_jit_free_unused_memory_16(G(a,16)); \+  else pcre2_jit_free_unused_memory_32(G(a,32))++#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \+  else \+    a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)++#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \+  if (test_mode == PCRE8_MODE) \+    a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d); \+  else if (test_mode == PCRE16_MODE) \+    a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d); \+  else \+    a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d);++#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c); \+  else \+    pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c);++#define PCRE2_JIT_STACK_FREE(a) \+  if (test_mode == PCRE8_MODE) \+    pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a); \+  else \+    pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a);++#define PCRE2_MAKETABLES(a) \+  if (test_mode == PCRE8_MODE) a = pcre2_maketables_8(NULL); \+  else if (test_mode == PCRE16_MODE) a = pcre2_maketables_16(NULL); \+  else a = pcre2_maketables_32(NULL)++#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h); \+  else \+    a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)++#define PCRE2_MATCH_DATA_CREATE(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    G(a,8) = pcre2_match_data_create_8(b,c); \+  else if (test_mode == PCRE16_MODE) \+    G(a,16) = pcre2_match_data_create_16(b,c); \+  else \+    G(a,32) = pcre2_match_data_create_32(b,c)++#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),c); \+  else if (test_mode == PCRE16_MODE) \+    G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),c); \+  else \+    G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),c)++#define PCRE2_MATCH_DATA_FREE(a) \+  if (test_mode == PCRE8_MODE) \+    pcre2_match_data_free_8(G(a,8)); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_match_data_free_16(G(a,16)); \+  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); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_pattern_info_16(G(b,16),c,d); \+  else \+    a = pcre2_pattern_info_32(G(b,32),c,d)++#define PCRE2_PRINTINT(a) \+  if (test_mode == PCRE8_MODE) \+    pcre2_printint_8(compiled_code8,outfile,a); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_printint_16(compiled_code16,outfile,a); \+  else \+    pcre2_printint_32(compiled_code32,outfile,a)++#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \+  if (test_mode == PCRE8_MODE) \+    r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8)); \+  else if (test_mode == PCRE16_MODE) \+    r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16)); \+  else \+    r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32))++#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \+  if (test_mode == PCRE8_MODE) \+    r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8)); \+  else if (test_mode == PCRE16_MODE) \+    r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16)); \+  else \+    r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32))++#define PCRE2_SERIALIZE_FREE(a) \+  if (test_mode == PCRE8_MODE) \+    pcre2_serialize_free_8(a); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_serialize_free_16(a); \+  else \+    pcre2_serialize_free_32(a)++#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \+  if (test_mode == PCRE8_MODE) \+    r = pcre2_serialize_get_number_of_codes_8(a); \+  else if (test_mode == PCRE16_MODE) \+    r = pcre2_serialize_get_number_of_codes_16(a); \+  else \+    r = pcre2_serialize_get_number_of_codes_32(a); \++#define PCRE2_SET_CALLOUT(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c); \+  else \+    pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c);++#define PCRE2_SET_CHARACTER_TABLES(a,b) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_character_tables_8(G(a,8),b); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_character_tables_16(G(a,16),b); \+  else \+    pcre2_set_character_tables_32(G(a,32),b)++#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_compile_recursion_guard_8(G(a,8),b,c); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_compile_recursion_guard_16(G(a,16),b,c); \+  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); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_match_limit_16(G(a,16),b); \+  else \+    pcre2_set_match_limit_32(G(a,32),b)++#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_max_pattern_length_8(G(a,8),b); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_max_pattern_length_16(G(a,16),b); \+  else \+    pcre2_set_max_pattern_length_32(G(a,32),b)++#define PCRE2_SET_OFFSET_LIMIT(a,b) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_offset_limit_8(G(a,8),b); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_offset_limit_16(G(a,16),b); \+  else \+    pcre2_set_offset_limit_32(G(a,32),b)++#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_parens_nest_limit_8(G(a,8),b); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_parens_nest_limit_16(G(a,16),b); \+  else \+    pcre2_set_parens_nest_limit_32(G(a,32),b)++#define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    pcre2_set_substitute_callout_8(G(a,8), \+      (int (*)(pcre2_substitute_callout_block_8 *, void *))b,c); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_set_substitute_callout_16(G(a,16), \+      (int (*)(pcre2_substitute_callout_block_16 *, void *))b,c); \+  else \+    pcre2_set_substitute_callout_32(G(a,32), \+      (int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)++#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),h, \+      (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h, \+      (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \+  else \+    a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h, \+      (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)++#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e); \+  else \+    a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)++#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e); \+  else \+    a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e)++#define PCRE2_SUBSTRING_FREE(a) \+  if (test_mode == PCRE8_MODE) pcre2_substring_free_8((PCRE2_UCHAR8 *)a); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_substring_free_16((PCRE2_UCHAR16 *)a); \+  else pcre2_substring_free_32((PCRE2_UCHAR32 *)a)++#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e); \+  else \+    a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e)++#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e); \+  else \+    a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e)++#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d); \+  else \+    a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d)++#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_length_bynumber_8(G(b,8),c,d); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_length_bynumber_16(G(b,16),c,d); \+  else \+    a = pcre2_substring_length_bynumber_32(G(b,32),c,d)++#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d); \+  else \+    a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d)++#define PCRE2_SUBSTRING_LIST_FREE(a) \+  if (test_mode == PCRE8_MODE) \+    pcre2_substring_list_free_8((PCRE2_SPTR8 *)a); \+  else if (test_mode == PCRE16_MODE) \+    pcre2_substring_list_free_16((PCRE2_SPTR16 *)a); \+  else \+    pcre2_substring_list_free_32((PCRE2_SPTR32 *)a)++#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \+  if (test_mode == PCRE8_MODE) \+    a = pcre2_substring_number_from_name_8(G(b,8),G(c,8)); \+  else if (test_mode == PCRE16_MODE) \+    a = pcre2_substring_number_from_name_16(G(b,16),G(c,16)); \+  else \+    a = pcre2_substring_number_from_name_32(G(b,32),G(c,32))++#define PTR(x) ( \+  (test_mode == PCRE8_MODE)? (void *)G(x,8) : \+  (test_mode == PCRE16_MODE)? (void *)G(x,16) : \+  (void *)G(x,32))++#define SETFLD(x,y,z) \+  if (test_mode == PCRE8_MODE) G(x,8)->y = z; \+  else if (test_mode == PCRE16_MODE) G(x,16)->y = z; \+  else G(x,32)->y = z++#define SETFLDVEC(x,y,v,z) \+  if (test_mode == PCRE8_MODE) G(x,8)->y[v] = z; \+  else if (test_mode == PCRE16_MODE) G(x,16)->y[v] = z; \+  else G(x,32)->y[v] = z++#define SETOP(x,y,z) \+  if (test_mode == PCRE8_MODE) G(x,8) z y; \+  else if (test_mode == PCRE16_MODE) G(x,16) z y; \+  else G(x,32) z y++#define SETCASTPTR(x,y) \+  if (test_mode == PCRE8_MODE) \+    G(x,8) = (uint8_t *)(y); \+  else if (test_mode == PCRE16_MODE) \+    G(x,16) = (uint16_t *)(y); \+  else \+    G(x,32) = (uint32_t *)(y)++#define STRLEN(p) ((test_mode == PCRE8_MODE)? ((int)strlen((char *)p)) : \+  (test_mode == PCRE16_MODE)? ((int)strlen16((PCRE2_SPTR16)p)) : \+  ((int)strlen32((PCRE2_SPTR32)p)))++#define SUB1(a,b) \+  if (test_mode == PCRE8_MODE) G(a,8)(G(b,8)); \+  else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16)); \+  else G(a,32)(G(b,32))++#define SUB2(a,b,c) \+  if (test_mode == PCRE8_MODE) G(a,8)(G(b,8),G(c,8)); \+  else if (test_mode == PCRE16_MODE) G(a,16)(G(b,16),G(c,16)); \+  else G(a,32)(G(b,32),G(c,32))++#define TEST(x,r,y) ( \+  (test_mode == PCRE8_MODE && G(x,8) r (y)) || \+  (test_mode == PCRE16_MODE && G(x,16) r (y)) || \+  (test_mode == PCRE32_MODE && G(x,32) r (y)))++#define TESTFLD(x,f,r,y) ( \+  (test_mode == PCRE8_MODE && G(x,8)->f r (y)) || \+  (test_mode == PCRE16_MODE && G(x,16)->f r (y)) || \+  (test_mode == PCRE32_MODE && G(x,32)->f r (y)))+++/* ----- Two out of three modes are supported ----- */++#else++/* We can use some macro trickery to make a single set of definitions work in+the three different cases. */++/* ----- 32-bit and 16-bit but not 8-bit supported ----- */++#if defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_16)+#define BITONE 32+#define BITTWO 16++/* ----- 32-bit and 8-bit but not 16-bit supported ----- */++#elif defined(SUPPORT_PCRE2_32) && defined(SUPPORT_PCRE2_8)+#define BITONE 32+#define BITTWO 8++/* ----- 16-bit and 8-bit but not 32-bit supported ----- */++#else+#define BITONE 16+#define BITTWO 8+#endif+++/* ----- 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))++#define CASTVAR(t,x) ( \+  (test_mode == G(G(PCRE,BITONE),_MODE))? \+    (t)G(x,BITONE) : (t)G(x,BITTWO))++#define CODE_UNIT(a,b) ( \+  (test_mode == G(G(PCRE,BITONE),_MODE))? \+  (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))); \+  else \+    memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_match_context_,BITTWO)))++#define FLD(a,b) \+  ((test_mode == G(G(PCRE,BITONE),_MODE))? G(a,BITONE)->b : G(a,BITTWO)->b)++#define PATCTXCPY(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_compile_context_,BITONE))); \+  else \+    memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_compile_context_,BITTWO)))++#define PCHARS(lv, p, offset, len, utf, f) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    lv = G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \+  else \+    lv = G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f)++#define PCHARSV(p, offset, len, utf, f) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    (void)G(pchars,BITONE)((G(PCRE2_SPTR,BITONE))(p)+offset, len, utf, f); \+  else \+    (void)G(pchars,BITTWO)((G(PCRE2_SPTR,BITTWO))(p)+offset, len, utf, f)++#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+     a = G(pcre2_callout_enumerate,BITONE)(G(compiled_code,BITONE), \+       (int (*)(struct G(pcre2_callout_enumerate_block_,BITONE) *, void *))b,c); \+  else \+     a = G(pcre2_callout_enumerate,BITTWO)(G(compiled_code,BITTWO), \+       (int (*)(struct G(pcre2_callout_enumerate_block_,BITTWO) *, void *))b,c)++#define PCRE2_CODE_COPY_FROM_VOID(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(a,BITONE) = G(pcre2_code_copy_,BITONE)(b); \+  else \+    G(a,BITTWO) = G(pcre2_code_copy_,BITTWO)(b)++#define PCRE2_CODE_COPY_TO_VOID(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = (void *)G(pcre2_code_copy_,BITONE)(G(b,BITONE)); \+  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, \+      G(g,BITONE),h,i,j); \+  else \+    a = G(pcre2_dfa_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \+      G(g,BITTWO),h,i,j)++#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/BYTEONE)); \+  else \+    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)) \+    a = G(pcre2_get_ovector_count_,BITONE)(G(b,BITONE)); \+  else \+    a = G(pcre2_get_ovector_count_,BITTWO)(G(b,BITTWO))++#define PCRE2_GET_STARTCHAR(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_get_startchar_,BITONE)(G(b,BITONE)); \+  else \+    a = G(pcre2_get_startchar_,BITTWO)(G(b,BITTWO))++#define PCRE2_JIT_COMPILE(r,a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    r = G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \+  else \+    r = G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b)++#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_jit_free_unused_memory_,BITONE)(G(a,BITONE)); \+  else \+    G(pcre2_jit_free_unused_memory_,BITTWO)(G(a,BITTWO))++#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_jit_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \+      G(g,BITONE),h); \+  else \+    a = G(pcre2_jit_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \+      G(g,BITTWO),h)++#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITONE)(b,c,d); \+  else \+    a = (PCRE2_JIT_STACK *)G(pcre2_jit_stack_create_,BITTWO)(b,c,d); \++#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_jit_stack_assign_,BITONE)(G(a,BITONE),(G(pcre2_jit_callback_,BITONE))b,c); \+  else \+    G(pcre2_jit_stack_assign_,BITTWO)(G(a,BITTWO),(G(pcre2_jit_callback_,BITTWO))b,c);++#define PCRE2_JIT_STACK_FREE(a) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_jit_stack_free_,BITONE)((G(pcre2_jit_stack_,BITONE) *)a); \+  else \+    G(pcre2_jit_stack_free_,BITTWO)((G(pcre2_jit_stack_,BITTWO) *)a);++#define PCRE2_MAKETABLES(a) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_maketables_,BITONE)(NULL); \+  else \+    a = G(pcre2_maketables_,BITTWO)(NULL)++#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \+      G(g,BITONE),h); \+  else \+    a = G(pcre2_match_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \+      G(g,BITTWO),h)++#define PCRE2_MATCH_DATA_CREATE(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(a,BITONE) = G(pcre2_match_data_create_,BITONE)(b,c); \+  else \+    G(a,BITTWO) = G(pcre2_match_data_create_,BITTWO)(b,c)++#define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(a,BITONE) = G(pcre2_match_data_create_from_pattern_,BITONE)(G(b,BITONE),c); \+  else \+    G(a,BITTWO) = G(pcre2_match_data_create_from_pattern_,BITTWO)(G(b,BITTWO),c)++#define PCRE2_MATCH_DATA_FREE(a) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_match_data_free_,BITONE)(G(a,BITONE)); \+  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); \+  else \+    a = G(pcre2_pattern_info_,BITTWO)(G(b,BITTWO),c,d)++#define PCRE2_PRINTINT(a) \+ if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_printint_,BITONE)(G(compiled_code,BITONE),outfile,a); \+  else \+    G(pcre2_printint_,BITTWO)(G(compiled_code,BITTWO),outfile,a)++#define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \+ if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    r = G(pcre2_serialize_decode_,BITONE)((G(pcre2_code_,BITONE) **)a,b,c,G(d,BITONE)); \+  else \+    r = G(pcre2_serialize_decode_,BITTWO)((G(pcre2_code_,BITTWO) **)a,b,c,G(d,BITTWO))++#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \+ if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    r = G(pcre2_serialize_encode_,BITONE)((G(const pcre2_code_,BITONE) **)a,b,c,d,G(e,BITONE)); \+  else \+    r = G(pcre2_serialize_encode_,BITTWO)((G(const pcre2_code_,BITTWO) **)a,b,c,d,G(e,BITTWO))++#define PCRE2_SERIALIZE_FREE(a) \+ if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_serialize_free_,BITONE)(a); \+  else \+    G(pcre2_serialize_free_,BITTWO)(a)++#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \+ if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    r = G(pcre2_serialize_get_number_of_codes_,BITONE)(a); \+  else \+    r = G(pcre2_serialize_get_number_of_codes_,BITTWO)(a)++#define PCRE2_SET_CALLOUT(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_callout_,BITONE)(G(a,BITONE), \+      (int (*)(G(pcre2_callout_block_,BITONE) *, void *))b,c); \+  else \+    G(pcre2_set_callout_,BITTWO)(G(a,BITTWO), \+      (int (*)(G(pcre2_callout_block_,BITTWO) *, void *))b,c);++#define PCRE2_SET_CHARACTER_TABLES(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_character_tables_,BITONE)(G(a,BITONE),b); \+  else \+    G(pcre2_set_character_tables_,BITTWO)(G(a,BITTWO),b)++#define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_compile_recursion_guard_,BITONE)(G(a,BITONE),b,c); \+  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); \+  else \+    G(pcre2_set_match_limit_,BITTWO)(G(a,BITTWO),b)++#define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_max_pattern_length_,BITONE)(G(a,BITONE),b); \+  else \+    G(pcre2_set_max_pattern_length_,BITTWO)(G(a,BITTWO),b)++#define PCRE2_SET_OFFSET_LIMIT(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_offset_limit_,BITONE)(G(a,BITONE),b); \+  else \+    G(pcre2_set_offset_limit_,BITTWO)(G(a,BITTWO),b)++#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_parens_nest_limit_,BITONE)(G(a,BITONE),b); \+  else \+    G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b)++#define PCRE2_SET_SUBSTITUTE_CALLOUT(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_set_substitute_callout_,BITONE)(G(a,BITONE), \+      (int (*)(G(pcre2_substitute_callout_block_,BITONE) *, void *))b,c); \+  else \+    G(pcre2_set_substitute_callout_,BITTWO)(G(a,BITTWO), \+      (int (*)(G(pcre2_substitute_callout_block_,BITTWO) *, void *))b,c)++#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, \+      G(g,BITONE),h,(G(PCRE2_SPTR,BITONE))i,j, \+      (G(PCRE2_UCHAR,BITONE) *)k,l); \+  else \+    a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \+      G(g,BITTWO),h,(G(PCRE2_SPTR,BITTWO))i,j, \+      (G(PCRE2_UCHAR,BITTWO) *)k,l)++#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_copy_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\+      (G(PCRE2_UCHAR,BITONE) *)d,e); \+  else \+    a = G(pcre2_substring_copy_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\+      (G(PCRE2_UCHAR,BITTWO) *)d,e)++#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_copy_bynumber_,BITONE)(G(b,BITONE),c,\+      (G(PCRE2_UCHAR,BITONE) *)d,e); \+  else \+    a = G(pcre2_substring_copy_bynumber_,BITTWO)(G(b,BITTWO),c,\+      (G(PCRE2_UCHAR,BITTWO) *)d,e)++#define PCRE2_SUBSTRING_FREE(a) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_substring_free_,BITONE)((G(PCRE2_UCHAR,BITONE) *)a); \+  else G(pcre2_substring_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) *)a)++#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_get_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\+      (G(PCRE2_UCHAR,BITONE) **)d,e); \+  else \+    a = G(pcre2_substring_get_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),\+      (G(PCRE2_UCHAR,BITTWO) **)d,e)++#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_get_bynumber_,BITONE)(G(b,BITONE),c,\+      (G(PCRE2_UCHAR,BITONE) **)d,e); \+  else \+    a = G(pcre2_substring_get_bynumber_,BITTWO)(G(b,BITTWO),c,\+      (G(PCRE2_UCHAR,BITTWO) **)d,e)++#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_length_byname_,BITONE)(G(b,BITONE),G(c,BITONE),d); \+  else \+    a = G(pcre2_substring_length_byname_,BITTWO)(G(b,BITTWO),G(c,BITTWO),d)++#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_length_bynumber_,BITONE)(G(b,BITONE),c,d); \+  else \+    a = G(pcre2_substring_length_bynumber_,BITTWO)(G(b,BITTWO),c,d)++#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_list_get_,BITONE)(G(b,BITONE), \+      (G(PCRE2_UCHAR,BITONE) ***)c,d); \+  else \+    a = G(pcre2_substring_list_get_,BITTWO)(G(b,BITTWO), \+      (G(PCRE2_UCHAR,BITTWO) ***)c,d)++#define PCRE2_SUBSTRING_LIST_FREE(a) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(pcre2_substring_list_free_,BITONE)((G(PCRE2_SPTR,BITONE) *)a); \+  else \+    G(pcre2_substring_list_free_,BITTWO)((G(PCRE2_SPTR,BITTWO) *)a)++#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    a = G(pcre2_substring_number_from_name_,BITONE)(G(b,BITONE),G(c,BITONE)); \+  else \+    a = G(pcre2_substring_number_from_name_,BITTWO)(G(b,BITTWO),G(c,BITTWO))++#define PTR(x) ( \+  (test_mode == G(G(PCRE,BITONE),_MODE))? (void *)G(x,BITONE) : \+  (void *)G(x,BITTWO))++#define SETFLD(x,y,z) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y = z; \+  else G(x,BITTWO)->y = z++#define SETFLDVEC(x,y,v,z) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE)->y[v] = z; \+  else G(x,BITTWO)->y[v] = z++#define SETOP(x,y,z) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) G(x,BITONE) z y; \+  else G(x,BITTWO) z y++#define SETCASTPTR(x,y) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(x,BITONE) = (G(G(uint,BITONE),_t) *)(y); \+  else \+    G(x,BITTWO) = (G(G(uint,BITTWO),_t) *)(y)++#define STRLEN(p) ((test_mode == G(G(PCRE,BITONE),_MODE))? \+  G(strlen,BITONE)((G(PCRE2_SPTR,BITONE))p) : \+  G(strlen,BITTWO)((G(PCRE2_SPTR,BITTWO))p))++#define SUB1(a,b) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(a,BITONE)(G(b,BITONE)); \+  else \+    G(a,BITTWO)(G(b,BITTWO))++#define SUB2(a,b,c) \+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \+    G(a,BITONE))(G(b,BITONE),G(c,BITONE)); \+  else \+    G(a,BITTWO))(G(b,BITTWO),G(c,BITTWO))++#define TEST(x,r,y) ( \+  (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE) r (y)) || \+  (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO) r (y)))++#define TESTFLD(x,f,r,y) ( \+  (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE)->f r (y)) || \+  (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO)->f r (y)))+++#endif  /* Two out of three modes */++/* ----- End of cases where more than one mode is supported ----- */+++/* ----- Only 8-bit mode is supported ----- */++#elif defined SUPPORT_PCRE2_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))+#define PCHARS(lv, p, offset, len, utf, f) \+  lv = pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)+#define PCHARSV(p, offset, len, utf, f) \+  (void)pchars8((PCRE2_SPTR8)(p)+offset, len, utf, f)+#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \+   a = pcre2_callout_enumerate_8(compiled_code8, \+     (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) \+  r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size))+#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_8(G(b,8))+#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_8(G(b,8))+#define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_8(G(a,8),b)+#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_8(G(a,8))+#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \+  a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h)+#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \+  a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_8(b,c,d);+#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \+  pcre2_jit_stack_assign_8(G(a,8),(pcre2_jit_callback_8)b,c);+#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_8((pcre2_jit_stack_8 *)a);+#define PCRE2_MAKETABLES(a) a = pcre2_maketables_8(NULL)+#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \+  a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h)+#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,8) = pcre2_match_data_create_8(b,c)+#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) \+  r = pcre2_serialize_decode_8((pcre2_code_8 **)a,b,c,G(d,8))+#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \+  r = pcre2_serialize_encode_8((const pcre2_code_8 **)a,b,c,d,G(e,8))+#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_8(a)+#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \+  r = pcre2_serialize_get_number_of_codes_8(a)+#define PCRE2_SET_CALLOUT(a,b,c) \+  pcre2_set_callout_8(G(a,8),(int (*)(pcre2_callout_block_8 *, void *))b,c)+#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_SUBSTITUTE_CALLOUT(a,b,c) \+  pcre2_set_substitute_callout_8(G(a,8), \+    (int (*)(pcre2_substitute_callout_block_8 *, void *))b,c)+#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),h, \+    (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)+#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \+  a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e)+#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \+  a = pcre2_substring_copy_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 *)d,e)+#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_8((PCRE2_UCHAR8 *)a)+#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \+  a = pcre2_substring_get_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 **)d,e)+#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \+  a = pcre2_substring_get_bynumber_8(G(b,8),c,(PCRE2_UCHAR8 **)d,e)+#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \+    a = pcre2_substring_length_byname_8(G(b,8),G(c,8),d)+#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \+    a = pcre2_substring_length_bynumber_8(G(b,8),c,d)+#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \+  a = pcre2_substring_list_get_8(G(b,8),(PCRE2_UCHAR8 ***)c,d)+#define PCRE2_SUBSTRING_LIST_FREE(a) \+  pcre2_substring_list_free_8((PCRE2_SPTR8 *)a)+#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \+  a = pcre2_substring_number_from_name_8(G(b,8),G(c,8));+#define PTR(x) (void *)G(x,8)+#define SETFLD(x,y,z) G(x,8)->y = z+#define SETFLDVEC(x,y,v,z) G(x,8)->y[v] = z+#define SETOP(x,y,z) G(x,8) z y+#define SETCASTPTR(x,y) G(x,8) = (uint8_t *)(y)+#define STRLEN(p) (int)strlen((char *)p)+#define SUB1(a,b) G(a,8)(G(b,8))+#define SUB2(a,b,c) G(a,8)(G(b,8),G(c,8))+#define TEST(x,r,y) (G(x,8) r (y))+#define TESTFLD(x,f,r,y) (G(x,8)->f r (y))+++/* ----- Only 16-bit mode is supported ----- */++#elif defined SUPPORT_PCRE2_16+#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))+#define PCHARS(lv, p, offset, len, utf, f) \+  lv = pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f)+#define PCHARSV(p, offset, len, utf, f) \+  (void)pchars16((PCRE2_SPTR16)(p)+offset, len, utf, f)+#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \+   a = pcre2_callout_enumerate_16(compiled_code16, \+     (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/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)+#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_16(G(a,16))+#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \+  a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h)+#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \+  a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_16(b,c,d);+#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \+  pcre2_jit_stack_assign_16(G(a,16),(pcre2_jit_callback_16)b,c);+#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_16((pcre2_jit_stack_16 *)a);+#define PCRE2_MAKETABLES(a) a = pcre2_maketables_16(NULL)+#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \+  a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h)+#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,16) = pcre2_match_data_create_16(b,c)+#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) \+  r = pcre2_serialize_decode_16((pcre2_code_16 **)a,b,c,G(d,16))+#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \+  r = pcre2_serialize_encode_16((const pcre2_code_16 **)a,b,c,d,G(e,16))+#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_16(a)+#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \+  r = pcre2_serialize_get_number_of_codes_16(a)+#define PCRE2_SET_CALLOUT(a,b,c) \+  pcre2_set_callout_16(G(a,16),(int (*)(pcre2_callout_block_16 *, void *))b,c);+#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_SUBSTITUTE_CALLOUT(a,b,c) \+  pcre2_set_substitute_callout_16(G(a,16), \+    (int (*)(pcre2_substitute_callout_block_16 *, void *))b,c)+#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),h, \+    (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)+#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \+  a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e)+#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \+  a = pcre2_substring_copy_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 *)d,e)+#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_16((PCRE2_UCHAR16 *)a)+#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \+  a = pcre2_substring_get_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 **)d,e)+#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \+  a = pcre2_substring_get_bynumber_16(G(b,16),c,(PCRE2_UCHAR16 **)d,e)+#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \+    a = pcre2_substring_length_byname_16(G(b,16),G(c,16),d)+#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \+    a = pcre2_substring_length_bynumber_16(G(b,16),c,d)+#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \+  a = pcre2_substring_list_get_16(G(b,16),(PCRE2_UCHAR16 ***)c,d)+#define PCRE2_SUBSTRING_LIST_FREE(a) \+  pcre2_substring_list_free_16((PCRE2_SPTR16 *)a)+#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \+  a = pcre2_substring_number_from_name_16(G(b,16),G(c,16));+#define PTR(x) (void *)G(x,16)+#define SETFLD(x,y,z) G(x,16)->y = z+#define SETFLDVEC(x,y,v,z) G(x,16)->y[v] = z+#define SETOP(x,y,z) G(x,16) z y+#define SETCASTPTR(x,y) G(x,16) = (uint16_t *)(y)+#define STRLEN(p) (int)strlen16((PCRE2_SPTR16)p)+#define SUB1(a,b) G(a,16)(G(b,16))+#define SUB2(a,b,c) G(a,16)(G(b,16),G(c,16))+#define TEST(x,r,y) (G(x,16) r (y))+#define TESTFLD(x,f,r,y) (G(x,16)->f r (y))+++/* ----- Only 32-bit mode is supported ----- */++#elif defined SUPPORT_PCRE2_32+#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))+#define PCHARS(lv, p, offset, len, utf, f) \+  lv = pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f)+#define PCHARSV(p, offset, len, utf, f) \+  (void)pchars32((PCRE2_SPTR32)(p)+offset, len, utf, f)+#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \+   a = pcre2_callout_enumerate_32(compiled_code32, \+     (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/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)+#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_32(G(a,32))+#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \+  a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)+#define PCRE2_JIT_STACK_CREATE(a,b,c,d) \+  a = (PCRE2_JIT_STACK *)pcre2_jit_stack_create_32(b,c,d);+#define PCRE2_JIT_STACK_ASSIGN(a,b,c) \+  pcre2_jit_stack_assign_32(G(a,32),(pcre2_jit_callback_32)b,c);+#define PCRE2_JIT_STACK_FREE(a) pcre2_jit_stack_free_32((pcre2_jit_stack_32 *)a);+#define PCRE2_MAKETABLES(a) a = pcre2_maketables_32(NULL)+#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \+  a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)+#define PCRE2_MATCH_DATA_CREATE(a,b,c) G(a,32) = pcre2_match_data_create_32(b,c)+#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) \+  r = pcre2_serialize_decode_32((pcre2_code_32 **)a,b,c,G(d,32))+#define PCRE2_SERIALIZE_ENCODE(r,a,b,c,d,e) \+  r = pcre2_serialize_encode_32((const pcre2_code_32 **)a,b,c,d,G(e,32))+#define PCRE2_SERIALIZE_FREE(a) pcre2_serialize_free_32(a)+#define PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(r,a) \+  r = pcre2_serialize_get_number_of_codes_32(a)+#define PCRE2_SET_CALLOUT(a,b,c) \+  pcre2_set_callout_32(G(a,32),(int (*)(pcre2_callout_block_32 *, void *))b,c)+#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_SUBSTITUTE_CALLOUT(a,b,c) \+  pcre2_set_substitute_callout_32(G(a,32), \+    (int (*)(pcre2_substitute_callout_block_32 *, void *))b,c)+#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),h, \+    (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)+#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \+  a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)+#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \+  a = pcre2_substring_copy_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 *)d,e);+#define PCRE2_SUBSTRING_FREE(a) pcre2_substring_free_32((PCRE2_UCHAR32 *)a)+#define PCRE2_SUBSTRING_GET_BYNAME(a,b,c,d,e) \+  a = pcre2_substring_get_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 **)d,e)+#define PCRE2_SUBSTRING_GET_BYNUMBER(a,b,c,d,e) \+  a = pcre2_substring_get_bynumber_32(G(b,32),c,(PCRE2_UCHAR32 **)d,e)+#define PCRE2_SUBSTRING_LENGTH_BYNAME(a,b,c,d) \+    a = pcre2_substring_length_byname_32(G(b,32),G(c,32),d)+#define PCRE2_SUBSTRING_LENGTH_BYNUMBER(a,b,c,d) \+    a = pcre2_substring_length_bynumber_32(G(b,32),c,d)+#define PCRE2_SUBSTRING_LIST_GET(a,b,c,d) \+  a = pcre2_substring_list_get_32(G(b,32),(PCRE2_UCHAR32 ***)c,d)+#define PCRE2_SUBSTRING_LIST_FREE(a) \+  pcre2_substring_list_free_32((PCRE2_SPTR32 *)a)+#define PCRE2_SUBSTRING_NUMBER_FROM_NAME(a,b,c) \+  a = pcre2_substring_number_from_name_32(G(b,32),G(c,32));+#define PTR(x) (void *)G(x,32)+#define SETFLD(x,y,z) G(x,32)->y = z+#define SETFLDVEC(x,y,v,z) G(x,32)->y[v] = z+#define SETOP(x,y,z) G(x,32) z y+#define SETCASTPTR(x,y) G(x,32) = (uint32_t *)(y)+#define STRLEN(p) (int)strlen32((PCRE2_SPTR32)p)+#define SUB1(a,b) G(a,32)(G(b,32))+#define SUB2(a,b,c) G(a,32)(G(b,32),G(c,32))+#define TEST(x,r,y) (G(x,32) r (y))+#define TESTFLD(x,f,r,y) (G(x,32)->f r (y))++#endif++/* ----- End of mode-specific function call macros ----- */+++++/*************************************************+*         Alternate character tables             *+*************************************************/++/* By default, the "tables" pointer in the compile context when calling+pcre2_compile() is not set (= NULL), thereby using the default tables of the+library. However, the tables modifier can be used to select alternate sets of+tables, for different kinds of testing. Note that the locale modifier also+adjusts the tables. */++/* This is the set of tables distributed as default with PCRE2. It recognizes+only ASCII characters. */++static const uint8_t tables1[] = {++/* This table is a lower casing table. */++    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, 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, 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,++/* This table is a case flipping table. */++    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, 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, 91, 92, 93, 94, 95,+   96, 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,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,++/* This table contains bit maps for various character classes. Each map is 32+bytes long and the bits run from the least significant end of each byte. The+classes that have their own maps are: space, xdigit, digit, upper, lower, word,+graph, print, punct, and cntrl. Other classes are built from combinations. */++  0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,+  0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,+  0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,+  0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++/* This table identifies various classes of character by individual bits:+  0x01   white space character+  0x02   letter+  0x04   decimal digit+  0x08   hexadecimal digit+  0x10   alphanumeric or '_'+  0x80   regular expression metacharacter or binary zero+*/++  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */+  0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */+  0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /*    - '  */+  0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /*  ( - /  */+  0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /*  0 - 7  */+  0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /*  8 - ?  */+  0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  @ - G  */+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */+  0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /*  X - _  */+  0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  ` - g  */+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  h - o  */+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  p - w  */+  0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /*  x -127 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */++/* This is a set of tables that came originally from a Windows user. It seems+to be at least an approximation of ISO 8859. In particular, there are+characters greater than 128 that are marked as spaces, letters, etc. */++static const uint8_t tables2[] = {+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,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,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,+224,225,226,227,228,229,230,231,+232,233,234,235,236,237,238,239,+240,241,242,243,244,245,246,215,+248,249,250,251,252,253,254,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,+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,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,91,92,93,94,95,+96,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,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,+224,225,226,227,228,229,230,231,+232,233,234,235,236,237,238,239,+240,241,242,243,244,245,246,215,+248,249,250,251,252,253,254,223,+192,193,194,195,196,197,198,199,+200,201,202,203,204,205,206,207,+208,209,210,211,212,213,214,247,+216,217,218,219,220,221,222,255,+0,62,0,0,1,0,0,0,+0,0,0,0,0,0,0,0,+32,0,0,0,1,0,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,255,3,+126,0,0,0,126,0,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,255,3,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,12,2,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,0,0,+254,255,255,7,0,0,0,0,+0,0,0,0,0,0,0,0,+255,255,127,127,0,0,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,254,255,255,7,+0,0,0,0,0,4,32,4,+0,0,0,128,255,255,127,255,+0,0,0,0,0,0,255,3,+254,255,255,135,254,255,255,7,+0,0,0,0,0,4,44,6,+255,255,127,255,255,255,127,255,+0,0,0,0,254,255,255,255,+255,255,255,255,255,255,255,127,+0,0,0,0,254,255,255,255,+255,255,255,255,255,255,255,255,+0,2,0,0,255,255,255,255,+255,255,255,255,255,255,255,127,+0,0,0,0,255,255,255,255,+255,255,255,255,255,255,255,255,+0,0,0,0,254,255,0,252,+1,0,0,248,1,0,0,120,+0,0,0,0,254,255,255,255,+0,0,128,0,0,0,128,0,+255,255,255,255,0,0,0,0,+0,0,0,0,0,0,0,128,+255,255,255,255,0,0,0,0,+0,0,0,0,0,0,0,0,+128,0,0,0,0,0,0,0,+0,1,1,0,1,1,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,0,0,+1,0,0,0,128,0,0,0,+128,128,128,128,0,0,128,0,+28,28,28,28,28,28,28,28,+28,28,0,0,0,0,0,128,+0,26,26,26,26,26,26,18,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,18,+18,18,18,128,128,0,128,16,+0,26,26,26,26,26,26,18,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,18,+18,18,18,128,128,0,0,0,+0,0,0,0,0,1,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,0,0,+0,0,0,0,0,0,0,0,+1,0,0,0,0,0,0,0,+0,0,18,0,0,0,0,0,+0,0,20,20,0,18,0,0,+0,20,18,0,0,0,0,0,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,0,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,18,+18,18,18,18,18,18,18,0,+18,18,18,18,18,18,18,18+};++++#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)+/*************************************************+*    Emulated memmove() for systems without it   *+*************************************************/++/* This function can make use of bcopy() if it is available. Otherwise do it by+steam, as there are some non-Unix environments that lack both memmove() and+bcopy(). */++static void *+emulated_memmove(void *d, const void *s, size_t n)+{+#ifdef HAVE_BCOPY+bcopy(s, d, n);+return d;+#else+size_t i;+unsigned char *dest = (unsigned char *)d;+const unsigned char *src = (const unsigned char *)s;+if (dest > src)+  {+  dest += n;+  src += n;+  for (i = 0; i < n; ++i) *(--dest) = *(--src);+  return (void *)dest;+  }+else+  {+  for (i = 0; i < n; ++i) *dest++ = *src++;+  return (void *)(dest - n);+  }+#endif   /* not HAVE_BCOPY */+}+#undef memmove+#define memmove(d,s,n) emulated_memmove(d,s,n)+#endif   /* not VPCOMPAT && not HAVE_MEMMOVE */++++#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              *+*************************************************/++/* Alternative memory functions, to test functionality. */++static void *my_malloc(PCRE2_SIZE size, void *data)+{+void *block = malloc(size);+(void)data;+if (show_memory)+  {+  if (block == NULL)+    {+    fprintf(outfile, "** malloc() failed for %" SIZ_FORM "\n", SIZ_CAST size);+    }+  else+    {+    fprintf(outfile, "malloc  %5" SIZ_FORM, SIZ_CAST 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;+}++static void my_free(void *block, void *data)+{+(void)data;+if (show_memory)+  {+  uint32_t i, j;+  BOOL found = FALSE;++  fprintf(outfile, "free");+  for (i = 0; i < malloclistptr; i++)+    {+    if (block == malloclist[i])+      {+      fprintf(outfile, "    %5" SIZ_FORM, SIZ_CAST 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);+}++++/*************************************************+*       Callback function for stack guard        *+*************************************************/++/* This is set up to be called from pcre2_compile() when the stackguard=n+modifier sets a value greater than zero. The test we do is whether the+parenthesis nesting depth is greater than the value set by the modifier.++Argument:  the current parenthesis nesting depth+Returns:   non-zero to kill the compilation+*/++static int+stack_guard(uint32_t depth, void *user_data)+{+(void)user_data;+return depth > pat_patctl.stackguard_test;+}+++/*************************************************+*         JIT memory callback                    *+*************************************************/++static PCRE2_JIT_STACK*+jit_callback(void *arg)+{+jit_was_used = TRUE;+return (PCRE2_JIT_STACK *)arg;+}+++/*************************************************+*      Convert UTF-8 character to code point     *+*************************************************/++/* This function reads one or more bytes that represent a UTF-8 character,+and returns the codepoint of that character. Note that the function supports+the original UTF-8 definition of RFC 2279, allowing for values in the range 0+to 0x7fffffff, up to 6 bytes long. This makes it possible to generate+codepoints greater than 0x10ffff which are useful for testing PCRE2's error+checking, and also for generating 32-bit non-UTF data values above the UTF+limit.++Argument:+  utf8bytes   a pointer to the byte vector+  vptr        a pointer to an int to receive the value++Returns:      >  0 => the number of bytes consumed+              -6 to 0 => malformed UTF-8 character at offset = (-return)+*/++static int+utf82ord(PCRE2_SPTR8 utf8bytes, uint32_t *vptr)+{+uint32_t c = *utf8bytes++;+uint32_t d = c;+int i, j, s;++for (i = -1; i < 6; i++)               /* i is number of additional bytes */+  {+  if ((d & 0x80) == 0) break;+  d <<= 1;+  }++if (i == -1) { *vptr = c; return 1; }  /* ascii character */+if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */++/* i now has a value in the range 1-5 */++s = 6*i;+d = (c & utf8_table3[i]) << s;++for (j = 0; j < i; j++)+  {+  c = *utf8bytes++;+  if ((c & 0xc0) != 0x80) return -(j+1);+  s -= 6;+  d |= (c & 0x3f) << s;+  }++/* Check that encoding was the correct unique one */++for (j = 0; j < utf8_table1_size; j++)+  if (d <= (uint32_t)utf8_table1[j]) break;+if (j != i) return -(i+1);++/* Valid value */++*vptr = d;+return i+1;+}++++/*************************************************+*             Print one character                *+*************************************************/++/* Print a single character either literally, or as a hex escape, and count how+many printed characters are used.++Arguments:+  c            the character+  utf          TRUE in UTF mode+  f            the FILE to print to, or NULL just to count characters++Returns:       number of characters written+*/++static int+pchar(uint32_t c, BOOL utf, FILE *f)+{+int n = 0;+char tempbuffer[16];++if (PRINTOK(c))+  {+  if (f != NULL) fprintf(f, "%c", c);+  return 1;+  }++if (c < 0x100)+  {+  if (utf)+    {+    if (f != NULL) fprintf(f, "\\x{%02x}", c);+    return 6;+    }+  else+    {+    if (f != NULL) fprintf(f, "\\x%02x", c);+    return 4;+    }+  }++if (f != NULL) n = fprintf(f, "\\x{%02x}", c);+  else n = sprintf(tempbuffer, "\\x{%02x}", c);++return n >= 0 ? n : 0;+}++++#ifdef SUPPORT_PCRE2_16+/*************************************************+*    Find length of 0-terminated 16-bit string   *+*************************************************/++static size_t strlen16(PCRE2_SPTR16 p)+{+PCRE2_SPTR16 pp = p;+while (*pp != 0) pp++;+return (int)(pp - p);+}+#endif  /* SUPPORT_PCRE2_16 */++++#ifdef SUPPORT_PCRE2_32+/*************************************************+*    Find length of 0-terminated 32-bit string   *+*************************************************/++static size_t strlen32(PCRE2_SPTR32 p)+{+PCRE2_SPTR32 pp = p;+while (*pp != 0) pp++;+return (int)(pp - p);+}+#endif  /* SUPPORT_PCRE2_32 */+++#ifdef SUPPORT_PCRE2_8+/*************************************************+*         Print 8-bit character string           *+*************************************************/++/* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.+For printing *MARK strings, a negative length is given, indicating that the+length is in the first code unit. If handed a NULL file, this function just+counts chars without printing (because pchar() does that). */++static int pchars8(PCRE2_SPTR8 p, int length, BOOL utf, FILE *f)+{+uint32_t c = 0;+int yield = 0;+if (length < 0) length = *p++;+while (length-- > 0)+  {+  if (utf)+    {+    int rc = utf82ord(p, &c);+    if (rc > 0 && rc <= length + 1)   /* Mustn't run over the end */+      {+      length -= rc - 1;+      p += rc;+      yield += pchar(c, utf, f);+      continue;+      }+    }+  c = *p++;+  yield += pchar(c, utf, f);+  }++return yield;+}+#endif+++#ifdef SUPPORT_PCRE2_16+/*************************************************+*           Print 16-bit character string        *+*************************************************/++/* Must handle UTF-16 strings in utf mode. Yields number of characters printed.+For printing *MARK strings, a negative length is given, indicating that the+length is in the first code unit. If handed a NULL file, just counts chars+without printing. */++static int pchars16(PCRE2_SPTR16 p, int length, BOOL utf, FILE *f)+{+int yield = 0;+if (length < 0) length = *p++;+while (length-- > 0)+  {+  uint32_t c = *p++ & 0xffff;+  if (utf && c >= 0xD800 && c < 0xDC00 && length > 0)+    {+    int d = *p & 0xffff;+    if (d >= 0xDC00 && d <= 0xDFFF)+      {+      c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;+      length--;+      p++;+      }+    }+  yield += pchar(c, utf, f);+  }+return yield;+}+#endif  /* SUPPORT_PCRE2_16 */++++#ifdef SUPPORT_PCRE2_32+/*************************************************+*           Print 32-bit character string        *+*************************************************/++/* Must handle UTF-32 strings in utf mode. Yields number of characters printed.+For printing *MARK strings, a negative length is given, indicating that the+length is in the first code unit. 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++;+while (length-- > 0)+  {+  uint32_t c = *p++;+  yield += pchar(c, utf, f);+  }+return yield;+}+#endif  /* SUPPORT_PCRE2_32 */+++++/*************************************************+*       Convert character value to UTF-8         *+*************************************************/++/* This function takes an integer value in the range 0 - 0x7fffffff+and encodes it as a UTF-8 character in 0 to 6 bytes. It is needed even when the+8-bit library is not supported, to generate UTF-8 output for non-ASCII+characters.++Arguments:+  cvalue     the character value+  utf8bytes  pointer to buffer for result - at least 6 bytes long++Returns:     number of characters placed in the buffer+*/++static int+ord2utf8(uint32_t cvalue, uint8_t *utf8bytes)+{+int i, j;+if (cvalue > 0x7fffffffu)+  return -1;+for (i = 0; i < utf8_table1_size; i++)+  if (cvalue <= (uint32_t)utf8_table1[i]) break;+utf8bytes += i;+for (j = i; j > 0; j--)+ {+ *utf8bytes-- = 0x80 | (cvalue & 0x3f);+ cvalue >>= 6;+ }+*utf8bytes = utf8_table2[i] | cvalue;+return i + 1;+}++++#ifdef SUPPORT_PCRE2_16+/*************************************************+*           Convert string to 16-bit             *+*************************************************/++/* 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,+for the purpose of testing that they are correctly faulted.++Arguments:+  p          points to a byte string+  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+               data items used (excluding the trailing zero)+             OR -1 if a UTF-8 string is malformed+             OR -2 if a value > 0x10ffff is encountered in UTF mode+             OR -3 if a value > 0xffff is encountered when not in UTF mode+*/++static PCRE2_SIZE+to16(uint8_t *p, int utf, PCRE2_SIZE *lenptr)+{+uint16_t *pp;+PCRE2_SIZE len = *lenptr;++if (pbuffer16_size < 2*len + 2)+  {+  if (pbuffer16 != NULL) free(pbuffer16);+  pbuffer16_size = 2*len + 2;+  if (pbuffer16_size < 4096) pbuffer16_size = 4096;+  pbuffer16 = (uint16_t *)malloc(pbuffer16_size);+  if (pbuffer16 == NULL)+    {+    fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer16\n",+      SIZ_CAST pbuffer16_size);+    exit(1);+    }+  }++pp = pbuffer16;+if (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)+  {+  for (; len > 0; len--) *pp++ = *p++;+  }+else while (len > 0)+  {+  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+    {+    c -= 0x10000;+    *pp++ = 0xD800 | (c >> 10);+    *pp++ = 0xDC00 | (c & 0x3ff);+    }+  }++*pp = 0;+*lenptr = pp - pbuffer16;+return 0;+}+#endif++++#ifdef SUPPORT_PCRE2_32+/*************************************************+*           Convert string to 32-bit             *+*************************************************/++/* 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,+for the purpose of testing that they are correctly faulted.++Arguments:+  p          points to a byte string+  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+               data items used (excluding the trailing zero)+             OR -1 if a UTF-8 string is malformed+             OR -2 if a value > 0x10ffff is encountered in UTF mode+*/++static PCRE2_SIZE+to32(uint8_t *p, int utf, PCRE2_SIZE *lenptr)+{+uint32_t *pp;+PCRE2_SIZE len = *lenptr;++if (pbuffer32_size < 4*len + 4)+  {+  if (pbuffer32 != NULL) free(pbuffer32);+  pbuffer32_size = 4*len + 4;+  if (pbuffer32_size < 8192) pbuffer32_size = 8192;+  pbuffer32 = (uint32_t *)malloc(pbuffer32_size);+  if (pbuffer32 == NULL)+    {+    fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer32\n",+      SIZ_CAST pbuffer32_size);+    exit(1);+    }+  }++pp = pbuffer32;++if (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)+  {+  for (; len > 0; len--) *pp++ = *p++;+  }++else while (len > 0)+  {+  int chlen;+  uint32_t 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 | topbit;+  }++*pp = 0;+*lenptr = pp - pbuffer32;+return 0;+}+#endif /* SUPPORT_PCRE2_32 */++++/* This function is no longer used. Keep it around for a while, just in case it+needs to be re-instated. */++#ifdef NEVERNEVERNEVER++/*************************************************+*         Move back by so many characters        *+*************************************************/++/* Given a code unit offset in a subject string, move backwards by a number of+characters, and return the resulting offset.++Arguments:+  subject   pointer to the string+  offset    start offset+  count     count to move back by+  utf       TRUE if in UTF mode++Returns:   a possibly changed offset+*/++static PCRE2_SIZE+backchars(uint8_t *subject, PCRE2_SIZE offset, uint32_t count, BOOL utf)+{+if (!utf || test_mode == PCRE32_MODE)+  return (count >= offset)? 0 : (offset - count);++else if (test_mode == PCRE8_MODE)+  {+  PCRE2_SPTR8 pp = (PCRE2_SPTR8)subject + offset;+  for (; count > 0 && pp > (PCRE2_SPTR8)subject; count--)+    {+    pp--;+    while ((*pp & 0xc0) == 0x80) pp--;+    }+  return pp - (PCRE2_SPTR8)subject;+  }++else  /* 16-bit mode */+  {+  PCRE2_SPTR16 pp = (PCRE2_SPTR16)subject + offset;+  for (; count > 0 && pp > (PCRE2_SPTR16)subject; count--)+    {+    pp--;+    if ((*pp & 0xfc00) == 0xdc00) pp--;+    }+  return pp - (PCRE2_SPTR16)subject;+  }+}+#endif  /* NEVERNEVERNEVER */++++/*************************************************+*           Expand input buffers                 *+*************************************************/++/* This function doubles the size of the input buffer and the buffer for+keeping an 8-bit copy of patterns (pbuffer8), and copies the current buffers to+the new ones.++Arguments: none+Returns:   nothing (aborts if malloc() fails)+*/++static void+expand_input_buffers(void)+{+int new_pbuffer8_size = 2*pbuffer8_size;+uint8_t *new_buffer = (uint8_t *)malloc(new_pbuffer8_size);+uint8_t *new_pbuffer8 = (uint8_t *)malloc(new_pbuffer8_size);++if (new_buffer == NULL || new_pbuffer8 == NULL)+  {+  fprintf(stderr, "pcre2test: malloc(%d) failed\n", new_pbuffer8_size);+  exit(1);+  }++memcpy(new_buffer, buffer, pbuffer8_size);+memcpy(new_pbuffer8, pbuffer8, pbuffer8_size);++pbuffer8_size = new_pbuffer8_size;++free(buffer);+free(pbuffer8);++buffer = new_buffer;+pbuffer8 = new_pbuffer8;+}++++/*************************************************+*        Read or extend an input line            *+*************************************************/++/* Input lines are read into buffer, but both patterns and data lines can be+continued over multiple input lines. In addition, if the buffer fills up, we+want to automatically expand it so as to be able to handle extremely large+lines that are needed for certain stress tests, although this is less likely+now that there are repetition features for both patterns and data. When the+input buffer is expanded, the other two buffers must also be expanded likewise,+and the contents of pbuffer, which are a copy of the input for callouts, must+be preserved (for when expansion happens for a data line). This is not the most+optimal way of handling this, but hey, this is just a test program!++Arguments:+  f            the file to read+  start        where in buffer to start (this *must* be within buffer)+  prompt       for stdin or readline()++Returns:       pointer to the start of new data+               could be a copy of start, or could be moved+               NULL if no data read and EOF reached+*/++static uint8_t *+extend_inputline(FILE *f, uint8_t *start, const char *prompt)+{+uint8_t *here = start;++for (;;)+  {+  size_t rlen = (size_t)(pbuffer8_size - (here - buffer));++  if (rlen > 1000)+    {+    size_t dlen;++    /* If libreadline or libedit support is required, use readline() to read a+    line if the input is a terminal. Note that readline() removes the trailing+    newline, so we must put it back again, to be compatible with fgets(). */++#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+    if (INTERACTIVE(f))+      {+      size_t len;+      char *s = readline(prompt);+      if (s == NULL) return (here == start)? NULL : start;+      len = strlen(s);+      if (len > 0) add_history(s);+      if (len > rlen - 1) len = rlen - 1;+      memcpy(here, s, len);+      here[len] = '\n';+      here[len+1] = 0;+      free(s);+      }+    else+#endif++    /* Read the next line by normal means, prompting if the file is a tty. */++      {+      if (INTERACTIVE(f)) printf("%s", prompt);+      if (fgets((char *)here, rlen,  f) == NULL)+        return (here == start)? NULL : start;+      }++    dlen = strlen((char *)here);+    here += dlen;++    /* Check for end of line reached. Take care not to read data from before+    start (dlen will be zero for a file starting with a binary zero). */++    if (here > start && here[-1] == '\n') return start;++    /* If we have not read a newline when reading a file, we have either filled+    the buffer or reached the end of the file. We can detect the former by+    checking that the string fills the buffer, and the latter by feof(). If+    neither of these is true, it means we read a binary zero which has caused+    strlen() to give a short length. This is a hard error because pcre2test+    expects to work with C strings. */++    if (!INTERACTIVE(f) && dlen < rlen - 1 && !feof(f))+      {+      fprintf(outfile, "** Binary zero encountered in input\n");+      fprintf(outfile, "** pcre2test run abandoned\n");+      exit(1);+      }+    }++  else+    {+    size_t start_offset = start - buffer;+    size_t here_offset = here - buffer;+    expand_input_buffers();+    start = buffer + start_offset;+    here = buffer + here_offset;+    }+  }++/* Control never gets here */+}++++/*************************************************+*         Case-independent strncmp() function    *+*************************************************/++/*+Arguments:+  s         first string+  t         second string+  n         number of characters to compare++Returns:    < 0, = 0, or > 0, according to the comparison+*/++static int+strncmpic(const uint8_t *s, const uint8_t *t, int n)+{+while (n--)+  {+  int c = tolower(*s++) - tolower(*t++);+  if (c != 0) return c;+  }+return 0;+}++++/*************************************************+*          Scan the main modifier list           *+*************************************************/++/* This function searches the modifier list for a long modifier name.++Argument:+  p         start of the name+  lenp      length of the name++Returns:    an index in the modifier list, or -1 on failure+*/++static int+scan_modifiers(const uint8_t *p, unsigned int len)+{+int bot = 0;+int top = MODLISTCOUNT;++while (top > bot)+  {+  int mid = (bot + top)/2;+  unsigned int mlen = strlen(modlist[mid].name);+  int c = strncmp((char *)p, modlist[mid].name, (len < mlen)? len : mlen);+  if (c == 0)+    {+    if (len == mlen) return mid;+    c = (int)len - (int)mlen;+    }+  if (c > 0) bot = mid + 1; else top = mid;+  }++return -1;++}++++/*************************************************+*        Check a modifer and find its field      *+*************************************************/++/* This function is called when a modifier has been identified. We check that+it is allowed here and find the field that is to be changed.++Arguments:+  m          the modifier list entry+  ctx        CTX_PAT     => pattern context+             CTX_POPPAT  => pattern context for popped pattern+             CTX_DEFPAT  => default pattern context+             CTX_DAT     => data context+             CTX_DEFDAT  => default data context+  pctl       point to pattern control block+  dctl       point to data control block+  c          a single character or 0++Returns:     a field pointer or NULL+*/++static void *+check_modifier(modstruct *m, int ctx, patctl *pctl, datctl *dctl, uint32_t c)+{+void *field = NULL;+PCRE2_SIZE offset = m->offset;++if (restrict_for_perl_test) switch(m->which)+  {+  case MOD_PNDP:+  case MOD_PATP:+  case MOD_PDP:+  break;++  default:+  fprintf(outfile, "** '%s' is not allowed in a Perl-compatible test\n",+    m->name);+  return NULL;+  }++switch (m->which)+  {+  case MOD_CTC:  /* Compile context modifier */+  if (ctx == CTX_DEFPAT) field = PTR(default_pat_context);+    else if (ctx == CTX_PAT) field = PTR(pat_context);+  break;++  case MOD_CTM:  /* Match context modifier */+  if (ctx == CTX_DEFDAT) field = PTR(default_dat_context);+    else if (ctx == CTX_DAT) field = PTR(dat_context);+  break;++  case MOD_DAT:  /* Data line modifier */+  if (dctl != NULL) field = dctl;+  break;++  case MOD_PAT:    /* Pattern modifier */+  case MOD_PATP:   /* Allowed for Perl test */+  if (pctl != NULL) field = pctl;+  break;++  case MOD_PD:   /* Pattern or data line modifier */+  case MOD_PDP:  /* Ditto, allowed for Perl test */+  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 || m->which == MOD_PDP ||+             ctx != CTX_DEFPAT))+      field = pctl;+  break;+  }++if (field == NULL)+  {+  if (c == 0)+    fprintf(outfile, "** '%s' is not valid here\n", m->name);+  else+    fprintf(outfile, "** /%c is not valid here\n", c);+  return NULL;+  }++return (char *)field + offset;+}++++/*************************************************+*            Decode a modifier list              *+*************************************************/++/* A pointer to a control block is NULL when called in cases when that block is+not relevant. They are never all relevant in one call. At least one of patctl+and datctl is NULL. The second argument specifies which context to use for+modifiers that apply to contexts.++Arguments:+  p          point to modifier string+  ctx        CTX_PAT     => pattern context+             CTX_POPPAT  => pattern context for popped pattern+             CTX_DEFPAT  => default pattern context+             CTX_DAT     => data context+             CTX_DEFDAT  => default data context+  pctl       point to pattern control block+  dctl       point to data control block++Returns: TRUE if successful decode, FALSE otherwise+*/++static BOOL+decode_modifiers(uint8_t *p, int ctx, patctl *pctl, datctl *dctl)+{+uint8_t *ep, *pp;+long li;+unsigned long uli;+BOOL first = TRUE;++for (;;)+  {+  void *field;+  modstruct *m;+  BOOL off = FALSE;+  unsigned int i, len;+  int index;+  char *endptr;++  /* Skip white space and commas. */++  while (isspace(*p) || *p == ',') p++;+  if (*p == 0) break;++  /* Find the end of the item; lose trailing whitespace at end of line. */++  for (ep = p; *ep != 0 && *ep != ','; ep++);+  if (*ep == 0)+    {+    while (ep > p && isspace(ep[-1])) ep--;+    *ep = 0;+    }++  /* Remember if the first character is '-'. */++  if (*p == '-')+    {+    off = TRUE;+    p++;+    }++  /* Find the length of a full-length modifier name, and scan for it. */++  pp = p;+  while (pp < ep && *pp != '=') pp++;+  index = scan_modifiers(p, pp - p);++  /* If the first modifier is unrecognized, try to interpret it as a sequence+  of single-character abbreviated modifiers. None of these modifiers have any+  associated data. They just set options or control bits. */++  if (index < 0)+    {+    uint32_t cc;+    uint8_t *mp = p;++    if (!first)+      {+      fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p);+      if (ep - p == 1)+        fprintf(outfile, "** Single-character modifiers must come first\n");+      return FALSE;+      }++    for (cc = *p; cc != ',' && cc != '\n' && cc != 0; cc = *(++p))+      {+      for (i = 0; i < C1MODLISTCOUNT; i++)+        if (cc == c1modlist[i].onechar) break;++      if (i >= C1MODLISTCOUNT)+        {+        fprintf(outfile, "** Unrecognized modifier '%c' in '%.*s'\n",+          *p, (int)(ep-mp), mp);+        return FALSE;+        }++      if (c1modlist[i].index >= 0)+        {+        index = c1modlist[i].index;+        }++      else+        {+        index = scan_modifiers((uint8_t *)(c1modlist[i].fullname),+          strlen(c1modlist[i].fullname));+        if (index < 0)+          {+          fprintf(outfile, "** Internal error: single-character equivalent "+            "modifier '%s' not found\n", c1modlist[i].fullname);+          return FALSE;+          }+        c1modlist[i].index = index;     /* Cache for next time */+        }++      field = check_modifier(modlist + index, ctx, pctl, dctl, *p);+      if (field == NULL) return FALSE;++      /* /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 */+    }++  /* We have a match on a full-name modifier. Check for the existence of data+  when needed. */++  m = modlist + index;      /* Save typing */+  if (m->type != MOD_CTL && m->type != MOD_OPT &&+      (m->type != MOD_IND || *pp == '='))+    {+    if (*pp++ != '=')+      {+      fprintf(outfile, "** '=' expected after '%s'\n", m->name);+      return FALSE;+      }+    if (off)+      {+      fprintf(outfile, "** '-' is not valid for '%s'\n", m->name);+      return FALSE;+      }+    }++  /* These on/off types have no data. */++  else if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0)+    {+    fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p);+    return FALSE;+    }++  /* Set the data length for those types that have data. Then find the field+  that is to be set. If check_modifier() returns NULL, it has already output an+  error message. */++  len = ep - pp;+  field = check_modifier(m, ctx, pctl, dctl, 0);+  if (field == NULL) return FALSE;++  /* Process according to data type. */++  switch (m->type)+    {+    case MOD_CTL:+    case MOD_OPT:+    if (off) *((uint32_t *)field) &= ~m->value;+      else *((uint32_t *)field) |= m->value;+    break;++    case MOD_BSR:+    if (len == 7 && strncmpic(pp, (const uint8_t *)"default", 7) == 0)+      {+#ifdef BSR_ANYCRLF+      *((uint16_t *)field) = PCRE2_BSR_ANYCRLF;+#else+      *((uint16_t *)field) = PCRE2_BSR_UNICODE;+#endif+      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_BSR_SET;+        else dctl->control2 &= ~CTL2_BSR_SET;+      }+    else+      {+      if (len == 7 && strncmpic(pp, (const uint8_t *)"anycrlf", 7) == 0)+        *((uint16_t *)field) = PCRE2_BSR_ANYCRLF;+      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->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);+    if (U32OVERFLOW(uli)) goto INVALID_VALUE;+    ((uint32_t *)field)[0] = (uint32_t)uli;+    if (*endptr == ':')+      {+      uli = strtoul((const char *)endptr+1, &endptr, 10);+      if (U32OVERFLOW(uli)) goto INVALID_VALUE;+      ((uint32_t *)field)[1] = (uint32_t)uli;+      }+    else ((uint32_t *)field)[1] = 0;+    pp = (uint8_t *)endptr;+    break;++    /* PCRE2_SIZE_MAX is usually SIZE_MAX, which may be greater, equal to, or+    less than ULONG_MAX. So first test for overflowing the long int, and then+    test for overflowing PCRE2_SIZE_MAX if it is smaller than ULONG_MAX. */++    case MOD_SIZ:    /* PCRE2_SIZE value */+    if (!isdigit(*pp)) goto INVALID_VALUE;+    uli = strtoul((const char *)pp, &endptr, 10);+    if (uli == ULONG_MAX) goto INVALID_VALUE;+#if ULONG_MAX > PCRE2_SIZE_MAX+    if (uli > PCRE2_SIZE_MAX) goto INVALID_VALUE;+#endif+    *((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli;+    pp = (uint8_t *)endptr;+    break;++    case MOD_IND:    /* Unsigned integer with default */+    if (len == 0)+      {+      *((uint32_t *)field) = (uint32_t)(m->value);+      break;+      }+    /* Fall through */++    case MOD_INT:    /* Unsigned integer */+    if (!isdigit(*pp)) goto INVALID_VALUE;+    uli = strtoul((const char *)pp, &endptr, 10);+    if (U32OVERFLOW(uli)) goto INVALID_VALUE;+    *((uint32_t *)field) = (uint32_t)uli;+    pp = (uint8_t *)endptr;+    break;++    case MOD_INS:   /* Signed integer */+    if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE;+    li = strtol((const char *)pp, &endptr, 10);+    if (S32OVERFLOW(li)) goto INVALID_VALUE;+    *((int32_t *)field) = (int32_t)li;+    pp = (uint8_t *)endptr;+    break;++    case MOD_NL:+    for (i = 0; i < sizeof(newlines)/sizeof(char *); i++)+      if (len == strlen(newlines[i]) &&+        strncmpic(pp, (const uint8_t *)newlines[i], len) == 0) break;+    if (i >= sizeof(newlines)/sizeof(char *)) goto INVALID_VALUE;+    if (i == 0)+      {+      *((uint16_t *)field) = NEWLINE_DEFAULT;+      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->control2 |= CTL2_NL_SET;+        else dctl->control2 |= CTL2_NL_SET;+      }+    pp = ep;+    break;++    case MOD_NN:              /* Name or (signed) number; may be several */+    if (isdigit(*pp) || *pp == '-')+      {+      int ct = MAXCPYGET - 1;+      int32_t value;+      li = strtol((const char *)pp, &endptr, 10);+      if (S32OVERFLOW(li)) goto INVALID_VALUE;+      value = (int32_t)li;+      field = (char *)field - m->offset + m->value;      /* Adjust field ptr */+      if (value >= 0)                                    /* Add new number */+        {+        while (*((int32_t *)field) >= 0 && ct-- > 0)   /* Skip previous */+          field = (char *)field + sizeof(int32_t);+        if (ct <= 0)+          {+          fprintf(outfile, "** Too many numeric '%s' modifiers\n", m->name);+          return FALSE;+          }+        }+      *((int32_t *)field) = value;+      if (ct > 0) ((int32_t *)field)[1] = -1;+      pp = (uint8_t *)endptr;+      }++    /* Multiple strings are put end to end. */++    else+      {+      char *nn = (char *)field;+      if (len > 0)                    /* Add new name */+        {+        if (len > MAX_NAME_SIZE)+          {+          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);+        }+      nn[len] = 0 ;+      nn[len+1] = 0;+      pp = ep;+      }+    break;++    case MOD_STR:+    if (len + 1 > m->value)+      {+      fprintf(outfile, "** Overlong value for '%s' (max %d code units)\n",+        m->name, m->value - 1);+      return FALSE;+      }+    memcpy(field, pp, len);+    ((uint8_t *)field)[len] = 0;+    pp = ep;+    break;+    }++  if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0)+    {+    fprintf(outfile, "** Comma expected after modifier item '%s'\n", m->name);+    return FALSE;+    }++  p = pp;+  first = FALSE;++  if (ctx == CTX_POPPAT &&+     (pctl->options != 0 ||+      pctl->tables_id != 0 ||+      pctl->locale[0] != 0 ||+      (pctl->control & NOTPOP_CONTROLS) != 0))+    {+    fprintf(outfile, "** '%s' is not valid here\n", m->name);+    return FALSE;+    }+  }++return TRUE;++INVALID_VALUE:+fprintf(outfile, "** Invalid value in '%.*s'\n", (int)(ep-p), p);+return FALSE;+}+++/*************************************************+*             Get info from a pattern            *+*************************************************/++/* A wrapped call to pcre2_pattern_info(), applied to the current compiled+pattern.++Arguments:+  what        code for the required information+  where       where to put the answer+  unsetok     PCRE2_ERROR_UNSET is an "expected" result++Returns:      the return from pcre2_pattern_info()+*/++static int+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)+  {+  fprintf(outfile, "Error %d from pcre2_pattern_info_%d(%d)\n", rc, test_mode,+    what);+  if (rc == PCRE2_ERROR_BADMODE)+    fprintf(outfile, "Running in %d-bit mode but pattern was compiled in "+      "%d-bit mode\n", test_mode,+      8 * (FLD(compiled_code, flags) & PCRE2_MODE_MASK));+  }+return rc;+}++++#ifdef SUPPORT_PCRE2_8+/*************************************************+*             Show something in a list           *+*************************************************/++/* This function just helps to keep the code that uses it tidier. It's used for+various lists of things where there needs to be introductory text before the+first item. As these calls are all in the POSIX-support code, they happen only+when 8-bit mode is supported. */++static void+prmsg(const char **msg, const char *s)+{+fprintf(outfile, "%s %s", *msg, s);+*msg = "";+}+#endif  /* SUPPORT_PCRE2_8 */++++/*************************************************+*                Show control bits               *+*************************************************/++/* Called for mutually exclusive controls and for unsupported POSIX controls.+Because the bits are unique, this can be used for both pattern and data control+words.++Arguments:+  controls    control bits+  controls2   more control bits+  before      text to print before++Returns:      nothing+*/++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%s%s%s%s%s%s%s%s%s%s%s",+  before,+  ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "",+  ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "",+  ((controls & CTL_ALLCAPTURES) != 0)? " allcaptures" : "",+  ((controls & CTL_ALLUSEDTEXT) != 0)? " allusedtext" : "",+  ((controls2 & CTL2_ALLVECTOR) != 0)? " allvector" : "",+  ((controls & CTL_ALTGLOBAL) != 0)? " altglobal" : "",+  ((controls & CTL_BINCODE) != 0)? " bincode" : "",+  ((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" : "",+  ((controls & CTL_HEXPAT) != 0)? " hex" : "",+  ((controls & CTL_INFO) != 0)? " info" : "",+  ((controls & CTL_JITFAST) != 0)? " jitfast" : "",+  ((controls & CTL_JITVERIFY) != 0)? " jitverify" : "",+  ((controls & CTL_MARK) != 0)? " mark" : "",+  ((controls & CTL_MEMORY) != 0)? " memory" : "",+  ((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_CALLOUT) != 0)? " substitute_callout" : "",+  ((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "",+  ((controls2 & CTL2_SUBSTITUTE_LITERAL) != 0)? " substitute_literal" : "",+  ((controls2 & CTL2_SUBSTITUTE_MATCHED) != 0)? " substitute_matched" : "",+  ((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "",+  ((controls2 & CTL2_SUBSTITUTE_REPLACEMENT_ONLY) != 0)? " substitute_replacement_only" : "",+  ((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" : "");+}++++/*************************************************+*                Show compile 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_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%s%s%s%s",+  before,+  ((options & PCRE2_ALT_BSUX) != 0)? " alt_bsux" : "",+  ((options & PCRE2_ALT_CIRCUMFLEX) != 0)? " alt_circumflex" : "",+  ((options & PCRE2_ALT_VERBNAMES) != 0)? " alt_verbnames" : "",+  ((options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? " allow_empty_class" : "",+  ((options & PCRE2_ANCHORED) != 0)? " anchored" : "",+  ((options & PCRE2_AUTO_CALLOUT) != 0)? " auto_callout" : "",+  ((options & PCRE2_CASELESS) != 0)? " caseless" : "",+  ((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_INVALID_UTF) != 0)? " match_invalid_utf" : "",+  ((options & PCRE2_MATCH_UNSET_BACKREF) != 0)? " match_unset_backref" : "",+  ((options & PCRE2_MULTILINE) != 0)? " multiline" : "",+  ((options & PCRE2_NEVER_BACKSLASH_C) != 0)? " never_backslash_c" : "",+  ((options & PCRE2_NEVER_UCP) != 0)? " never_ucp" : "",+  ((options & PCRE2_NEVER_UTF) != 0)? " never_utf" : "",+  ((options & PCRE2_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",+  ((options & PCRE2_NO_AUTO_POSSESS) != 0)? " no_auto_possess" : "",+  ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? " no_dotstar_anchor" : "",+  ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",+  ((options & PCRE2_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",+  ((options & PCRE2_UCP) != 0)? " ucp" : "",+  ((options & PCRE2_UNGREEDY) != 0)? " ungreedy" : "",+  ((options & PCRE2_USE_OFFSET_LIMIT) != 0)? " use_offset_limit" : "",+  ((options & PCRE2_UTF) != 0)? " utf" : "",+  after);+}+++/*************************************************+*           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%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_ALT_BSUX) != 0)? " extra_alt_bsux" : "",+  ((options & PCRE2_EXTRA_MATCH_WORD) != 0)? " match_word" : "",+  ((options & PCRE2_EXTRA_MATCH_LINE) != 0)? " match_line" : "",+  ((options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0)? " escaped_cr_is_lf" : "",+  after);+}++++#ifdef SUPPORT_PCRE2_8+/*************************************************+*                Show match options              *+*************************************************/++/* Called for unsupported POSIX options. */++static void+show_match_options(uint32_t options)+{+fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s",+  ((options & PCRE2_ANCHORED) != 0)? " anchored" : "",+  ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)? " copy_matched_subject" : "",+  ((options & PCRE2_DFA_RESTART) != 0)? " dfa_restart" : "",+  ((options & PCRE2_DFA_SHORTEST) != 0)? " dfa_shortest" : "",+  ((options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",+  ((options & PCRE2_NO_JIT) != 0)? " no_jit" : "",+  ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",+  ((options & PCRE2_NOTBOL) != 0)? " notbol" : "",+  ((options & PCRE2_NOTEMPTY) != 0)? " notempty" : "",+  ((options & PCRE2_NOTEMPTY_ATSTART) != 0)? " notempty_atstart" : "",+  ((options & PCRE2_NOTEOL) != 0)? " noteol" : "",+  ((options & PCRE2_PARTIAL_HARD) != 0)? " partial_hard" : "",+  ((options & PCRE2_PARTIAL_SOFT) != 0)? " partial_soft" : "");+}+#endif  /* SUPPORT_PCRE2_8 */++++/*************************************************+*      Show memory usage info for a pattern      *+*************************************************/++static void+show_memory_info(void)+{+uint32_t name_count, name_entry_size;+size_t size, cblock_size;++/* One of the test_mode values will always be true, but to stop a compiler+warning we must initialize cblock_size. */++cblock_size = 0;+#ifdef SUPPORT_PCRE2_8+if (test_mode == PCRE8_MODE) cblock_size = sizeof(pcre2_real_code_8);+#endif+#ifdef SUPPORT_PCRE2_16+if (test_mode == PCRE16_MODE) cblock_size = sizeof(pcre2_real_code_16);+#endif+#ifdef SUPPORT_PCRE2_32+if (test_mode == PCRE32_MODE) cblock_size = sizeof(pcre2_real_code_32);+#endif++(void)pattern_info(PCRE2_INFO_SIZE, &size, FALSE);+(void)pattern_info(PCRE2_INFO_NAMECOUNT, &name_count, FALSE);+(void)pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size, FALSE);+fprintf(outfile, "Memory allocation (code space): %d\n",+  (int)(size - name_count*name_entry_size*code_unit_size - cblock_size));+if (pat_patctl.jit != 0)+  {+  (void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE);+  fprintf(outfile, "Memory allocation (JIT code): %d\n", (int)size);+  }+}++++/*************************************************+*       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  *+*************************************************/++/* The only differences in the callout emumeration 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:+  cb            pointer to enumerate block+  callout_data  user data++Returns:    0+*/++static int callout_callback(pcre2_callout_enumerate_block_8 *cb,+  void *callout_data)+{+uint32_t i;+BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;++(void)callout_data;  /* Not currently displayed */++fprintf(outfile, "Callout ");+if (cb->callout_string != NULL)+  {+  uint32_t delimiter = CODE_UNIT(cb->callout_string, -1);+  fprintf(outfile, "%c", delimiter);+  PCHARSV(cb->callout_string, 0,+    cb->callout_string_length, utf, outfile);+  for (i = 0; callout_start_delims[i] != 0; i++)+    if (delimiter == callout_start_delims[i])+      {+      delimiter = callout_end_delims[i];+      break;+      }+  fprintf(outfile, "%c  ", delimiter);+  }+else fprintf(outfile, "%d  ", cb->callout_number);++fprintf(outfile, "%.*s\n",+  (int)((cb->next_item_length == 0)? 1 : cb->next_item_length),+  pbuffer8 + cb->pattern_position);++return 0;+}++++/*************************************************+*        Show information about a pattern        *+*************************************************/++/* This function is called after a pattern has been compiled if any of the+information-requesting controls have been set.++Arguments:  none++Returns:    PR_OK     continue processing next line+            PR_SKIP   skip to a blank line+            PR_ABEND  abort the pcre2test run+*/++static int+show_pattern_info(void)+{+uint32_t compile_options, overall_options, extra_options;+BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;++if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0)+  {+  fprintf(outfile, "------------------------------------------------------------------\n");+  PCRE2_PRINTINT((pat_patctl.control & CTL_FULLBINCODE) != 0);+  }++if ((pat_patctl.control & CTL_INFO) != 0)+  {+  int rc;+  void *nametable;+  uint8_t *start_bits;+  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,+    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:+    match_limit_set = TRUE;+    break;++    case PCRE2_ERROR_UNSET:+    match_limit_set = FALSE;+    break;++    default:+    return PR_ABEND;+    }++  switch(pattern_info(PCRE2_INFO_DEPTHLIMIT, &depth_limit, TRUE))+    {+    case 0:+    depth_limit_set = TRUE;+    break;++    case PCRE2_ERROR_UNSET:+    depth_limit_set = FALSE;+    break;++    default:+    return PR_ABEND;+    }++  /* These info requests should always succeed. */++  if (pattern_info(PCRE2_INFO_BACKREFMAX, &backrefmax, FALSE) ++      pattern_info(PCRE2_INFO_BSR, &bsr_convention, FALSE) ++      pattern_info(PCRE2_INFO_CAPTURECOUNT, &capture_count, FALSE) ++      pattern_info(PCRE2_INFO_FIRSTBITMAP, &start_bits, FALSE) ++      pattern_info(PCRE2_INFO_FIRSTCODEUNIT, &first_cunit, FALSE) ++      pattern_info(PCRE2_INFO_FIRSTCODETYPE, &first_ctype, FALSE) ++      pattern_info(PCRE2_INFO_HASBACKSLASHC, &hasbackslashc, FALSE) ++      pattern_info(PCRE2_INFO_HASCRORLF, &hascrorlf, FALSE) ++      pattern_info(PCRE2_INFO_JCHANGED, &jchanged, FALSE) ++      pattern_info(PCRE2_INFO_LASTCODEUNIT, &last_cunit, FALSE) ++      pattern_info(PCRE2_INFO_LASTCODETYPE, &last_ctype, FALSE) ++      pattern_info(PCRE2_INFO_MATCHEMPTY, &match_empty, FALSE) ++      pattern_info(PCRE2_INFO_MINLENGTH, &minlength, FALSE) ++      pattern_info(PCRE2_INFO_NAMECOUNT, &namecount, FALSE) ++      pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize, FALSE) ++      pattern_info(PCRE2_INFO_NAMETABLE, &nametable, FALSE) ++      pattern_info(PCRE2_INFO_NEWLINE, &newline_convention, FALSE)+      != 0)+    return PR_ABEND;++  fprintf(outfile, "Capture group count = %d\n", capture_count);++  if (backrefmax > 0)+    fprintf(outfile, "Max back reference = %d\n", backrefmax);++  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 (depth_limit_set)+    fprintf(outfile, "Depth limit = %u\n", depth_limit);++  if (namecount > 0)+    {+    fprintf(outfile, "Named capture groups:\n");+    for (; namecount > 0; namecount--)+      {+      int imm2_size = test_mode == PCRE8_MODE ? 2 : 1;+      uint32_t length = (uint32_t)STRLEN(nametable + imm2_size);+      fprintf(outfile, "  ");++      /* In UTF mode the name may be a UTF string containing non-ASCII+      letters and digits. We must output it as a UTF-8 string. In non-UTF mode,+      use the normal string printing functions, which use escapes for all+      non-ASCII characters. */++      if (utf)+        {+#ifdef SUPPORT_PCRE2_32+        if (test_mode == PCRE32_MODE)+          {+          PCRE2_SPTR32 nameptr = (PCRE2_SPTR32)nametable + imm2_size;+          while (*nameptr != 0)+            {+            uint8_t u8buff[6];+            int len = ord2utf8(*nameptr++, u8buff);+            fprintf(outfile, "%.*s", len, u8buff);+            }+          }+#endif+#ifdef SUPPORT_PCRE2_16+        if (test_mode == PCRE16_MODE)+          {+          PCRE2_SPTR16 nameptr = (PCRE2_SPTR16)nametable + imm2_size;+          while (*nameptr != 0)+            {+            int len;+            uint8_t u8buff[6];+            uint32_t c = *nameptr++ & 0xffff;+            if (c >= 0xD800 && c < 0xDC00)+              c = ((c & 0x3ff) << 10) + (*nameptr++ & 0x3ff) + 0x10000;+            len = ord2utf8(c, u8buff);+            fprintf(outfile, "%.*s", len, u8buff);+            }+          }+#endif+#ifdef SUPPORT_PCRE2_8+        if (test_mode == PCRE8_MODE)+          fprintf(outfile, "%s", (PCRE2_SPTR8)nametable + imm2_size);+#endif+        }+      else  /* Not UTF mode */+        {+        PCHARSV(nametable, imm2_size, length, FALSE, outfile);+        }++      while (length++ < nameentrysize - imm2_size) putc(' ', outfile);++#ifdef SUPPORT_PCRE2_32+      if (test_mode == PCRE32_MODE)+        fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR32)nametable)[0]));+#endif+#ifdef SUPPORT_PCRE2_16+      if (test_mode == PCRE16_MODE)+        fprintf(outfile, "%3d\n", (int)(((PCRE2_SPTR16)nametable)[0]));+#endif+#ifdef SUPPORT_PCRE2_8+      if (test_mode == PCRE8_MODE)+        fprintf(outfile, "%3d\n", (int)(+        ((((PCRE2_SPTR8)nametable)[0]) << 8) | ((PCRE2_SPTR8)nametable)[1]));+#endif++      nametable = (void*)((PCRE2_SPTR8)nametable + nameentrysize * code_unit_size);+      }+    }++  if (hascrorlf)     fprintf(outfile, "Contains explicit CR or LF match\n");+  if (hasbackslashc) fprintf(outfile, "Contains \\C\n");+  if (match_empty)   fprintf(outfile, "May match empty string\n");++  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. */++  if ((pat_patctl.options & PCRE2_NEVER_UTF) == 0)+    {+    compile_options &= ~PCRE2_NEVER_UTF;+    overall_options &= ~PCRE2_NEVER_UTF;+    }++  if ((pat_patctl.options & PCRE2_NEVER_UCP) == 0)+    {+    compile_options &= ~PCRE2_NEVER_UCP;+    overall_options &= ~PCRE2_NEVER_UCP;+    }++  if ((compile_options|overall_options) != 0)+    {+    if (compile_options == overall_options)+      show_compile_options(compile_options, "Options:", "\n");+    else+      {+      show_compile_options(compile_options, "Compile options:", "\n");+      show_compile_options(overall_options, "Overall options:", "\n");+      }+    }++  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.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");++  if ((FLD(compiled_code, flags) & PCRE2_NL_SET) != 0)+    {+    switch (newline_convention)+      {+      case PCRE2_NEWLINE_CR:+      fprintf(outfile, "Forced newline is CR\n");+      break;++      case PCRE2_NEWLINE_LF:+      fprintf(outfile, "Forced newline is LF\n");+      break;++      case PCRE2_NEWLINE_CRLF:+      fprintf(outfile, "Forced newline is CRLF\n");+      break;++      case PCRE2_NEWLINE_ANYCRLF:+      fprintf(outfile, "Forced newline is CR, LF, or CRLF\n");+      break;++      case PCRE2_NEWLINE_ANY:+      fprintf(outfile, "Forced newline is any Unicode newline\n");+      break;++      case PCRE2_NEWLINE_NUL:+      fprintf(outfile, "Forced newline is NUL\n");+      break;++      default:+      break;+      }+    }++  if (first_ctype == 2)+    {+    fprintf(outfile, "First code unit at start or follows newline\n");+    }+  else if (first_ctype == 1)+    {+    const char *caseless =+      ((FLD(compiled_code, flags) & PCRE2_FIRSTCASELESS) == 0)?+      "" : " (caseless)";+    if (PRINTOK(first_cunit))+      fprintf(outfile, "First code unit = \'%c\'%s\n", first_cunit, caseless);+    else+      {+      fprintf(outfile, "First code unit = ");+      pchar(first_cunit, FALSE, outfile);+      fprintf(outfile, "%s\n", caseless);+      }+    }+  else if (start_bits != NULL)+    {+    int i;+    int c = 24;+    fprintf(outfile, "Starting code units: ");+    for (i = 0; i < 256; i++)+      {+      if ((start_bits[i/8] & (1u << (i&7))) != 0)+        {+        if (c > 75)+          {+          fprintf(outfile, "\n  ");+          c = 2;+          }+        if (PRINTOK(i) && i != ' ')+          {+          fprintf(outfile, "%c ", i);+          c += 2;+          }+        else+          {+          fprintf(outfile, "\\x%02x ", i);+          c += 5;+          }+        }+      }+    fprintf(outfile, "\n");+    }++  if (last_ctype != 0)+    {+    const char *caseless =+      ((FLD(compiled_code, flags) & PCRE2_LASTCASELESS) == 0)?+      "" : " (caseless)";+    if (PRINTOK(last_cunit))+      fprintf(outfile, "Last code unit = \'%c\'%s\n", last_cunit, caseless);+    else+      {+      fprintf(outfile, "Last code unit = ");+      pchar(last_cunit, FALSE, outfile);+      fprintf(outfile, "%s\n", caseless);+      }+    }++  if ((FLD(compiled_code, overall_options) & PCRE2_NO_START_OPTIMIZE) == 0)+    fprintf(outfile, "Subject length lower bound = %d\n", minlength);++  if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)+    {+    if (FLD(compiled_code, executable_jit) != NULL)+      fprintf(outfile, "JIT compilation was successful\n");+    else+      {+#ifdef SUPPORT_JIT+      fprintf(outfile, "JIT compilation was not successful");+      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");+#endif+      }+    }+  }++if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0)+  {+  int errorcode;+  PCRE2_CALLOUT_ENUMERATE(errorcode, callout_callback, 0);+  if (errorcode != 0)+    {+    fprintf(outfile, "Callout enumerate failed: error %d: ", errorcode);+    if (errorcode < 0 && !print_error_message(errorcode, "", "\n"))+      return PR_ABEND;+    return PR_SKIP;+    }+  }++return PR_OK;+}++++/*************************************************+*              Handle serialization error        *+*************************************************/++/* Print an error message after a serialization failure.++Arguments:+  rc         the error code+  msg        an initial message for what failed++Returns:     FALSE if print_error_message() fails+*/++static BOOL+serial_error(int rc, const char *msg)+{+fprintf(outfile, "%s failed: error %d: ", msg, rc);+return print_error_message(rc, "", "\n");+}++++/*************************************************+*        Open file for save/load commands        *+*************************************************/++/* This function decodes the file name and opens the file.++Arguments:+  buffptr     point after the #command+  mode        open mode+  fptr        points to the FILE variable+  name        name of # command++Returns:      PR_OK or PR_ABEND+*/++static int+open_file(uint8_t *buffptr, const char *mode, FILE **fptr, const char *name)+{+char *endf;+char *filename = (char *)buffptr;+while (isspace(*filename)) filename++;+endf = filename + strlen8(filename);+while (endf > filename && isspace(endf[-1])) endf--;++if (endf == filename)+  {+  fprintf(outfile, "** File name expected after %s\n", name);+  return PR_ABEND;+  }++*endf = 0;+*fptr = fopen((const char *)filename, mode);+if (*fptr == NULL)+  {+  fprintf(outfile, "** Failed to open '%s': %s\n", filename, strerror(errno));+  return PR_ABEND;+  }++return PR_OK;+}++++/*************************************************+*               Process command line             *+*************************************************/++/* This function is called for lines beginning with # and a character that is+not ! or whitespace, when encountered between tests, which means that there is+no compiled pattern (compiled_code is NULL). The line is in buffer.++Arguments:  none++Returns:    PR_OK     continue processing next line+            PR_SKIP   skip to a blank line+            PR_ABEND  abort the pcre2test run+*/++static int+process_command(void)+{+FILE *f;+PCRE2_SIZE serial_size;+size_t i;+int rc, cmd, cmdlen, yield;+uint16_t first_listed_newline;+const char *cmdname;+uint8_t *argptr, *serial;++yield = PR_OK;+cmd = CMD_UNKNOWN;+cmdlen = 0;++for (i = 0; i < cmdlistcount; i++)+  {+  cmdname = cmdlist[i].name;+  cmdlen = strlen(cmdname);+  if (strncmp((char *)(buffer+1), cmdname, cmdlen) == 0 &&+      isspace(buffer[cmdlen+1]))+    {+    cmd = cmdlist[i].value;+    break;+    }+  }++argptr = buffer + cmdlen + 1;++if (restrict_for_perl_test && cmd != CMD_PATTERN && cmd != CMD_SUBJECT)+  {+  fprintf(outfile, "** #%s is not allowed after #perltest\n", cmdname);+  return PR_ABEND;+  }++switch(cmd)+  {+  case CMD_UNKNOWN:+  fprintf(outfile, "** Unknown command: %s", buffer);+  break;++  case CMD_FORBID_UTF:+  forbid_utf = PCRE2_NEVER_UTF|PCRE2_NEVER_UCP;+  break;++  case CMD_PERLTEST:+  restrict_for_perl_test = TRUE;+  break;++  /* Set default pattern modifiers */++  case CMD_PATTERN:+  (void)decode_modifiers(argptr, CTX_DEFPAT, &def_patctl, NULL);+  if (def_patctl.jit == 0 && (def_patctl.control & CTL_JITVERIFY) != 0)+    def_patctl.jit = JIT_DEFAULT;+  break;++  /* Set default subject modifiers */++  case CMD_SUBJECT:+  (void)decode_modifiers(argptr, CTX_DEFDAT, NULL, &def_datctl);+  break;++  /* Check the default newline, and if not one of those listed, set up the+  first one to be forced. An empty list unsets. */++  case CMD_NEWLINE_DEFAULT:+  local_newline_default = 0;   /* Unset */+  first_listed_newline = 0;+  for (;;)+    {+    while (isspace(*argptr)) argptr++;+    if (*argptr == 0) break;+    for (i = 1; i < sizeof(newlines)/sizeof(char *); i++)+      {+      size_t nlen = strlen(newlines[i]);+      if (strncmpic(argptr, (const uint8_t *)newlines[i], nlen) == 0 &&+          isspace(argptr[nlen]))+        {+        if (i == NEWLINE_DEFAULT) return PR_OK;  /* Default is valid */+        if (first_listed_newline == 0) first_listed_newline = i;+        }+      }+    while (*argptr != 0 && !isspace(*argptr)) argptr++;+    }+  local_newline_default = first_listed_newline;+  break;++  /* Pop or copy a compiled pattern off the stack. Modifiers that do not affect+  the compiled pattern (e.g. to give information) are permitted. The default+  pattern modifiers are ignored. */++  case CMD_POP:+  case CMD_POPCOPY:+  if (patstacknext <= 0)+    {+    fprintf(outfile, "** Can't pop off an empty stack\n");+    return PR_SKIP;+    }+  memset(&pat_patctl, 0, sizeof(patctl));   /* Completely unset */+  if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL))+    return PR_SKIP;++  if (cmd == CMD_POP)+    {+    SET(compiled_code, patstack[--patstacknext]);+    }+  else+    {+    PCRE2_CODE_COPY_FROM_VOID(compiled_code, patstack[patstacknext - 1]);+    }++  if (pat_patctl.jit != 0)+    {+    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();+    if (rc != PR_OK) return rc;+    }+  break;++  /* Save the stack of compiled patterns to a file, then empty the stack. */++  case CMD_SAVE:+  if (patstacknext <= 0)+    {+    fprintf(outfile, "** No stacked patterns to save\n");+    return PR_OK;+    }++  rc = open_file(argptr+1, BINARY_OUTPUT_MODE, &f, "#save");+  if (rc != PR_OK) return rc;++  PCRE2_SERIALIZE_ENCODE(rc, patstack, patstacknext, &serial, &serial_size,+    general_context);+  if (rc < 0)+    {+    fclose(f);+    if (!serial_error(rc, "Serialization")) return PR_ABEND;+    break;+    }++  /* Write the length at the start of the file to make it straightforward to+  get the right memory when re-loading. This saves having to read the file size+  in different operating systems. To allow for different endianness (even+  though reloading with the opposite endianness does not work), write the+  length byte-by-byte. */++  for (i = 0; i < 4; i++) fputc((serial_size >> (i*8)) & 255, f);+  if (fwrite(serial, 1, serial_size, f) != serial_size)+    {+    fprintf(outfile, "** Wrong return from fwrite()\n");+    fclose(f);+    return PR_ABEND;+    }++  fclose(f);+  PCRE2_SERIALIZE_FREE(serial);+  while(patstacknext > 0)+    {+    SET(compiled_code, patstack[--patstacknext]);+    SUB1(pcre2_code_free, compiled_code);+    }+  SET(compiled_code, NULL);+  break;++  /* Load a set of compiled patterns from a file onto the stack */++  case CMD_LOAD:+  rc = open_file(argptr+1, BINARY_INPUT_MODE, &f, "#load");+  if (rc != PR_OK) return rc;++  serial_size = 0;+  for (i = 0; i < 4; i++) serial_size |= fgetc(f) << (i*8);++  serial = malloc(serial_size);+  if (serial == NULL)+    {+    fprintf(outfile, "** Failed to get memory (size %" SIZ_FORM ") for #load\n",+      SIZ_CAST serial_size);+    fclose(f);+    return PR_ABEND;+    }++  i = fread(serial, 1, serial_size, f);+  fclose(f);++  if (i != serial_size)+    {+    fprintf(outfile, "** Wrong return from fread()\n");+    yield = PR_ABEND;+    }+  else+    {+    PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(rc, serial);+    if (rc < 0)+      {+      if (!serial_error(rc, "Get number of codes")) yield = PR_ABEND;+      }+    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;++  /* Load a set of binary tables into tables3. */++  case CMD_LOADTABLES:+  rc = open_file(argptr+1, BINARY_INPUT_MODE, &f, "#loadtables");+  if (rc != PR_OK) return rc;++  if (tables3 == NULL)+    {+    (void)PCRE2_CONFIG(PCRE2_CONFIG_TABLES_LENGTH, &loadtables_length);+    tables3 = malloc(loadtables_length);+    }++  if (tables3 == NULL)+    {+    fprintf(outfile, "** Failed: malloc failed for #loadtables\n");+    yield = PR_ABEND;+    }+  else if (fread(tables3, 1, loadtables_length, f) != loadtables_length)+    {+    fprintf(outfile, "** Wrong return from fread()\n");+    yield = PR_ABEND;+    }++  fclose(f);+  break;+  }++return yield;+}++++/*************************************************+*               Process pattern line             *+*************************************************/++/* This function is called when the input buffer contains the start of a+pattern. The first character is known to be a valid delimiter. The pattern is+read, modifiers are interpreted, and a suitable local context is set up for+this test. The pattern is then compiled.++Arguments:  none++Returns:    PR_OK     continue processing next line+            PR_SKIP   skip to a blank line+            PR_ABEND  abort the pcre2test run+*/++static int+process_pattern(void)+{+BOOL utf;+uint32_t k;+uint8_t *p = buffer;+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;++/* The perltest.sh script supports only / as a delimiter. */++if (restrict_for_perl_test && delimiter != '/')+  {+  fprintf(outfile, "** The only allowed delimiter after #perltest is '/'\n");+  return PR_ABEND;  +  } ++/* Initialize the context and pattern/data controls for this test from the+defaults. */++PATCTXCPY(pat_context, default_pat_context);+memcpy(&pat_patctl, &def_patctl, sizeof(patctl));++/* Find the end of the pattern, reading more lines if necessary. */++for(;;)+  {+  while (*p != 0)+    {+    if (*p == '\\' && p[1] != 0) p++;+      else if (*p == delimiter) break;+    p++;+    }+  if (*p != 0) break;+  if ((p = extend_inputline(infile, p, "    > ")) == NULL)+    {+    fprintf(outfile, "** Unexpected EOF\n");+    return PR_ABEND;+    }+  if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)p);+  }++/* If the first character after the delimiter is backslash, make the pattern+end with backslash. This is purely to provide a way of testing for the error+message when a pattern ends with backslash. */++if (p[1] == '\\') *p++ = '\\';++/* Terminate the pattern at the delimiter, and compute the length. */++*p++ = 0;+patlen = p - buffer - 2;++/* Look for modifiers and options after the final delimiter. */++if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP;++/* Note that the match_invalid_utf option also sets utf when passed to+pcre2_compile(). */++utf = (pat_patctl.options & (PCRE2_UTF|PCRE2_MATCH_INVALID_UTF)) != 0;++/* 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++)+  {+  uint32_t c = pat_patctl.control & exclusive_pat_controls[k];+  if (c != 0 && c != (c & (~c+1)))+    {+    show_controls(c, 0, "** Not allowed together:");+    fprintf(outfile, "\n");+    return PR_SKIP;+    }+  }++/* Assume full JIT compile for jitverify and/or jitfast if nothing else was+specified. */++if (pat_patctl.jit == 0 &&+    (pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0)+  pat_patctl.jit = JIT_DEFAULT;++/* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting+in callouts. Convert from hex if requested (literal strings in quotes may be+present within the hexadecimal pairs). The result must necessarily be fewer+characters so will always fit in pbuffer8. */++if ((pat_patctl.control & CTL_HEXPAT) != 0)+  {+  uint8_t *pp, *pt;+  uint32_t c, d;++  pt = pbuffer8;+  for (pp = buffer + 1; *pp != 0; pp++)+    {+    if (isspace(*pp)) continue;+    c = *pp++;++    /* Handle a literal substring */++    if (c == '\'' || c == '"')+      {+      uint8_t *pq = pp;+      for (;; pp++)+        {+        d = *pp;+        if (d == 0)+          {+          fprintf(outfile, "** Missing closing quote in hex pattern: "+            "opening quote is at offset %" PTR_FORM ".\n", pq - buffer - 2);+          return PR_SKIP;+          }+        if (d == c) break;+        *pt++ = d;+        }+      }++    /* Expect a hex pair */++    else+      {+      if (!isxdigit(c))+        {+        fprintf(outfile, "** Unexpected non-hex-digit '%c' at offset %"+          PTR_FORM " in hex pattern: quote missing?\n", c, pp - buffer - 2);+        return PR_SKIP;+        }+      if (*pp == 0)+        {+        fprintf(outfile, "** Odd number of digits in hex pattern\n");+        return PR_SKIP;+        }+      d = *pp;+      if (!isxdigit(d))+        {+        fprintf(outfile, "** Unexpected non-hex-digit '%c' at offset %"+          PTR_FORM " in hex pattern: quote missing?\n", d, pp - buffer - 1);+        return PR_SKIP;+        }+      c = toupper(c);+      d = toupper(d);+      *pt++ = ((isdigit(c)? (c - '0') : (c - 'A' + 10)) << 4) ++               (isdigit(d)? (d - '0') : (d - 'A' + 10));+      }+    }+  *pt = 0;+  patlen = pt - pbuffer8;+  }++/* If not a hex string, process for repetition expansion if requested. */++else if ((pat_patctl.control & CTL_EXPAND) != 0)+  {+  uint8_t *pp, *pt;++  pt = pbuffer8;+  for (pp = buffer + 1; *pp != 0; pp++)+    {+    uint8_t *pc = pp;+    uint32_t count = 1;+    size_t length = 1;++    /* Check for replication syntax; if not found, the defaults just set will+    prevail and one character will be copied. */++    if (pp[0] == '\\' && pp[1] == '[')+      {+      uint8_t *pe;+      for (pe = pp + 2; *pe != 0; pe++)+        {+        if (pe[0] == ']' && pe[1] == '{')+          {+          uint32_t clen = pe - pc - 2;+          uint32_t i = 0;+          unsigned long uli;+          char *endptr;++          pe += 2;+          uli = strtoul((const char *)pe, &endptr, 10);+          if (U32OVERFLOW(uli))+            {+            fprintf(outfile, "** Pattern repeat count too large\n");+            return PR_SKIP;+            }++          i = (uint32_t)uli;+          pe = (uint8_t *)endptr;+          if (*pe == '}')+            {+            if (i == 0)+              {+              fprintf(outfile, "** Zero repeat not allowed\n");+              return PR_SKIP;+              }+            pc += 2;+            count = i;+            length = clen;+            pp = pe;+            break;+            }+          }+        }+      }++    /* Add to output. If the buffer is too small expand it. The function for+    expanding buffers always keeps buffer and pbuffer8 in step as far as their+    size goes. */++    while (pt + count * length > pbuffer8 + pbuffer8_size)+      {+      size_t pc_offset = pc - buffer;+      size_t pp_offset = pp - buffer;+      size_t pt_offset = pt - pbuffer8;+      expand_input_buffers();+      pc = buffer + pc_offset;+      pp = buffer + pp_offset;+      pt = pbuffer8 + pt_offset;+      }++    for (; count > 0; count--)+      {+      memcpy(pt, pc, length);+      pt += length;+      }+    }++  *pt = 0;+  patlen = pt - pbuffer8;++  if ((pat_patctl.control & CTL_INFO) != 0)+    fprintf(outfile, "Expanded: %s\n", pbuffer8);+  }++/* Neither hex nor expanded, just copy the input verbatim. */++else+  {+  strncpy((char *)pbuffer8, (char *)(buffer+1), patlen + 1);+  }++/* Sort out character tables */++if (pat_patctl.locale[0] != 0)+  {+  if (pat_patctl.tables_id != 0)+    {+    fprintf(outfile, "** 'Locale' and 'tables' must not both be set\n");+    return PR_SKIP;+    }+  if (setlocale(LC_CTYPE, (const char *)pat_patctl.locale) == NULL)+    {+    fprintf(outfile, "** Failed to set locale '%s'\n", pat_patctl.locale);+    return PR_SKIP;+    }+  if (strcmp((const char *)pat_patctl.locale, (const char *)locale_name) != 0)+    {+    strcpy((char *)locale_name, (char *)pat_patctl.locale);+    if (locale_tables != NULL) free((void *)locale_tables);+    PCRE2_MAKETABLES(locale_tables);+    }+  use_tables = locale_tables;+  }++else switch (pat_patctl.tables_id)+  {+  case 0: use_tables = NULL; break;+  case 1: use_tables = tables1; break;+  case 2: use_tables = tables2; break;++  case 3:+  if (tables3 == NULL)+    {+    fprintf(outfile, "** 'Tables = 3' is invalid: binary tables have not "+      "been loaded\n");+    return PR_SKIP;+    }+  use_tables = tables3;+  break;++  default:+  fprintf(outfile, "** 'Tables' must specify 0, 1, 2, or 3.\n");+  return PR_SKIP;+  }++PCRE2_SET_CHARACTER_TABLES(pat_context, use_tables);++/* Set up for the stackguard test. */++if (pat_patctl.stackguard_test != 0)+  {+  PCRE2_SET_COMPILE_RECURSION_GUARD(pat_context, stack_guard, NULL);+  }++/* Handle compiling via the POSIX interface, which doesn't support the+timing, showing, or debugging options, nor the ability to pass over+local character tables. Neither does it have 16-bit or 32-bit support. */++if ((pat_patctl.control & CTL_POSIX) != 0)+  {+#ifdef SUPPORT_PCRE2_8+  int rc;+  int cflags = 0;+  const char *msg = "** Ignored with POSIX interface:";+#endif++  if (test_mode != PCRE8_MODE)+    {+    fprintf(outfile, "** The POSIX interface is available only in 8-bit mode\n");+    return PR_SKIP;+    }++#ifdef SUPPORT_PCRE2_8+  /* Check for features that the POSIX interface does not support. */++  if (pat_patctl.locale[0] != 0) prmsg(&msg, "locale");+  if (pat_patctl.replacement[0] != 0) prmsg(&msg, "replace");+  if (pat_patctl.tables_id != 0) prmsg(&msg, "tables");+  if (pat_patctl.stackguard_test != 0) prmsg(&msg, "stackguard");+  if (timeit > 0) prmsg(&msg, "timing");+  if (pat_patctl.jit != 0) prmsg(&msg, "JIT");++  if ((pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS) != 0)+    {+    show_compile_options(+      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)+    {+    show_controls(pat_patctl.control & ~POSIX_SUPPORTED_COMPILE_CONTROLS,+      pat_patctl.control2 & ~POSIX_SUPPORTED_COMPILE_CONTROLS2, msg);+    msg = "";+    }++  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");++  /* Translate PCRE2 options to POSIX options and then compile. */++  if (utf) cflags |= REG_UTF;+  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 */++  if (rc != 0)+    {+    size_t bsize, usize;+    int psize;++    preg.re_pcre2_code = NULL;     /* In case something was left in there */+    preg.re_match_data = NULL;++    bsize = (pat_patctl.regerror_buffsize != 0)?+      pat_patctl.regerror_buffsize : pbuffer8_size;+    if (bsize + 8 < pbuffer8_size)+      memcpy(pbuffer8 + bsize, "DEADBEEF", 8);+    usize = regerror(rc, &preg, (char *)pbuffer8, bsize);++    /* Inside regerror(), snprintf() is used. If the buffer is too small, some+    versions of snprintf() put a zero byte at the end, but others do not.+    Therefore, we print a maximum of one less than the size of the buffer. */++    psize = (int)bsize - 1;+    fprintf(outfile, "Failed: POSIX code %d: %.*s\n", rc, psize, pbuffer8);+    if (usize > bsize)+      {+      fprintf(outfile, "** regerror() message truncated\n");+      if (memcmp(pbuffer8 + bsize, "DEADBEEF", 8) != 0)+        fprintf(outfile, "** regerror() buffer overflow\n");+      }+    return PR_SKIP;+    }++  /* Compiling succeeded. Check that the values in the preg block are sensible.+  It can happen that pcre2test is accidentally linked with a different POSIX+  library which succeeds, but of course puts different things into preg. In+  this situation, calling regfree() may cause a segfault (or invalid free() in+  valgrind), so ensure that preg.re_pcre2_code is NULL, which suppresses the+  calling of regfree() on exit. */++  if (preg.re_pcre2_code == NULL ||+      ((pcre2_real_code_8 *)preg.re_pcre2_code)->magic_number != MAGIC_NUMBER ||+      ((pcre2_real_code_8 *)preg.re_pcre2_code)->top_bracket != preg.re_nsub ||+      preg.re_match_data == NULL ||+      preg.re_cflags != cflags)+    {+    fprintf(outfile,+      "** The regcomp() function returned zero (success), but the values set\n"+      "** in the preg block are not valid for PCRE2. Check that pcre2test is\n"+      "** linked with PCRE2's pcre2posix module (-lpcre2-posix) and not with\n"+      "** some other POSIX regex library.\n**\n");+    preg.re_pcre2_code = NULL;+    return PR_ABEND;+    }++  return PR_OK;+#endif  /* SUPPORT_PCRE2_8 */+  }++/* 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|CTL_PUSHTABLESCOPY)) != 0)+  {+  if (pat_patctl.replacement[0] != 0)+    {+    fprintf(outfile, "** Replacement text is not supported with 'push'.\n");+    return PR_OK;+    }+  if ((pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS) != 0 ||+      (pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2) != 0)+    {+    show_controls(pat_patctl.control & ~PUSH_SUPPORTED_COMPILE_CONTROLS,+                  pat_patctl.control2 & ~PUSH_SUPPORTED_COMPILE_CONTROLS2,+      "** Ignored when compiled pattern is stacked with 'push':");+    fprintf(outfile, "\n");+    }+  if ((pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS) != 0 ||+      (pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2) != 0)+    {+    show_controls(pat_patctl.control & PUSH_COMPILE_ONLY_CONTROLS,+                  pat_patctl.control2 & PUSH_COMPILE_ONLY_CONTROLS2,+      "** Applies only to compile when pattern is stacked with 'push':");+    fprintf(outfile, "\n");+    }+  }++/* Convert the input in non-8-bit modes. */++errorcode = 0;++#ifdef SUPPORT_PCRE2_16+if (test_mode == PCRE16_MODE) errorcode = to16(pbuffer8, utf, &patlen);+#endif++#ifdef SUPPORT_PCRE2_32+if (test_mode == PCRE32_MODE) errorcode = to32(pbuffer8, utf, &patlen);+#endif++switch(errorcode)+  {+  case -1:+  fprintf(outfile, "** Failed: invalid UTF-8 string cannot be "+    "converted to %d-bit string\n", (test_mode == PCRE16_MODE)? 16:32);+  return PR_SKIP;++  case -2:+  fprintf(outfile, "** Failed: character value greater than 0x10ffff "+    "cannot be converted to UTF\n");+  return PR_SKIP;++  case -3:+  fprintf(outfile, "** Failed: character value greater than 0xffff "+    "cannot be converted to 16-bit in non-UTF mode\n");+  return PR_SKIP;++  default:+  break;+  }++/* 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+ends up back in the usual place. */++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 %" SIZ_FORM ": ",+      SIZ_CAST 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.control2 & CTL2_NL_SET) == 0 && local_newline_default != 0)+  {+  SETFLD(pat_context, newline_convention, local_newline_default);+  }++/* 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)+  {+  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|use_forbid_utf, &errorcode, &erroroffset,+        use_pat_context);+    time_taken += clock() - start_time;+    if (TEST(compiled_code, !=, NULL))+      { SUB1(pcre2_code_free, compiled_code); }+    }+  total_compile_time += time_taken;+  fprintf(outfile, "Compile time %.4f milliseconds\n",+    (((double)time_taken * 1000.0) / (double)timeit) /+      (double)CLOCKS_PER_SEC);+  }++/* A final compile that is used "for real". */++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))+  {+  fprintf(outfile, "Failed: error %d at offset %d: ", errorcode,+    (int)erroroffset);+  if (!print_error_message(errorcode, "", "\n")) return PR_ABEND;+  return PR_SKIP;+  }++/* If forbid_utf is non-zero, we are running a non-UTF test. UTF and UCP are+locked out at compile time, but we must also check for occurrences of \P, \p,+and \X, which are only supported when Unicode is supported. */++if (forbid_utf != 0)+  {+  if ((FLD(compiled_code, flags) & PCRE2_HASBKPORX) != 0)+    {+    fprintf(outfile, "** \\P, \\p, and \\X are not allowed after the "+      "#forbid_utf command\n");+    return PR_SKIP;+    }+  }++/* Remember the maximum lookbehind, for partial matching. */++if (pattern_info(PCRE2_INFO_MAXLOOKBEHIND, &maxlookbehind, FALSE) != 0)+  return PR_ABEND;++/* Remember the number of captures. */++if (pattern_info(PCRE2_INFO_CAPTURECOUNT, &maxcapcount, FALSE) < 0)+  return PR_ABEND;++/* 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.control2 & CTL2_NL_SET) != 0)+  {+  SETFLD(compiled_code, flags, FLD(compiled_code, flags) | PCRE2_NL_SET);+  }++/* 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();+  if (rc != PR_OK) return rc;+  }++/* The "push" control requests that the compiled pattern be remembered on a+stack. This is mainly for testing the serialization functionality. */++if ((pat_patctl.control & CTL_PUSH) != 0)+  {+  if (patstacknext >= PATSTACKSIZE)+    {+    fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE);+    return PR_ABEND;+    }+  patstack[patstacknext++] = PTR(compiled_code);+  SET(compiled_code, NULL);+  }++/* 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|CTL_PUSHTABLESCOPY)) != 0)+  {+  if (patstacknext >= PATSTACKSIZE)+    {+    fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE);+    return PR_ABEND;+    }+  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;+}++++/*************************************************+*          Check heap, match or depth limit      *+*************************************************/++/* This is used for DFA, normal, and JIT fast matching. For DFA matching it+should only be 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, PCRE2_SIZE ulen, int errnumber, const char *msg)+{+int capcount;+uint32_t min = 0;+uint32_t mid = 64;+uint32_t max = UINT32_MAX;++PCRE2_SET_MATCH_LIMIT(dat_context, max);+PCRE2_SET_DEPTH_LIMIT(dat_context, max);+PCRE2_SET_HEAP_LIMIT(dat_context, max);++for (;;)+  {+  uint32_t stack_start = 0;++  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_DEPTH_LIMIT(dat_context, mid);+    }++  if ((dat_datctl.control & CTL_DFA) != 0)+    {+    stack_start = DFA_START_RWS_SIZE/1024;+    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+    {+    stack_start = START_FRAMES_SIZE/1024;+    PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,+      dat_datctl.options, match_data, PTR(dat_context));+    }++  if (capcount == errnumber)+    {+    if ((mid & 0x80000000u) != 0)+      {+      fprintf(outfile, "Can't find minimum %s limit: check pattern for "+        "restriction\n", msg);+      break;+      }++    min = mid;+    mid = (mid == max - 1)? max : (max != UINT32_MAX)? (min + max)/2 : mid*2;+    }+  else if (capcount >= 0 ||+           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 (for pcre2_match()) or the initial stack+    workspace vector (for pcre2_dfa_match()), 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 < stack_start)+      {+      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 + max)/2;+    }+  else break;    /* Some other error */+  }++return capcount;+}++++/*************************************************+*        Substitute callout function             *+*************************************************/++/* Called from pcre2_substitute() when the substitute_callout modifier is set.+Print out the data that is passed back. The substitute callout block is+identical for all code unit widths, so we just pick one.++Arguments:+  scb         pointer to substitute callout block+  data_ptr    callout data++Returns:      nothing+*/++static int+substitute_callout_function(pcre2_substitute_callout_block_8 *scb,+  void *data_ptr)+{+int yield = 0;+BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;+(void)data_ptr;   /* Not used */++fprintf(outfile, "%2d(%d) Old %" SIZ_FORM " %" SIZ_FORM " \"",+  scb->subscount, scb->oveccount,+  SIZ_CAST scb->ovector[0], SIZ_CAST scb->ovector[1]);++PCHARSV(scb->input, scb->ovector[0], scb->ovector[1] - scb->ovector[0],+  utf, outfile);++fprintf(outfile, "\" New %" SIZ_FORM " %" SIZ_FORM " \"",+  SIZ_CAST scb->output_offsets[0], SIZ_CAST scb->output_offsets[1]);++PCHARSV(scb->output, scb->output_offsets[0],+  scb->output_offsets[1] - scb->output_offsets[0], utf, outfile);++if (scb->subscount == dat_datctl.substitute_stop)+  {+  yield = -1;+  fprintf(outfile, " STOPPED");+  }+else if (scb->subscount == dat_datctl.substitute_skip)+  {+  yield = +1;+  fprintf(outfile, " SKIPPED");+  }++fprintf(outfile, "\"\n");+return yield;+}+++/*************************************************+*              Callout function                  *+*************************************************/++/* Called from a PCRE2 library as a result of the (?C) item. We print out where+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.++Arguments:+  cb                a pointer to a callout block+  callout_data_ptr  the provided callout data++Returns:            0 or 1 or an error, as determined by settings+*/++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;++/* 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. */++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. */++if (cb->callout_string != NULL)+  {+  uint32_t delimiter = CODE_UNIT(cb->callout_string, -1);+  fprintf(outfile, "Callout (%" SIZ_FORM "): %c",+    SIZ_CAST cb->callout_string_offset, delimiter);+  PCHARSV(cb->callout_string, 0,+    cb->callout_string_length, utf, outfile);+  for (i = 0; callout_start_delims[i] != 0; i++)+    if (delimiter == callout_start_delims[i])+      {+      delimiter = callout_end_delims[i];+      break;+      }+  fprintf(outfile, "%c", delimiter);+  if (!callout_capture) fprintf(outfile, "\n");+  }++/* Show captured strings if required */++if (callout_capture)+  {+  if (cb->callout_string == NULL)+    fprintf(outfile, "Callout %d:", cb->callout_number);+  fprintf(outfile, " last capture = %d\n", cb->capture_last);+  for (i = 2; i < cb->capture_top * 2; i += 2)+    {+    fprintf(outfile, "%2d: ", i/2);+    if (cb->offset_vector[i] == PCRE2_UNSET)+      fprintf(outfile, "<unset>");+    else+      {+      PCHARSV(cb->subject, cb->offset_vector[i],+        cb->offset_vector[i+1] - cb->offset_vector[i], utf, f);+      }+    fprintf(outfile, "\n");+    }+  }++/* 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 (callout_where)+  {+  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)+    {+    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");+  }++first_callout = FALSE;++/* Show any mark info */++if (cb->mark != last_callout_mark)+  {+  if (cb->mark == NULL)+    fprintf(outfile, "Latest Mark: <unset>\n");+  else+    {+    fprintf(outfile, "Latest Mark: ");+    PCHARSV(cb->mark, -1, -1, utf, outfile);+    putc('\n', outfile);+    }+  last_callout_mark = cb->mark;+  }++/* Show callout data */++if (callout_data_ptr != NULL)+  {+  int callout_data = *((int32_t *)callout_data_ptr);+  if (callout_data != 0)+    {+    fprintf(outfile, "Callout data = %d\n", callout_data);+    return callout_data;+    }+  }++/* 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;+}++++/*************************************************+*       Handle *MARK and copy/get tests          *+*************************************************/++/* This function is called after complete and partial matches. It runs the+tests for substring extraction.++Arguments:+  utf       TRUE for utf+  capcount  return from pcre2_match()++Returns:    FALSE if print_error_message() fails+*/++static BOOL+copy_and_get(BOOL utf, int capcount)+{+int i;+uint8_t *nptr;++/* Test copy strings by number */++for (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++)+  {+  int rc;+  PCRE2_SIZE length, length2;+  uint32_t copybuffer[256];+  uint32_t n = (uint32_t)(dat_datctl.copy_numbers[i]);+  length = sizeof(copybuffer)/code_unit_size;+  PCRE2_SUBSTRING_COPY_BYNUMBER(rc, match_data, n, copybuffer, &length);+  if (rc < 0)+    {+    fprintf(outfile, "Copy substring %d failed (%d): ", n, rc);+    if (!print_error_message(rc, "", "\n")) return FALSE;+    }+  else+    {+    PCRE2_SUBSTRING_LENGTH_BYNUMBER(rc, match_data, n, &length2);+    if (rc < 0)+      {+      fprintf(outfile, "Get substring %d length failed (%d): ", n, rc);+      if (!print_error_message(rc, "", "\n")) return FALSE;+      }+    else if (length2 != length)+      {+      fprintf(outfile, "Mismatched substring lengths: %"+        SIZ_FORM " %" SIZ_FORM "\n", SIZ_CAST length, SIZ_CAST length2);+      }+    fprintf(outfile, "%2dC ", n);+    PCHARSV(copybuffer, 0, length, utf, outfile);+    fprintf(outfile, " (%" SIZ_FORM ")\n", SIZ_CAST length);+    }+  }++/* Test copy strings by name */++nptr = dat_datctl.copy_names;+for (;;)+  {+  int rc;+  int groupnumber;+  PCRE2_SIZE length, length2;+  uint32_t copybuffer[256];+  int namelen = strlen((const char *)nptr);+#if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32+  PCRE2_SIZE cnl = namelen;+#endif+  if (namelen == 0) break;++#ifdef SUPPORT_PCRE2_8+  if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr);+#endif+#ifdef SUPPORT_PCRE2_16+  if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl);+#endif+#ifdef SUPPORT_PCRE2_32+  if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl);+#endif++  PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer);+  if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING)+    fprintf(outfile, "Number not found for group '%s'\n", nptr);++  length = sizeof(copybuffer)/code_unit_size;+  PCRE2_SUBSTRING_COPY_BYNAME(rc, match_data, pbuffer, copybuffer, &length);+  if (rc < 0)+    {+    fprintf(outfile, "Copy substring '%s' failed (%d): ", nptr, rc);+    if (!print_error_message(rc, "", "\n")) return FALSE;+    }+  else+    {+    PCRE2_SUBSTRING_LENGTH_BYNAME(rc, match_data, pbuffer, &length2);+    if (rc < 0)+      {+      fprintf(outfile, "Get substring '%s' length failed (%d): ", nptr, rc);+      if (!print_error_message(rc, "", "\n")) return FALSE;+      }+    else if (length2 != length)+      {+      fprintf(outfile, "Mismatched substring lengths: %"+        SIZ_FORM " %" SIZ_FORM "\n", SIZ_CAST length, SIZ_CAST length2);+      }+    fprintf(outfile, "  C ");+    PCHARSV(copybuffer, 0, length, utf, outfile);+    fprintf(outfile, " (%" SIZ_FORM ") %s", SIZ_CAST length, nptr);+    if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber);+      else fprintf(outfile, " (non-unique)\n");+    }+  nptr += namelen + 1;+  }++/* Test get strings by number */++for (i = 0; i < MAXCPYGET && dat_datctl.get_numbers[i] >= 0; i++)+  {+  int rc;+  PCRE2_SIZE length;+  void *gotbuffer;+  uint32_t n = (uint32_t)(dat_datctl.get_numbers[i]);+  PCRE2_SUBSTRING_GET_BYNUMBER(rc, match_data, n, &gotbuffer, &length);+  if (rc < 0)+    {+    fprintf(outfile, "Get substring %d failed (%d): ", n, rc);+    if (!print_error_message(rc, "", "\n")) return FALSE;+    }+  else+    {+    fprintf(outfile, "%2dG ", n);+    PCHARSV(gotbuffer, 0, length, utf, outfile);+    fprintf(outfile, " (%" SIZ_FORM ")\n", SIZ_CAST length);+    PCRE2_SUBSTRING_FREE(gotbuffer);+    }+  }++/* Test get strings by name */++nptr = dat_datctl.get_names;+for (;;)+  {+  PCRE2_SIZE length;+  void *gotbuffer;+  int rc;+  int groupnumber;+  int namelen = strlen((const char *)nptr);+#if defined SUPPORT_PCRE2_16 || defined SUPPORT_PCRE2_32+  PCRE2_SIZE cnl = namelen;+#endif+  if (namelen == 0) break;++#ifdef SUPPORT_PCRE2_8+  if (test_mode == PCRE8_MODE) strcpy((char *)pbuffer8, (char *)nptr);+#endif+#ifdef SUPPORT_PCRE2_16+  if (test_mode == PCRE16_MODE)(void)to16(nptr, utf, &cnl);+#endif+#ifdef SUPPORT_PCRE2_32+  if (test_mode == PCRE32_MODE)(void)to32(nptr, utf, &cnl);+#endif++  PCRE2_SUBSTRING_NUMBER_FROM_NAME(groupnumber, compiled_code, pbuffer);+  if (groupnumber < 0 && groupnumber != PCRE2_ERROR_NOUNIQUESUBSTRING)+    fprintf(outfile, "Number not found for group '%s'\n", nptr);++  PCRE2_SUBSTRING_GET_BYNAME(rc, match_data, pbuffer, &gotbuffer, &length);+  if (rc < 0)+    {+    fprintf(outfile, "Get substring '%s' failed (%d): ", nptr, rc);+    if (!print_error_message(rc, "", "\n")) return FALSE;+    }+  else+    {+    fprintf(outfile, "  G ");+    PCHARSV(gotbuffer, 0, length, utf, outfile);+    fprintf(outfile, " (%" SIZ_FORM ") %s", SIZ_CAST length, nptr);+    if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber);+      else fprintf(outfile, " (non-unique)\n");+    PCRE2_SUBSTRING_FREE(gotbuffer);+    }+  nptr += namelen + 1;+  }++/* Test getting the complete list of captured strings. */++if ((dat_datctl.control & CTL_GETALL) != 0)+  {+  int rc;+  void **stringlist;+  PCRE2_SIZE *lengths;+  PCRE2_SUBSTRING_LIST_GET(rc, match_data, &stringlist, &lengths);+  if (rc < 0)+    {+    fprintf(outfile, "get substring list failed (%d): ", rc);+    if (!print_error_message(rc, "", "\n")) return FALSE;+    }+  else+    {+    for (i = 0; i < capcount; i++)+      {+      fprintf(outfile, "%2dL ", i);+      PCHARSV(stringlist[i], 0, lengths[i], utf, outfile);+      putc('\n', outfile);+      }+    if (stringlist[i] != NULL)+      fprintf(outfile, "string list not terminated by NULL\n");+    PCRE2_SUBSTRING_LIST_FREE(stringlist);+    }+  }++return TRUE;+}++++/*************************************************+*            Show an entire ovector              *+*************************************************/++/* This function is called after partial matching or match failure, when the+"allvector" modifier is set. It is a means of checking the contents of the+entire ovector, to ensure no modification of fields that should be unchanged.++Arguments:+  ovector      points to the ovector+  oveccount    number of pairs++Returns:       nothing+*/++static void+show_ovector(PCRE2_SIZE *ovector, uint32_t oveccount)+{+uint32_t i;+for (i = 0; i < 2*oveccount; i += 2)+  {+  PCRE2_SIZE start = ovector[i];+  PCRE2_SIZE end = ovector[i+1];++  fprintf(outfile, "%2d: ", i/2);+  if (start == PCRE2_UNSET && end == PCRE2_UNSET)+    fprintf(outfile, "<unset>\n");+  else if (start == JUNK_OFFSET && end == JUNK_OFFSET)+    fprintf(outfile, "<unchanged>\n");+  else+    fprintf(outfile, "%ld %ld\n", (unsigned long int)start,+      (unsigned long int)end);+  }+}+++/*************************************************+*               Process a data line              *+*************************************************/++/* The line is in buffer; it will not be empty.++Arguments:  none++Returns:    PR_OK     continue processing next line+            PR_SKIP   skip to a blank line+            PR_ABEND  abort the pcre2test run+*/++static int+process_data(void)+{+PCRE2_SIZE len, ulen, arg_ulen;+uint32_t gmatched;+uint32_t c, k;+uint32_t g_notempty = 0;+uint8_t *p, *pp, *start_rep;+size_t needlen;+void *use_dat_context;+BOOL utf;+BOOL subject_literal;++PCRE2_SIZE *ovector;+PCRE2_SIZE ovecsave[3];+uint32_t oveccount;++#ifdef SUPPORT_PCRE2_8+uint8_t *q8 = NULL;+#endif+#ifdef SUPPORT_PCRE2_16+uint16_t *q16 = NULL;+#endif+#ifdef SUPPORT_PCRE2_32+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+options because those that are common apply separately to compiling and+matching. */++DATCTXCPY(dat_context, default_dat_context);+memcpy(&dat_datctl, &def_datctl, sizeof(datctl));+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;++if (dat_datctl.substitute_skip == 0)+    dat_datctl.substitute_skip = pat_patctl.substitute_skip;+if (dat_datctl.substitute_stop == 0)+    dat_datctl.substitute_stop = pat_patctl.substitute_stop;++/* Initialize for scanning the data line. */++#ifdef SUPPORT_PCRE2_8+utf = ((((pat_patctl.control & CTL_POSIX) != 0)?+  ((pcre2_real_code_8 *)preg.re_pcre2_code)->overall_options :+  FLD(compiled_code, overall_options)) & PCRE2_UTF) != 0;+#else+utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;+#endif++start_rep = NULL;+len = strlen((const char *)buffer);+while (len > 0 && isspace(buffer[len-1])) len--;+buffer[len] = 0;+p = buffer;+while (isspace(*p)) p++;++/* Check that the data is well-formed UTF-8 if we're in UTF mode. To create+invalid input to pcre2_match(), you must use \x?? or \x{} sequences. */++if (utf)+  {+  uint8_t *q;+  uint32_t cc;+  int n = 1;+  for (q = p; n > 0 && *q; q += n) n = utf82ord(q, &cc);+  if (n <= 0)+    {+    fprintf(outfile, "** Failed: invalid UTF-8 string cannot be used as input "+      "in UTF mode\n");+    return PR_OK;+    }+  }++#ifdef SUPPORT_VALGRIND+/* Mark the dbuffer as addressable but undefined again. */+if (dbuffer != NULL)+  {+  VALGRIND_MAKE_MEM_UNDEFINED(dbuffer, dbuffer_size);+  }+#endif++/* Allocate a buffer to hold the data line; len+1 is an upper bound on+the number of code units that will be needed (though the buffer may have to be+extended if replication is involved). */++needlen = (size_t)((len+1) * code_unit_size);+if (dbuffer == NULL || needlen >= dbuffer_size)+  {+  while (needlen >= dbuffer_size) dbuffer_size *= 2;+  dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size);+  if (dbuffer == NULL)+    {+    fprintf(stderr, "pcre2test: realloc(%d) failed\n", (int)dbuffer_size);+    exit(1);+    }+  }+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 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)+  {+  int32_t i = 0;+  size_t replen;++  /* ] may mark the end of a replicated sequence */++  if (c == ']' && start_rep != NULL)+    {+    long li;+    char *endptr;+    size_t qoffset = CAST8VAR(q) - dbuffer;+    size_t rep_offset = start_rep - dbuffer;++    if (*p++ != '{')+      {+      fprintf(outfile, "** Expected '{' after \\[....]\n");+      return PR_OK;+      }++    li = strtol((const char *)p, &endptr, 10);+    if (S32OVERFLOW(li))+      {+      fprintf(outfile, "** Repeat count too large\n");+      return PR_OK;+      }++    p = (uint8_t *)endptr;+    if (*p++ != '}')+      {+      fprintf(outfile, "** Expected '}' after \\[...]{...\n");+      return PR_OK;+      }++    i = (int32_t)li;+    if (i-- == 0)+      {+      fprintf(outfile, "** Zero repeat not allowed\n");+      return PR_OK;+      }++    replen = CAST8VAR(q) - start_rep;+    needlen += replen * i;++    if (needlen >= dbuffer_size)+      {+      while (needlen >= dbuffer_size) dbuffer_size *= 2;+      dbuffer = (uint8_t *)realloc(dbuffer, dbuffer_size);+      if (dbuffer == NULL)+        {+        fprintf(stderr, "pcre2test: realloc(%d) failed\n", (int)dbuffer_size);+        exit(1);+        }+      SETCASTPTR(q, dbuffer + qoffset);+      start_rep = dbuffer + rep_offset;+      }++    while (i-- > 0)+      {+      memcpy(CAST8VAR(q), start_rep, replen);+      SETPLUS(q, replen/code_unit_size);+      }++    start_rep = NULL;+    continue;+    }++  /* 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 != '\\' || subject_literal)+    {+    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 */++  else switch ((c = *p++))+    {+    case '\\': break;+    case 'a': c = CHAR_BEL; break;+    case 'b': c = '\b'; break;+    case 'e': c = CHAR_ESC; break;+    case 'f': c = '\f'; break;+    case 'n': c = '\n'; break;+    case 'r': c = '\r'; break;+    case 't': c = '\t'; break;+    case 'v': c = '\v'; break;++    case '0': case '1': case '2': case '3':+    case '4': case '5': case '6': case '7':+    c -= '0';+    while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')+      c = c * 8 + *p++ - '0';+    break;++    case 'o':+    if (*p == '{')+      {+      uint8_t *pt = p;+      c = 0;+      for (pt++; isdigit(*pt) && *pt != '8' && *pt != '9'; pt++)+        {+        if (++i == 12)+          fprintf(outfile, "** Too many octal digits in \\o{...} item; "+                           "using only the first twelve.\n");+        else c = c * 8 + *pt - '0';+        }+      if (*pt == '}') p = pt + 1;+        else fprintf(outfile, "** Missing } after \\o{ (assumed)\n");+      }+    break;++    case 'x':+    if (*p == '{')+      {+      uint8_t *pt = p;+      c = 0;++      /* We used to have "while (isxdigit(*(++pt)))" here, but it fails+      when isxdigit() is a macro that refers to its argument more than+      once. This is banned by the C Standard, but apparently happens in at+      least one MacOS environment. */++      for (pt++; isxdigit(*pt); pt++)+        {+        if (++i == 9)+          fprintf(outfile, "** Too many hex digits in \\x{...} item; "+                           "using only the first eight.\n");+        else c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10);+        }+      if (*pt == '}')+        {+        p = pt + 1;+        break;+        }+      /* Not correct form for \x{...}; fall through */+      }++    /* \x without {} always defines just one byte in 8-bit mode. This+    allows UTF-8 characters to be constructed byte by byte, and also allows+    invalid UTF-8 sequences to be made. Just copy the byte in UTF-8 mode.+    Otherwise, pass it down as data. */++    c = 0;+    while (i++ < 2 && isxdigit(*p))+      {+      c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10);+      p++;+      }+#if defined SUPPORT_PCRE2_8+    if (utf && (test_mode == PCRE8_MODE))+      {+      *q8++ = c;+      continue;+      }+#endif+    break;++    case 0:     /* \ followed by EOF allows for an empty line */+    p--;+    continue;++    case '=':   /* \= terminates the data, starts modifiers */+    goto ENDSTRING;++    case '[':   /* \[ introduces a replicated character sequence */+    if (start_rep != NULL)+      {+      fprintf(outfile, "** Nested replication is not supported\n");+      return PR_OK;+      }+    start_rep = CAST8VAR(q);+    continue;++    default:+    if (isalnum(c))+      {+      fprintf(outfile, "** Unrecognized escape sequence \"\\%c\"\n", c);+      return PR_OK;+      }+    }++  /* We now have a character value in c that may be greater than 255.+  In 8-bit mode we convert to UTF-8 if we are in UTF mode. Values greater+  than 127 in UTF mode must have come from \x{...} or octal constructs+  because values from \x.. get this far only in non-UTF mode. */++#ifdef SUPPORT_PCRE2_8+  if (test_mode == PCRE8_MODE)+    {+    if (utf)+      {+      if (c > 0x7fffffff)+        {+        fprintf(outfile, "** Character \\x{%x} is greater than 0x7fffffff "+          "and so cannot be converted to UTF-8\n", c);+        return PR_OK;+        }+      q8 += ord2utf8(c, q8);+      }+    else+      {+      if (c > 0xffu)+        {+        fprintf(outfile, "** Character \\x{%x} is greater than 255 "+          "and UTF-8 mode is not enabled.\n", c);+        fprintf(outfile, "** Truncation will probably give the wrong "+          "result.\n");+        }+      *q8++ = (uint8_t)c;+      }+    }+#endif+#ifdef SUPPORT_PCRE2_16+  if (test_mode == PCRE16_MODE)+    {+    if (utf)+      {+      if (c > 0x10ffffu)+        {+        fprintf(outfile, "** Failed: character \\x{%x} is greater than "+          "0x10ffff and so cannot be converted to UTF-16\n", c);+        return PR_OK;+        }+      else if (c >= 0x10000u)+        {+        c-= 0x10000u;+        *q16++ = 0xD800 | (c >> 10);+        *q16++ = 0xDC00 | (c & 0x3ff);+        }+      else+        *q16++ = c;+      }+    else+      {+      if (c > 0xffffu)+        {+        fprintf(outfile, "** Character \\x{%x} is greater than 0xffff "+          "and UTF-16 mode is not enabled.\n", c);+        fprintf(outfile, "** Truncation will probably give the wrong "+          "result.\n");+        }++      *q16++ = (uint16_t)c;+      }+    }+#endif+#ifdef SUPPORT_PCRE2_32+  if (test_mode == PCRE32_MODE)+    {+    *q32++ = c;+    }+#endif+  }++ENDSTRING:+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. */++if (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl))+  return PR_OK;++/* Setting substitute_{skip,fail} implies a substitute callout. */++if (dat_datctl.substitute_skip != 0 || dat_datctl.substitute_stop != 0)+  dat_datctl.control2 |= CTL2_SUBSTITUTE_CALLOUT;++/* Check for mutually exclusive modifiers. At present, these are all in the+first control word. */++for (k = 0; k < sizeof(exclusive_dat_controls)/sizeof(uint32_t); k++)+  {+  c = dat_datctl.control & exclusive_dat_controls[k];+  if (c != 0 && c != (c & (~c+1)))+    {+    show_controls(c, 0, "** Not allowed together:");+    fprintf(outfile, "\n");+    return PR_OK;+    }+  }++if (pat_patctl.replacement[0] != 0)+  {+  if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0 &&+      (dat_datctl.control & CTL_NULLCONTEXT) != 0)+    {+    fprintf(outfile, "** Replacement callouts are not supported with null_context.\n");+    return PR_OK;+    }++  if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)+    fprintf(outfile, "** Ignored with replacement text: allcaptures\n");+  }++/* Warn for modifiers that are ignored for DFA. */++if ((dat_datctl.control & CTL_DFA) != 0)+  {+  if ((dat_datctl.control & CTL_ALLCAPTURES) != 0)+    fprintf(outfile, "** Ignored after DFA matching: allcaptures\n");+  }++/* We now have the subject in dbuffer, with len containing the byte length, and+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);+pp = memmove(dbuffer + dbuffer_size - len - c, dbuffer, len + c);+#ifdef SUPPORT_VALGRIND+  VALGRIND_MAKE_MEM_NOACCESS(dbuffer, dbuffer_size - (len + c));+#endif++/* Now pp points to the subject string. POSIX matching is only possible in+8-bit mode, and it does not support timing or other fancy features. Some were+checked at compile time, but we need to check the match-time settings here. */++#ifdef SUPPORT_PCRE2_8+if ((pat_patctl.control & CTL_POSIX) != 0)+  {+  int rc;+  int eflags = 0;+  regmatch_t *pmatch = NULL;+  const char *msg = "** Ignored with POSIX interface:";++  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)+    {+    fprintf(outfile, "%s", msg);+    show_match_options(dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS);+    msg = "";+    }+  if ((dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS) != 0 ||+      (dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2) != 0)+    {+    show_controls(dat_datctl.control & ~POSIX_SUPPORTED_MATCH_CONTROLS,+                  dat_datctl.control2 & ~POSIX_SUPPORTED_MATCH_CONTROLS2, msg);+    msg = "";+    }++  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.oveccount, pmatch, eflags);+  if (rc != 0)+    {+    (void)regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size);+    fprintf(outfile, "No match: POSIX code %d: %s\n", rc, pbuffer8);+    }+  else if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0)+    fprintf(outfile, "Matched with REG_NOSUB\n");+  else if (dat_datctl.oveccount == 0)+    fprintf(outfile, "Matched without capture\n");+  else+    {+    size_t i, j;+    size_t last_printed = (size_t)dat_datctl.oveccount;+    for (i = 0; i < (size_t)dat_datctl.oveccount; i++)+      {+      if (pmatch[i].rm_so >= 0)+        {+        PCRE2_SIZE start = pmatch[i].rm_so;+        PCRE2_SIZE end = pmatch[i].rm_eo;+        for (j = last_printed + 1; j < i; j++)+          fprintf(outfile, "%2d: <unset>\n", (int)j);+        last_printed = i;+        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, 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);+          /* 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"); }+        }+      }+    }+  free(pmatch);+  return PR_OK;+  }+#endif  /* SUPPORT_PCRE2_8 */++ /* Handle matching via the native interface. Check for consistency of+modifiers. */++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. */++if ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT &&+    FLD(compiled_code, executable_jit) != NULL)+  {+  fprintf(outfile, "** Showing all consulted text is not supported by JIT: ignored\n");+  dat_datctl.control &= ~CTL_ALLUSEDTEXT;+  }++/* Handle passing the subject as zero-terminated. */++if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)+  arg_ulen = PCRE2_ZERO_TERMINATED;++/* The nullcontext modifier is used to test calling pcre2_[jit_]match() with a+NULL context. */++use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)?+  NULL : PTR(dat_context);++/* 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)+  {+  if (dat_datctl.jitstack != jit_stack_size)+    {+    PCRE2_JIT_STACK_FREE(jit_stack);+    PCRE2_JIT_STACK_CREATE(jit_stack, 1, dat_datctl.jitstack * 1024, NULL);+    jit_stack_size = dat_datctl.jitstack;+    }+  PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, jit_stack);+  }++/* Or de-assign */++else if (jit_stack != NULL)+  {+  PCRE2_JIT_STACK_ASSIGN(dat_context, NULL, NULL);+  PCRE2_JIT_STACK_FREE(jit_stack);+  jit_stack = NULL;+  jit_stack_size = 0;+  }++/* When no JIT stack is assigned, we must ensure that there is a JIT callback+if we want to verify that JIT was actually used. */++if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL)+   {+   PCRE2_JIT_STACK_ASSIGN(dat_context, jit_callback, NULL);+   }++/* Adjust match_data according to size of offsets required. A size of zero+causes a new match data block to be obtained that exactly fits the pattern. */++if (dat_datctl.oveccount == 0)+  {+  PCRE2_MATCH_DATA_FREE(match_data);+  PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(match_data, compiled_code, NULL);+  PCRE2_GET_OVECTOR_COUNT(max_oveccount, match_data);+  }+else if (dat_datctl.oveccount <= max_oveccount)+  {+  SETFLD(match_data, oveccount, dat_datctl.oveccount);+  }+else+  {+  max_oveccount = dat_datctl.oveccount;+  PCRE2_MATCH_DATA_FREE(match_data);+  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;+  }++ovector = FLD(match_data, ovector);+PCRE2_GET_OVECTOR_COUNT(oveccount, match_data);++/* Replacement processing is ignored for DFA matching. */++if (dat_datctl.replacement[0] != 0 && (dat_datctl.control & CTL_DFA) != 0)+  {+  fprintf(outfile, "** Ignored for DFA matching: replace\n");+  dat_datctl.replacement[0] = 0;+  }++/* If a replacement string is provided, call pcre2_substitute() instead of one+of the matching functions. First we have to convert the replacement string to+the appropriate width. */++if (dat_datctl.replacement[0] != 0)+  {+  int rc;+  uint8_t *pr;+  uint8_t rbuffer[REPLACE_BUFFSIZE];+  uint8_t nbuffer[REPLACE_BUFFSIZE];+  uint32_t xoptions;+  uint32_t emoption;  /* External match option */+  PCRE2_SIZE j, rlen, nsize, erroroffset;+  BOOL badutf = FALSE;++#ifdef SUPPORT_PCRE2_8+  uint8_t *r8 = NULL;+#endif+#ifdef SUPPORT_PCRE2_16+  uint16_t *r16 = NULL;+#endif+#ifdef SUPPORT_PCRE2_32+  uint32_t *r32 = NULL;+#endif++  /* Fill the ovector with junk to detect elements that do not get set+  when they should be (relevant only when "allvector" is specified). */++  for (j = 0; j < 2*oveccount; j++) ovector[j] = JUNK_OFFSET;++  if (timeitm)+    fprintf(outfile, "** Timing is not supported with replace: ignored\n");++  if ((dat_datctl.control & CTL_ALTGLOBAL) != 0)+    fprintf(outfile, "** Altglobal is not supported with replace: ignored\n");++  /* Check for a test that does substitution after an initial external match.+  If this is set, we run the external match, but leave the interpretation of+  its output to pcre2_substitute(). */++  emoption = ((dat_datctl.control2 & CTL2_SUBSTITUTE_MATCHED) == 0)? 0 :+    PCRE2_SUBSTITUTE_MATCHED;++  if (emoption != 0)+    {+    PCRE2_MATCH(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,+      dat_datctl.options, match_data, use_dat_context);+    }++  xoptions = emoption |+             (((dat_datctl.control & CTL_GLOBAL) == 0)? 0 :+                PCRE2_SUBSTITUTE_GLOBAL) |+             (((dat_datctl.control2 & CTL2_SUBSTITUTE_EXTENDED) == 0)? 0 :+                PCRE2_SUBSTITUTE_EXTENDED) |+             (((dat_datctl.control2 & CTL2_SUBSTITUTE_LITERAL) == 0)? 0 :+                PCRE2_SUBSTITUTE_LITERAL) |+             (((dat_datctl.control2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) == 0)? 0 :+                PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) |+             (((dat_datctl.control2 & CTL2_SUBSTITUTE_REPLACEMENT_ONLY) == 0)? 0 :+                PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) |+             (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) == 0)? 0 :+                PCRE2_SUBSTITUTE_UNKNOWN_UNSET) |+             (((dat_datctl.control2 & CTL2_SUBSTITUTE_UNSET_EMPTY) == 0)? 0 :+                PCRE2_SUBSTITUTE_UNSET_EMPTY);++  SETCASTPTR(r, rbuffer);  /* Sets r8, r16, or r32, as appropriate. */+  pr = dat_datctl.replacement;++  /* If the replacement starts with '[<number>]' we interpret that as length+  value for the replacement buffer. */++  nsize = REPLACE_BUFFSIZE/code_unit_size;+  if (*pr == '[')+    {+    PCRE2_SIZE n = 0;+    while ((c = *(++pr)) >= CHAR_0 && c <= CHAR_9) n = n * 10 + c - CHAR_0;+    if (*pr++ != ']')+      {+      fprintf(outfile, "Bad buffer size in replacement string\n");+      return PR_OK;+      }+    if (n > nsize)+      {+      fprintf(outfile, "Replacement buffer setting (%" SIZ_FORM ") is too "+        "large (max %" SIZ_FORM ")\n", SIZ_CAST n, SIZ_CAST nsize);+      return PR_OK;+      }+    nsize = n;+    }++  /* Now copy the replacement string to a buffer of the appropriate width. No+  escape processing is done for replacements. In UTF mode, check for an invalid+  UTF-8 input string, and if it is invalid, just copy its code units without+  UTF interpretation. This provides a means of checking that an invalid string+  is detected. Otherwise, UTF-8 can be used to include wide characters in a+  replacement. */++  if (utf) badutf = valid_utf(pr, strlen((const char *)pr), &erroroffset);++  /* Not UTF or invalid UTF-8: just copy the code units. */++  if (!utf || badutf)+    {+    while ((c = *pr++) != 0)+      {+#ifdef SUPPORT_PCRE2_8+      if (test_mode == PCRE8_MODE) *r8++ = c;+#endif+#ifdef SUPPORT_PCRE2_16+      if (test_mode == PCRE16_MODE) *r16++ = c;+#endif+#ifdef SUPPORT_PCRE2_32+      if (test_mode == PCRE32_MODE) *r32++ = c;+#endif+      }+    }++  /* Valid UTF-8 replacement string */++  else while ((c = *pr++) != 0)+    {+    if (HASUTF8EXTRALEN(c)) { GETUTF8INC(c, pr); }++#ifdef SUPPORT_PCRE2_8+    if (test_mode == PCRE8_MODE) r8 += ord2utf8(c, r8);+#endif++#ifdef SUPPORT_PCRE2_16+    if (test_mode == PCRE16_MODE)+      {+      if (c >= 0x10000u)+        {+        c-= 0x10000u;+        *r16++ = 0xD800 | (c >> 10);+        *r16++ = 0xDC00 | (c & 0x3ff);+        }+      else *r16++ = c;+      }+#endif++#ifdef SUPPORT_PCRE2_32+    if (test_mode == PCRE32_MODE) *r32++ = c;+#endif+    }++  SET(*r, 0);+  if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)+    rlen = PCRE2_ZERO_TERMINATED;+  else+    rlen = (CASTVAR(uint8_t *, r) - rbuffer)/code_unit_size;++  if ((dat_datctl.control2 & CTL2_SUBSTITUTE_CALLOUT) != 0)+    {+    PCRE2_SET_SUBSTITUTE_CALLOUT(dat_context, substitute_callout_function, NULL);+    }+  else+    {+    PCRE2_SET_SUBSTITUTE_CALLOUT(dat_context, NULL, NULL);  /* No callout */+    }++  PCRE2_SUBSTITUTE(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,+    dat_datctl.options|xoptions, match_data, use_dat_context,+    rbuffer, rlen, nbuffer, &nsize);++  if (rc < 0)+    {+    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, ": ");+    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);+    }+  else+    {+    fprintf(outfile, "%2d: ", rc);+    PCHARSV(nbuffer, 0, nsize, utf, outfile);+    }++  fprintf(outfile, "\n");+  show_memory = FALSE;++  /* Show final ovector contents if requested. */++  if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)+    show_ovector(ovector, oveccount);++  return PR_OK;+  }   /* End of substitution handling */++/* When a replacement string is not provided, run a loop for global matching+with one of the basic matching functions. For altglobal (or first time round+the loop), set an "unset" value for the previous match info. */++ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;++for (gmatched = 0;; gmatched++)+  {+  PCRE2_SIZE j;+  int capcount;++  /* Fill the ovector with junk to detect elements that do not get set+  when they should be. */++  for (j = 0; j < 2*oveccount; j++) ovector[j] = JUNK_OFFSET;++  /* When matching is via pcre2_match(), we will detect the use of JIT via the+  stack callback function. */++  jit_was_used = (pat_patctl.control & CTL_JITFAST) != 0;++  /* Do timing if required. */++  if (timeitm > 0)+    {+    int i;+    clock_t start_time, time_taken;++    if ((dat_datctl.control & CTL_DFA) != 0)+      {+      if ((dat_datctl.options & PCRE2_DFA_RESTART) != 0)+        {+        fprintf(outfile, "Timing DFA restarts is not supported\n");+        return PR_OK;+        }+      if (dfa_workspace == NULL)+        dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));+      start_time = clock();+      for (i = 0; i < timeitm; i++)+        {+        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);+        }+      }++    else if ((pat_patctl.control & CTL_JITFAST) != 0)+      {+      start_time = clock();+      for (i = 0; i < timeitm; i++)+        {+        PCRE2_JIT_MATCH(capcount, compiled_code, pp, arg_ulen,+          dat_datctl.offset, dat_datctl.options | g_notempty, match_data,+          use_dat_context);+        }+      }++    else+      {+      start_time = clock();+      for (i = 0; i < timeitm; i++)+        {+        PCRE2_MATCH(capcount, compiled_code, pp, arg_ulen,+          dat_datctl.offset, dat_datctl.options | g_notempty, match_data,+          use_dat_context);+        }+      }+    total_match_time += (time_taken = clock() - start_time);+    fprintf(outfile, "Match time %.4f milliseconds\n",+      (((double)time_taken * 1000.0) / (double)timeitm) /+        (double)CLOCKS_PER_SEC);+    }++  /* Find the heap, match and depth limits if requested. 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 = 0;  /* This stops compiler warnings */++    if (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");+      }++    if (capcount == 0)+      {+      fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n");+      capcount = dat_datctl.oveccount;+      }+    }++  /* Otherwise just run a single match, setting up a callout if required (the+  default). There is a copy of the pattern in pbuffer8 for use by callouts. */++  else+    {+    if ((dat_datctl.control & CTL_CALLOUT_NONE) == 0)+      {+      PCRE2_SET_CALLOUT(dat_context, callout_function,+        (void *)(&dat_datctl.callout_data));+      first_callout = TRUE;+      last_callout_mark = NULL;+      callout_count = 0;+      }+    else+      {+      PCRE2_SET_CALLOUT(dat_context, NULL, NULL);  /* No callout */+      }++    /* Run a single DFA or NFA match. */++    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, arg_ulen,+        dat_datctl.offset, dat_datctl.options | g_notempty, match_data,+        use_dat_context, dfa_workspace, DFA_WS_DIMENSION);+      if (capcount == 0)+        {+        fprintf(outfile, "Matched, but offsets vector is too small to show all matches\n");+        capcount = dat_datctl.oveccount;+        }+      }+    else+      {+      if ((pat_patctl.control & CTL_JITFAST) != 0)+        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, arg_ulen, dat_datctl.offset,+          dat_datctl.options | g_notempty, match_data, use_dat_context);+      if (capcount == 0)+        {+        fprintf(outfile, "Matched, but too many substrings\n");+        capcount = dat_datctl.oveccount;+        }+      }+    }++  /* The result of the match is now in capcount. First handle a successful+  match. */++  if (capcount >= 0)+    {+    int i;++    if (capcount > (int)oveccount)   /* Check for lunatic return value */+      {+      fprintf(outfile,+        "** PCRE2 error: returned count %d is too big for ovector count %d\n",+        capcount, oveccount);+      capcount = oveccount;+      if ((dat_datctl.control & CTL_ANYGLOB) != 0)+        {+        fprintf(outfile, "** Global loop abandoned\n");+        dat_datctl.control &= ~CTL_ANYGLOB;        /* Break g/G loop */+        }+      }++    /* If PCRE2_COPY_MATCHED_SUBJECT was set, check that things are as they+    should be, but not for fast JIT, where it isn't supported. */++    if ((dat_datctl.options & PCRE2_COPY_MATCHED_SUBJECT) != 0 &&+        (pat_patctl.control & CTL_JITFAST) == 0)+      {+      if ((FLD(match_data, flags) & PCRE2_MD_COPIED_SUBJECT) == 0)+        fprintf(outfile,+          "** PCRE2 error: flag not set after copy_matched_subject\n");++      if (CASTFLD(void *, match_data, subject) == pp)+        fprintf(outfile,+          "** PCRE2 error: copy_matched_subject has not copied\n");++      if (memcmp(CASTFLD(void *, match_data, subject), pp, ulen) != 0)+        fprintf(outfile,+          "** PCRE2 error: copy_matched_subject mismatch\n");+      }++    /* If this is not the first time round a global loop, check that the+    returned string has changed. If it has not, check for an empty string match+    at different starting offset from the previous match. This is a failed test+    retry for null-matching patterns that don't match at their starting offset,+    for example /(?<=\G.)/. A repeated match at the same point is not such a+    pattern, and must be discarded, and we then proceed to seek a non-null+    match at the current point. For any other repeated match, there is a bug+    somewhere and we must break the loop because it will go on for ever. We+    know that there are always at least two elements in the ovector. */++    if (gmatched > 0 && ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])+      {+      if (ovector[0] == ovector[1] && ovecsave[2] != dat_datctl.offset)+        {+        g_notempty = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;+        ovecsave[2] = dat_datctl.offset;+        continue;    /* Back to the top of the loop */+        }+      fprintf(outfile,+        "** PCRE2 error: global repeat returned the same string as previous\n");+      fprintf(outfile, "** Global loop abandoned\n");+      dat_datctl.control &= ~CTL_ANYGLOB;        /* Break g/G loop */+      }++    /* "allcaptures" requests showing of all captures in the pattern, to check+    unset ones at the end. It may be set on the pattern or the data. Implement+    by setting capcount to the maximum. This is not relevant for DFA matching,+    so ignore it (warning given above). */++    if ((dat_datctl.control & (CTL_ALLCAPTURES|CTL_DFA)) == CTL_ALLCAPTURES)+      {+      capcount = maxcapcount + 1;   /* Allow for full match */+      if (capcount > (int)oveccount) capcount = oveccount;+      }++    /* "allvector" request showing the entire ovector. */++    if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0) capcount = oveccount;++    /* Output the captured substrings. Note that, for the matched string,+    the use of \K in an assertion can make the start later than the end. */++    for (i = 0; i < 2*capcount; i += 2)+      {+      PCRE2_SIZE lleft, lmiddle, lright;+      PCRE2_SIZE start = ovector[i];+      PCRE2_SIZE end = ovector[i+1];++      if (start > end)+        {+        start = ovector[i+1];+        end = ovector[i];+        fprintf(outfile, "Start of matched string is beyond its end - "+          "displaying from end to start.\n");+        }++      fprintf(outfile, "%2d: ", i/2);++      /* Check for an unset group */++      if (start == PCRE2_UNSET && end == PCRE2_UNSET)+        {+        fprintf(outfile, "<unset>\n");+        continue;+        }++      /* Check for silly offsets, in particular, values that have not been+      set when they should have been. However, if we are past the end of the+      captures for this pattern ("allvector" causes this), or if we are DFA+      matching, it isn't an error if the entry is unchanged. */++      if (start > ulen || end > ulen)+        {+        if (((dat_datctl.control & CTL_DFA) != 0 ||+              i >= (int)(2*maxcapcount + 2)) &&+            start == JUNK_OFFSET && end == JUNK_OFFSET)+          fprintf(outfile, "<unchanged>\n");+        else+          fprintf(outfile, "ERROR: bad value(s) for offset(s): 0x%lx 0x%lx\n",+            (unsigned long int)start, (unsigned long int)end);+        continue;+        }++      /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with+      JIT, it is disabled above, with a comment.) When the match is done by the+      interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is+      set, and if the leftmost consulted character is before the start of the+      match or the rightmost consulted character is past the end of the match,+      we want to show all consulted characters for the main matched string, and+      indicate which were lookarounds. */++      if (i == 0)+        {+        BOOL showallused;+        PCRE2_SIZE leftchar, rightchar;++        if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0)+          {+          leftchar = FLD(match_data, leftchar);+          rightchar = FLD(match_data, rightchar);+          showallused = i == 0 && (leftchar < start || rightchar > end);+          }+        else showallused = FALSE;++        if (showallused)+          {+          PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile);+          PCHARS(lmiddle, pp, start, end - start, utf, outfile);+          PCHARS(lright, pp, end, rightchar - end, utf, outfile);+          if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)+            fprintf(outfile, " (JIT)");+          fprintf(outfile, "\n    ");+          for (j = 0; j < lleft; j++) fprintf(outfile, "<");+          for (j = 0; j < lmiddle; j++) fprintf(outfile, " ");+          for (j = 0; j < lright; j++) fprintf(outfile, ">");+          }++        /* When a pattern contains \K, the start of match position may be+        different to the start of the matched string. When this is the case,+        show it when requested. */++        else if ((dat_datctl.control & CTL_STARTCHAR) != 0)+          {+          PCRE2_SIZE startchar;+          PCRE2_GET_STARTCHAR(startchar, match_data);+          PCHARS(lleft, pp, startchar, start - startchar, utf, outfile);+          PCHARSV(pp, start, end - start, utf, outfile);+          if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)+            fprintf(outfile, " (JIT)");+          if (startchar != start)+            {+            fprintf(outfile, "\n    ");+            for (j = 0; j < lleft; j++) fprintf(outfile, "^");+            }+          }++        /* Otherwise, just show the matched string. */++        else+          {+          PCHARSV(pp, start, end - start, utf, outfile);+          if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)+            fprintf(outfile, " (JIT)");+          }+        }++      /* Not the main matched string. Just show it unadorned. */++      else+        {+        PCHARSV(pp, start, end - start, 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. */++      if ((dat_datctl.control & CTL_ALLAFTERTEXT) != 0 ||+          (i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0))+        {+        fprintf(outfile, "%2d+ ", i/2);+        PCHARSV(pp, ovector[i+1], ulen - ovector[i+1], utf, outfile);+        fprintf(outfile, "\n");+        }+      }++    /* Output (*MARK) data if requested */++    if ((dat_datctl.control & CTL_MARK) != 0 &&+         TESTFLD(match_data, mark, !=, NULL))+      {+      fprintf(outfile, "MK: ");+      PCHARSV(CASTFLD(void *, match_data, mark), -1, -1, utf, outfile);+      fprintf(outfile, "\n");+      }++    /* Process copy/get strings */++    if (!copy_and_get(utf, capcount)) return PR_ABEND;++    }    /* End of handling a successful match */++  /* There was a partial match. The value of ovector[0] is the bumpalong point,+  that is, startchar, not any \K point that might have been passed. When JIT is+  not in use, "allusedtext" may be set, in which case we indicate the leftmost+  consulted character. */++  else if (capcount == PCRE2_ERROR_PARTIAL)+    {+    PCRE2_SIZE leftchar;+    int backlength;+    int rubriclength = 0;++    if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0)+      {+      leftchar = FLD(match_data, leftchar);+      }+    else leftchar = ovector[0];++    fprintf(outfile, "Partial match");+    if ((dat_datctl.control & CTL_MARK) != 0 &&+         TESTFLD(match_data, mark, !=, NULL))+      {+      fprintf(outfile, ", mark=");+      PCHARS(rubriclength, CASTFLD(void *, match_data, mark), -1, -1, utf,+        outfile);+      rubriclength += 7;+      }+    fprintf(outfile, ": ");+    rubriclength += 15;++    PCHARS(backlength, pp, leftchar, ovector[0] - leftchar, utf, outfile);+    PCHARSV(pp, ovector[0], ulen - ovector[0], utf, outfile);++    if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)+      fprintf(outfile, " (JIT)");+    fprintf(outfile, "\n");++    if (backlength != 0)+      {+      int i;+      for (i = 0; i < rubriclength; i++) fprintf(outfile, " ");+      for (i = 0; i < backlength; i++) fprintf(outfile, "<");+      fprintf(outfile, "\n");+      }++    if (ulen != ovector[1])+      fprintf(outfile, "** ovector[1] is not equal to the subject length: "+        "%ld != %ld\n", (unsigned long int)ovector[1], (unsigned long int)ulen);++    /* Process copy/get strings */++    if (!copy_and_get(utf, 1)) return PR_ABEND;++    /* "allvector" outputs the entire vector */++    if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)+      show_ovector(ovector, oveccount);++    break;  /* Out of the /g loop */+    }       /* End of handling partial match */++  /* Failed to match. If this is a /g or /G loop, we might previously have+  set g_notempty (to PCRE2_NOTEMPTY_ATSTART|PCRE2_ANCHORED) after a null match.+  If that is the case, this is not necessarily the end. We want to advance the+  start offset, and continue. We won't be at the end of the string - that was+  checked before setting g_notempty. We achieve the effect by pretending that a+  single character was matched.++  Complication arises in the case when the newline convention is "any", "crlf",+  or "anycrlf". If the previous match was at the end of a line terminated by+  CRLF, an advance of one character just passes the CR, whereas we should+  prefer the longer newline sequence, as does the code in pcre2_match().++  Otherwise, in the case of UTF-8 or UTF-16 matching, the advance must be one+  character, not one byte. */++  else if (g_notempty != 0)   /* There was a previous null match */+    {+    uint16_t nl = FLD(compiled_code, newline_convention);+    PCRE2_SIZE start_offset = dat_datctl.offset;    /* Where the match was */+    PCRE2_SIZE end_offset = start_offset + 1;++    if ((nl == PCRE2_NEWLINE_CRLF || nl == PCRE2_NEWLINE_ANY ||+         nl == PCRE2_NEWLINE_ANYCRLF) &&+        start_offset < ulen - 1 &&+        CODE_UNIT(pp, start_offset) == '\r' &&+        CODE_UNIT(pp, end_offset) == '\n')+      end_offset++;++    else if (utf && test_mode != PCRE32_MODE)+      {+      if (test_mode == PCRE8_MODE)+        {+        for (; end_offset < ulen; end_offset++)+          if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break;+        }+      else  /* 16-bit mode */+        {+        for (; end_offset < ulen; end_offset++)+          if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break;+        }+      }++    SETFLDVEC(match_data, ovector, 0, start_offset);+    SETFLDVEC(match_data, ovector, 1, end_offset);+    }  /* End of handling null match in a global loop */++  /* A "normal" match failure. There will be a negative error number in+  capcount. */++  else+    {+    switch(capcount)+      {+      case PCRE2_ERROR_NOMATCH:+      if (gmatched == 0)+        {+        fprintf(outfile, "No match");+        if ((dat_datctl.control & CTL_MARK) != 0 &&+             TESTFLD(match_data, mark, !=, NULL))+          {+          fprintf(outfile, ", mark = ");+          PCHARSV(CASTFLD(void *, match_data, mark), -1, -1, utf, outfile);+          }+        if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)+          fprintf(outfile, " (JIT)");+        fprintf(outfile, "\n");++        /* "allvector" outputs the entire vector */++        if ((dat_datctl.control2 & CTL2_ALLVECTOR) != 0)+          show_ovector(ovector, oveccount);+        }+      break;++      case PCRE2_ERROR_BADUTFOFFSET:+      fprintf(outfile, "Error %d (bad UTF-%d offset)\n", capcount, test_mode);+      break;++      default:+      fprintf(outfile, "Failed: error %d: ", capcount);+      if (!print_error_message(capcount, "", "")) return PR_ABEND;+      if (capcount <= PCRE2_ERROR_UTF8_ERR1 &&+          capcount >= PCRE2_ERROR_UTF32_ERR2)+        {+        PCRE2_SIZE startchar;+        PCRE2_GET_STARTCHAR(startchar, match_data);+        fprintf(outfile, " at offset %" SIZ_FORM, SIZ_CAST startchar);+        }+      fprintf(outfile, "\n");+      break;+      }++    break;  /* Out of the /g loop */+    }       /* End of failed match handling */++  /* Control reaches here in two circumstances: (a) after a match, and (b)+  after a non-match that immediately followed a match on an empty string when+  doing a global search. Such a match is done with PCRE2_NOTEMPTY_ATSTART and+  PCRE2_ANCHORED set in g_notempty. The code above turns it into a fake match+  of one character. So effectively we get here only after a match. If we+  are not doing a global search, we are done. */++  if ((dat_datctl.control & CTL_ANYGLOB) == 0) break; else+    {+    PCRE2_SIZE match_offset = FLD(match_data, ovector)[0];+    PCRE2_SIZE end_offset = FLD(match_data, ovector)[1];++    /* We must now set up for the next iteration of a global search. If we have+    matched an empty string, first check to see if we are at the end of the+    subject. If so, the loop is over. Otherwise, mimic what Perl's /g option+    does. Set PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED and try the match again+    at the same point. If this fails it will be picked up above, where a fake+    match is set up so that at this point we advance to the next character.++    However, in order to cope with patterns that never match at their starting+    offset (e.g. /(?<=\G.)/) we don't do this when the match offset is greater+    than the starting offset. This means there will be a retry with the+    starting offset at the match offset. If this returns the same match again,+    it is picked up above and ignored, and the special action is then taken. */++    if (match_offset == end_offset)+      {+      if (end_offset == ulen) break;           /* End of subject */+      if (match_offset <= dat_datctl.offset)+        g_notempty = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;+      }++    /* However, even after matching a non-empty string, there is still one+    tricky case. 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. In the case of a normal /g iteration without special action, this+    leads to a loop that keeps on returning the same substring. The loop would+    be caught above, but we really want to move on to the next match. */++    else+      {+      g_notempty = 0;   /* Set for a "normal" repeat */+      if ((dat_datctl.control & CTL_GLOBAL) != 0)+        {+        PCRE2_SIZE startchar;+        PCRE2_GET_STARTCHAR(startchar, match_data);+        if (end_offset <= startchar)+          {+          if (startchar >= ulen) break;       /* End of subject */+          end_offset = startchar + 1;+          if (utf && test_mode != PCRE32_MODE)+            {+            if (test_mode == PCRE8_MODE)+              {+              for (; end_offset < ulen; end_offset++)+                if ((((PCRE2_SPTR8)pp)[end_offset] & 0xc0) != 0x80) break;+              }+            else  /* 16-bit mode */+              {+              for (; end_offset < ulen; end_offset++)+                if ((((PCRE2_SPTR16)pp)[end_offset] & 0xfc00) != 0xdc00) break;+              }+            }+          }+        }+      }++    /* For a normal global (/g) iteration, save the current ovector[0,1] and+    the starting offset so that we can check that they do change each time.+    Otherwise a matching bug that returns the same string causes an infinite+    loop. It has happened! Then update the start offset, leaving other+    parameters alone. */++    if ((dat_datctl.control & CTL_GLOBAL) != 0)+      {+      ovecsave[0] = ovector[0];+      ovecsave[1] = ovector[1];+      ovecsave[2] = dat_datctl.offset;+      dat_datctl.offset = end_offset;+      }++    /* For altglobal, just update the pointer and length. */++    else+      {+      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 */++show_memory = FALSE;+return PR_OK;+}+++++/*************************************************+*               Print PCRE2 version              *+*************************************************/++static void+print_version(FILE *f)+{+VERSION_TYPE *vp;+fprintf(f, "PCRE2 version ");+for (vp = version; *vp != 0; vp++) fprintf(f, "%c", *vp);+fprintf(f, "\n");+}++++/*************************************************+*               Print Unicode version            *+*************************************************/++static void+print_unicode_version(FILE *f)+{+VERSION_TYPE *vp;+fprintf(f, "Unicode version ");+for (vp = uversion; *vp != 0; vp++) fprintf(f, "%c", *vp);+}++++/*************************************************+*               Print JIT target                 *+*************************************************/++static void+print_jit_target(FILE *f)+{+VERSION_TYPE *vp;+for (vp = jittarget; *vp != 0; vp++) fprintf(f, "%c", *vp);+}++++/*************************************************+*       Print newline configuration              *+*************************************************/++/* Output is always to stdout.++Arguments:+  rc         the return code from PCRE2_CONFIG_NEWLINE+  isc        TRUE if called from "-C newline"+Returns:     nothing+*/++static void+print_newline_config(uint32_t optval, BOOL isc)+{+if (!isc) printf("  Default newline sequence is ");+if (optval < sizeof(newlines)/sizeof(char *))+  printf("%s\n", newlines[optval]);+else+  printf("a non-standard value: %d\n", optval);+}++++/*************************************************+*             Usage function                     *+*************************************************/++static void+usage(void)+{+printf("Usage:     pcre2test [options] [<input file> [<output file>]]\n\n");+printf("Input and output default to stdin and stdout.\n");+#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)+printf("If input is a terminal, readline() is used to read from it.\n");+#else+printf("This version of pcre2test is not linked with readline().\n");+#endif+printf("\nOptions:\n");+#ifdef SUPPORT_PCRE2_8+printf("  -8            use the 8-bit library\n");+#endif+#ifdef SUPPORT_PCRE2_16+printf("  -16           use the 16-bit library\n");+#endif+#ifdef SUPPORT_PCRE2_32+printf("  -32           use the 32-bit library\n");+#endif+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");+printf("     backslash-C    use of \\C is enabled [0, 1]\n");+printf("     bsr            \\R type [ANYCRLF, ANY]\n");+printf("     ebcdic         compiled for EBCDIC character code [0,1]\n");+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, 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 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 modifier 'info'\n");+printf("  -jit          set default pattern modifier 'jit'\n");+printf("  -jitfast      set default pattern modifier 'jitfast'\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 modifier fields\n");+printf("  -subject <s>  set default subject modifier fields\n");+printf("  -S <n>        set stack size to <n> mebibytes\n");+printf("  -t [<n>]      time compilation and execution, repeating <n> times\n");+printf("  -tm [<n>]     time execution (matching) only, repeating <n> times\n");+printf("  -T            same as -t, but show total times at the end\n");+printf("  -TM           same as -tm, but show total time at the end\n");+printf("  -version      show PCRE2 version and exit\n");+}++++/*************************************************+*             Handle -C option                   *+*************************************************/++/* This option outputs configuration options and sets an appropriate return+code when asked for a single option. The code is abstracted into a separate+function because of its size. Use whichever pcre2_config() function is+available.++Argument:   an option name or NULL+Returns:    the return code+*/++static int+c_option(const char *arg)+{+uint32_t optval;+unsigned int i = COPTLISTCOUNT;+int yield = 0;++if (arg != NULL && arg[0] != CHAR_MINUS)+  {+  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 0;+    }++  switch (coptlist[i].type)+    {+    case CONF_BSR:+    (void)PCRE2_CONFIG(coptlist[i].value, &optval);+    printf("%s\n", (optval == PCRE2_BSR_ANYCRLF)? "ANYCRLF" : "ANY");+    break;++    case CONF_FIX:+    yield = coptlist[i].value;+    printf("%d\n", yield);+    break;++    case CONF_FIZ:+    optval = coptlist[i].value;+    printf("%d\n", optval);+    break;++    case CONF_INT:+    (void)PCRE2_CONFIG(coptlist[i].value, &yield);+    printf("%d\n", yield);+    break;++    case CONF_NL:+    (void)PCRE2_CONFIG(coptlist[i].value, &optval);+    print_newline_config(optval, TRUE);+    break;+    }++/* For VMS, return the value by setting a symbol, for certain values only. This+is contributed code which the PCRE2 developers have no means of testing. */++#ifdef __VMS++/* This is the original code provided by the first VMS contributor. */+#ifdef NEVER+  if (copytlist[i].type == CONF_FIX || coptlist[i].type == CONF_INT)+    {+    char ucname[16];+    strcpy(ucname, coptlist[i].name);+    for (i = 0; ucname[i] != 0; i++) ucname[i] = toupper[ucname[i]];+    vms_setsymbol(ucname, 0, optval);+    }+#endif++/* This is the new code, provided by a second VMS contributor. */++  if (coptlist[i].type == CONF_FIX || coptlist[i].type == CONF_INT)+    {+    char nam_buf[22], val_buf[4];+    $DESCRIPTOR(nam, nam_buf);+    $DESCRIPTOR(val, val_buf);++    strcpy(nam_buf, coptlist[i].name);+    nam.dsc$w_length = strlen(nam_buf);+    sprintf(val_buf, "%d", yield);+    val.dsc$w_length = strlen(val_buf);+    lib$set_symbol(&nam, &val);+    }+#endif  /* __VMS */++  return yield;+  }++/* No argument for -C: output all configuration information. */++print_version(stdout);+printf("Compiled with\n");++#ifdef EBCDIC+printf("  EBCDIC code support: LF is 0x%02x\n", CHAR_LF);+#if defined NATIVE_ZOS+printf("  EBCDIC code page %s or similar\n", pcrz_cpversion());+#endif+#endif++(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);+if (optval != 0)+  {+  printf("  UTF and UCP support (");+  print_unicode_version(stdout);+  printf(")\n");+  }+else printf("  No Unicode support\n");++(void)PCRE2_CONFIG(PCRE2_CONFIG_JIT, &optval);+if (optval != 0)+  {+  printf("  Just-in-time compiler support: ");+  print_jit_target(stdout);+  printf("\n");+  }+else+  {+  printf("  No just-in-time compiler support\n");+  }++(void)PCRE2_CONFIG(PCRE2_CONFIG_NEWLINE, &optval);+print_newline_config(optval, FALSE);+(void)PCRE2_CONFIG(PCRE2_CONFIG_BSR, &optval);+printf("  \\R matches %s\n",+  (optval == PCRE2_BSR_ANYCRLF)? "CR, LF, or CRLF only" :+                                 "all Unicode newlines");+(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 kibibytes\n", optval);+(void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval);+printf("  Default match limit = %d\n", optval);+(void)PCRE2_CONFIG(PCRE2_CONFIG_DEPTHLIMIT, &optval);+printf("  Default depth limit = %d\n", optval);++#if defined SUPPORT_LIBREADLINE+printf("  pcre2test has libreadline support\n");+#elif defined SUPPORT_LIBEDIT+printf("  pcre2test has libedit support\n");+#else+printf("  pcre2test has neither libreadline nor libedit support\n");+#endif++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;+BOOL notdone = TRUE;+BOOL quiet = FALSE;+BOOL showtotaltimes = FALSE;+BOOL skipping = FALSE;+char *arg_subject = NULL;+char *arg_pattern = NULL;+char *arg_error = NULL;++/* The offsets to the options and control bits fields of the pattern and data+control blocks must be the same so that common options and controls such as+"anchored" or "memory" can work for either of them from a single table entry.+We cannot test this till runtime because "offsetof" does not work in the+preprocessor. */++if (PO(options) != DO(options) || PO(control) != DO(control) ||+    PO(control2) != DO(control2))+  {+  fprintf(stderr, "** Coding error: "+    "options and control offsets for pattern and data must be the same.\n");+  return 1;+  }++/* Get the PCRE2 and Unicode version number and JIT target information, at the+same time checking that a request for the length gives the same answer. Also+check lengths for non-string items. */++if (PCRE2_CONFIG(PCRE2_CONFIG_VERSION, NULL) !=+    PCRE2_CONFIG(PCRE2_CONFIG_VERSION, version) ||++    PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, NULL) !=+    PCRE2_CONFIG(PCRE2_CONFIG_UNICODE_VERSION, uversion) ||++    PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, NULL) !=+    PCRE2_CONFIG(PCRE2_CONFIG_JITTARGET, jittarget) ||++    PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, NULL) != sizeof(uint32_t) ||+    PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, NULL) != sizeof(uint32_t))+  {+  fprintf(stderr, "** Error in pcre2_config(): bad length\n");+  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. */++buffer = (uint8_t *)malloc(pbuffer8_size);+pbuffer8 = (uint8_t *)malloc(pbuffer8_size);++/* The following  _setmode() stuff is some Windows magic that tells its runtime+library to translate CRLF into a single LF character. At least, that's what+I've been told: never having used Windows I take this all on trust. Originally+it set 0x8000, but then I was advised that _O_BINARY was better. */++#if defined(_WIN32) || defined(WIN32)+_setmode( _fileno( stdout ), _O_BINARY );+#endif++/* 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.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. */++while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0)+  {+  char *endptr;+  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)+    {+    yield = c_option(argv[op + 1]);+    goto EXIT;+    }++  /* 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");+    exit(1);+#endif+    }++  /* Set quiet (no version verification) */++  else if (strcmp(arg, "-q") == 0) quiet = TRUE;++  /* Set system stack size */++  else if (strcmp(arg, "-S") == 0 && argc > 2 &&+      ((uli = strtoul(argv[op+1], &endptr, 10)), *endptr == 0))+    {+#if defined(_WIN32) || defined(WIN32) || defined(__minix) || defined(NATIVE_ZOS) || defined(__VMS)+    fprintf(stderr, "pcre2test: -S is not supported on this OS\n");+    exit(1);+#else+    int rc;+    uint32_t stack_size;+    struct rlimit rlim;+    if (U32OVERFLOW(uli))+      {+      fprintf(stderr, "** Argument for -S is too big\n");+      exit(1);+      }+    stack_size = (uint32_t)uli;+    getrlimit(RLIMIT_STACK, &rlim);+    rlim.rlim_cur = stack_size * 1024 * 1024;+    if (rlim.rlim_cur > rlim.rlim_max)+      {+      fprintf(stderr,+        "pcre2test: requested stack size %luMiB is greater than hard limit "+          "%luMiB\n", (unsigned long int)stack_size,+          (unsigned long int)(rlim.rlim_max));+      exit(1);+      }+    rc = setrlimit(RLIMIT_STACK, &rlim);+    if (rc != 0)+      {+      fprintf(stderr, "pcre2test: setting stack size %luMiB failed: %s\n",+        (unsigned long int)stack_size, strerror(errno));+      exit(1);+      }+    op++;+    argc--;+#endif+    }++  /* Set some common pattern and subject controls */++  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 ||+           strcmp(arg, "-jitfast") == 0)+    {+    if (arg[4] == 'v') def_patctl.control |= CTL_JITVERIFY;+      else if (arg[4] == 'f') def_patctl.control |= CTL_JITFAST;+    def_patctl.jit = JIT_DEFAULT;  /* full & partial */+#ifndef SUPPORT_JIT+    fprintf(stderr, "** Warning: JIT support is not available: "+                    "-jit[fast|verify] calls functions that do nothing.\n");+#endif+    }++  /* Set timing parameters */++  else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0 ||+           strcmp(arg, "-T") == 0 || strcmp(arg, "-TM") == 0)+    {+    int both = arg[2] == 0;+    showtotaltimes = arg[1] == 'T';+    if (argc > 2 && (uli = strtoul(argv[op+1], &endptr, 10), *endptr == 0))+      {+      if (uli == 0)+        {+        fprintf(stderr, "** Argument for %s must not be zero\n", arg);+        exit(1);+        }+      if (U32OVERFLOW(uli))+        {+        fprintf(stderr, "** Argument for %s is too big\n", arg);+        exit(1);+        }+      timeitm = (int)uli;+      op++;+      argc--;+      }+    else timeitm = LOOPREPEAT;+    if (both) timeit = timeitm;+    }++  /* Give help */++  else if (strcmp(arg, "-help") == 0 ||+           strcmp(arg, "--help") == 0)+    {+    usage();+    goto EXIT;+    }++  /* Show version */++  else if (strcmp(arg, "-version") == 0 ||+           strcmp(arg, "--version") == 0)+    {+    print_version(stdout);+    goto EXIT;+    }++  /* The following options save their data for processing once we know what+  the running mode is. */++  else if (strcmp(arg, "-error") == 0)+    {+    arg_error = argv[op+1];+    goto CHECK_VALUE_EXISTS;+    }++  else if (strcmp(arg, "-subject") == 0)+    {+    arg_subject = argv[op+1];+    goto CHECK_VALUE_EXISTS;+    }++  else if (strcmp(arg, "-pattern") == 0)+    {+    arg_pattern = argv[op+1];+    CHECK_VALUE_EXISTS:+    if (argc <= 2)+      {+      fprintf(stderr, "** Missing value for %s\n", arg);+      yield = 1;+      goto EXIT;+      }+    op++;+    argc--;+    }++  /* Unrecognized option */++  else+    {+    fprintf(stderr, "** Unknown or malformed option '%s'\n", arg);+    usage();+    yield = 1;+    goto EXIT;+    }+  op++;+  argc--;+  }++/* If -error was present, get the error numbers, show the messages, and exit.+We wait to do this until we know which mode we are in. */++if (arg_error != NULL)+  {+  int len;+  int errcode;+  char *endptr;++/* 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)+    {+    pbuffer16_size = 256;+    pbuffer16 = (uint16_t *)malloc(pbuffer16_size);+    if (pbuffer16 == NULL)+      {+      fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer16\n",+        SIZ_CAST pbuffer16_size);+      yield = 1;+      goto EXIT;+      }+    }+#endif++#ifdef SUPPORT_PCRE2_32+  if (test_mode == PCRE32_MODE)+    {+    pbuffer32_size = 512;+    pbuffer32 = (uint32_t *)malloc(pbuffer32_size);+    if (pbuffer32 == NULL)+      {+      fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer32\n",+        SIZ_CAST pbuffer32_size);+      yield = 1;+      goto EXIT;+      }+    }+#endif++  /* Loop along a list of error numbers. */++  for (;;)+    {+    errcode = strtol(arg_error, &endptr, 10);+    if (*endptr != 0 && *endptr != CHAR_COMMA)+      {+      fprintf(stderr, "** '%s' is not a valid error number list\n", arg_error);+      yield = 1;+      goto EXIT;+      }+    printf("Error %d: ", errcode);+    PCRE2_GET_ERROR_MESSAGE(len, errcode, pbuffer);+    if (len < 0)+      {+      switch (len)+        {+        case PCRE2_ERROR_BADDATA:+        printf("PCRE2_ERROR_BADDATA (unknown error number)");+        break;++        case PCRE2_ERROR_NOMEMORY:+        printf("PCRE2_ERROR_NOMEMORY (buffer too small)");+        break;++        default:+        printf("Unexpected return (%d) from pcre2_get_error_message()", len);+        break;+        }+      }+    else+      {+      PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, stdout);+      }+    printf("\n");+    if (*endptr == 0) goto EXIT;+    arg_error = endptr + 1;+    }+  /* Control never reaches here */+  }  /* End of -error handling */++/* Initialize things that cannot be done until we know which test mode we are+running in. Exercise the general context copying and match data size functions,+which are not otherwise used. */++code_unit_size = test_mode/8;+max_oveccount = DEFAULT_OVECCOUNT;++/* Use macros to save a lot of duplication. */++#define CREATECONTEXTS \+  G(general_context,BITS) = G(pcre2_general_context_create_,BITS)(&my_malloc, &my_free, NULL); \+  G(general_context_copy,BITS) = G(pcre2_general_context_copy_,BITS)(G(general_context,BITS)); \+  G(default_pat_context,BITS) = G(pcre2_compile_context_create_,BITS)(G(general_context,BITS)); \+  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))++#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); \+  (void)G(pcre2_get_match_data_size_,BITS)(G(match_data,BITS))+++/* Call the appropriate functions for the current mode, and exercise some+functions that are not otherwise called. */++#ifdef SUPPORT_PCRE2_8+#undef BITS+#define BITS 8+if (test_mode == PCRE8_MODE)+  {+  CREATECONTEXTS;+  CONTEXTTESTS;+  }+#endif++#ifdef SUPPORT_PCRE2_16+#undef BITS+#define BITS 16+if (test_mode == PCRE16_MODE)+  {+  CREATECONTEXTS;+  CONTEXTTESTS;+  }+#endif++#ifdef SUPPORT_PCRE2_32+#undef BITS+#define BITS 32+if (test_mode == PCRE32_MODE)+  {+  CREATECONTEXTS;+  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, 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+to do them all in the same way. */++outfile = stderr;+if ((arg_pattern != NULL &&+    !decode_modifiers((uint8_t *)arg_pattern, CTX_DEFPAT, &def_patctl, NULL)) ||+    (arg_subject != NULL &&+    !decode_modifiers((uint8_t *)arg_subject, CTX_DEFDAT, NULL, &def_datctl)))+  {+  yield = 1;+  goto EXIT;+  }++/* Sort out the input and output files, defaulting to stdin/stdout. */++infile = stdin;+outfile = stdout;++if (argc > 1 && strcmp(argv[op], "-") != 0)+  {+  infile = fopen(argv[op], INPUT_MODE);+  if (infile == NULL)+    {+    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': %s\n", argv[op+1], strerror(errno));+    yield = 1;+    goto EXIT;+    }+  }++/* Output a heading line unless quiet, then process input lines. */++if (!quiet) print_version(outfile);++SET(compiled_code, NULL);++#ifdef SUPPORT_PCRE2_8+preg.re_pcre2_code = NULL;+preg.re_match_data = NULL;+#endif++while (notdone)+  {+  uint8_t *p;+  int rc = PR_OK;+  BOOL expectdata = TEST(compiled_code, !=, NULL);+#ifdef SUPPORT_PCRE2_8+  expectdata |= preg.re_pcre2_code != NULL;+#endif++  if (extend_inputline(infile, buffer, expectdata? "data> " : "  re> ") == NULL)+    break;+  if (!INTERACTIVE(infile)) fprintf(outfile, "%s", (char *)buffer);+  fflush(outfile);+  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. */++  if (expectdata || skipping)+    {+    while (isspace(*p)) p++;+    if (*p == 0)+      {+#ifdef SUPPORT_PCRE2_8+      if (preg.re_pcre2_code != NULL)+        {+        regfree(&preg);+        preg.re_pcre2_code = NULL;+        preg.re_match_data = NULL;+        }+#endif  /* SUPPORT_PCRE2_8 */+      if (TEST(compiled_code, !=, NULL))+        {+        SUB1(pcre2_code_free, compiled_code);+        SET(compiled_code, NULL);+        }+      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. 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 == '#')+    {+    if (isspace(p[1]) || p[1] == '!' || p[1] == 0) continue;+    rc = process_command();+    }++  else if (strchr("/!\"'`%&-=_:;,@~", *p) != NULL)+    {+    rc = process_pattern();+    dfa_matched = 0;+    }++  else+    {+    while (isspace(*p)) p++;+    if (*p != 0)+      {+      fprintf(outfile, "** Invalid pattern delimiter '%c' (x%x).\n", *buffer,+        *buffer);+      rc = PR_SKIP;+      }+    }++  if (rc == PR_SKIP && !INTERACTIVE(infile)) skipping = TRUE;+  else if (rc == PR_ABEND)+    {+    fprintf(outfile, "** pcre2test run abandoned\n");+    yield = 1;+    goto EXIT;+    }+  }++/* Finish off a normal run. */++if (INTERACTIVE(infile)) fprintf(outfile, "\n");++if (showtotaltimes)+  {+  const char *pad = "";+  fprintf(outfile, "--------------------------------------\n");+  if (timeit > 0)+    {+    fprintf(outfile, "Total compile time %.4f milliseconds\n",+      (((double)total_compile_time * 1000.0) / (double)timeit) /+        (double)CLOCKS_PER_SEC);+    if (total_jit_compile_time > 0)+      fprintf(outfile, "Total JIT compile  %.4f milliseconds\n",+        (((double)total_jit_compile_time * 1000.0) / (double)timeit) /+          (double)CLOCKS_PER_SEC);+    pad = "  ";+    }+  fprintf(outfile, "Total match time %s%.4f milliseconds\n", pad,+    (((double)total_match_time * 1000.0) / (double)timeitm) /+      (double)CLOCKS_PER_SEC);+  }+++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);++free(buffer);+free(dbuffer);+free(pbuffer8);+free(dfa_workspace);+free((void *)locale_tables);+free(tables3);+PCRE2_MATCH_DATA_FREE(match_data);+SUB1(pcre2_code_free, compiled_code);++while(patstacknext-- > 0)+  {+  SET(compiled_code, patstack[patstacknext]);+  SUB1(pcre2_code_free, compiled_code);+  }++PCRE2_JIT_FREE_UNUSED_MEMORY(general_context);+if (jit_stack != NULL)+  {+  PCRE2_JIT_STACK_FREE(jit_stack);+  }++#define FREECONTEXTS \+  G(pcre2_general_context_free_,BITS)(G(general_context,BITS)); \+  G(pcre2_general_context_free_,BITS)(G(general_context_copy,BITS)); \+  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_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+#define BITS 8+if (preg.re_pcre2_code != NULL) regfree(&preg);+FREECONTEXTS;+#endif++#ifdef SUPPORT_PCRE2_16+#undef BITS+#define BITS 16+free(pbuffer16);+FREECONTEXTS;+#endif++#ifdef SUPPORT_PCRE2_32+#undef BITS+#define BITS 32+free(pbuffer32);+FREECONTEXTS;+#endif++#if defined(__VMS)+  yield = SS$_NORMAL;  /* Return values via DCL symbols */+#endif++return yield;+}++/* End of pcre2test.c */
+ src/c/pcre2/src/sljit/sljitConfig.h view
@@ -0,0 +1,172 @@+/*+ *    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.+ */++#ifndef SLJIT_CONFIG_H_+#define SLJIT_CONFIG_H_++#ifdef __cplusplus+extern "C" {+#endif++/*+  This file contains the basic configuration options for the SLJIT compiler+  and their default values. These options can be overridden in the+  sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a+  non-zero value.+*/++/* --------------------------------------------------------------------- */+/*  Architecture                                                         */+/* --------------------------------------------------------------------- */++/* Architecture selection. */+/* #define SLJIT_CONFIG_X86_32 1 */+/* #define SLJIT_CONFIG_X86_64 1 */+/* #define SLJIT_CONFIG_ARM_V5 1 */+/* #define SLJIT_CONFIG_ARM_V7 1 */+/* #define SLJIT_CONFIG_ARM_THUMB2 1 */+/* #define SLJIT_CONFIG_ARM_64 1 */+/* #define SLJIT_CONFIG_PPC_32 1 */+/* #define SLJIT_CONFIG_PPC_64 1 */+/* #define SLJIT_CONFIG_MIPS_32 1 */+/* #define SLJIT_CONFIG_MIPS_64 1 */+/* #define SLJIT_CONFIG_SPARC_32 1 */+/* #define SLJIT_CONFIG_TILEGX 1 */++/* #define SLJIT_CONFIG_AUTO 1 */+/* #define SLJIT_CONFIG_UNSUPPORTED 1 */++/* --------------------------------------------------------------------- */+/*  Utilities                                                            */+/* --------------------------------------------------------------------- */++/* Implements a stack like data structure (by using mmap / VirtualAlloc  */+/* or a custom allocator). */+#ifndef SLJIT_UTIL_STACK+/* Enabled by default */+#define SLJIT_UTIL_STACK 1+#endif++/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */+#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION+/* Disabled by default */+#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0+#endif++/* Single threaded application. Does not require any locks. */+#ifndef SLJIT_SINGLE_THREADED+/* Disabled by default. */+#define SLJIT_SINGLE_THREADED 0+#endif++/* --------------------------------------------------------------------- */+/*  Configuration                                                        */+/* --------------------------------------------------------------------- */++/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should+   define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */+#ifndef SLJIT_STD_MACROS_DEFINED+/* Disabled by default. */+#define SLJIT_STD_MACROS_DEFINED 0+#endif++/* Executable code allocation:+   If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should+   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.+   Instead, it creates a shared memory segment (usually backed by a file)+   and maps it twice, with different permissions, depending on the use+   case.+   The trade-off is increased use of virtual memory, incompatibility with+   fork(), and some possible additional security risks by the use of+   publicly accessible files for the generated code. */+#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR+/* Disabled by default. */+#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0+#endif++/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an+   allocator which does not set writable and executable permission+   flags at the same time.+   Instead, it creates a new independent map on each invocation and+   switches permissions at the underlying pages as needed.+   The trade-off is increased memory use and degraded performance. */+#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR+/* Disabled by default. */+#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0+#endif++#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */++/* Force cdecl calling convention even if a better calling+   convention (e.g. fastcall) is supported by the C compiler.+   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+#endif++/* Return with error when an invalid argument is passed. */+#ifndef SLJIT_ARGUMENT_CHECKS+/* Disabled by default */+#define SLJIT_ARGUMENT_CHECKS 0+#endif++/* Debug checks (assertions, etc.). */+#ifndef SLJIT_DEBUG+/* Enabled by default */+#define SLJIT_DEBUG 1+#endif++/* Verbose operations. */+#ifndef SLJIT_VERBOSE+/* Enabled by default */+#define SLJIT_VERBOSE 1+#endif++/*+  SLJIT_IS_FPU_AVAILABLE+    The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE.+      zero value - FPU is NOT present.+      nonzero value - FPU is present.+*/++/* For further configurations, see the beginning of sljitConfigInternal.h */++#ifdef __cplusplus+} /* extern "C" */+#endif++#endif /* SLJIT_CONFIG_H_ */
+ src/c/pcre2/src/sljit/sljitConfigInternal.h view
@@ -0,0 +1,800 @@+/*+ *    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.+ */++#ifndef SLJIT_CONFIG_INTERNAL_H_+#define SLJIT_CONFIG_INTERNAL_H_++#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \+	|| (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))+#include <stdio.h>+#endif++#if (defined SLJIT_DEBUG && SLJIT_DEBUG \+	&& (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS)))+#include <stdlib.h>+#endif++#ifdef __cplusplus+extern "C" {+#endif++/*+   SLJIT defines the following architecture dependent types and macros:++   Types:+     sljit_s8, sljit_u8   : signed and unsigned 8 bit integer type+     sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type+     sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type+     sljit_sw, sljit_uw   : signed and unsigned machine word, enough to store a pointer+     sljit_p              : unsgined pointer value (usually the same as sljit_uw, but+                            some 64 bit ABIs may use 32 bit pointers)+     sljit_f32            : 32 bit single precision floating point value+     sljit_f64            : 64 bit double precision floating point value++   Macros for feature detection (boolean):+     SLJIT_32BIT_ARCHITECTURE : 32 bit architecture+     SLJIT_64BIT_ARCHITECTURE : 64 bit architecture+     SLJIT_LITTLE_ENDIAN : little endian architecture+     SLJIT_BIG_ENDIAN : big endian architecture+     SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)+     SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information++   Constants:+     SLJIT_NUMBER_OF_REGISTERS : number of available registers+     SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers+     SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers+     SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers+     SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers+     SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers+     SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index+     SLJIT_F32_SHIFT : the shift required to apply when accessing+                       a single precision floating point array by index+     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_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT+     SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)+*/++/*****************/+/* Sanity check. */+/*****************/++#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \+	|| (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \+	|| (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \+	|| (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \+	|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \+	|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \+	|| (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \+	|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \+	|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \+	|| (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \+	|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \+	|| (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \+	|| (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \+	|| (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))+#error "An architecture must be selected"+#endif++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \+	+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \+	+ (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \+	+ (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \+	+ (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \+	+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \+	+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \+	+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \+	+ (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \+	+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \+	+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \+	+ (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \+	+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \+	+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2+#error "Multiple architectures are selected"+#endif++/********************************************************/+/* Automatic CPU detection (requires compiler support). */+/********************************************************/++#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)++#ifndef _WIN32++#if defined(__i386__) || defined(__i386)+#define SLJIT_CONFIG_X86_32 1+#elif defined(__x86_64__)+#define SLJIT_CONFIG_X86_64 1+#elif defined(__arm__) || defined(__ARM__)+#ifdef __thumb2__+#define SLJIT_CONFIG_ARM_THUMB2 1+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)+#define SLJIT_CONFIG_ARM_V7 1+#else+#define SLJIT_CONFIG_ARM_V5 1+#endif+#elif defined (__aarch64__)+#define SLJIT_CONFIG_ARM_64 1+#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__))+#define SLJIT_CONFIG_PPC_64 1+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)+#define SLJIT_CONFIG_PPC_32 1+#elif defined(__mips__) && !defined(_LP64)+#define SLJIT_CONFIG_MIPS_32 1+#elif defined(__mips64)+#define SLJIT_CONFIG_MIPS_64 1+#elif defined(__sparc__) || defined(__sparc)+#define SLJIT_CONFIG_SPARC_32 1+#elif defined(__tilegx__)+#define SLJIT_CONFIG_TILEGX 1+#else+/* Unsupported architecture */+#define SLJIT_CONFIG_UNSUPPORTED 1+#endif++#else /* _WIN32 */++#if defined(_M_X64) || defined(__x86_64__)+#define SLJIT_CONFIG_X86_64 1+#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)+#define SLJIT_CONFIG_ARM_THUMB2 1+#elif (defined(_M_ARM) && _M_ARM >= 7)+#define SLJIT_CONFIG_ARM_V7 1+#elif defined(_ARM_)+#define SLJIT_CONFIG_ARM_V5 1+#elif defined(_M_ARM64) || defined(__aarch64__)+#define SLJIT_CONFIG_ARM_64 1+#else+#define SLJIT_CONFIG_X86_32 1+#endif++#endif /* !_WIN32 */+#endif /* SLJIT_CONFIG_AUTO */++#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)+#undef SLJIT_EXECUTABLE_ALLOCATOR+#endif++/******************************/+/* CPU family type detection. */+/******************************/++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \+	|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)+#define SLJIT_CONFIG_ARM_32 1+#endif++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+#define SLJIT_CONFIG_X86 1+#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)+#define SLJIT_CONFIG_ARM 1+#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define SLJIT_CONFIG_PPC 1+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+#define SLJIT_CONFIG_MIPS 1+#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) || (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)+#define SLJIT_CONFIG_SPARC 1+#endif++/***********************************************************/+/* Intel Control-flow Enforcement Technology (CET) spport. */+/***********************************************************/++#ifdef SLJIT_CONFIG_X86++#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)+#define SLJIT_CONFIG_X86_CET 1+#endif++#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)+#include <x86intrin.h>+#endif++#endif /* SLJIT_CONFIG_X86 */++/**********************************/+/* External function definitions. */+/**********************************/++/* General macros:+   Note: SLJIT is designed to be independent from them as possible.++   In release mode (SLJIT_DEBUG is not defined) only the following+   external functions are needed:+*/++#ifndef SLJIT_MALLOC+#define SLJIT_MALLOC(size, allocator_data) malloc(size)+#endif++#ifndef SLJIT_FREE+#define SLJIT_FREE(ptr, allocator_data) free(ptr)+#endif++#ifndef SLJIT_MEMCPY+#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)+#endif++#ifndef SLJIT_MEMMOVE+#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)+#endif++#ifndef SLJIT_ZEROMEM+#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)+#endif++/***************************/+/* Compiler helper macros. */+/***************************/++#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)++#if defined(__GNUC__) && (__GNUC__ >= 3)+#define SLJIT_LIKELY(x)		__builtin_expect((x), 1)+#define SLJIT_UNLIKELY(x)	__builtin_expect((x), 0)+#else+#define SLJIT_LIKELY(x)		(x)+#define SLJIT_UNLIKELY(x)	(x)+#endif++#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */++#ifndef SLJIT_INLINE+/* Inline functions. Some old compilers do not support them. */+#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510+#define SLJIT_INLINE+#else+#define SLJIT_INLINE __inline+#endif+#endif /* !SLJIT_INLINE */++#ifndef SLJIT_NOINLINE+/* Not inline functions. */+#if defined(__GNUC__)+#define SLJIT_NOINLINE __attribute__ ((noinline))+#else+#define SLJIT_NOINLINE+#endif+#endif /* !SLJIT_INLINE */++#ifndef SLJIT_UNUSED_ARG+/* Unused arguments. */+#define SLJIT_UNUSED_ARG(arg) (void)arg+#endif++/*********************************/+/* Type of public API functions. */+/*********************************/++#ifndef SLJIT_API_FUNC_ATTRIBUTE +#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)+/* Static ABI functions. For all-in-one programs. */++#if defined(__GNUC__)+/* Disable unused warnings in gcc. */+#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))+#else+#define SLJIT_API_FUNC_ATTRIBUTE static+#endif++#else+#define SLJIT_API_FUNC_ATTRIBUTE+#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */+#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */++/****************************/+/* Instruction cache flush. */+/****************************/++#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin)+#if __has_builtin(__builtin___clear_cache)++#define SLJIT_CACHE_FLUSH(from, to) \+	__builtin___clear_cache((char*)(from), (char*)(to))++#endif /* __has_builtin(__builtin___clear_cache) */+#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */++#ifndef SLJIT_CACHE_FLUSH++#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)++/* Not required to implement on archs with unified caches. */+#define SLJIT_CACHE_FLUSH(from, to)++#elif defined __APPLE__++/* Supported by all macs since Mac OS 10.5.+   However, it does not work on non-jailbroken iOS devices,+   although the compilation is successful. */++#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) \+	__builtin___clear_cache((char*)(from), (char*)(to))++#elif defined __ANDROID__++/* Android lacks __clear_cache; instead, cacheflush should be used. */++#define SLJIT_CACHE_FLUSH(from, to) \+    cacheflush((long)(from), (long)(to), 0)++#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)++/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */+#define SLJIT_CACHE_FLUSH(from, to) \+	sparc_cache_flush((from), (to))+#define SLJIT_CACHE_FLUSH_OWN_IMPL 1++#elif defined _WIN32++#define SLJIT_CACHE_FLUSH(from, to) \+	FlushInstructionCache(GetCurrentProcess(), (char*)(from), (char*)(to) - (char*)(from))++#else++/* Calls __ARM_NR_cacheflush on ARM-Linux. */+#define SLJIT_CACHE_FLUSH(from, to) \+	__clear_cache((char*)(from), (char*)(to))++#endif++#endif /* !SLJIT_CACHE_FLUSH */++/******************************************************/+/*    Integer and floating point type definitions.    */+/******************************************************/++/* 8 bit byte type. */+typedef unsigned char sljit_u8;+typedef signed char sljit_s8;++/* 16 bit half-word type. */+typedef unsigned short int sljit_u16;+typedef signed short int sljit_s16;++/* 32 bit integer type. */+typedef unsigned int sljit_u32;+typedef signed int sljit_s32;++/* Machine word type. Enough for storing a pointer.+     32 bit for 32 bit machines.+     64 bit for 64 bit machines. */+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)+/* Just to have something. */+#define SLJIT_WORD_SHIFT 0+typedef unsigned long int sljit_uw;+typedef long int sljit_sw;+#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \+	&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \+	&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \+	&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \+	&& !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)+#define SLJIT_32BIT_ARCHITECTURE 1+#define SLJIT_WORD_SHIFT 2+typedef unsigned int sljit_uw;+typedef int sljit_sw;+#else+#define SLJIT_64BIT_ARCHITECTURE 1+#define SLJIT_WORD_SHIFT 3+#ifdef _WIN32+#ifdef __GNUC__+/* These types do not require windows.h */+typedef unsigned long long sljit_uw;+typedef long long sljit_sw;+#else+typedef unsigned __int64 sljit_uw;+typedef __int64 sljit_sw;+#endif+#else /* !_WIN32 */+typedef unsigned long int sljit_uw;+typedef long int sljit_sw;+#endif /* _WIN32 */+#endif++typedef sljit_uw sljit_p;++/* Floating point types. */+typedef float sljit_f32;+typedef double sljit_f64;++/* Shift for pointer sized data. */+#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT++/* Shift for double precision sized data. */+#define SLJIT_F32_SHIFT 2+#define SLJIT_F64_SHIFT 3++#ifndef SLJIT_W++/* Defining long constants. */+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)+#define SLJIT_W(w)	(w##l)+#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)+#ifdef _WIN64+#define SLJIT_W(w)	(w##ll)+#else /* !windows */+#define SLJIT_W(w)	(w##l)+#endif /* windows */+#else /* 32 bit */+#define SLJIT_W(w)	(w)+#endif /* unknown */++#endif /* !SLJIT_W */++/*************************/+/* Endianness detection. */+/*************************/++#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)++/* These macros are mostly useful for the applications. */+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \+	|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)++#ifdef __LITTLE_ENDIAN__+#define SLJIT_LITTLE_ENDIAN 1+#else+#define SLJIT_BIG_ENDIAN 1+#endif++#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \+	|| (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)++#ifdef __MIPSEL__+#define SLJIT_LITTLE_ENDIAN 1+#else+#define SLJIT_BIG_ENDIAN 1+#endif++#ifndef SLJIT_MIPS_REV++/* Auto detecting mips revision. */+#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)+#define SLJIT_MIPS_REV 6+#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \+	|| (defined __clang__ && defined _MIPS_ARCH_OCTEON) \+	|| (defined __clang__ && defined _MIPS_ARCH_P5600)+/* clang either forgets to define (clang-7) __mips_isa_rev at all+ * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)+ * and -march=p5600 (MIPS32 R5).+ * It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5+ * (should be set to N exactly) so we cannot rely on this too.+ */+#define SLJIT_MIPS_REV 1+#endif++#endif /* !SLJIT_MIPS_REV */++#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)++#define SLJIT_BIG_ENDIAN 1++#else+#define SLJIT_LITTLE_ENDIAN 1+#endif++#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */++/* Sanity check. */+#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)+#error "Exactly one endianness must be selected"+#endif++#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)+#error "Exactly one endianness must be selected"+#endif++#ifndef SLJIT_UNALIGNED++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \+	|| (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \+	|| (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \+	|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \+	|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \+	|| (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \+	|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define SLJIT_UNALIGNED 1+#endif++#endif /* !SLJIT_UNALIGNED */++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+/* Auto detect SSE2 support using CPUID.+   On 64 bit x86 cpus, sse2 must be present. */+#define SLJIT_DETECT_SSE2 1+#endif++/*****************************************************************************************/+/* Calling convention of functions generated by SLJIT or called from the generated code. */+/*****************************************************************************************/++#ifndef SLJIT_FUNC++#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) \+	|| !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)++#define SLJIT_FUNC++#elif defined(__GNUC__) && !defined(__APPLE__)++#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)+#define SLJIT_FUNC __attribute__ ((fastcall))+#define SLJIT_X86_32_FASTCALL 1+#else+#define SLJIT_FUNC+#endif /* gcc >= 3.4 */++#elif defined(_MSC_VER)++#define SLJIT_FUNC __fastcall+#define SLJIT_X86_32_FASTCALL 1++#elif defined(__BORLANDC__)++#define SLJIT_FUNC __msfastcall+#define SLJIT_X86_32_FASTCALL 1++#else /* Unknown compiler. */++/* The cdecl calling convention is usually the x86 default. */+#define SLJIT_FUNC++#endif /* SLJIT_USE_CDECL_CALLING_CONVENTION */++#endif /* !SLJIT_FUNC */++#ifndef SLJIT_INDIRECT_CALL+#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \+	|| ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)+/* It seems certain ppc compilers use an indirect addressing for functions+   which makes things complicated. */+#define SLJIT_INDIRECT_CALL 1+#endif+#endif /* SLJIT_INDIRECT_CALL */++/* The offset which needs to be substracted from the return address to+determine the next executed instruction after return. */+#ifndef SLJIT_RETURN_ADDRESS_OFFSET+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+#define SLJIT_RETURN_ADDRESS_OFFSET 8+#else+#define SLJIT_RETURN_ADDRESS_OFFSET 0+#endif+#endif /* SLJIT_RETURN_ADDRESS_OFFSET */++/***************************************************/+/* Functions of the built-in executable allocator. */+/***************************************************/++#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);+#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)+#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)++#ifndef SLJIT_MALLOC_EXEC+#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))+#endif /* SLJIT_MALLOC_EXEC */++#ifndef SLJIT_FREE_EXEC+#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))+#endif /* SLJIT_FREE_EXEC */++#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 /* SLJIT_EXECUTABLE_ALLOCATOR */++/**********************************************/+/* Registers and locals offset determination. */+/**********************************************/++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)++#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_SAVED_REGISTERS 6+#define SLJIT_LOCALS_OFFSET_BASE 0+#else /* _WIN64 */+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8+#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 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 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 26+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10+#define SLJIT_LOCALS_OFFSET_BASE 0++#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)++#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))+#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+/* Add +1 for double alignment. */+#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * sizeof(sljit_sw))+#else+#define SLJIT_LOCALS_OFFSET_BASE (3 * sizeof(sljit_sw))+#endif /* SLJIT_CONFIG_PPC_64 || _AIX */++#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)++#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))+#else+#define SLJIT_LOCALS_OFFSET_BASE 0+#endif++#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)++#define SLJIT_NUMBER_OF_REGISTERS 18+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+/* 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)++#define SLJIT_NUMBER_OF_REGISTERS 10+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5+#define SLJIT_LOCALS_OFFSET_BASE 0++#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)++#define SLJIT_NUMBER_OF_REGISTERS 0+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0+#define SLJIT_LOCALS_OFFSET_BASE 0++#endif++#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE)++#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \+	(SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)++#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 6+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && (defined _WIN64)+#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 1+#else+#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0+#endif++#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \+	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)++/*************************************/+/* Debug and verbose related macros. */+/*************************************/++#if (defined SLJIT_DEBUG && SLJIT_DEBUG)++#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)++/* SLJIT_HALT_PROCESS must halt the process. */+#ifndef SLJIT_HALT_PROCESS+#define SLJIT_HALT_PROCESS() \+	abort();+#endif /* !SLJIT_HALT_PROCESS */++#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */++/* Feel free to redefine these two macros. */+#ifndef SLJIT_ASSERT++#define SLJIT_ASSERT(x) \+	do { \+		if (SLJIT_UNLIKELY(!(x))) { \+			printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \+			SLJIT_HALT_PROCESS(); \+		} \+	} while (0)++#endif /* !SLJIT_ASSERT */++#ifndef SLJIT_UNREACHABLE++#define SLJIT_UNREACHABLE() \+	do { \+		printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \+		SLJIT_HALT_PROCESS(); \+	} while (0)++#endif /* !SLJIT_UNREACHABLE */++#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */++/* Forcing empty, but valid statements. */+#undef SLJIT_ASSERT+#undef SLJIT_UNREACHABLE++#define SLJIT_ASSERT(x) \+	do { } while (0)+#define SLJIT_UNREACHABLE() \+	do { } while (0)++#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */++#ifndef SLJIT_COMPILE_ASSERT++#define SLJIT_COMPILE_ASSERT(x, description) \+	switch(0) { case 0: case ((x) ? 1 : 0): break; }++#endif /* !SLJIT_COMPILE_ASSERT */++#ifdef __cplusplus+} /* extern "C" */+#endif++#endif /* SLJIT_CONFIG_INTERNAL_H_ */
+ src/c/pcre2/src/sljit/sljitExecAllocator.c view
@@ -0,0 +1,385 @@+/*+ *    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++/*+   alloc_chunk / free_chunk :+     * allocate executable system memory chunks+     * the size is always divisible by CHUNK_SIZE+   SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :+     * provided as part of sljitUtils+     * only the allocator requires this lock, sljit is fully thread safe+       as it only uses local variables+*/++#ifdef _WIN32++static SLJIT_INLINE void* alloc_chunk(sljit_uw size)+{+	return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);+}++static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)+{+	SLJIT_UNUSED_ARG(size);+	VirtualFree(chunk, 0, MEM_RELEASE);+}++#else++#ifdef __APPLE__+#ifdef MAP_ANON+/* Configures TARGET_OS_OSX when appropriate */+#include <TargetConditionals.h>++#if TARGET_OS_OSX && defined(MAP_JIT)+#include <sys/utsname.h>+#endif /* TARGET_OS_OSX && MAP_JIT */++#ifdef MAP_JIT++/*+   On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a+   version where it's OK to have more than one JIT block.+   On non-macOS systems, returns MAP_JIT if it is defined.+*/+static SLJIT_INLINE int get_map_jit_flag()+{+#if TARGET_OS_OSX+	sljit_sw page_size = get_page_alignment() + 1;+	void *ptr;+	static int map_jit_flag = -1;++	/*+	  The following code is thread safe because multiple initialization+	  sets map_jit_flag to the same value and the code has no side-effects.+	  Changing the kernel version witout system restart is (very) unlikely.+	*/+	if (map_jit_flag == -1) {+		struct utsname name;++		map_jit_flag = 0;+		uname(&name);++		/* Kernel version for 10.14.0 (Mojave) */+		if (atoi(name.release) >= 18) {+			/* Only use MAP_JIT if a hardened runtime is used */++			ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);++			if (ptr == MAP_FAILED) {+				map_jit_flag = MAP_JIT;+			} else {+				munmap(ptr, page_size);+			}+		}+	}++	return map_jit_flag;+#else /* !TARGET_OS_OSX */+	return MAP_JIT;+#endif /* TARGET_OS_OSX */+}++#endif /* MAP_JIT */+#endif /* MAP_ANON */+#endif /* __APPLE__ */++static SLJIT_INLINE void* alloc_chunk(sljit_uw size)+{+	void *retval;+	const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;++#ifdef MAP_ANON++	int flags = MAP_PRIVATE | MAP_ANON;++#ifdef MAP_JIT+	flags |= get_map_jit_flag();+#endif++	retval = mmap(NULL, size, prot, flags, -1, 0);+#else /* !MAP_ANON */+	if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))+		return NULL;++	retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);+#endif /* MAP_ANON */++	if (retval == MAP_FAILED)+		retval = NULL;+	else {+		if (mprotect(retval, size, prot) < 0) {+			munmap(retval, size);+			retval = NULL;+		}+	}++	return retval;+}++static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)+{+	munmap(chunk, size);+}++#endif++/* --------------------------------------------------------------------- */+/*  Common functions                                                     */+/* --------------------------------------------------------------------- */++#define CHUNK_MASK	(~(CHUNK_SIZE - 1))++struct block_header {+	sljit_uw size;+	sljit_uw prev_size;+};++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*)(((sljit_u8*)base) + sizeof(struct block_header)))+#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 block_header *header;+	struct block_header *next_header;+	struct free_block *free_block;+	sljit_uw chunk_size;++	SLJIT_ALLOCATOR_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;+				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;+			SLJIT_ALLOCATOR_UNLOCK();+			return MEM_START(header);+		}+		free_block = free_block->next;+	}++	chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;+	header = (struct block_header*)alloc_chunk(chunk_size);+	if (!header) {+		SLJIT_ALLOCATOR_UNLOCK();+		return NULL;+	}++	chunk_size -= sizeof(struct block_header);+	total_size += chunk_size;++	header->prev_size = 0;+	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;+		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;+	SLJIT_ALLOCATOR_UNLOCK();+	return MEM_START(header);+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)+{+	struct block_header *header;+	struct free_block* free_block;++	SLJIT_ALLOCATOR_LOCK();+	header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));+	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));+		}+	}++	SLJIT_ALLOCATOR_UNLOCK();+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)+{+	struct free_block* free_block;+	struct free_block* next_free_block;++	SLJIT_ALLOCATOR_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));+	SLJIT_ALLOCATOR_UNLOCK();+}
+ src/c/pcre2/src/sljit/sljitLir.c view
@@ -0,0 +1,2702 @@+/*+ *    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.+ */++#include "sljitLir.h"++#ifdef _WIN32++#include <windows.h>++#endif /* _WIN32 */++#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)) \+			return compiler->error; \+	} while (0)++#define CHECK_ERROR_PTR() \+	do { \+		if (SLJIT_UNLIKELY(compiler->error)) \+			return NULL; \+	} while (0)++#define FAIL_IF(expr) \+	do { \+		if (SLJIT_UNLIKELY(expr)) \+			return compiler->error; \+	} while (0)++#define PTR_FAIL_IF(expr) \+	do { \+		if (SLJIT_UNLIKELY(expr)) \+			return NULL; \+	} while (0)++#define FAIL_IF_NULL(ptr) \+	do { \+		if (SLJIT_UNLIKELY(!(ptr))) { \+			compiler->error = SLJIT_ERR_ALLOC_FAILED; \+			return SLJIT_ERR_ALLOC_FAILED; \+		} \+	} while (0)++#define PTR_FAIL_IF_NULL(ptr) \+	do { \+		if (SLJIT_UNLIKELY(!(ptr))) { \+			compiler->error = SLJIT_ERR_ALLOC_FAILED; \+			return NULL; \+		} \+	} while (0)++#define PTR_FAIL_WITH_EXEC_IF(ptr) \+	do { \+		if (SLJIT_UNLIKELY(!(ptr))) { \+			compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \+			return NULL; \+		} \+	} while (0)++#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)++#define VARIABLE_FLAG_SHIFT (10)+#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT)+#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)++#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_Z | VARIABLE_FLAG_MASK))++#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)+#define TYPE_CAST_NEEDED(op) \+	((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++#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)+#define ABUF_SIZE	2048+#else+#define ABUF_SIZE	4096+#endif++/* Parameter parsing. */+#define REG_MASK		0x3f+#define OFFS_REG(reg)		(((reg) >> 8) & REG_MASK)+#define OFFS_REG_MASK		(REG_MASK << 8)+#define TO_OFFS_REG(reg)	((reg) << 8)+/* When reg cannot be unused. */+#define FAST_IS_REG(reg)	((reg) <= REG_MASK)+/* 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+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+#	define PATCH_MD		0x10+#endif+#	define TYPE_SHIFT	13+#endif++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)+#	define IS_BL		0x4+#	define PATCH_B		0x8+#endif++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+#	define CPOOL_SIZE	512+#endif++#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)+#	define IS_COND		0x04+#	define IS_BL		0x08+	/* conditional + imm8 */+#	define PATCH_TYPE1	0x10+	/* conditional + imm20 */+#	define PATCH_TYPE2	0x20+	/* IT + imm24 */+#	define PATCH_TYPE3	0x30+	/* imm11 */+#	define PATCH_TYPE4	0x40+	/* imm24 */+#	define PATCH_TYPE5	0x50+	/* BL + imm24 */+#	define PATCH_BL		0x60+	/* 0xf00 cc code for branches */+#endif++#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)+#	define IS_COND		0x004+#	define IS_CBZ		0x008+#	define IS_BL		0x010+#	define PATCH_B		0x020+#	define PATCH_COND	0x040+#	define PATCH_ABS48	0x080+#	define PATCH_ABS64	0x100+#endif++#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)+#	define IS_COND		0x004+#	define IS_CALL		0x008+#	define PATCH_B		0x010+#	define PATCH_ABS_B	0x020+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#	define PATCH_ABS32	0x040+#	define PATCH_ABS48	0x080+#endif+#	define REMOVE_COND	0x100+#endif++#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)+#	define IS_MOVABLE	0x004+#	define IS_JAL		0x008+#	define IS_CALL		0x010+#	define IS_BIT26_COND	0x020+#	define IS_BIT16_COND	0x040+#	define IS_BIT23_COND	0x080++#	define IS_COND		(IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)++#	define PATCH_B		0x100+#	define PATCH_J		0x200++#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+#	define PATCH_ABS32	0x400+#	define PATCH_ABS48	0x800+#endif++	/* instruction types */+#	define MOVABLE_INS	0+	/* 1 - 31 last destination register */+	/* no destination (i.e: store) */+#	define UNMOVABLE_INS	32+	/* FPU status register */+#	define FCSR_FCC		33+#endif++#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)+#	define IS_JAL		0x04+#	define IS_COND		0x08++#	define PATCH_B		0x10+#	define PATCH_J		0x20+#endif++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+#	define IS_MOVABLE	0x04+#	define IS_COND		0x08+#	define IS_CALL		0x10++#	define PATCH_B		0x20+#	define PATCH_CALL	0x40++	/* instruction types */+#	define MOVABLE_INS	0+	/* 1 - 31 last destination register */+	/* no destination (i.e: store) */+#	define UNMOVABLE_INS	32++#	define DST_INS_MASK	0xff++	/* ICC_SET is the same as SET_FLAGS. */+#	define ICC_IS_SET	(1 << 23)+#	define FCC_IS_SET	(1 << 24)+#endif++/* Stack management. */++#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \+	(((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \+		(saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \+		extra) * sizeof(sljit_sw))++#define ADJUST_LOCAL_OFFSET(p, i) \+	if ((p) == (SLJIT_MEM1(SLJIT_SP))) \+		(i) += SLJIT_LOCALS_OFFSET;++#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */++/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */+#include "sljitUtils.c"++#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"+#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)+#include "sljitWXExecAllocator.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++#ifndef SLJIT_UPDATE_WX_FLAGS+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)+#endif++/* Argument checking features. */++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)++/* Returns with error when an invalid argument is passed. */++#define CHECK_ARGUMENT(x) \+	do { \+		if (SLJIT_UNLIKELY(!(x))) \+			return 1; \+	} while (0)++#define CHECK_RETURN_TYPE sljit_s32+#define CHECK_RETURN_OK return 0++#define CHECK(x) \+	do { \+		if (SLJIT_UNLIKELY(x)) { \+			compiler->error = SLJIT_ERR_BAD_ARGUMENT; \+			return SLJIT_ERR_BAD_ARGUMENT; \+		} \+	} while (0)++#define CHECK_PTR(x) \+	do { \+		if (SLJIT_UNLIKELY(x)) { \+			compiler->error = SLJIT_ERR_BAD_ARGUMENT; \+			return NULL; \+		} \+	} while (0)++#define CHECK_REG_INDEX(x) \+	do { \+		if (SLJIT_UNLIKELY(x)) { \+			return -2; \+		} \+	} while (0)++#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)++/* Assertion failure occures if an invalid argument is passed. */+#undef SLJIT_ARGUMENT_CHECKS+#define SLJIT_ARGUMENT_CHECKS 1++#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)+#define CHECK_RETURN_TYPE void+#define CHECK_RETURN_OK return+#define CHECK(x) x+#define CHECK_PTR(x) x+#define CHECK_REG_INDEX(x) x++#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)++/* Arguments are not checked. */+#define CHECK_RETURN_TYPE void+#define CHECK_RETURN_OK return+#define CHECK(x) x+#define CHECK_PTR(x) x+#define CHECK_REG_INDEX(x) x++#else++/* Arguments are not checked. */+#define CHECK(x)+#define CHECK_PTR(x)+#define CHECK_REG_INDEX(x)++#endif /* SLJIT_ARGUMENT_CHECKS */++/* --------------------------------------------------------------------- */+/*  Public functions                                                     */+/* --------------------------------------------------------------------- */++#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)+#define SLJIT_NEEDS_COMPILER_INIT 1+static sljit_s32 compiler_initialized = 0;+/* A thread safe initialization. */+static void init_compiler(void);+#endif++SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)+{+	struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);+	if (!compiler)+		return NULL;+	SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));++	SLJIT_COMPILE_ASSERT(+		sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1+		&& sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2+		&& sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4+		&& (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)+		&& sizeof(sljit_p) <= sizeof(sljit_sw)+		&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)+		&& (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),+		invalid_integer_types);+	SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP,+		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;++	compiler->allocator_data = allocator_data;+	compiler->exec_allocator_data = exec_allocator_data;+	compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);+	compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);++	if (!compiler->buf || !compiler->abuf) {+		if (compiler->buf)+			SLJIT_FREE(compiler->buf, allocator_data);+		if (compiler->abuf)+			SLJIT_FREE(compiler->abuf, allocator_data);+		SLJIT_FREE(compiler, allocator_data);+		return NULL;+	}++	compiler->buf->next = NULL;+	compiler->buf->used_size = 0;+	compiler->abuf->next = NULL;+	compiler->abuf->used_size = 0;++	compiler->scratches = -1;+	compiler->saveds = -1;+	compiler->fscratches = -1;+	compiler->fsaveds = -1;+	compiler->local_size = -1;++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	compiler->args = -1;+#endif++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)+		+ CPOOL_SIZE * sizeof(sljit_u8), allocator_data);+	if (!compiler->cpool) {+		SLJIT_FREE(compiler->buf, allocator_data);+		SLJIT_FREE(compiler->abuf, allocator_data);+		SLJIT_FREE(compiler, allocator_data);+		return NULL;+	}+	compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);+	compiler->cpool_diff = 0xffffffff;+#endif++#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)+	compiler->delay_slot = UNMOVABLE_INS;+#endif++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+	compiler->delay_slot = UNMOVABLE_INS;+#endif++#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)+	if (!compiler_initialized) {+		init_compiler();+		compiler_initialized = 1;+	}+#endif++	return compiler;+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	struct sljit_memory_fragment *curr;+	void *allocator_data = compiler->allocator_data;+	SLJIT_UNUSED_ARG(allocator_data);++	buf = compiler->buf;+	while (buf) {+		curr = buf;+		buf = buf->next;+		SLJIT_FREE(curr, allocator_data);+	}++	buf = compiler->abuf;+	while (buf) {+		curr = buf;+		buf = buf->next;+		SLJIT_FREE(curr, allocator_data);+	}++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	SLJIT_FREE(compiler->cpool, allocator_data);+#endif+	SLJIT_FREE(compiler, allocator_data);+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)+{+	if (compiler->error == SLJIT_SUCCESS)+		compiler->error = SLJIT_ERR_ALLOC_FAILED;+}++#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)+{+	/* Remove thumb mode flag. */+	SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1), exec_allocator_data);+}+#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)+{+	/* Resolve indirection. */+	code = (void*)(*(sljit_uw*)code);+	SLJIT_FREE_EXEC(code, exec_allocator_data);+}+#else+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)+{+	SLJIT_FREE_EXEC(code, exec_allocator_data);+}+#endif++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)+{+	if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {+		jump->flags &= ~JUMP_ADDR;+		jump->flags |= JUMP_LABEL;+		jump->u.label = label;+	}+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)+{+	if (SLJIT_LIKELY(!!jump)) {+		jump->flags &= ~JUMP_LABEL;+		jump->flags |= JUMP_ADDR;+		jump->u.target = target;+	}+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)+{+	if (SLJIT_LIKELY(!!put_label))+		put_label->label = label;+}++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                                                    */+/* --------------------------------------------------------------------- */++static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)+{+	sljit_u8 *ret;+	struct sljit_memory_fragment *new_frag;++	SLJIT_ASSERT(size <= 256);+	if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {+		ret = compiler->buf->memory + compiler->buf->used_size;+		compiler->buf->used_size += size;+		return ret;+	}+	new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);+	PTR_FAIL_IF_NULL(new_frag);+	new_frag->next = compiler->buf;+	compiler->buf = new_frag;+	new_frag->used_size = size;+	return new_frag->memory;+}++static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)+{+	sljit_u8 *ret;+	struct sljit_memory_fragment *new_frag;++	SLJIT_ASSERT(size <= 256);+	if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {+		ret = compiler->abuf->memory + compiler->abuf->used_size;+		compiler->abuf->used_size += size;+		return ret;+	}+	new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);+	PTR_FAIL_IF_NULL(new_frag);+	new_frag->next = compiler->abuf;+	compiler->abuf = new_frag;+	new_frag->used_size = size;+	return new_frag->memory;+}++SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)+{+	CHECK_ERROR_PTR();++#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)+	if (size <= 0 || size > 128)+		return NULL;+	size = (size + 7) & ~7;+#else+	if (size <= 0 || size > 64)+		return NULL;+	size = (size + 3) & ~3;+#endif+	return ensure_abuf(compiler, size);+}++static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf = compiler->buf;+	struct sljit_memory_fragment *prev = NULL;+	struct sljit_memory_fragment *tmp;++	do {+		tmp = buf->next;+		buf->next = prev;+		prev = buf;+		buf = tmp;+	} while (buf != NULL);++	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;+}++#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)++static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,+	struct sljit_const *const_, struct sljit_put_label *put_label)+{+	sljit_uw result = ~(sljit_uw)0;++	if (label)+		result = label->size;++	if (jump && jump->addr < result)+		result = jump->addr;++	if (const_ && const_->addr < result)+		result = const_->addr;++	if (put_label && put_label->addr < result)+		result = put_label->addr;++	return result;+}++#endif /* !SLJIT_CONFIG_X86 */++static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	SLJIT_UNUSED_ARG(args);+	SLJIT_UNUSED_ARG(local_size);++	compiler->options = options;+	compiler->scratches = scratches;+	compiler->saveds = saveds;+	compiler->fscratches = fscratches;+	compiler->fsaveds = fsaveds;+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	compiler->logical_local_size = local_size;+#endif+}++static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	SLJIT_UNUSED_ARG(args);+	SLJIT_UNUSED_ARG(local_size);++	compiler->options = options;+	compiler->scratches = scratches;+	compiler->saveds = saveds;+	compiler->fscratches = fscratches;+	compiler->fsaveds = fsaveds;+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	compiler->logical_local_size = local_size;+#endif+}++static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)+{+	label->next = NULL;+	label->size = compiler->size;+	if (compiler->last_label)+		compiler->last_label->next = label;+	else+		compiler->labels = label;+	compiler->last_label = label;+}++static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags)+{+	jump->next = NULL;+	jump->flags = flags;+	if (compiler->last_jump)+		compiler->last_jump->next = jump;+	else+		compiler->jumps = jump;+	compiler->last_jump = jump;+}++static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)+{+	const_->next = NULL;+	const_->addr = compiler->size;+	if (compiler->last_const)+		compiler->last_const->next = const_;+	else+		compiler->consts = const_;+	compiler->last_const = const_;+}++static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset)+{+	put_label->next = NULL;+	put_label->label = NULL;+	put_label->addr = compiler->size - offset;+	put_label->flags = 0;+	if (compiler->last_put_label)+		compiler->last_put_label->next = put_label;+	else+		compiler->put_labels = put_label;+	compiler->last_put_label = put_label;+}++#define ADDRESSING_DEPENDS_ON(exp, reg) \+	(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)++#define FUNCTION_CHECK_IS_REG(r) \+	(((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_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)+#else+#define CHECK_IF_VIRTUAL_REGISTER(p) 0+#endif++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;+	}++	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(function_fcheck(compiler, p, i));++#endif /* SLJIT_ARGUMENT_CHECKS */++#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)++SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)+{+	compiler->verbose = verbose;+}++#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)+#ifdef _WIN64+#	define SLJIT_PRINT_D	"I64"+#else+#	define SLJIT_PRINT_D	"l"+#endif+#else+#	define SLJIT_PRINT_D	""+#endif++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");+}++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");+}++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",+	(char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s",+	(char*)"endbr", (char*)"skip_frames_before_return"+};++static const char* op1_names[] = {+	(char*)"", (char*)".u8", (char*)".s8", (char*)".u16",+	(char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",+	(char*)"", (char*)".u8", (char*)".s8", (char*)".u16",+	(char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",+	(char*)"not", (char*)"neg", (char*)"clz",+};++static const char* op2_names[] = {+	(char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",+	(char*)"mul", (char*)"and", (char*)"or", (char*)"xor",+	(char*)"shl", (char*)"lshr", (char*)"ashr",+};++static const char* op_src_names[] = {+	(char*)"fast_return", (char*)"skip_frames_before_fast_return",+	(char*)"prefetch_l1", (char*)"prefetch_l2",+	(char*)"prefetch_l3", (char*)"prefetch_once",+};++static const char* fop1_names[] = {+	(char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv",+	(char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg",+	(char*)"abs",+};++static const char* fop2_names[] = {+	(char*)"add", (char*)"sub", (char*)"mul", (char*)"div"+};++#define JUMP_POSTFIX(type) \+	((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \+	: ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : ""))++static char* jump_names[] = {+	(char*)"equal", (char*)"not_equal",+	(char*)"less", (char*)"greater_equal",+	(char*)"greater", (char*)"less_equal",+	(char*)"sig_less", (char*)"sig_greater_equal",+	(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*)"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 */++/* --------------------------------------------------------------------- */+/*  Arch dependent                                                       */+/* --------------------------------------------------------------------- */++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \+	|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	struct sljit_jump *jump;+#endif++	SLJIT_UNUSED_ARG(compiler);++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(compiler->size > 0);+	jump = compiler->jumps;+	while (jump) {+		/* All jumps have target. */+		CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR));+		jump = jump->next;+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+#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_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(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:%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 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_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(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:%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_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(compiler->scratches >= 0);+	if (op != SLJIT_UNUSED) {+		CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P);+		FUNCTION_CHECK_SRC(src, srcw);+	}+	else+		CHECK_ARGUMENT(src == 0 && srcw == 0);+	compiler->last_flags = 0;+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		if (op == SLJIT_UNUSED)+			fprintf(compiler->verbose, "  return\n");+		else {+			fprintf(compiler->verbose, "  return%s ", op1_names[op - SLJIT_OP1_BASE]);+			sljit_verbose_param(compiler, src, srcw);+			fprintf(compiler->verbose, "\n");+		}+	}+#endif+	CHECK_RETURN_OK;+}++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, 0);+	compiler->last_flags = 0;+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  fast_enter ");+		sljit_verbose_param(compiler, dst, dstw);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)+		|| ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)+		|| (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));+	CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);+	if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)+		compiler->last_flags = 0;+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose))+	{+		fprintf(compiler->verbose, "  %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);+		if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {+			fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w");+		}+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);++	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, HAS_FLAGS(op));+	FUNCTION_CHECK_SRC(src, srcw);++	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_MOV_P)+		{+			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 ", 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);+		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_op2(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)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);++	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, HAS_FLAGS(op));+	FUNCTION_CHECK_SRC(src1, src1w);+	FUNCTION_CHECK_SRC(src2, src2w);+	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 ", 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);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_param(compiler, src2, src2w);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);+	FUNCTION_CHECK_SRC(src, srcw);++	if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN)+	{+		CHECK_ARGUMENT(src != SLJIT_IMM);+		compiler->last_flags = 0;+	}+	else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE)+	{+		CHECK_ARGUMENT(src & SLJIT_MEM);+	}+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  %s ", op_src_names[op - SLJIT_OP_SRC_BASE]);+		sljit_verbose_param(compiler, src, srcw);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)+{+	SLJIT_UNUSED_ARG(reg);+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS);+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg)+{+	SLJIT_UNUSED_ARG(reg);+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	int i;+#endif++	SLJIT_UNUSED_ARG(compiler);++#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)+	CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)+		|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));+#else+	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)) {+		fprintf(compiler->verbose, "  op_custom");+		for (i = 0; i < size; i++)+			fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));+	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));+	FUNCTION_FCHECK(src, srcw);+	FUNCTION_FCHECK(dst, dstw);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)+			fprintf(compiler->verbose, "  %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],+				(op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32");+		else+			fprintf(compiler->verbose, "  %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],+				(op & SLJIT_F32_OP) ? ".f32" : ".f64");++		sljit_verbose_fparam(compiler, dst, dstw);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_fparam(compiler, src, srcw);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	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_has_cpu_feature(SLJIT_HAS_FPU));+	CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);+	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", 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);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_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)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	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);+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));+	FUNCTION_FCHECK(src, srcw);+	FUNCTION_CHECK_DST(dst, dstw, 0);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],+			(GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw",+			(op & SLJIT_F32_OP) ? ".f32" : ".f64");+		sljit_verbose_param(compiler, dst, dstw);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_fparam(compiler, src, srcw);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	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);+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));+	FUNCTION_CHECK_SRC(src, srcw);+	FUNCTION_FCHECK(dst, dstw);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],+			(op & SLJIT_F32_OP) ? ".f32" : ".f64",+			(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw");+		sljit_verbose_fparam(compiler, dst, dstw);+		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_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)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));+	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));+	FUNCTION_FCHECK(src1, src1w);+	FUNCTION_FCHECK(src2, src2w);+	FUNCTION_FCHECK(dst, dstw);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");+		sljit_verbose_fparam(compiler, dst, dstw);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_fparam(compiler, src1, src1w);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_fparam(compiler, src2, src2w);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)+{+	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");+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));+	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));++	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))+		fprintf(compiler->verbose, "  jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",+			jump_names[type & 0xff], JUMP_POSTFIX(type));+#endif+	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)+{+#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_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)) {+		fprintf(compiler->verbose, "  cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",+			jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : "");+		sljit_verbose_param(compiler, src1, src1w);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_param(compiler, src2, src2w);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	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)) {+		fprintf(compiler->verbose, "  fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",+			jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64");+		sljit_verbose_fparam(compiler, src1, src1w);+		fprintf(compiler->verbose, ", ");+		sljit_verbose_fparam(compiler, src2, src2w);+		fprintf(compiler->verbose, "\n");+	}+#endif+	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)+{+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {+		compiler->skip_checks = 0;+		CHECK_RETURN_OK;+	}++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);+	FUNCTION_CHECK_SRC(src, srcw);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  ijump.%s ", jump_names[type]);+		sljit_verbose_param(compiler, src, srcw);+		fprintf(compiler->verbose, "\n");+	}+#endif+	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 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((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 & 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, ",+			!(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);+		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, 0);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  local_base ");+		sljit_verbose_param(compiler, dst, dstw);+		fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)+{+	SLJIT_UNUSED_ARG(init_value);++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	FUNCTION_CHECK_DST(dst, dstw, 0);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  const ");+		sljit_verbose_param(compiler, dst, dstw);+		fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);+	}+#endif+	CHECK_RETURN_OK;+}++static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	FUNCTION_CHECK_DST(dst, dstw, 0);+#endif+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {+		fprintf(compiler->verbose, "  put_label ");+		sljit_verbose_param(compiler, dst, dstw);+		fprintf(compiler->verbose, "\n");+	}+#endif+	CHECK_RETURN_OK;+}++#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */++#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \+	SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \+		invalid_float_opcodes); \+	if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \+		if (GET_OPCODE(op) == SLJIT_CMP_F64) { \+			CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \+			ADJUST_LOCAL_OFFSET(dst, dstw); \+			ADJUST_LOCAL_OFFSET(src, srcw); \+			return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \+		} \+		if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \+			CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \+			ADJUST_LOCAL_OFFSET(dst, dstw); \+			ADJUST_LOCAL_OFFSET(src, srcw); \+			return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \+		} \+		CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \+		ADJUST_LOCAL_OFFSET(dst, dstw); \+		ADJUST_LOCAL_OFFSET(src, srcw); \+		return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \+	} \+	CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \+	ADJUST_LOCAL_OFFSET(dst, dstw); \+	ADJUST_LOCAL_OFFSET(src, srcw);++static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	/* Return if don't need to do anything. */+	if (op == SLJIT_UNUSED)+		return SLJIT_SUCCESS;++#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)+	/* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */+	if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))+		return SLJIT_SUCCESS;+#else+	if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))+		return SLJIT_SUCCESS;+#endif++#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \+		|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	compiler->skip_checks = 1;+#endif+	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_REV && SLJIT_MIPS_REV >= 1))++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)+#define SLJIT_CPUINFO_PART1 " 32bit ("+#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)+#define SLJIT_CPUINFO_PART1 " 64bit ("+#else+#error "Internal error: CPU type info missing"+#endif++#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)+#define SLJIT_CPUINFO_PART2 "little endian + "+#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)+#define SLJIT_CPUINFO_PART2 "big endian + "+#else+#error "Internal error: CPU type info missing"+#endif++#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)+#define SLJIT_CPUINFO_PART3 "unaligned)"+#else+#define SLJIT_CPUINFO_PART3 "aligned)"+#endif++#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3++#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)+#	include "sljitNativeX86_common.c"+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+#	include "sljitNativeARM_32.c"+#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)+#	include "sljitNativeARM_32.c"+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)+#	include "sljitNativeARM_T2_32.c"+#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)+#	include "sljitNativeARM_64.c"+#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)+#	include "sljitNativePPC_common.c"+#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)+#	include "sljitNativeMIPS_common.c"+#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)+#	include "sljitNativeSPARC_common.c"+#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)+#	include "sljitNativeTILEGX_64.c"+#endif++#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)++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)+{+	/* Default compare for most architectures. */+	sljit_s32 flags, tmp_src, condition;+	sljit_sw tmp_srcw;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));++	condition = type & 0xff;+#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)+	if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {+		if ((src1 & SLJIT_IMM) && !src1w) {+			src1 = src2;+			src1w = src2w;+			src2 = SLJIT_IMM;+			src2w = 0;+		}+		if ((src2 & SLJIT_IMM) && !src2w)+			return emit_cmp_to0(compiler, type, src1, src1w);+	}+#endif++	if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {+		/* Immediate is prefered as second argument by most architectures. */+		switch (condition) {+		case SLJIT_LESS:+			condition = SLJIT_GREATER;+			break;+		case SLJIT_GREATER_EQUAL:+			condition = SLJIT_LESS_EQUAL;+			break;+		case SLJIT_GREATER:+			condition = SLJIT_LESS;+			break;+		case SLJIT_LESS_EQUAL:+			condition = SLJIT_GREATER_EQUAL;+			break;+		case SLJIT_SIG_LESS:+			condition = SLJIT_SIG_GREATER;+			break;+		case SLJIT_SIG_GREATER_EQUAL:+			condition = SLJIT_SIG_LESS_EQUAL;+			break;+		case SLJIT_SIG_GREATER:+			condition = SLJIT_SIG_LESS;+			break;+		case SLJIT_SIG_LESS_EQUAL:+			condition = SLJIT_SIG_GREATER_EQUAL;+			break;+		}++		type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP));+		tmp_src = src1;+		src1 = src2;+		src2 = tmp_src;+		tmp_srcw = src1w;+		src1w = src2w;+		src2w = tmp_srcw;+	}++	if (condition <= SLJIT_NOT_ZERO)+		flags = SLJIT_SET_Z;+	else+		flags = condition << VARIABLE_FLAG_SHIFT;++#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	compiler->skip_checks = 1;+#endif+	PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP),+		SLJIT_UNUSED, 0, src1, src1w, src2, src2w));+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	compiler->skip_checks = 1;+#endif+	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)+{+	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_fcmp(compiler, type, 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 | ((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+	return sljit_emit_jump(compiler, type);+}++#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++#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++#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \+	&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)++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();+	CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));++	ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+	compiler->skip_checks = 1;+#endif+	if (offset != 0)+		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);+}++#endif++#else /* SLJIT_CONFIG_UNSUPPORTED */++/* Empty function bodies for those machines, which are not (yet) supported. */++SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)+{+	return "unsupported";+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)+{+	SLJIT_UNUSED_ARG(allocator_data);+	SLJIT_UNUSED_ARG(exec_allocator_data);+	SLJIT_UNREACHABLE();+	return NULL;+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)+{+	SLJIT_UNUSED_ARG(compiler);+	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_UNREACHABLE();+	return NULL;+}++#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(verbose);+	SLJIT_UNREACHABLE();+}+#endif++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	SLJIT_UNUSED_ARG(compiler);+	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, void *exec_allocator_data)+{+	SLJIT_UNUSED_ARG(code);+	SLJIT_UNUSED_ARG(exec_allocator_data);+	SLJIT_UNREACHABLE();+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(options);+	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_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(options);+	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_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNUSED_ARG(src);+	SLJIT_UNUSED_ARG(srcw);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++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)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNUSED_ARG(src);+	SLJIT_UNUSED_ARG(srcw);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNUSED_ARG(src1);+	SLJIT_UNUSED_ARG(src1w);+	SLJIT_UNUSED_ARG(src2);+	SLJIT_UNUSED_ARG(src2w);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNUSED_ARG(src);+	SLJIT_UNUSED_ARG(srcw);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	SLJIT_UNREACHABLE();+	return reg;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(instruction);+	SLJIT_UNUSED_ARG(size);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++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);+}++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_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNUSED_ARG(src);+	SLJIT_UNUSED_ARG(srcw);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++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_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(op);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNUSED_ARG(src1);+	SLJIT_UNUSED_ARG(src1w);+	SLJIT_UNUSED_ARG(src2);+	SLJIT_UNUSED_ARG(src2w);+	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_UNREACHABLE();+	return NULL;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(type);+	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;+}++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)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(type);+	SLJIT_UNUSED_ARG(src1);+	SLJIT_UNUSED_ARG(src1w);+	SLJIT_UNUSED_ARG(src2);+	SLJIT_UNUSED_ARG(src2w);+	SLJIT_UNREACHABLE();+	return NULL;+}++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_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(type);+	SLJIT_UNUSED_ARG(src1);+	SLJIT_UNUSED_ARG(src1w);+	SLJIT_UNUSED_ARG(src2);+	SLJIT_UNUSED_ARG(src2w);+	SLJIT_UNREACHABLE();+	return NULL;+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)+{+	SLJIT_UNUSED_ARG(jump);+	SLJIT_UNUSED_ARG(label);+	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_UNREACHABLE();+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)+{+	SLJIT_UNUSED_ARG(put_label);+	SLJIT_UNUSED_ARG(label);+	SLJIT_UNREACHABLE();+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(type);+	SLJIT_UNUSED_ARG(src);+	SLJIT_UNUSED_ARG(srcw);+	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 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_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;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNUSED_ARG(offset);+	SLJIT_UNREACHABLE();+	return SLJIT_ERR_UNSUPPORTED;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	SLJIT_UNUSED_ARG(initval);+	SLJIT_UNREACHABLE();+	return NULL;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(dst);+	SLJIT_UNUSED_ARG(dstw);+	return NULL;+}++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_target);+	SLJIT_UNUSED_ARG(executable_offset);+	SLJIT_UNREACHABLE();+}++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_UNUSED_ARG(executable_offset);+	SLJIT_UNREACHABLE();+}++#endif /* !SLJIT_CONFIG_UNSUPPORTED */
+ src/c/pcre2/src/sljit/sljitLir.h view
@@ -0,0 +1,1544 @@+/*+ *    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.+ */++#ifndef SLJIT_LIR_H_+#define SLJIT_LIR_H_++/*+   ------------------------------------------------------------------------+    Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)+   ------------------------------------------------------------------------++   Short description+    Advantages:+      - The execution can be continued from any LIR instruction. In other+        words, it is possible to jump to any label from anywhere, even from+        a code fragment, which is compiled later, if both compiled code+        shares the same context. See sljit_emit_enter for more details+      - Supports self modifying code: target of (conditional) jump and call+        instructions and some constant values can be dynamically modified+        during runtime+        - although it is not suggested to do it frequently+        - can be used for inline caching: save an important value once+          in the instruction stream+        - since this feature limits the optimization possibilities, a+          special flag must be passed at compile time when these+          instructions are emitted+      - A fixed stack space can be allocated for local variables+      - The compiler is thread-safe+      - The compiler is highly configurable through preprocessor macros.+        You can disable unneeded features (multithreading in single+        threaded applications), and you can use your own system functions+        (including memory allocators). See sljitConfig.h+    Disadvantages:+      - No automatic register allocation, and temporary results are+        not stored on the stack. (hence the name comes)+    In practice:+      - This approach is very effective for interpreters+        - One of the saved registers typically points to a stack interface+        - It can jump to any exception handler anytime (even if it belongs+          to another function)+        - Hot paths can be modified during runtime reflecting the changes+          of the fastest execution path of the dynamic language+        - SLJIT supports complex memory addressing modes+        - mainly position and context independent code (except some cases)++    For valgrind users:+      - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"+*/++#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)+#include "sljitConfigPre.h"+#endif /* SLJIT_HAVE_CONFIG_PRE */++#include "sljitConfig.h"++/* The following header file defines useful macros for fine tuning+sljit based code generators. They are listed in the beginning+of sljitConfigInternal.h */++#include "sljitConfigInternal.h"++#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)+#include "sljitConfigPost.h"+#endif /* SLJIT_HAVE_CONFIG_POST */++#ifdef __cplusplus+extern "C" {+#endif++/* --------------------------------------------------------------------- */+/*  Error codes                                                          */+/* --------------------------------------------------------------------- */++/* Indicates no error. */+#define SLJIT_SUCCESS			0+/* After the call of sljit_generate_code(), the error code of the compiler+   is set to this value to avoid future sljit calls (in debug mode at least).+   The complier should be freed after sljit_generate_code(). */+#define SLJIT_ERR_COMPILED		1+/* Cannot allocate non executable memory. */+#define SLJIT_ERR_ALLOC_FAILED		2+/* Cannot allocate executable memory.+   Only for sljit_generate_code() */+#define SLJIT_ERR_EX_ALLOC_FAILED	3+/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */+#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                                                            */+/* --------------------------------------------------------------------- */++/*+  Scratch (R) registers: registers whose may not preserve their values+  across function calls.++  Saved (S) registers: registers whose preserve their values across+  function calls.++  The scratch and saved register sets are overlap. The last scratch register+  is the first saved register, the one before the last is the second saved+  register, and so on.++  If an architecture provides two scratch and three saved registers,+  its scratch and saved register sets are the following:++     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++  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 >= 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: 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 scratch 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.++  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 S1 register+        is not available at all.+*/++/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1+   or sljit_emit_op2 operations the result is discarded. Some status+   flags must be set when the destination is SLJIT_UNUSED, because the+   operation would have no effect otherwise. Other SLJIT operations do+   not support SLJIT_UNUSED as a destination operand. */+#define SLJIT_UNUSED		0++/* Scratch registers. */+#define SLJIT_R0	1+#define SLJIT_R1	2+#define SLJIT_R2	3+/* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they+   are allocated on the stack). These registers are called virtual+   and cannot be used for memory addressing (cannot be part of+   any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such+   limitation on other CPUs. See sljit_get_register_index(). */+#define SLJIT_R3	4+#define SLJIT_R4	5+#define SLJIT_R5	6+#define SLJIT_R6	7+#define SLJIT_R7	8+#define SLJIT_R8	9+#define SLJIT_R9	10+/* All R registers provided by the architecture can be accessed by SLJIT_R(i)+   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */+#define SLJIT_R(i)	(1 + (i))++/* Saved registers. */+#define SLJIT_S0	(SLJIT_NUMBER_OF_REGISTERS)+#define SLJIT_S1	(SLJIT_NUMBER_OF_REGISTERS - 1)+#define SLJIT_S2	(SLJIT_NUMBER_OF_REGISTERS - 2)+/* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they+   are allocated on the stack). These registers are called virtual+   and cannot be used for memory addressing (cannot be part of+   any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such+   limitation on other CPUs. See sljit_get_register_index(). */+#define SLJIT_S3	(SLJIT_NUMBER_OF_REGISTERS - 3)+#define SLJIT_S4	(SLJIT_NUMBER_OF_REGISTERS - 4)+#define SLJIT_S5	(SLJIT_NUMBER_OF_REGISTERS - 5)+#define SLJIT_S6	(SLJIT_NUMBER_OF_REGISTERS - 6)+#define SLJIT_S7	(SLJIT_NUMBER_OF_REGISTERS - 7)+#define SLJIT_S8	(SLJIT_NUMBER_OF_REGISTERS - 8)+#define SLJIT_S9	(SLJIT_NUMBER_OF_REGISTERS - 9)+/* All S registers provided by the architecture can be accessed by SLJIT_S(i)+   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */+#define SLJIT_S(i)	(SLJIT_NUMBER_OF_REGISTERS - (i))++/* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */+#define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1)++/* The SLJIT_SP provides direct access to the linear stack space allocated by+   sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP).+   The immediate offset is extended by the relative stack offset automatically.+   The sljit_get_local_base can be used to obtain the absolute offset. */+#define SLJIT_SP	(SLJIT_NUMBER_OF_REGISTERS + 1)++/* Return with machine word. */++#define SLJIT_RETURN_REG	SLJIT_R0++/* --------------------------------------------------------------------- */+/*  Floating point registers                                             */+/* --------------------------------------------------------------------- */++/* Each floating point register can store a 32 or a 64 bit precision+   value. The FR and FS register sets are overlap in the same way as R+   and S register sets. See above. */++/* Note: SLJIT_UNUSED as destination is not valid for floating point+   operations, since they cannot be used for setting flags. */++/* Floating point scratch registers. */+#define SLJIT_FR0	1+#define SLJIT_FR1	2+#define SLJIT_FR2	3+#define SLJIT_FR3	4+#define SLJIT_FR4	5+#define SLJIT_FR5	6+/* All FR registers provided by the architecture can be accessed by SLJIT_FR(i)+   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */+#define SLJIT_FR(i)	(1 + (i))++/* Floating point saved registers. */+#define SLJIT_FS0	(SLJIT_NUMBER_OF_FLOAT_REGISTERS)+#define SLJIT_FS1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1)+#define SLJIT_FS2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2)+#define SLJIT_FS3	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3)+#define SLJIT_FS4	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4)+#define SLJIT_FS5	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5)+/* All S registers provided by the architecture can be accessed by SLJIT_FS(i)+   The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */+#define SLJIT_FS(i)	(SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i))++/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */+#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                                        */+/* --------------------------------------------------------------------- */++/*+	The following structures are private, and can be changed in the+	future. Keeping them here allows code inlining.+*/++struct sljit_memory_fragment {+	struct sljit_memory_fragment *next;+	sljit_uw used_size;+	/* Must be aligned to sljit_sw. */+	sljit_u8 memory[1];+};++struct sljit_label {+	struct sljit_label *next;+	sljit_uw addr;+	/* The maximum size difference. */+	sljit_uw size;+};++struct sljit_jump {+	struct sljit_jump *next;+	sljit_uw addr;+	sljit_uw flags;+	union {+		sljit_uw target;+		struct sljit_label *label;+	} u;+};++struct sljit_put_label {+	struct sljit_put_label *next;+	struct sljit_label *label;+	sljit_uw addr;+	sljit_uw flags;+};++struct sljit_const {+	struct sljit_const *next;+	sljit_uw addr;+};++struct sljit_compiler {+	sljit_s32 error;+	sljit_s32 options;++	struct sljit_label *labels;+	struct sljit_jump *jumps;+	struct sljit_put_label *put_labels;+	struct sljit_const *consts;+	struct sljit_label *last_label;+	struct sljit_jump *last_jump;+	struct sljit_const *last_const;+	struct sljit_put_label *last_put_label;++	void *allocator_data;+	void *exec_allocator_data;+	struct sljit_memory_fragment *buf;+	struct sljit_memory_fragment *abuf;++	/* Used scratch registers. */+	sljit_s32 scratches;+	/* Used saved registers. */+	sljit_s32 saveds;+	/* Used float scratch registers. */+	sljit_s32 fscratches;+	/* Used float saved registers. */+	sljit_s32 fsaveds;+	/* Local stack size. */+	sljit_s32 local_size;+	/* Code size. */+	sljit_uw size;+	/* 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+#endif++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	/* Constant pool handling. */+	sljit_uw *cpool;+	sljit_u8 *cpool_unique;+	sljit_uw cpool_diff;+	sljit_uw cpool_fill;+	/* Other members. */+	/* Contains pointer, "ldr pc, [...]" pairs. */+	sljit_uw patches;+#endif++#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;+#endif++#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)+	sljit_sw imm;+#endif++#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)+	sljit_s32 delay_slot;+	sljit_s32 cache_arg;+	sljit_sw cache_argw;+#endif++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+	sljit_s32 delay_slot;+	sljit_s32 cache_arg;+	sljit_sw cache_argw;+#endif++#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)+	sljit_s32 cache_arg;+	sljit_sw cache_argw;+#endif++#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+	FILE* verbose;+#endif++#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++#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+};++/* --------------------------------------------------------------------- */+/*  Main functions                                                       */+/* --------------------------------------------------------------------- */++/* Creates an sljit compiler. The allocator_data is required by some+   custom memory managers. This pointer is passed to SLJIT_MALLOC+   and SLJIT_FREE macros. Most allocators (including the default+   one) ignores this value, and it is recommended to pass NULL+   as a dummy value for allocator_data. The exec_allocator_data+   has the same purpose but this one is passed to SLJIT_MALLOC_EXEC /+   SLJIT_MALLOC_FREE functions.++   Returns NULL if failed. */+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data);++/* Frees everything except the compiled machine code. */+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);++/* Returns the current error code. If an error is occurred, future sljit+   calls which uses the same compiler argument returns early with the same+   error code. Thus there is no need for checking the error after every+   call, it is enough to do it before the code is compiled. Removing+   these checks increases the performance of the compiling process. */+static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }++/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except+   if an error was detected before. After the error code is set+   the compiler behaves as if the allocation failure happened+   during an sljit function call. This can greatly simplify error+   checking, since only the compiler status needs to be checked+   after the compilation. */+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler);++/*+   Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,+   and <= 128 bytes on 64 bit architectures. The memory area is owned by the+   compiler, and freed by sljit_free_compiler. The returned pointer is+   sizeof(sljit_sw) aligned. Excellent for allocating small blocks during+   the compiling, and no need to worry about freeing them. The size is+   enough to contain at most 16 pointers. If the size is outside of the range,+   the function will return with NULL. However, this return value does not+   indicate that there is no more memory (does not set the current error code+   of the compiler to out-of-memory status).+*/+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size);++#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)+/* Passing NULL disables verbose. */+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);+#endif++/*+   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, void *exec_allocator_data);++/*+   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] Has zero register (setting a memory location to zero is efficient). */+#define SLJIT_HAS_ZERO_REGISTER		2+/* [Emulated] Count leading zero is supported. */+#define SLJIT_HAS_CLZ			3+/* [Emulated] Conditional move is supported. */+#define SLJIT_HAS_CMOV			4+/* [Emulated] Conditional move is supported. */+#define SLJIT_HAS_PREFETCH		5++#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 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+   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 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+   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+   SLJIT_SP + local_size (exclusive) can be modified freely until+   the function returns. The stack space is not initialized.++   Note: the following conditions must met:+         0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS+         0 <= saveds <= SLJIT_NUMBER_OF_REGISTERS+         scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS+         0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS+         0 <= fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS+         fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS++   Note: every call of sljit_emit_enter and sljit_set_context+         overwrites the previous context.+*/++/* The absolute address returned by sljit_get_local_base with+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 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,+   number of used registers, etc.) which initialized by sljit_emit_enter. Several+   functions (like sljit_emit_return) requres this context to be able to generate+   the appropriate code. However, some code fragments (like inline cache) may have+   no normal entry point so their context is unknown for the compiler. Their context+   can be provided to the compiler by the sljit_set_context function.++   Note: every call of sljit_emit_enter and sljit_set_context overwrites+         the previous context. */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);++/* Return from machine code.  The op argument can be SLJIT_UNUSED which means the+   function does not return with anything or any opcode between SLJIT_MOV and+   SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op+   is SLJIT_UNUSED, otherwise see below the description about source and+   destination arguments. */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw);++/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL).+   Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations 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_FAST_RETURN to continue the execution after the fast call.++   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.++   Although returning to different address by SLJIT_FAST_RETURN is possible,+   this address usually cannot be predicted by the return address predictor of+   modern CPUs which may reduce performance. Furthermore certain security+   enhancement technologies such as Intel Control-flow Enforcement Technology+   (CET) may disallow returning to a different address.++   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);++/*+   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+    [reg+imm]        - indirect memory address+    [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)+                       useful for (byte, half, int, sljit_sw) array access+                       (fully supported by both x86 and ARM architectures, and cheap operation on others)+*/++/*+   IMPORTANT NOTE: memory access MUST be naturally aligned unless+                   SLJIT_UNALIGNED macro is defined and its value is 1.++     length | alignment+   ---------+-----------+     byte   | 1 byte (any physical_address is accepted)+     half   | 2 byte (physical_address & 0x1 == 0)+     int    | 4 byte (physical_address & 0x3 == 0)+     word   | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1+            | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1+    pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte+            | on 64 bit machines)++   Note:   Different architectures have different addressing limitations.+           A single instruction is enough for the following addressing+           modes. Other adrressing modes are emulated by instruction+           sequences. This information could help to improve those code+           generators which focuses only a few architectures.++   x86:    [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)+           [reg+(reg<<imm)] is supported+           [imm], -2^32+1 <= imm <= 2^32-1 is supported+           Write-back is not supported+   arm:    [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed+                bytes, any halfs or floating point values)+           [reg+(reg<<imm)] is supported+           Write-back is supported+   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.+           [reg+reg] is supported+           Write-back is supported except for one instruction: 32 bit signed+                load with [reg+imm] addressing mode on 64 bit.+   mips:   [reg+imm], -65536 <= imm <= 65535+   sparc:  [reg+imm], -4096 <= imm <= 4095+           [reg+reg] is supported+*/++/* 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 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 converted 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++/* 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.++   This option is part of the instruction name, so there is no need to+   manually set it. E.g:++     SLJIT_MOV_F32 = (SLJIT_MOV_F64 | SLJIT_F32_OP)+ */+#define SLJIT_F32_OP		SLJIT_I32_OP++/* Many CPUs (x86, ARM, PPC) have status flags which can be set according+   to the result of an operation. Other CPUs (MIPS) do not have status+   flags, and results must be stored in registers. To cover both architecture+   types efficiently only two flags are defined by SLJIT:++    * 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 has 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 need 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+       the instruction does not set flags (See: SLJIT_KEEP_FLAGS).+     - flag combinations: '|' means 'logical or'. */++/* Starting index of opcodes for sljit_emit_op0. */+#define SLJIT_OP0_BASE			0++/* 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: - (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)+/* Flags: - (may destroy flags)+   Unsigned multiplication of SLJIT_R0 and SLJIT_R1.+   Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */+#define SLJIT_LMUL_UW			(SLJIT_OP0_BASE + 2)+/* Flags: - (may destroy flags)+   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: - (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: - (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.+   Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),+         the behaviour is undefined. */+#define SLJIT_DIVMOD_SW			(SLJIT_OP0_BASE + 5)+#define SLJIT_DIVMOD_S32		(SLJIT_DIVMOD_SW | SLJIT_I32_OP)+/* 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: - (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.+   Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),+         the behaviour is undefined. */+#define SLJIT_DIV_SW			(SLJIT_OP0_BASE + 7)+#define SLJIT_DIV_S32			(SLJIT_DIV_SW | SLJIT_I32_OP)+/* Flags: - (does not modify flags)+   ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64+   when Intel Control-flow Enforcement Technology (CET) is enabled.+   No instruction for other architectures.  */+#define SLJIT_ENDBR			(SLJIT_OP0_BASE + 8)+/* Flags: - (may destroy flags)+   Skip stack frames before return.  */+#define SLJIT_SKIP_FRAMES_BEFORE_RETURN	(SLJIT_OP0_BASE + 9)++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);++/* Starting index of opcodes for sljit_emit_op1. */+#define SLJIT_OP1_BASE			32++/* The MOV instruction transfers data from source to destination.++   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+*/++/* Flags: - (does not modify flags) */+#define SLJIT_MOV			(SLJIT_OP1_BASE + 0)+/* Flags: - (does not modify flags) */+#define SLJIT_MOV_U8			(SLJIT_OP1_BASE + 1)+#define SLJIT_MOV32_U8			(SLJIT_MOV_U8 | SLJIT_I32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_MOV_S8			(SLJIT_OP1_BASE + 2)+#define SLJIT_MOV32_S8			(SLJIT_MOV_S8 | SLJIT_I32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_MOV_U16			(SLJIT_OP1_BASE + 3)+#define SLJIT_MOV32_U16			(SLJIT_MOV_U16 | SLJIT_I32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_MOV_S16			(SLJIT_OP1_BASE + 4)+#define SLJIT_MOV32_S16			(SLJIT_MOV_S16 | SLJIT_I32_OP)+/* 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: - (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: - (does not modify flags) */+#define SLJIT_MOV32			(SLJIT_MOV_S32 | SLJIT_I32_OP)+/* 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: Z+   Note: immediate source argument is not supported */+#define SLJIT_NOT			(SLJIT_OP1_BASE + 8)+#define SLJIT_NOT32			(SLJIT_NOT | SLJIT_I32_OP)+/* 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: - (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,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw);++/* Starting index of opcodes for sljit_emit_op2. */+#define SLJIT_OP2_BASE			96++/* Flags: Z | OVERFLOW | CARRY */+#define SLJIT_ADD			(SLJIT_OP2_BASE + 0)+#define SLJIT_ADD32			(SLJIT_ADD | SLJIT_I32_OP)+/* Flags: CARRY */+#define SLJIT_ADDC			(SLJIT_OP2_BASE + 1)+#define SLJIT_ADDC32			(SLJIT_ADDC | SLJIT_I32_OP)+/* 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: CARRY */+#define SLJIT_SUBC			(SLJIT_OP2_BASE + 3)+#define SLJIT_SUBC32			(SLJIT_SUBC | SLJIT_I32_OP)+/* Note: integer mul+   Flags: MUL_OVERFLOW */+#define SLJIT_MUL			(SLJIT_OP2_BASE + 4)+#define SLJIT_MUL32			(SLJIT_MUL | SLJIT_I32_OP)+/* Flags: Z */+#define SLJIT_AND			(SLJIT_OP2_BASE + 5)+#define SLJIT_AND32			(SLJIT_AND | SLJIT_I32_OP)+/* Flags: Z */+#define SLJIT_OR			(SLJIT_OP2_BASE + 6)+#define SLJIT_OR32			(SLJIT_OR | SLJIT_I32_OP)+/* Flags: Z */+#define SLJIT_XOR			(SLJIT_OP2_BASE + 7)+#define SLJIT_XOR32			(SLJIT_XOR | SLJIT_I32_OP)+/* 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: 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: 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_ASHR			(SLJIT_OP2_BASE + 10)+#define SLJIT_ASHR32			(SLJIT_ASHR | SLJIT_I32_OP)++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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);++/* Starting index of opcodes for sljit_emit_op2. */+#define SLJIT_OP_SRC_BASE		128++/* Note: src cannot be an immedate value+   Flags: - (does not modify flags) */+#define SLJIT_FAST_RETURN		(SLJIT_OP_SRC_BASE + 0)+/* Skip stack frames before fast return.+   Note: src cannot be an immedate value+   Flags: may destroy flags. */+#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN	(SLJIT_OP_SRC_BASE + 1)+/* Prefetch value into the level 1 data cache+   Note: if the target CPU does not support data prefetch,+         no instructions are emitted.+   Note: this instruction never fails, even if the memory address is invalid.+   Flags: - (does not modify flags) */+#define SLJIT_PREFETCH_L1		(SLJIT_OP_SRC_BASE + 2)+/* Prefetch value into the level 2 data cache+   Note: same as SLJIT_PREFETCH_L1 if the target CPU+         does not support this instruction form.+   Note: this instruction never fails, even if the memory address is invalid.+   Flags: - (does not modify flags) */+#define SLJIT_PREFETCH_L2		(SLJIT_OP_SRC_BASE + 3)+/* Prefetch value into the level 3 data cache+   Note: same as SLJIT_PREFETCH_L2 if the target CPU+         does not support this instruction form.+   Note: this instruction never fails, even if the memory address is invalid.+   Flags: - (does not modify flags) */+#define SLJIT_PREFETCH_L3		(SLJIT_OP_SRC_BASE + 4)+/* Prefetch a value which is only used once (and can be discarded afterwards)+   Note: same as SLJIT_PREFETCH_L1 if the target CPU+         does not support this instruction form.+   Note: this instruction never fails, even if the memory address is invalid.+   Flags: - (does not modify flags) */+#define SLJIT_PREFETCH_ONCE		(SLJIT_OP_SRC_BASE + 5)++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw);++/* Starting index of opcodes for sljit_emit_fop1. */+#define SLJIT_FOP1_BASE			160++/* 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: - (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: - (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: - (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: - (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: - (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.+   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: - (does not modify flags) */+#define SLJIT_NEG_F64			(SLJIT_FOP1_BASE + 7)+#define SLJIT_NEG_F32			(SLJIT_NEG_F64 | SLJIT_F32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_ABS_F64			(SLJIT_FOP1_BASE + 8)+#define SLJIT_ABS_F32			(SLJIT_ABS_F64 | SLJIT_F32_OP)++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);++/* Starting index of opcodes for sljit_emit_fop2. */+#define SLJIT_FOP2_BASE			192++/* Flags: - (does not modify flags) */+#define SLJIT_ADD_F64			(SLJIT_FOP2_BASE + 0)+#define SLJIT_ADD_F32			(SLJIT_ADD_F64 | SLJIT_F32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_SUB_F64			(SLJIT_FOP2_BASE + 1)+#define SLJIT_SUB_F32			(SLJIT_SUB_F64 | SLJIT_F32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_MUL_F64			(SLJIT_FOP2_BASE + 2)+#define SLJIT_MUL_F32			(SLJIT_MUL_F64 | SLJIT_F32_OP)+/* Flags: - (does not modify flags) */+#define SLJIT_DIV_F64			(SLJIT_FOP2_BASE + 3)+#define SLJIT_DIV_F32			(SLJIT_DIV_F64 | SLJIT_F32_OP)++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);++/* Label and jump instructions. */++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);++/* Invert (negate) conditional type: xor (^) with 0x1 */++/* Integer comparison types. */+#define SLJIT_EQUAL			0+#define SLJIT_EQUAL32			(SLJIT_EQUAL | SLJIT_I32_OP)+#define SLJIT_ZERO			0+#define SLJIT_ZERO32			(SLJIT_ZERO | SLJIT_I32_OP)+#define SLJIT_NOT_EQUAL			1+#define SLJIT_NOT_EQUAL32		(SLJIT_NOT_EQUAL | SLJIT_I32_OP)+#define SLJIT_NOT_ZERO			1+#define SLJIT_NOT_ZERO32		(SLJIT_NOT_ZERO | SLJIT_I32_OP)++#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			16+#define SLJIT_EQUAL_F32			(SLJIT_EQUAL_F64 | SLJIT_F32_OP)+#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_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_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_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_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_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_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			24+	/* Fast calling method. See sljit_emit_fast_enter / SLJIT_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 declared 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_FAST_CALL+    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP++   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+   architectures (i.e: ARM64 or MIPS) may employ special optimizations here.+   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: 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);++/* Basic floating point comparison. In most architectures it is implemented as+   an SLJIT_FCMP operation (setting appropriate flags) followed by a+   sljit_emit_jump. However some architectures (i.e: MIPS) may employ+   special optimizations here. It is suggested to use this comparison form+   when appropriate.+    type must be between SLJIT_EQUAL_F64 and SLJIT_ORDERED_F32+    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP+   Flags: destroy flags.+   Note: if either operand is NaN, the behaviour is undefined for+         types up to SLJIT_S_LESS_EQUAL. */+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);++/* Set the destination of the jump to this label. */+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);+/* 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);++/* Emit an indirect jump or fast call.+   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_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_MOV32:+     Set dst to the value represented by the type (0 or 1).+     Flags: - (does not modify flags)+   If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR+     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 type);++/* 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 form 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);++/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)+   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);++/* Store the value of a label (see: sljit_set_put_label)+   Flags: - (does not modify flags) */+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);++/* Set the value stored by put_label to this label. */+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label);++/* After the code generation the address for label, jump and const instructions+   are computed. Since these structures are freed by sljit_free_compiler, the+   addresses must be preserved by the user program elsewere. */+static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }+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 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	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+   it is useful to know the type of the code generator. */+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);++/* Portable helper function to get an offset of a member. */+#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)++#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)++/* 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.++   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.+	   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;+};++/* 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_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 (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) */++#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)++/* Get the entry address of a given function. */+#define SLJIT_FUNC_OFFSET(func_name)	((sljit_sw)func_name)++#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */++/* All JIT related code should be placed in the same context (library, binary, etc.). */++#define SLJIT_FUNC_OFFSET(func_name)	(*(sljit_sw*)(void*)func_name)++/* For powerpc64, the function pointers point to a context descriptor. */+struct sljit_function_context {+	sljit_sw addr;+	sljit_sw r2;+	sljit_sw r11;+};++/* Fill the context arguments using the addr and the function.+   If func_ptr is NULL, it will not be set to the address of context+   If addr is NULL, the function address also comes from the func pointer. */+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func);++#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                                               */+/* --------------------------------------------------------------------- */++/* The following function is a helper function for sljit_emit_op_custom.+   It returns with the real machine register index ( >=0 ) of any SLJIT_R,+   SLJIT_S and SLJIT_SP registers.++   Note: it returns with -1 for virtual registers (only on x86-32). */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg);++/* The following function is a helper function for sljit_emit_op_custom.+   It returns with the real machine register index of any SLJIT_FLOAT register.++   Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg);++/* Any instruction can be inserted into the instruction stream by+   sljit_emit_op_custom. It has a similar purpose as inline assembly.+   The size parameter must match to the instruction size of the target+   architecture:++         x86: 0 < size <= 15. The instruction argument can be byte aligned.+      Thumb2: if size == 2, the instruction argument must be 2 byte aligned.+              if size == 4, the instruction argument must be 4 byte aligned.+   Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size);++/* Define the currently available CPU status flags. It is usually used after an+   sljit_emit_op_custom call to define which flags are set. */++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,+	sljit_s32 current_flags);++#ifdef __cplusplus+} /* extern "C" */+#endif++#endif /* SLJIT_LIR_H_ */
+ src/c/pcre2/src/sljit/sljitNativeARM_32.c view
@@ -0,0 +1,2824 @@+/*+ *    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.+ */++#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 ARM_ABI_INFO;+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	return "ARMv5" SLJIT_CPUINFO ARM_ABI_INFO;+#else+#error "Internal error: Unknown ARM architecture"+#endif+}++/* Last register + 1. */+#define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)+#define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)+#define TMP_PC		(SLJIT_NUMBER_OF_REGISTERS + 4)++#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. */+#define CONST_POOL_ALIGNMENT	8+#define CONST_POOL_EMPTY	0xffffffff++#define ALIGN_INSTRUCTION(ptr) \+	(sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))+#define MAX_DIFFERENCE(max_diff) \+	(((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 + 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])+#define RD(rd) (reg_map[rd] << 12)+#define RN(rn) (reg_map[rn] << 16)++/* --------------------------------------------------------------------- */+/*  Instrucion forms                                                     */+/* --------------------------------------------------------------------- */++/* The instruction includes the AL condition.+   INST_NAME - CONDITIONAL remove this flag. */+#define COND_MASK	0xf0000000+#define CONDITIONAL	0xe0000000+#define PUSH_POOL	0xff000000++#define ADC		0xe0a00000+#define ADD		0xe0800000+#define AND		0xe0000000+#define B		0xea000000+#define BIC		0xe1c00000+#define BL		0xeb000000+#define BLX		0xe12fff30+#define BX		0xe12fff10+#define CLZ		0xe16f0f10+#define CMN		0xe1600000+#define CMP		0xe1400000+#define BKPT		0xe1200070+#define EOR		0xe0200000+#define MOV		0xe1a00000+#define MUL		0xe0000090+#define MVN		0xe1e00000+#define NOP		0xe1a00000+#define ORR		0xe1800000+#define PUSH		0xe92d0000+#define POP		0xe8bd0000+#define RSB		0xe0600000+#define RSC		0xe0e00000+#define SBC		0xe0c00000+#define SMULL		0xe0c00090+#define SUB		0xe0400000+#define UMULL		0xe0800090+#define VABS_F32	0xeeb00ac0+#define VADD_F32	0xee300a00+#define VCMP_F32	0xeeb40a40+#define VCVT_F32_S32	0xeeb80ac0+#define VCVT_F64_F32	0xeeb70ac0+#define VCVT_S32_F32	0xeebd0ac0+#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+#define VSTR_F32	0xed000a00+#define VSUB_F32	0xee300a40++#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)+/* Arm v7 specific instructions. */+#define MOVW		0xe3000000+#define MOVT		0xe3400000+#define SXTB		0xe6af0070+#define SXTH		0xe6bf0070+#define UXTB		0xe6ef0070+#define UXTH		0xe6ff0070+#endif++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)++static sljit_s32 push_cpool(struct sljit_compiler *compiler)+{+	/* Pushing the constant pool into the instruction stream. */+	sljit_uw* inst;+	sljit_uw* cpool_ptr;+	sljit_uw* cpool_end;+	sljit_s32 i;++	/* The label could point the address after the constant pool. */+	if (compiler->last_label && compiler->last_label->size == compiler->size)+		compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1;++	SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE);+	inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+	FAIL_IF(!inst);+	compiler->size++;+	*inst = 0xff000000 | compiler->cpool_fill;++	for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) {+		inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+		FAIL_IF(!inst);+		compiler->size++;+		*inst = 0;+	}++	cpool_ptr = compiler->cpool;+	cpool_end = cpool_ptr + compiler->cpool_fill;+	while (cpool_ptr < cpool_end) {+		inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+		FAIL_IF(!inst);+		compiler->size++;+		*inst = *cpool_ptr++;+	}+	compiler->cpool_diff = CONST_POOL_EMPTY;+	compiler->cpool_fill = 0;+	return SLJIT_SUCCESS;+}++static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst)+{+	sljit_uw* ptr;++	if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))+		FAIL_IF(push_cpool(compiler));++	ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+	FAIL_IF(!ptr);+	compiler->size++;+	*ptr = inst;+	return SLJIT_SUCCESS;+}++static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)+{+	sljit_uw* ptr;+	sljit_uw cpool_index = CPOOL_SIZE;+	sljit_uw* cpool_ptr;+	sljit_uw* cpool_end;+	sljit_u8* cpool_unique_ptr;++	if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))+		FAIL_IF(push_cpool(compiler));+	else if (compiler->cpool_fill > 0) {+		cpool_ptr = compiler->cpool;+		cpool_end = cpool_ptr + compiler->cpool_fill;+		cpool_unique_ptr = compiler->cpool_unique;+		do {+			if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) {+				cpool_index = cpool_ptr - compiler->cpool;+				break;+			}+			cpool_ptr++;+			cpool_unique_ptr++;+		} while (cpool_ptr < cpool_end);+	}++	if (cpool_index == CPOOL_SIZE) {+		/* Must allocate a new entry in the literal pool. */+		if (compiler->cpool_fill < CPOOL_SIZE) {+			cpool_index = compiler->cpool_fill;+			compiler->cpool_fill++;+		}+		else {+			FAIL_IF(push_cpool(compiler));+			cpool_index = 0;+			compiler->cpool_fill = 1;+		}+	}++	SLJIT_ASSERT((inst & 0xfff) == 0);+	ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+	FAIL_IF(!ptr);+	compiler->size++;+	*ptr = inst | cpool_index;++	compiler->cpool[cpool_index] = literal;+	compiler->cpool_unique[cpool_index] = 0;+	if (compiler->cpool_diff == CONST_POOL_EMPTY)+		compiler->cpool_diff = compiler->size;+	return SLJIT_SUCCESS;+}++static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)+{+	sljit_uw* ptr;+	if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))+		FAIL_IF(push_cpool(compiler));++	SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0);+	ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+	FAIL_IF(!ptr);+	compiler->size++;+	*ptr = inst | compiler->cpool_fill;++	compiler->cpool[compiler->cpool_fill] = literal;+	compiler->cpool_unique[compiler->cpool_fill] = 1;+	compiler->cpool_fill++;+	if (compiler->cpool_diff == CONST_POOL_EMPTY)+		compiler->cpool_diff = compiler->size;+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 prepare_blx(struct sljit_compiler *compiler)+{+	/* Place for at least two instruction (doesn't matter whether the first has a literal). */+	if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))+		return push_cpool(compiler);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_blx(struct sljit_compiler *compiler)+{+	/* 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));+}++static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size)+{+	sljit_uw diff;+	sljit_uw ind;+	sljit_uw counter = 0;+	sljit_uw* clear_const_pool = const_pool;+	sljit_uw* clear_const_pool_end = const_pool + cpool_size;++	SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT);+	/* Set unused flag for all literals in the constant pool.+	   I.e.: unused literals can belong to branches, which can be encoded as B or BL.+	   We can "compress" the constant pool by discarding these literals. */+	while (clear_const_pool < clear_const_pool_end)+		*clear_const_pool++ = (sljit_uw)(-1);++	while (last_pc_patch < code_ptr) {+		/* Data transfer instruction with Rn == r15. */+		if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) {+			diff = const_pool - last_pc_patch;+			ind = (*last_pc_patch) & 0xfff;++			/* Must be a load instruction with immediate offset. */+			SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));+			if ((sljit_s32)const_pool[ind] < 0) {+				const_pool[ind] = counter;+				ind = counter;+				counter++;+			}+			else+				ind = const_pool[ind];++			SLJIT_ASSERT(diff >= 1);+			if (diff >= 2 || ind > 0) {+				diff = (diff + ind - 2) << 2;+				SLJIT_ASSERT(diff <= 0xfff);+				*last_pc_patch = (*last_pc_patch & ~0xfff) | diff;+			}+			else+				*last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004;+		}+		last_pc_patch++;+	}+	return counter;+}++/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */+struct future_patch {+	struct future_patch* next;+	sljit_s32 index;+	sljit_s32 value;+};++static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)+{+	sljit_s32 value;+	struct future_patch *curr_patch, *prev_patch;++	SLJIT_UNUSED_ARG(compiler);++	/* Using the values generated by patch_pc_relative_loads. */+	if (!*first_patch)+		value = (sljit_s32)cpool_start_address[cpool_current_index];+	else {+		curr_patch = *first_patch;+		prev_patch = NULL;+		while (1) {+			if (!curr_patch) {+				value = (sljit_s32)cpool_start_address[cpool_current_index];+				break;+			}+			if ((sljit_uw)curr_patch->index == cpool_current_index) {+				value = curr_patch->value;+				if (prev_patch)+					prev_patch->next = curr_patch->next;+				else+					*first_patch = curr_patch->next;+				SLJIT_FREE(curr_patch, compiler->allocator_data);+				break;+			}+			prev_patch = curr_patch;+			curr_patch = curr_patch->next;+		}+	}++	if (value >= 0) {+		if ((sljit_uw)value > cpool_current_index) {+			curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch), compiler->allocator_data);+			if (!curr_patch) {+				while (*first_patch) {+					curr_patch = *first_patch;+					*first_patch = (*first_patch)->next;+					SLJIT_FREE(curr_patch, compiler->allocator_data);+				}+				return SLJIT_ERR_ALLOC_FAILED;+			}+			curr_patch->next = *first_patch;+			curr_patch->index = value;+			curr_patch->value = cpool_start_address[value];+			*first_patch = curr_patch;+		}+		cpool_start_address[value] = *buf_ptr;+	}+	return SLJIT_SUCCESS;+}++#else++static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst)+{+	sljit_uw* ptr;++	ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));+	FAIL_IF(!ptr);+	compiler->size++;+	*ptr = inst;+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)+{+	FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));+	return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));+}++#endif++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;++	if (jump->flags & SLJIT_REWRITABLE_JUMP)+		return 0;++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	if (jump->flags & IS_BL)+		code_ptr--;++	if (jump->flags & JUMP_ADDR)+		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));+	}++	/* Branch to Thumb code has not been optimized yet. */+	if (diff & 0x3)+		return 0;++	if (jump->flags & IS_BL) {+		if (diff <= 0x01ffffff && diff >= -0x02000000) {+			*code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);+			jump->flags |= PATCH_B;+			return 1;+		}+	}+	else {+		if (diff <= 0x01ffffff && diff >= -0x02000000) {+			*code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK);+			jump->flags |= PATCH_B;+		}+	}+#else+	if (jump->flags & JUMP_ADDR)+		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);+	}++	/* Branch to Thumb code has not been optimized yet. */+	if (diff & 0x3)+		return 0;++	if (diff <= 0x01ffffff && diff >= -0x02000000) {+		code_ptr -= 2;+		*code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK);+		jump->flags |= PATCH_B;+		return 1;+	}+#endif+	return 0;+}++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 *)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) - executable_offset) >> 2);++	SLJIT_UNUSED_ARG(executable_offset);++	if (diff <= 0x7fffff && diff >= -0x800000) {+		/* Turn to branch. */+		if (!bl) {+			if (flush_cache) {+				SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);+			}+			inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);+			if (flush_cache) {+				SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);+				inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+				SLJIT_CACHE_FLUSH(inst, inst + 1);+			}+		} else {+			if (flush_cache) {+				SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);+			}+			inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);+			inst[1] = NOP;+			if (flush_cache) {+				SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+				inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+				SLJIT_CACHE_FLUSH(inst, inst + 2);+			}+		}+	} else {+		/* Get the position of the constant. */+		if (mov_pc & (1 << 23))+			ptr = inst + ((mov_pc & 0xfff) >> 2) + 2;+		else+			ptr = inst + 1;++		if (*inst != mov_pc) {+			if (flush_cache) {+				SLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0);+			}+			inst[0] = mov_pc;+			if (!bl) {+				if (flush_cache) {+					SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);+					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_cache) {+					SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+					inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+					SLJIT_CACHE_FLUSH(inst, inst + 2);+				}+			}+		}++		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);+		}++		*ptr = new_addr;++		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);+		}+	}+#else+	sljit_uw *inst = (sljit_uw*)jump_ptr;++	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);++	if (flush_cache) {+		SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);+	}++	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_cache) {+		SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+		inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+		SLJIT_CACHE_FLUSH(inst, inst + 2);+	}+#endif+}++static sljit_uw get_imm(sljit_uw imm);++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;+	sljit_uw *inst = (sljit_uw*)ptr[0];+	sljit_uw ldr_literal = ptr[1];+	sljit_uw src2;++	SLJIT_UNUSED_ARG(executable_offset);++	src2 = get_imm(new_constant);+	if (src2) {+		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);+		}++		*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;++		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);+			inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+			SLJIT_CACHE_FLUSH(inst, inst + 1);+		}+		return;+	}++	src2 = get_imm(~new_constant);+	if (src2) {+		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);+		}++		*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;++		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);+			inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+			SLJIT_CACHE_FLUSH(inst, inst + 1);+		}+		return;+	}++	if (ldr_literal & (1 << 23))+		ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2;+	else+		ptr = inst + 1;++	if (*inst != ldr_literal) {+		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);+		}++		*inst = ldr_literal;++		if (flush_cache) {+			SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);+			inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+			SLJIT_CACHE_FLUSH(inst, inst + 1);+		}+	}++	if (flush_cache) {+		SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);+	}++	*ptr = new_constant;++	if (flush_cache) {+		SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);+	}+#else+	sljit_uw *inst = (sljit_uw*)addr;++	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);++	if (flush_cache) {+		SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);+	}++	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_cache) {+		SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+		inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);+		SLJIT_CACHE_FLUSH(inst, inst + 2);+	}+#endif+}++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_uw *code;+	sljit_uw *code_ptr;+	sljit_uw *buf_ptr;+	sljit_uw *buf_end;+	sljit_uw size;+	sljit_uw word_count;+	sljit_uw next_addr;+	sljit_sw executable_offset;+	sljit_sw addr;+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	sljit_uw cpool_size;+	sljit_uw cpool_skip_alignment;+	sljit_uw cpool_current_index;+	sljit_uw *cpool_start_address;+	sljit_uw *last_pc_patch;+	struct future_patch *first_patch;+#endif++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	/* Second code generation pass. */+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	size = compiler->size + (compiler->patches << 1);+	if (compiler->cpool_fill > 0)+		size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;+#else+	size = compiler->size;+#endif+	code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	cpool_size = 0;+	cpool_skip_alignment = 0;+	cpool_current_index = 0;+	cpool_start_address = NULL;+	first_patch = NULL;+	last_pc_patch = code;+#endif++	code_ptr = code;+	word_count = 0;+	next_addr = 1;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;++	if (label && label->size == 0) {+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);+		label = label->next;+	}++	do {+		buf_ptr = (sljit_uw*)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 2);+		do {+			word_count++;+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+			if (cpool_size > 0) {+				if (cpool_skip_alignment > 0) {+					buf_ptr++;+					cpool_skip_alignment--;+				}+				else {+					if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {+						SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);+						compiler->error = SLJIT_ERR_ALLOC_FAILED;+						return NULL;+					}+					buf_ptr++;+					if (++cpool_current_index >= cpool_size) {+						SLJIT_ASSERT(!first_patch);+						cpool_size = 0;+						if (label && label->size == word_count) {+							/* Points after the current instruction. */+							label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);+							label->size = code_ptr - code;+							label = label->next;++							next_addr = compute_next_addr(label, jump, const_, put_label);+						}+					}+				}+			}+			else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {+#endif+				*code_ptr = *buf_ptr++;+				if (next_addr == word_count) {+					SLJIT_ASSERT(!label || label->size >= word_count);+					SLJIT_ASSERT(!jump || jump->addr >= word_count);+					SLJIT_ASSERT(!const_ || const_->addr >= word_count);+					SLJIT_ASSERT(!put_label || put_label->addr >= word_count);++				/* These structures are ordered by their address. */+					if (jump && jump->addr == word_count) {+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+						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, 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)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);+						label->size = (code_ptr + 1) - code;+						label = label->next;+					}+					if (const_ && const_->addr == word_count) {+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+						const_->addr = (sljit_uw)code_ptr;+#else+						const_->addr = (sljit_uw)(code_ptr - 1);+#endif+						const_ = const_->next;+					}+					if (put_label && put_label->addr == word_count) {+						SLJIT_ASSERT(put_label->label);+						put_label->addr = (sljit_uw)code_ptr;+						put_label = put_label->next;+					}+					next_addr = compute_next_addr(label, jump, const_, put_label);+				}+				code_ptr++;+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+			}+			else {+				/* Fortunately, no need to shift. */+				cpool_size = *buf_ptr++ & ~PUSH_POOL;+				SLJIT_ASSERT(cpool_size > 0);+				cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1);+				cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size);+				if (cpool_current_index > 0) {+					/* Unconditional branch. */+					*code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL);+					code_ptr = cpool_start_address + cpool_current_index;+				}+				cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1;+				cpool_current_index = 0;+				last_pc_patch = code_ptr;+			}+#endif+		} while (buf_ptr < buf_end);+		buf = buf->next;+	} while (buf);++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	SLJIT_ASSERT(cpool_size == 0);+	if (compiler->cpool_fill > 0) {+		cpool_start_address = ALIGN_INSTRUCTION(code_ptr);+		cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill);+		if (cpool_current_index > 0)+			code_ptr = cpool_start_address + cpool_current_index;++		buf_ptr = compiler->cpool;+		buf_end = buf_ptr + compiler->cpool_fill;+		cpool_current_index = 0;+		while (buf_ptr < buf_end) {+			if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {+				SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);+				compiler->error = SLJIT_ERR_ALLOC_FAILED;+				return NULL;+			}+			buf_ptr++;+			cpool_current_index++;+		}+		SLJIT_ASSERT(!first_patch);+	}+#endif++	jump = compiler->jumps;+	while (jump) {+		buf_ptr = (sljit_uw *)jump->addr;++		if (jump->flags & PATCH_B) {+			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 - addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - addr) >= -0x02000000);+				*buf_ptr |= (((sljit_sw)jump->u.label->addr - addr) >> 2) & 0x00ffffff;+			}+			else {+				SLJIT_ASSERT(((sljit_sw)jump->u.target - addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - addr) >= -0x02000000);+				*buf_ptr |= (((sljit_sw)jump->u.target - addr) >> 2) & 0x00ffffff;+			}+		}+		else if (jump->flags & SLJIT_REWRITABLE_JUMP) {+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+			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, 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, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);+#endif+		}+		else {+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+			if (jump->flags & IS_BL)+				buf_ptr--;+			if (*buf_ptr & (1 << 23))+				buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;+			else+				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, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);+#endif+		}+		jump = jump->next;+	}++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	const_ = compiler->consts;+	while (const_) {+		buf_ptr = (sljit_uw*)const_->addr;+		const_->addr = (sljit_uw)code_ptr;++		code_ptr[0] = (sljit_uw)buf_ptr;+		code_ptr[1] = *buf_ptr;+		if (*buf_ptr & (1 << 23))+			buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;+		else+			buf_ptr += 1;+		/* Set the value again (can be a simple constant). */+		inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);+		code_ptr += 2;++		const_ = const_->next;+	}+#endif++	put_label = compiler->put_labels;+	while (put_label) {+		addr = put_label->label->addr;+		buf_ptr = (sljit_uw*)put_label->addr;++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+		SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000);+		buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr;+#else+		SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT);+		buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff);+		buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff);+#endif+		put_label = put_label->next;+	}++	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);+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);+	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:+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)+	case SLJIT_HAS_PREFETCH:+#endif+		return 1;++	default:+		return 0;+	}+}++/* --------------------------------------------------------------------- */+/*  Entry, exit                                                          */+/* --------------------------------------------------------------------- */++/* Creates an index in data_transfer_insts array. */+#define WORD_SIZE	0x00+#define BYTE_SIZE	0x01+#define HALF_SIZE	0x02+#define PRELOAD		0x03+#define SIGNED		0x04+#define LOAD_DATA	0x08++/* 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,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w);++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 args, size, i, tmp;+	sljit_uw push;++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	/* Push saved registers, temporary registers+	   stmdb sp!, {..., lr} */+	push = PUSH | (1 << 14);++	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--)+		push |= 1 << reg_map[i];++	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)+		push |= 1 << reg_map[i];++	FAIL_IF(push_inst(compiler, push));++	/* Stack must be aligned to 8 bytes: */+	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)+		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, MOV | RD(SLJIT_S0) | RM(SLJIT_R0)));+	if (args >= 2)+		FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S1) | RM(SLJIT_R1)));+	if (args >= 3)+		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 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, 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;+	return SLJIT_SUCCESS;+}++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_uw pop;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	if (compiler->local_size > 0)+		FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));++	/* Push saved registers, temporary registers+	   ldmia sp!, {..., pc} */+	pop = POP | (1 << 15);++	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];++	for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--)+		pop |= 1 << reg_map[i];++	return push_inst(compiler, pop);+}++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++/* flags: */+  /* Arguments are swapped. */+#define ARGS_SWAPPED	0x01+  /* Inverted immediate. */+#define INV_IMM		0x02+  /* Source and destination is register. */+#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+   src1: reg+   src2: reg or imm (if allowed)+   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_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, 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, 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)+{+	switch (GET_OPCODE(op)) {+	case SLJIT_MOV:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));+		if (dst != src2) {+			if (src2 & SRC2_IMM) {+				return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | 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 & MOVE_REG_CONV) {+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+			if (op == SLJIT_MOV_U8)+				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);+			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 & MOVE_REG_CONV) {+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+			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);+			return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_NOT:+		if (src2 & SRC2_IMM) {+			return push_inst(compiler, ((flags & INV_IMM) ? MOV : MVN) | (flags & SET_FLAGS) | RD(dst) | 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)));+		return SLJIT_SUCCESS;++	case SLJIT_ADD:+		SLJIT_ASSERT(!(flags & INV_IMM));+		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));+		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 & (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));+		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 (!HAS_FLAGS(op))+			return push_inst(compiler, MUL | (reg_map[dst] << 16) | (reg_map[src2] << 8) | reg_map[src1]);++		FAIL_IF(push_inst(compiler, SMULL | (reg_map[TMP_REG1] << 16) | (reg_map[dst] << 12) | (reg_map[src2] << 8) | reg_map[src1]));++		/* cmp TMP_REG1, dst asr #31. */+		return push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | RM(dst) | 0xfc0);++	case SLJIT_AND:+		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));+		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));+		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);++	case SLJIT_LSHR:+		EMIT_SHIFT_INS_AND_RETURN(1);++	case SLJIT_ASHR:+		EMIT_SHIFT_INS_AND_RETURN(2);+	}++	SLJIT_UNREACHABLE();+	return SLJIT_SUCCESS;+}++#undef EMIT_SHIFT_INS_AND_RETURN++/* Tests whether the immediate can be stored in the 12 bit imm field.+   Returns with 0 if not possible. */+static sljit_uw get_imm(sljit_uw imm)+{+	sljit_s32 rol;++	if (imm <= 0xff)+		return SRC2_IMM | imm;++	if (!(imm & 0xff000000)) {+		imm <<= 8;+		rol = 8;+	}+	else {+		imm = (imm << 24) | (imm >> 8);+		rol = 0;+	}++	if (!(imm & 0xff000000)) {+		imm <<= 8;+		rol += 4;+	}++	if (!(imm & 0xf0000000)) {+		imm <<= 4;+		rol += 2;+	}++	if (!(imm & 0xc0000000)) {+		imm <<= 2;+		rol += 1;+	}++	if (!(imm & 0x00ffffff))+		return SRC2_IMM | (imm >> 24) | (rol << 8);+	else+		return 0;+}++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive)+{+	sljit_uw mask;+	sljit_uw imm1;+	sljit_uw imm2;+	sljit_s32 rol;++	/* Step1: Search a zero byte (8 continous zero bit). */+	mask = 0xff000000;+	rol = 8;+	while(1) {+		if (!(imm & mask)) {+			/* Rol imm by rol. */+			imm = (imm << rol) | (imm >> (32 - rol));+			/* Calculate arm rol. */+			rol = 4 + (rol >> 1);+			break;+		}+		rol += 2;+		mask >>= 2;+		if (mask & 0x3) {+			/* rol by 8. */+			imm = (imm << 8) | (imm >> 24);+			mask = 0xff00;+			rol = 24;+			while (1) {+				if (!(imm & mask)) {+					/* Rol imm by rol. */+					imm = (imm << rol) | (imm >> (32 - rol));+					/* Calculate arm rol. */+					rol = (rol >> 1) - 8;+					break;+				}+				rol += 2;+				mask >>= 2;+				if (mask & 0x3)+					return 0;+			}+			break;+		}+	}++	/* The low 8 bit must be zero. */+	SLJIT_ASSERT(!(imm & 0xff));++	if (!(imm & 0xff000000)) {+		imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);+		imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);+	}+	else if (imm & 0xc0000000) {+		imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);+		imm <<= 8;+		rol += 4;++		if (!(imm & 0xff000000)) {+			imm <<= 8;+			rol += 4;+		}++		if (!(imm & 0xf0000000)) {+			imm <<= 4;+			rol += 2;+		}++		if (!(imm & 0xc0000000)) {+			imm <<= 2;+			rol += 1;+		}++		if (!(imm & 0x00ffffff))+			imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);+		else+			return 0;+	}+	else {+		if (!(imm & 0xf0000000)) {+			imm <<= 4;+			rol += 2;+		}++		if (!(imm & 0xc0000000)) {+			imm <<= 2;+			rol += 1;+		}++		imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);+		imm <<= 8;+		rol += 4;++		if (!(imm & 0xf0000000)) {+			imm <<= 4;+			rol += 2;+		}++		if (!(imm & 0xc0000000)) {+			imm <<= 2;+			rol += 1;+		}++		if (!(imm & 0x00ffffff))+			imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);+		else+			return 0;+	}++	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++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm)+{+	sljit_uw tmp;++#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)+	if (!(imm & ~0xffff))+		return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff));+#endif++	/* Create imm by 1 inst. */+	tmp = get_imm(imm);+	if (tmp)+		return push_inst(compiler, MOV | RD(reg) | tmp);++	tmp = get_imm(~imm);+	if (tmp)+		return push_inst(compiler, MVN | RD(reg) | tmp);++#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)+	/* Create imm by 2 inst. */+	FAIL_IF(generate_int(compiler, reg, imm, 1));+	FAIL_IF(generate_int(compiler, reg, ~imm, 0));++	/* Load integer. */+	return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), imm);+#else+	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+}++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_uw imm, offset_reg;+	sljit_uw is_type1_transfer = IS_TYPE1_TRANSFER(flags);++	SLJIT_ASSERT (arg & SLJIT_MEM);+	SLJIT_ASSERT((arg & REG_MASK) != tmp_reg);++	if ((arg & REG_MASK) == SLJIT_UNUSED) {+		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;+		}++		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) {+		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)));+	}++	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));+	}+	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)));+		}+	}++	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,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	/* 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_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))+		flags |= UNUSED_RETURN;++	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_reg = get_imm(~src1w);+				if (src2_reg) {+					flags |= ARGS_SWAPPED | INV_IMM;+					src1 = src2;+					src1w = src2w;+					break;+				}+			}+			if (GET_OPCODE(op) == SLJIT_ADD) {+				src2_reg = get_imm(-src1w);+				if (src2_reg) {+					/* Note: add is commutative operation. */+					src1 = src2;+					src1w = src2w;+					op = SLJIT_SUB | GET_ALL_FLAGS(op);+					break;+				}+			}+		}+	} while(0);++	/* 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);+		}++		if (FAST_IS_REG(src2) && dst_reg != TMP_REG2)+			flags |= MOVE_REG_CONV;+	}++	/* Source 2. */+	if (src2_reg == 0) {+		src2_reg = (op <= SLJIT_MOV_P) ? dst_reg : TMP_REG2;++		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(load_immediate(compiler, src2_reg, src2w));+	}++	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+extern "C" {+#endif++#if defined(__GNUC__)+extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);+extern int __aeabi_idivmod(int numerator, int denominator);+#else+#error "Software divmod functions are needed"+#endif++#ifdef __cplusplus+}+#endif++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));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_BREAKPOINT:+		FAIL_IF(push_inst(compiler, BKPT));+		break;+	case SLJIT_NOP:+		FAIL_IF(push_inst(compiler, NOP));+		break;+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+		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]);+	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_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++] = 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] */));+			}+		}++#if defined(__GNUC__)+		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,+			((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));+#else+#error "Software divmod functions are needed"+#endif++		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 */);+		}+		return SLJIT_SUCCESS;+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++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)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV:+	case SLJIT_MOV_U32:+	case SLJIT_MOV_S32:+	case SLJIT_MOV_P:+		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_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 | 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_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 | 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);++	case SLJIT_NEG:+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \+			|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+		compiler->skip_checks = 1;+#endif+		return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw);++	case SLJIT_CLZ:+		return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	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:+	case SLJIT_SUB:+	case SLJIT_SUBC:+	case SLJIT_OR:+	case SLJIT_XOR:+		return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_MUL:+		return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_AND:+		return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SHL:+	case SLJIT_LSHR:+	case SLJIT_ASHR:+		if (src2 & SLJIT_IMM) {+			compiler->shift_imm = src2w & 0x1f;+			return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w);+		}+		else {+			compiler->shift_imm = 0x20;+			return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);+		}+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		SLJIT_ASSERT(reg_map[TMP_REG2] == 14);++		if (FAST_IS_REG(src))+			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));+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		return SLJIT_SUCCESS;+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)+		SLJIT_ASSERT(src & SLJIT_MEM);+		return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);+#else /* !SLJIT_CONFIG_ARM_V7 */+		return SLJIT_SUCCESS;+#endif /* SLJIT_CONFIG_ARM_V7 */+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++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 (freg_map[reg] << 1);+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	return push_inst(compiler, *(sljit_uw*)instruction);+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */+++#define FPU_LOAD (1 << 20)+#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \+	((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg_map[freg] << 12) | (offs))+#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \+	((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_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, 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) {+		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));++		imm = get_imm(argw & ~0x3fc);+		if (imm) {+			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, 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));+		}+	}++	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_REG2, argw));++	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;+	}++	FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_F32_OP, TMP_FREG1, src, 0)));++	if (FAST_IS_REG(dst))+		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);+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	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) | (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) | (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)));++	if (dst & SLJIT_MEM)+		return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	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;+	}++	if (src2 & SLJIT_MEM) {+		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));+		src2 = TMP_FREG2;+	}++	FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_F32_OP, src1, src2, 0)));+	return push_inst(compiler, VMRS);+}++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_s32 dst_r;++	CHECK_ERROR();++	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;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV_F64:+		if (src != dst_r) {+			if (dst_r != TMP_FREG1)+				FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_F32_OP, dst_r, src, 0)));+			else+				dst_r = src;+		}+		break;+	case SLJIT_NEG_F64:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_F32_OP, dst_r, src, 0)));+		break;+	case SLJIT_ABS_F64:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_F32_OP, dst_r, src, 0)));+		break;+	case SLJIT_CONV_F64_FROM_F32:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_F32_OP, dst_r, src, 0)));+		op ^= SLJIT_F32_OP;+		break;+	}++	if (dst & SLJIT_MEM)+		return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw);+	return SLJIT_SUCCESS;+}++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_s32 dst_r;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	op ^= SLJIT_F32_OP;++	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;++	if (src2 & SLJIT_MEM) {+		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w));+		src2 = TMP_FREG2;+	}++	if (src1 & SLJIT_MEM) {+		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));+		src1 = TMP_FREG1;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));+		break;++	case SLJIT_SUB_F64:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));+		break;++	case SLJIT_MUL_F64:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));+		break;++	case SLJIT_DIV_F64:+		FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_F32_OP, dst_r, src2, src1)));+		break;+	}++	if (dst_r == TMP_FREG1)+		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw));++	return SLJIT_SUCCESS;+}++#undef FPU_LOAD+#undef EMIT_FPU_DATA_TRANSFER++/* --------------------------------------------------------------------- */+/*  Other instructions                                                   */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	SLJIT_ASSERT(reg_map[TMP_REG2] == 14);++	if (FAST_IS_REG(dst))+		return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2));++	/* Memory. */+	return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1);+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++static sljit_uw get_cc(sljit_s32 type)+{+	switch (type) {+	case SLJIT_EQUAL:+	case SLJIT_MUL_NOT_OVERFLOW:+	case SLJIT_EQUAL_F64:+		return 0x00000000;++	case SLJIT_NOT_EQUAL:+	case SLJIT_MUL_OVERFLOW:+	case SLJIT_NOT_EQUAL_F64:+		return 0x10000000;++	case SLJIT_LESS:+	case SLJIT_LESS_F64:+		return 0x30000000;++	case SLJIT_GREATER_EQUAL:+	case SLJIT_GREATER_EQUAL_F64:+		return 0x20000000;++	case SLJIT_GREATER:+	case SLJIT_GREATER_F64:+		return 0x80000000;++	case SLJIT_LESS_EQUAL:+	case SLJIT_LESS_EQUAL_F64:+		return 0x90000000;++	case SLJIT_SIG_LESS:+		return 0xb0000000;++	case SLJIT_SIG_GREATER_EQUAL:+		return 0xa0000000;++	case SLJIT_SIG_GREATER:+		return 0xc0000000;++	case SLJIT_SIG_LESS_EQUAL:+		return 0xd0000000;++	case SLJIT_OVERFLOW:+	case SLJIT_UNORDERED_F64:+		return 0x60000000;++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_ORDERED_F64:+		return 0x70000000;++	default:+		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);+		return 0xe0000000;+	}+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	return label;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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;++	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_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) {+		jump->addr = compiler->size;+		compiler->patches++;+	}++	if (type >= SLJIT_FAST_CALL) {+		jump->flags |= IS_BL;+		PTR_FAIL_IF(emit_blx(compiler));+	}++	if (!(jump->flags & SLJIT_REWRITABLE_JUMP))+		jump->addr = compiler->size;+#else+	if (type >= SLJIT_FAST_CALL)+		jump->flags |= IS_BL;+	PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0));+	PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type)));+	jump->addr = compiler->size;+#endif+	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;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	SLJIT_ASSERT(reg_map[TMP_REG1] != 14);++	if (!(src & SLJIT_IMM)) {+		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_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));+	jump->u.target = srcw;++#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_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+	FAIL_IF(emit_imm(compiler, TMP_REG1, 0));+	FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));+#endif+	jump->addr = compiler->size;+	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 type)+{+	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, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	op = GET_OPCODE(op);+	cc = get_cc(type & 0xff);+	dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if (op < SLJIT_ADD) {+		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 : (op == SLJIT_OR ? ORR : EOR));++	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;+#endif+	}++	return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src)) & ~COND_MASK) | cc);+}++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)+{+	struct sljit_const *const_;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	dst_r = 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_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), init_value));+	compiler->patches++;+#else+	PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));+#endif++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));+	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	dst_r = 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_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));+	compiler->patches++;+#else+	PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));+#endif++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 0);++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));+	return put_label;+}++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, executable_offset, new_target, 1);+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)+{+	inline_set_const(addr, executable_offset, new_constant, 1);+}
+ src/c/pcre2/src/sljit/sljitNativeARM_64.c view
@@ -0,0 +1,2048 @@+/*+ *    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.+ */++SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)+{+	return "ARM-64" SLJIT_CPUINFO;+}++/* Length of an instruction word */+typedef sljit_u32 sljit_ins;++#define TMP_ZERO	(0)++#define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)+#define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)+#define TMP_LR		(SLJIT_NUMBER_OF_REGISTERS + 4)+#define TMP_FP		(SLJIT_NUMBER_OF_REGISTERS + 5)++#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, 11, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 31, 9, 10, 30, 29+};++static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {+	0, 0, 1, 2, 3, 4, 5, 6, 7+};++#define W_OP (1u << 31)+#define RD(rd) (reg_map[rd])+#define RT(rt) (reg_map[rt])+#define RN(rn) (reg_map[rn] << 5)+#define RT2(rt2) (reg_map[rt2] << 10)+#define RM(rm) (reg_map[rm] << 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                                                     */+/* --------------------------------------------------------------------- */++#define ADC 0x9a000000+#define ADD 0x8b000000+#define ADDE 0x8b200000+#define ADDI 0x91000000+#define AND 0x8a000000+#define ANDI 0x92000000+#define ASRV 0x9ac02800+#define B 0x14000000+#define B_CC 0x54000000+#define BL 0x94000000+#define BLR 0xd63f0000+#define BR 0xd61f0000+#define BRK 0xd4200000+#define CBZ 0xb4000000+#define CLZ 0xdac01000+#define CSEL 0x9a800000+#define CSINC 0x9a800400+#define EOR 0xca000000+#define EORI 0xd2000000+#define FABS 0x1e60c000+#define FADD 0x1e602800+#define FCMP 0x1e602000+#define FCVT 0x1e224000+#define FCVTZS 0x9e780000+#define FDIV 0x1e601800+#define FMOV 0x1e604000+#define FMUL 0x1e600800+#define FNEG 0x1e614000+#define FSUB 0x1e603800+#define LDRI 0xf9400000+#define LDP 0xa9400000+#define LDP_PRE 0xa9c00000+#define LDR_PRE 0xf8400c00+#define LSLV 0x9ac02000+#define LSRV 0x9ac02400+#define MADD 0x9b000000+#define MOVK 0xf2800000+#define MOVN 0x92800000+#define MOVZ 0xd2800000+#define NOP 0xd503201f+#define ORN 0xaa200000+#define ORR 0xaa000000+#define ORRI 0xb2000000+#define RET 0xd65f0000+#define SBC 0xda000000+#define SBFM 0x93000000+#define SCVTF 0x9e620000+#define SDIV 0x9ac00c00+#define SMADDL 0x9b200000+#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+#define UBFM 0xd3000000+#define UDIV 0x9ac00800+#define UMULH 0x9bc03c00++/* dest_reg is the absolute name of the register+   Useful for reordering instructions in the delay slot. */+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)+{+	sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)+{+	FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));+	FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21)));+	FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 32) & 0xffff) << 5) | (2 << 21)));+	return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));+}++static SLJIT_INLINE sljit_sw 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;++	if (jump->flags & SLJIT_REWRITABLE_JUMP) {+		jump->flags |= PATCH_ABS64;+		return 0;+	}++	if (jump->flags & JUMP_ADDR)+		target_addr = jump->u.target;+	else {+		SLJIT_ASSERT(jump->flags & JUMP_LABEL);+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;+	}++	diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset;++	if (jump->flags & IS_COND) {+		diff += sizeof(sljit_ins);+		if (diff <= 0xfffff && diff >= -0x100000) {+			code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;+			jump->addr -= sizeof(sljit_ins);+			jump->flags |= PATCH_COND;+			return 5;+		}+		diff -= sizeof(sljit_ins);+	}++	if (diff <= 0x7ffffff && diff >= -0x8000000) {+		jump->flags |= PATCH_B;+		return 4;+	}++	if (target_addr < 0x100000000l) {+		if (jump->flags & IS_COND)+			code_ptr[-5] -= (2 << 5);+		code_ptr[-2] = code_ptr[0];+		return 2;+	}++	if (target_addr < 0x1000000000000l) {+		if (jump->flags & IS_COND)+			code_ptr[-5] -= (1 << 5);+		jump->flags |= PATCH_ABS48;+		code_ptr[-1] = code_ptr[0];+		return 1;+	}++	jump->flags |= PATCH_ABS64;+	return 0;+}++static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)+{+	if (max_label < 0x100000000l) {+		put_label->flags = 0;+		return 2;+	}++	if (max_label < 0x1000000000000l) {+		put_label->flags = 1;+		return 1;+	}++	put_label->flags = 2;+	return 0;+}++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_ins *code;+	sljit_ins *code_ptr;+	sljit_ins *buf_ptr;+	sljit_ins *buf_end;+	sljit_uw word_count;+	sljit_uw next_addr;+	sljit_sw executable_offset;+	sljit_uw addr;+	sljit_s32 dst;++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	word_count = 0;+	next_addr = 0;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;++	do {+		buf_ptr = (sljit_ins*)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 2);+		do {+			*code_ptr = *buf_ptr++;+			if (next_addr == word_count) {+				SLJIT_ASSERT(!label || label->size >= word_count);+				SLJIT_ASSERT(!jump || jump->addr >= word_count);+				SLJIT_ASSERT(!const_ || const_->addr >= word_count);+				SLJIT_ASSERT(!put_label || put_label->addr >= word_count);++				/* These structures are ordered by their address. */+				if (label && label->size == word_count) {+					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, executable_offset);+						jump = jump->next;+				}+				if (const_ && const_->addr == word_count) {+					const_->addr = (sljit_uw)code_ptr;+					const_ = const_->next;+				}+				if (put_label && put_label->addr == word_count) {+					SLJIT_ASSERT(put_label->label);+					put_label->addr = (sljit_uw)(code_ptr - 3);+					code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));+					put_label = put_label->next;+				}+				next_addr = compute_next_addr(label, jump, const_, put_label);+			}+			code_ptr ++;+			word_count ++;+		} while (buf_ptr < buf_end);++		buf = buf->next;+	} while (buf);++	if (label && label->size == word_count) {+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);+		label->size = code_ptr - code;+		label = label->next;+	}++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);+	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);++	jump = compiler->jumps;+	while (jump) {+		do {+			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;+			buf_ptr = (sljit_ins *)jump->addr;++			if (jump->flags & PATCH_B) {+				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)+					buf_ptr[-1] -= (4 << 5);+				break;+			}+			if (jump->flags & PATCH_COND) {+				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;+			}++			SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl);+			SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl);++			dst = buf_ptr[0] & 0x1f;+			buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5);+			buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21);+			if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))+				buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21);+			if (jump->flags & PATCH_ABS64)+				buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21);+		} while (0);+		jump = jump->next;+	}++	put_label = compiler->put_labels;+	while (put_label) {+		addr = put_label->label->addr;+		buf_ptr = (sljit_ins *)put_label->addr;++		buf_ptr[0] |= (addr & 0xffff) << 5;+		buf_ptr[1] |= ((addr >> 16) & 0xffff) << 5;++		if (put_label->flags >= 1)+			buf_ptr[2] |= ((addr >> 32) & 0xffff) << 5;++		if (put_label->flags >= 2)+			buf_ptr[3] |= ((addr >> 48) & 0xffff) << 5;++		put_label = put_label->next;+	}++	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);+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);+	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:+	case SLJIT_HAS_PREFETCH:+		return 1;++	default:+		return 0;+	}+}++/* --------------------------------------------------------------------- */+/*  Core code generator functions.                                       */+/* --------------------------------------------------------------------- */++#define COUNT_TRAILING_ZERO(value, result) \+	result = 0; \+	if (!(value & 0xffffffff)) { \+		result += 32; \+		value >>= 32; \+	} \+	if (!(value & 0xffff)) { \+		result += 16; \+		value >>= 16; \+	} \+	if (!(value & 0xff)) { \+		result += 8; \+		value >>= 8; \+	} \+	if (!(value & 0xf)) { \+		result += 4; \+		value >>= 4; \+	} \+	if (!(value & 0x3)) { \+		result += 2; \+		value >>= 2; \+	} \+	if (!(value & 0x1)) { \+		result += 1; \+		value >>= 1; \+	}++#define LOGICAL_IMM_CHECK 0x100++static sljit_ins logical_imm(sljit_sw imm, sljit_s32 len)+{+	sljit_s32 negated, ones, right;+	sljit_uw mask, uimm;+	sljit_ins ins;++	if (len & LOGICAL_IMM_CHECK) {+		len &= ~LOGICAL_IMM_CHECK;+		if (len == 32 && (imm == 0 || imm == -1))+			return 0;+		if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1))+			return 0;+	}++	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_UNREACHABLE();+			return 0;+		}++		mask = ((sljit_uw)1 << len) - 1;+		if ((uimm & mask) != ((uimm >> len) & mask))+			break;+		len >>= 1;+	}++	len <<= 1;++	negated = 0;+	if (uimm & 0x1) {+		negated = 1;+		uimm = ~uimm;+	}++	if (len < 64)+		uimm &= ((sljit_uw)1 << len) - 1;++	/* Unsigned right shift. */+	COUNT_TRAILING_ZERO(uimm, right);++	/* Signed shift. We also know that the highest bit is set. */+	imm = (sljit_sw)~uimm;+	SLJIT_ASSERT(imm < 0);++	COUNT_TRAILING_ZERO(imm, ones);++	if (~imm)+		return 0;++	if (len == 64)+		ins = 1 << 22;+	else+		ins = (0x3f - ((len << 1) - 1)) << 10;++	if (negated)+		return ins | ((len - ones - 1) << 10) | ((len - ones - right) << 16);++	return ins | ((ones - 1) << 10) | ((len - right) << 16);+}++#undef COUNT_TRAILING_ZERO++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm)+{+	sljit_uw imm = (sljit_uw)simm;+	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 < 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);++		FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));+		return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));+	}++	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. */++	zeros = 0;+	ones = 0;+	for (i = 4; i > 0; i--) {+		if ((simm & 0xffff) == 0)+			zeros++;+		if ((simm & 0xffff) == 0xffff)+			ones++;+		simm >>= 16;+	}++	simm = (sljit_sw)imm;+	first = 1;+	if (ones > zeros) {+		simm = ~simm;+		for (i = 0; i < 4; i++) {+			if (!(simm & 0xffff)) {+				simm >>= 16;+				continue;+			}+			if (first) {+				first = 0;+				FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));+			}+			else+				FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((~simm & 0xffff) << 5) | (i << 21)));+			simm >>= 16;+		}+		return SLJIT_SUCCESS;+	}++	for (i = 0; i < 4; i++) {+		if (!(simm & 0xffff)) {+			simm >>= 16;+			continue;+		}+		if (first) {+			first = 0;+			FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));+		}+		else+			FAIL_IF(push_inst(compiler, MOVK | RD(dst) | ((simm & 0xffff) << 5) | (i << 21)));+		simm >>= 16;+	}+	return SLJIT_SUCCESS;+}++#define ARG1_IMM	0x0010000+#define ARG2_IMM	0x0020000+#define INT_OP		0x0040000+#define SET_FLAGS	0x0080000+#define UNUSED_RETURN	0x0100000++#define CHECK_FLAGS(flag_bits) \+	if (flags & SET_FLAGS) { \+		inv_bits |= flag_bits; \+		if (flags & UNUSED_RETURN) \+			dst = TMP_ZERO; \+	}++static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2)+{+	/* dst must be register, TMP_REG1+	   arg1 must be register, TMP_REG1, imm+	   arg2 must be register, TMP_REG2, imm */+	sljit_ins inv_bits = (flags & INT_OP) ? W_OP : 0;+	sljit_ins inst_bits;+	sljit_s32 op = (flags & 0xffff);+	sljit_s32 reg;+	sljit_sw imm, nimm;++	if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {+		/* Both are immediates. */+		flags &= ~ARG1_IMM;+		if (arg1 == 0 && op != SLJIT_ADD && op != SLJIT_SUB)+			arg1 = TMP_ZERO;+		else {+			FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));+			arg1 = TMP_REG1;+		}+	}++	if (flags & (ARG1_IMM | ARG2_IMM)) {+		reg = (flags & ARG2_IMM) ? arg1 : arg2;+		imm = (flags & ARG2_IMM) ? arg2 : arg1;++		switch (op) {+		case SLJIT_MUL:+		case SLJIT_NEG:+		case SLJIT_CLZ:+		case SLJIT_ADDC:+		case SLJIT_SUBC:+			/* No form with immediate operand (except imm 0, which+			is represented by a ZERO register). */+			break;+		case SLJIT_MOV:+			SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);+			return load_immediate(compiler, dst, imm);+		case SLJIT_NOT:+			SLJIT_ASSERT(flags & ARG2_IMM);+			FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm));+			goto set_flags;+		case SLJIT_SUB:+			if (flags & ARG1_IMM)+				break;+			imm = -imm;+			/* Fall through. */+		case SLJIT_ADD:+			if (imm == 0) {+				CHECK_FLAGS(1 << 29);+				return push_inst(compiler, ((op == SLJIT_ADD ? ADDI : SUBI) ^ inv_bits) | RD(dst) | RN(reg));+			}+			if (imm > 0 && imm <= 0xfff) {+				CHECK_FLAGS(1 << 29);+				return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | (imm << 10));+			}+			nimm = -imm;+			if (nimm > 0 && nimm <= 0xfff) {+				CHECK_FLAGS(1 << 29);+				return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | (nimm << 10));+			}+			if (imm > 0 && imm <= 0xffffff && !(imm & 0xfff)) {+				CHECK_FLAGS(1 << 29);+				return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22));+			}+			if (nimm > 0 && nimm <= 0xffffff && !(nimm & 0xfff)) {+				CHECK_FLAGS(1 << 29);+				return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22));+			}+			if (imm > 0 && imm <= 0xffffff && !(flags & SET_FLAGS)) {+				FAIL_IF(push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(reg) | ((imm >> 12) << 10) | (1 << 22)));+				return push_inst(compiler, (ADDI ^ inv_bits) | RD(dst) | RN(dst) | ((imm & 0xfff) << 10));+			}+			if (nimm > 0 && nimm <= 0xffffff && !(flags & SET_FLAGS)) {+				FAIL_IF(push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(reg) | ((nimm >> 12) << 10) | (1 << 22)));+				return push_inst(compiler, (SUBI ^ inv_bits) | RD(dst) | RN(dst) | ((nimm & 0xfff) << 10));+			}+			break;+		case SLJIT_AND:+			inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));+			if (!inst_bits)+				break;+			CHECK_FLAGS(3 << 29);+			return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits);+		case SLJIT_OR:+		case SLJIT_XOR:+			inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));+			if (!inst_bits)+				break;+			if (op == SLJIT_OR)+				inst_bits |= ORRI;+			else+				inst_bits |= EORI;+			FAIL_IF(push_inst(compiler, (inst_bits ^ inv_bits) | RD(dst) | RN(reg)));+			goto set_flags;+		case SLJIT_SHL:+			if (flags & ARG1_IMM)+				break;+			if (flags & INT_OP) {+				imm &= 0x1f;+				FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | ((-imm & 0x1f) << 16) | ((31 - imm) << 10)));+			}+			else {+				imm &= 0x3f;+				FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | ((-imm & 0x3f) << 16) | ((63 - imm) << 10)));+			}+			goto set_flags;+		case SLJIT_LSHR:+		case SLJIT_ASHR:+			if (flags & ARG1_IMM)+				break;+			if (op == SLJIT_ASHR)+				inv_bits |= 1 << 30;+			if (flags & INT_OP) {+				imm &= 0x1f;+				FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (imm << 16) | (31 << 10)));+			}+			else {+				imm &= 0x3f;+				FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | (1 << 22) | (imm << 16) | (63 << 10)));+			}+			goto set_flags;+		default:+			SLJIT_UNREACHABLE();+			break;+		}++		if (flags & ARG2_IMM) {+			if (arg2 == 0)+				arg2 = TMP_ZERO;+			else {+				FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));+				arg2 = TMP_REG2;+			}+		}+		else {+			if (arg1 == 0)+				arg1 = TMP_ZERO;+			else {+				FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));+				arg1 = TMP_REG1;+			}+		}+	}++	/* Both arguments are registers. */+	switch (op) {+	case SLJIT_MOV:+	case SLJIT_MOV_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:+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);+		return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (7 << 10));+	case SLJIT_MOV_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:+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);+		return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (15 << 10));+	case SLJIT_MOV_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:+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);+		if ((flags & INT_OP) && dst == arg2)+			return SLJIT_SUCCESS;+		return push_inst(compiler, (ORR ^ W_OP) | RD(dst) | RN(TMP_ZERO) | RM(arg2));+	case SLJIT_MOV_S32:+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);+		if ((flags & INT_OP) && dst == arg2)+			return SLJIT_SUCCESS;+		return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10));+	case SLJIT_NOT:+		SLJIT_ASSERT(arg1 == TMP_REG1);+		FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)));+		break; /* Set flags. */+	case SLJIT_NEG:+		SLJIT_ASSERT(arg1 == TMP_REG1);+		if (flags & SET_FLAGS)+			inv_bits |= 1 << 29;+		return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2));+	case SLJIT_CLZ:+		SLJIT_ASSERT(arg1 == TMP_REG1);+		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));+	case SLJIT_ADDC:+		CHECK_FLAGS(1 << 29);+		return push_inst(compiler, (ADC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));+	case SLJIT_SUB:+		CHECK_FLAGS(1 << 29);+		return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));+	case SLJIT_SUBC:+		CHECK_FLAGS(1 << 29);+		return push_inst(compiler, (SBC ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));+	case SLJIT_MUL:+		if (!(flags & SET_FLAGS))+			return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO));+		if (flags & INT_OP) {+			FAIL_IF(push_inst(compiler, SMADDL | RD(dst) | RN(arg1) | RM(arg2) | (31 << 10)));+			FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(TMP_ZERO) | RM(dst) | (2 << 22) | (31 << 10)));+			return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));+		}+		FAIL_IF(push_inst(compiler, SMULH | RD(TMP_LR) | RN(arg1) | RM(arg2)));+		FAIL_IF(push_inst(compiler, MADD | RD(dst) | RN(arg1) | RM(arg2) | RT2(TMP_ZERO)));+		return push_inst(compiler, SUBS | RD(TMP_ZERO) | RN(TMP_LR) | RM(dst) | (2 << 22) | (63 << 10));+	case SLJIT_AND:+		CHECK_FLAGS(3 << 29);+		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)));+		break; /* Set flags. */+	case SLJIT_XOR:+		FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));+		break; /* Set flags. */+	case SLJIT_SHL:+		FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));+		break; /* Set flags. */+	case SLJIT_LSHR:+		FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));+		break; /* Set flags. */+	case SLJIT_ASHR:+		FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));+		break; /* Set flags. */+	default:+		SLJIT_UNREACHABLE();+		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		0x10+#define SIGNED		0x20++#define BYTE_SIZE	0x0+#define HALF_SIZE	0x1+#define INT_SIZE	0x2+#define WORD_SIZE	0x3++#define MEM_SIZE_SHIFT(flags) ((flags) & 0x3)++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(arg & OFFS_REG_MASK)) {+		argw &= 0x3;++		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, 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 (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 >= 0 && (argw & ((1 << shift) - 1)) == 0) {+		if ((argw >> shift) <= 0xfff) {+			return push_inst(compiler, STRBI | type | RT(reg) | RN(arg) | (argw << (10 - shift)));+		}++		if (argw <= 0xffffff) {+			FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | ((argw >> 12) << 10)));++			argw = ((argw & 0xfff) >> shift);+			return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | (argw << 10));+		}+	}++	if (argw <= 255 && argw >= -256)+		return push_inst(compiler, STURBI | type | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12));++	FAIL_IF(load_immediate(compiler, tmp_reg, argw));++	return push_inst(compiler, STRB | type | RT(reg) | RN(arg) | RM(tmp_reg));+}++/* --------------------------------------------------------------------- */+/*  Entry, exit                                                          */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 args, i, tmp, offs, prev, saved_regs_size;++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);+	if (saved_regs_size & 0x8)+		saved_regs_size += sizeof(sljit_sw);++	local_size = (local_size + 15) & ~0xf;+	compiler->local_size = local_size + saved_regs_size;++	FAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR)+		| RN(SLJIT_SP) | ((-(saved_regs_size >> 3) & 0x7f) << 15)));++#ifdef _WIN32+	if (local_size >= 4096)+		FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(SLJIT_SP) | (1 << 10) | (1 << 22)));+	else if (local_size > 256)+		FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(SLJIT_SP) | (local_size << 10)));+#endif++	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	prev = -1;+	offs = 2 << 15;+	for (i = SLJIT_S0; i >= tmp; i--) {+		if (prev == -1) {+			prev = i;+			continue;+		}+		FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));+		offs += 2 << 15;+		prev = -1;+	}++	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		if (prev == -1) {+			prev = i;+			continue;+		}+		FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));+		offs += 2 << 15;+		prev = -1;+	}++	if (prev != -1)+		FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5)));+++	FAIL_IF(push_inst(compiler, ADDI | RD(TMP_FP) | RN(SLJIT_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)+		FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S1) | RN(TMP_ZERO) | RM(SLJIT_R1)));+	if (args >= 3)+		FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2)));++#ifdef _WIN32+	if (local_size >= 4096) {+		if (local_size < 4 * 4096) {+			/* No need for a loop. */+			if (local_size >= 2 * 4096) {+				FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));+				FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10) | (1 << 22)));+				local_size -= 4096;+			}++			if (local_size >= 2 * 4096) {+				FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));+				FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10) | (1 << 22)));+				local_size -= 4096;+			}++			FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));+			local_size -= 4096;+		}+		else {+			FAIL_IF(push_inst(compiler, MOVZ | RD(TMP_REG2) | (((local_size >> 12) - 1) << 5)));+			FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));+			FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10) | (1 << 22)));+			FAIL_IF(push_inst(compiler, SUBI | (1 << 29) | RD(TMP_REG2) | RN(TMP_REG2) | (1 << 10)));+			FAIL_IF(push_inst(compiler, B_CC | ((((sljit_ins) -3) & 0x7ffff) << 5) | 0x1 /* not-equal */));+			FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));++			local_size &= 0xfff;+		}++		if (local_size > 256) {+			FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (local_size << 10)));+			FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));+		}+		else if (local_size > 0)+			FAIL_IF(push_inst(compiler, LDR_PRE | RT(TMP_ZERO) | RN(TMP_REG1) | ((-local_size & 0x1ff) << 12)));++		FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_REG1) | (0 << 10)));+	}+	else if (local_size > 256) {+		FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1)));+		FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_REG1) | (0 << 10)));+	}+	else if (local_size > 0)+		FAIL_IF(push_inst(compiler, LDR_PRE | RT(TMP_ZERO) | RN(SLJIT_SP) | ((-local_size & 0x1ff) << 12)));++#else /* !_WIN32 */++	/* The local_size does not include saved registers size. */+	if (local_size > 0xfff) {+		FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((local_size >> 12) << 10) | (1 << 22)));+		local_size &= 0xfff;+	}+	if (local_size != 0)+		FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (local_size << 10)));++#endif /* _WIN32 */++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 saved_regs_size;++	CHECK_ERROR();+	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);+	if (saved_regs_size & 0x8)+		saved_regs_size += sizeof(sljit_sw);++	compiler->local_size = saved_regs_size + ((local_size + 15) & ~0xf);+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 local_size;+	sljit_s32 i, tmp, offs, prev, saved_regs_size;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 2);+	if (saved_regs_size & 0x8)+		saved_regs_size += sizeof(sljit_sw);++	local_size = compiler->local_size - saved_regs_size;++	/* Load LR as early as possible. */+	if (local_size == 0)+		FAIL_IF(push_inst(compiler, LDP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));+	else if (local_size < 63 * sizeof(sljit_sw)) {+		FAIL_IF(push_inst(compiler, LDP_PRE | RT(TMP_FP) | RT2(TMP_LR)+			| RN(SLJIT_SP) | (local_size << (15 - 3))));+	}+	else {+		if (local_size > 0xfff) {+			FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((local_size >> 12) << 10) | (1 << 22)));+			local_size &= 0xfff;+		}+		if (local_size)+			FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | (local_size << 10)));++		FAIL_IF(push_inst(compiler, LDP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP)));+	}++	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;+	prev = -1;+	offs = 2 << 15;+	for (i = SLJIT_S0; i >= tmp; i--) {+		if (prev == -1) {+			prev = i;+			continue;+		}+		FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));+		offs += 2 << 15;+		prev = -1;+	}++	for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		if (prev == -1) {+			prev = i;+			continue;+		}+		FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs));+		offs += 2 << 15;+		prev = -1;+	}++	if (prev != -1)+		FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5)));++	/* These two can be executed in parallel. */+	FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | (saved_regs_size << 10)));+	return push_inst(compiler, RET | RN(TMP_LR));+}++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+	sljit_ins inv_bits = (op & SLJIT_I32_OP) ? W_OP : 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_BREAKPOINT:+		return push_inst(compiler, BRK);+	case SLJIT_NOP:+		return push_inst(compiler, NOP);+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+		FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));+		FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));+		return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));+	case SLJIT_DIVMOD_UW:+	case SLJIT_DIVMOD_SW:+		FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));+		FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));+		FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));+		return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));+	case SLJIT_DIV_UW:+	case SLJIT_DIV_SW:+		return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++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)+{+	sljit_s32 dst_r, flags, mem_flags;+	sljit_s32 op_flags = GET_ALL_FLAGS(op);++	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src, srcw);++	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;++	op = GET_OPCODE(op);+	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:+			mem_flags = WORD_SIZE;+			break;+		case SLJIT_MOV_U8:+			mem_flags = BYTE_SIZE;+			if (src & SLJIT_IMM)+				srcw = (sljit_u8)srcw;+			break;+		case SLJIT_MOV_S8:+			mem_flags = BYTE_SIZE | SIGNED;+			if (src & SLJIT_IMM)+				srcw = (sljit_s8)srcw;+			break;+		case SLJIT_MOV_U16:+			mem_flags = HALF_SIZE;+			if (src & SLJIT_IMM)+				srcw = (sljit_u16)srcw;+			break;+		case SLJIT_MOV_S16:+			mem_flags = HALF_SIZE | SIGNED;+			if (src & SLJIT_IMM)+				srcw = (sljit_s16)srcw;+			break;+		case SLJIT_MOV_U32:+			mem_flags = INT_SIZE;+			if (src & SLJIT_IMM)+				srcw = (sljit_u32)srcw;+			break;+		case SLJIT_MOV_S32:+			mem_flags = INT_SIZE | SIGNED;+			if (src & SLJIT_IMM)+				srcw = (sljit_s32)srcw;+			break;+		default:+			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))+			dst_r = src;+		else+			FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, src, srcw, TMP_REG1));++		if (dst & SLJIT_MEM)+			return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);+		return SLJIT_SUCCESS;+	}++	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;+	}++	if (dst == SLJIT_UNUSED)+		flags |= UNUSED_RETURN;++	if (src & SLJIT_MEM) {+		FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src, srcw, TMP_REG2));+		src = TMP_REG2;+	}++	emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, src);++	if (SLJIT_UNLIKELY(dst & SLJIT_MEM))+		return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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_s32 dst_r, flags, mem_flags;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))+		return SLJIT_SUCCESS;++	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;+	flags = HAS_FLAGS(op) ? SET_FLAGS : 0;+	mem_flags = WORD_SIZE;++	if (op & SLJIT_I32_OP) {+		flags |= INT_OP;+		mem_flags = INT_SIZE;+	}++	if (dst == SLJIT_UNUSED)+		flags |= UNUSED_RETURN;++	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) {+		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+		src2w = src2;++	emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);++	if (dst & SLJIT_MEM)+		return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		if (FAST_IS_REG(src))+			FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));+		else+			FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));++		return push_inst(compiler, RET | RN(TMP_LR));+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		return SLJIT_SUCCESS;+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+		SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);++		/* The reg_map[op] should provide the appropriate constant. */+		if (op == SLJIT_PREFETCH_L1)+			op = 1;+		else if (op == SLJIT_PREFETCH_L2)+			op = 3;+		else if (op == SLJIT_PREFETCH_L3)+			op = 5;+		else+			op = 2;++		/* Signed word sized load is the prefetch instruction. */+		return emit_op_mem(compiler, WORD_SIZE | SIGNED, op, src, srcw, TMP_REG1);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++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 freg_map[reg];+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	return push_inst(compiler, *(sljit_ins*)instruction);+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */++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 type = (shift << 30);++	SLJIT_ASSERT(arg & SLJIT_MEM);++	if (!(flags & STORE))+		type |= 0x00400000;++	if (arg & OFFS_REG_MASK) {+		argw &= 3;+		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));++		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 == SLJIT_UNUSED) {+		FAIL_IF(load_immediate(compiler, TMP_REG1, argw & ~(0xfff << shift)));++		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 (argw <= 255 && argw >= -256)+		return push_inst(compiler, STUR_FI | type | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12));++	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 = 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)+		inv_bits |= W_OP;++	if (src & SLJIT_MEM) {+		emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);+		src = TMP_FREG1;+	}++	FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));++	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;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;+	sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;++	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)+		inv_bits |= W_OP;++	if (src & SLJIT_MEM) {+		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)+		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)+			srcw = (sljit_s32)srcw;+#endif+		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));+		src = TMP_REG1;+	}++	FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));++	if (dst & SLJIT_MEM)+		return emit_fop_mem(compiler, ((op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	sljit_s32 mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;+	sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;++	if (src1 & SLJIT_MEM) {+		emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);+		src1 = TMP_FREG1;+	}++	if (src2 & SLJIT_MEM) {+		emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);+		src2 = TMP_FREG2;+	}++	return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));+}++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_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;+	sljit_ins inv_bits;++	CHECK_ERROR();++	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 ^ 0x1) : mem_flags, dst_r, src, srcw);+		src = dst_r;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV_F64:+		if (src != dst_r) {+			if (dst_r != TMP_FREG1)+				FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));+			else+				dst_r = src;+		}+		break;+	case SLJIT_NEG_F64:+		FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));+		break;+	case SLJIT_ABS_F64:+		FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));+		break;+	case SLJIT_CONV_F64_FROM_F32:+		FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_F32_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));+		break;+	}++	if (dst & SLJIT_MEM)+		return emit_fop_mem(compiler, mem_flags | STORE, dst_r, dst, dstw);+	return SLJIT_SUCCESS;+}++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_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;+	sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;+	if (src1 & SLJIT_MEM) {+		emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);+		src1 = TMP_FREG1;+	}+	if (src2 & SLJIT_MEM) {+		emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w);+		src2 = TMP_FREG2;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));+		break;+	case SLJIT_SUB_F64:+		FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));+		break;+	case SLJIT_MUL_F64:+		FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));+		break;+	case SLJIT_DIV_F64:+		FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));+		break;+	}++	if (!(dst & SLJIT_MEM))+		return SLJIT_SUCCESS;+	return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw);+}++/* --------------------------------------------------------------------- */+/*  Other instructions                                                   */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	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, TMP_REG1);+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++static sljit_uw get_cc(sljit_s32 type)+{+	switch (type) {+	case SLJIT_EQUAL:+	case SLJIT_MUL_NOT_OVERFLOW:+	case SLJIT_EQUAL_F64:+		return 0x1;++	case SLJIT_NOT_EQUAL:+	case SLJIT_MUL_OVERFLOW:+	case SLJIT_NOT_EQUAL_F64:+		return 0x0;++	case SLJIT_LESS:+	case SLJIT_LESS_F64:+		return 0x2;++	case SLJIT_GREATER_EQUAL:+	case SLJIT_GREATER_EQUAL_F64:+		return 0x3;++	case SLJIT_GREATER:+	case SLJIT_GREATER_F64:+		return 0x9;++	case SLJIT_LESS_EQUAL:+	case SLJIT_LESS_EQUAL_F64:+		return 0x8;++	case SLJIT_SIG_LESS:+		return 0xa;++	case SLJIT_SIG_GREATER_EQUAL:+		return 0xb;++	case SLJIT_SIG_GREATER:+		return 0xd;++	case SLJIT_SIG_LESS_EQUAL:+		return 0xc;++	case SLJIT_OVERFLOW:+	case SLJIT_UNORDERED_F64:+		return 0x7;++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_ORDERED_F64:+		return 0x6;++	default:+		SLJIT_UNREACHABLE();+		return 0xe;+	}+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	return label;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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;++	if (type < SLJIT_JUMP) {+		jump->flags |= IS_COND;+		PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(type)));+	}+	else if (type >= SLJIT_FAST_CALL)+		jump->flags |= IS_BL;++	PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));+	jump->addr = compiler->size;+	PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)));++	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)+{+	struct sljit_jump *jump;+	sljit_ins inv_bits = (type & SLJIT_I32_OP) ? W_OP : 0;++	SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);+	ADJUST_LOCAL_OFFSET(src, srcw);++	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_CBZ | IS_COND;++	if (src & SLJIT_MEM) {+		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)+		inv_bits |= 1 << 24;++	PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));+	PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));+	jump->addr = compiler->size;+	PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1)));+	return jump;+}++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;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	if (!(src & SLJIT_IMM)) {+		if (src & SLJIT_MEM) {+			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));+	jump->u.target = srcw;++	FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));+	jump->addr = compiler->size;+	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 type)+{+	sljit_s32 dst_r, src_r, flags, mem_flags;+	sljit_ins cc;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	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) {+			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;+	}++	flags = HAS_FLAGS(op) ? SET_FLAGS : 0;+	mem_flags = WORD_SIZE;++	if (op & SLJIT_I32_OP) {+		flags |= INT_OP;+		mem_flags = INT_SIZE;+	}++	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_r, TMP_REG2);++	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) ? W_OP : 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;++	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 sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)+{+	sljit_s32 dst_reg;+	sljit_ins ins;++	CHECK_ERROR();+	CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));++	SLJIT_ASSERT (SLJIT_LOCALS_OFFSET_BASE == 0);++	dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if (offset <= 0xffffff && offset >= -0xffffff) {+		ins = ADDI;+		if (offset < 0) {+			offset = -offset;+			ins = SUBI;+		}++		if (offset <= 0xfff)+			FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | (offset << 10)));+		else {+			FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | ((offset & 0xfff000) >> (12 - 10)) | (1 << 22)));++			offset &= 0xfff;+			if (offset != 0)+				FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(dst_reg) | (offset << 10)));+		}+	}+	else {+		FAIL_IF(load_immediate (compiler, dst_reg, offset));+		/* Add extended register form. */+		FAIL_IF(push_inst(compiler, ADDE | (0x3 << 13) | RD(dst_reg) | RN(SLJIT_SP) | RM(dst_reg)));+	}++	if (SLJIT_UNLIKELY(dst & SLJIT_MEM))+		return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG1);+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)+{+	struct sljit_const *const_;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	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, TMP_REG2));+	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;+	PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0));++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 1);++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));++	return put_label;+}++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_s32 dst;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);++	dst = inst[0] & 0x1f;+	SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));+	inst[0] = MOVZ | dst | ((new_target & 0xffff) << 5);+	inst[1] = MOVK | dst | (((new_target >> 16) & 0xffff) << 5) | (1 << 21);+	inst[2] = MOVK | dst | (((new_target >> 32) & 0xffff) << 5) | (2 << 21);+	inst[3] = MOVK | dst | ((new_target >> 48) << 5) | (3 << 21);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}
+ src/c/pcre2/src/sljit/sljitNativeARM_T2_32.c view
@@ -0,0 +1,2383 @@+/*+ *    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.+ */++SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)+{+#ifdef __SOFTFP__+	return "ARM-Thumb2" SLJIT_CPUINFO " ABI:softfp";+#else+	return "ARM-Thumb2" SLJIT_CPUINFO " ABI:hardfp";+#endif+}++/* Length of an instruction word. */+typedef sljit_u32 sljit_ins;++/* Last register + 1. */+#define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)+#define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)+#define TMP_PC		(SLJIT_NUMBER_OF_REGISTERS + 4)++#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 + 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) \+	((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to))++/* Thumb16 encodings. */+#define RD3(rd) (reg_map[rd])+#define RN3(rn) (reg_map[rn] << 3)+#define RM3(rm) (reg_map[rm] << 6)+#define RDN3(rdn) (reg_map[rdn] << 8)+#define IMM3(imm) (imm << 6)+#define IMM8(imm) (imm)++/* Thumb16 helpers. */+#define SET_REGS44(rd, rn) \+	((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4))+#define IS_2_LO_REGS(reg1, reg2) \+	(reg_map[reg1] <= 7 && reg_map[reg2] <= 7)+#define IS_3_LO_REGS(reg1, reg2, reg3) \+	(reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)++/* Thumb32 encodings. */+#define RD4(rd) (reg_map[rd] << 8)+#define RN4(rn) (reg_map[rn] << 16)+#define RM4(rm) (reg_map[rm])+#define RT4(rt) (reg_map[rt] << 12)+#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) \+	(COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))++/* --------------------------------------------------------------------- */+/*  Instrucion forms                                                     */+/* --------------------------------------------------------------------- */++/* dot '.' changed to _+   I immediate form (possibly followed by number of immediate bits). */+#define ADCI		0xf1400000+#define ADCS		0x4140+#define ADC_W		0xeb400000+#define ADD		0x4400+#define ADDS		0x1800+#define ADDSI3		0x1c00+#define ADDSI8		0x3000+#define ADD_W		0xeb000000+#define ADDWI		0xf2000000+#define ADD_SP		0xb000+#define ADD_W		0xeb000000+#define ADD_WI		0xf1000000+#define ANDI		0xf0000000+#define ANDS		0x4000+#define AND_W		0xea000000+#define ASRS		0x4100+#define ASRSI		0x1000+#define ASR_W		0xfa40f000+#define ASR_WI		0xea4f0020+#define BCC		0xd000+#define BICI		0xf0200000+#define BKPT		0xbe00+#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+#define EOR_W		0xea800000+#define IT		0xbf00+#define LDRI		0xf8500800+#define LSLS		0x4080+#define LSLSI		0x0000+#define LSL_W		0xfa00f000+#define LSL_WI		0xea4f0000+#define LSRS		0x40c0+#define LSRSI		0x0800+#define LSR_W		0xfa20f000+#define LSR_WI		0xea4f0010+#define MOV		0x4600+#define MOVS		0x0000+#define MOVSI		0x2000+#define MOVT		0xf2c00000+#define MOVW		0xf2400000+#define MOV_W		0xea4f0000+#define MOV_WI		0xf04f0000+#define MUL		0xfb00f000+#define MVNS		0x43c0+#define MVN_W		0xea6f0000+#define MVN_WI		0xf06f0000+#define NOP		0xbf00+#define ORNI		0xf0600000+#define ORRI		0xf0400000+#define ORRS		0x4300+#define ORR_W		0xea400000+#define POP		0xbc00+#define POP_W		0xe8bd0000+#define PUSH		0xb400+#define PUSH_W		0xe92d0000+#define RSB_WI		0xf1c00000+#define RSBSI		0x4240+#define SBCI		0xf1600000+#define SBCS		0x4180+#define SBC_W		0xeb600000+#define SDIV		0xfb90f0f0+#define SMULL		0xfb800000+#define STR_SP		0x9000+#define SUBS		0x1a00+#define SUBSI3		0x1e00+#define SUBSI8		0x3800+#define SUB_W		0xeba00000+#define SUBWI		0xf2a00000+#define SUB_SP		0xb080+#define SUB_WI		0xf1a00000+#define SXTB		0xb240+#define SXTB_W		0xfa4ff080+#define SXTH		0xb200+#define SXTH_W		0xfa0ff080+#define TST		0x4200+#define UDIV		0xfbb0f0f0+#define UMULL		0xfba00000+#define UXTB		0xb2c0+#define UXTB_W		0xfa5ff080+#define UXTH		0xb280+#define UXTH_W		0xfa1ff080+#define VABS_F32	0xeeb00ac0+#define VADD_F32	0xee300a00+#define VCMP_F32	0xeeb40a40+#define VCVT_F32_S32	0xeeb80ac0+#define VCVT_F64_F32	0xeeb70ac0+#define VCVT_S32_F32	0xeebd0ac0+#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+#define VSTR_F32	0xed000a00+#define VSUB_F32	0xee300a40++static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst)+{+	sljit_u16 *ptr;+	SLJIT_ASSERT(!(inst & 0xffff0000));++	ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));+	FAIL_IF(!ptr);+	*ptr = inst;+	compiler->size++;+	return SLJIT_SUCCESS;+}++static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)+{+	sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr++ = inst >> 16;+	*ptr = inst;+	compiler->size += 2;+	return SLJIT_SUCCESS;+}++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));+}++static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)+{+	sljit_s32 dst = inst[1] & 0x0f00;+	SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));+	inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1);+	inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff);+	inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1);+	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, sljit_sw executable_offset)+{+	sljit_sw diff;++	if (jump->flags & SLJIT_REWRITABLE_JUMP)+		return 0;++	if (jump->flags & JUMP_ADDR) {+		/* 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) - executable_offset) >> 1;+	}+	else {+		SLJIT_ASSERT(jump->flags & JUMP_LABEL);+		diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1;+	}++	if (jump->flags & IS_COND) {+		SLJIT_ASSERT(!(jump->flags & IS_BL));+		if (diff <= 127 && diff >= -128) {+			jump->flags |= PATCH_TYPE1;+			return 5;+		}+		if (diff <= 524287 && diff >= -524288) {+			jump->flags |= PATCH_TYPE2;+			return 4;+		}+		/* +1 comes from the prefix IT instruction. */+		diff--;+		if (diff <= 8388607 && diff >= -8388608) {+			jump->flags |= PATCH_TYPE3;+			return 3;+		}+	}+	else if (jump->flags & IS_BL) {+		if (diff <= 8388607 && diff >= -8388608) {+			jump->flags |= PATCH_BL;+			return 3;+		}+	}+	else {+		if (diff <= 1023 && diff >= -1024) {+			jump->flags |= PATCH_TYPE4;+			return 4;+		}+		if (diff <= 8388607 && diff >= -8388608) {+			jump->flags |= PATCH_TYPE5;+			return 3;+		}+	}++	return 0;+}++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;+	sljit_u16 *jump_inst;+	sljit_s32 s, j1, j2;++	if (SLJIT_UNLIKELY(type == 0)) {+		modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);+		return;+	}++	if (jump->flags & JUMP_ADDR) {+		SLJIT_ASSERT(jump->u.target & 0x1);+		diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 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) {+	case 1:+		/* Encoding T1 of 'B' instruction */+		SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND));+		jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff);+		return;+	case 2:+		/* Encoding T3 of 'B' instruction */+		SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND));+		jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1);+		jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff);+		return;+	case 3:+		SLJIT_ASSERT(jump->flags & IS_COND);+		*jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8;+		diff--;+		type = 5;+		break;+	case 4:+		/* Encoding T2 of 'B' instruction */+		SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND));+		jump_inst[0] = 0xe000 | (diff & 0x7ff);+		return;+	}++	SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608);++	/* Really complex instruction form for branches. */+	s = (diff >> 23) & 0x1;+	j1 = (~(diff >> 22) ^ s) & 0x1;+	j2 = (~(diff >> 21) ^ s) & 0x1;+	jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10);+	jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff);++	/* The others have a common form. */+	if (type == 5) /* Encoding T4 of 'B' instruction */+		jump_inst[1] |= 0x9000;+	else if (type == 6) /* Encoding T1 of 'BL' instruction */+		jump_inst[1] |= 0xd000;+	else+		SLJIT_UNREACHABLE();+}++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_u16 *code;+	sljit_u16 *code_ptr;+	sljit_u16 *buf_ptr;+	sljit_u16 *buf_end;+	sljit_uw half_count;+	sljit_uw next_addr;+	sljit_sw executable_offset;++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	half_count = 0;+	next_addr = 0;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;++	do {+		buf_ptr = (sljit_u16*)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 1);+		do {+			*code_ptr = *buf_ptr++;+			if (next_addr == half_count) {+				SLJIT_ASSERT(!label || label->size >= half_count);+				SLJIT_ASSERT(!jump || jump->addr >= half_count);+				SLJIT_ASSERT(!const_ || const_->addr >= half_count);+				SLJIT_ASSERT(!put_label || put_label->addr >= half_count);++				/* These structures are ordered by their address. */+				if (label && label->size == half_count) {+					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, executable_offset);+						jump = jump->next;+				}+				if (const_ && const_->addr == half_count) {+					const_->addr = (sljit_uw)code_ptr;+					const_ = const_->next;+				}+				if (put_label && put_label->addr == half_count) {+					SLJIT_ASSERT(put_label->label);+					put_label->addr = (sljit_uw)code_ptr;+					put_label = put_label->next;+				}+				next_addr = compute_next_addr(label, jump, const_, put_label);+			}+			code_ptr ++;+			half_count ++;+		} while (buf_ptr < buf_end);++		buf = buf->next;+	} while (buf);++	if (label && label->size == half_count) {+		label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;+		label->size = code_ptr - code;+		label = label->next;+	}++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);+	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);++	jump = compiler->jumps;+	while (jump) {+		set_jump_instruction(jump, executable_offset);+		jump = jump->next;+	}++	put_label = compiler->put_labels;+	while (put_label) {+		modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr);+		put_label = put_label->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);+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);++	/* 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:+	case SLJIT_HAS_PREFETCH:+		return 1;++	default:+		return 0;+	}+}++/* --------------------------------------------------------------------- */+/*  Core code generator functions.                                       */+/* --------------------------------------------------------------------- */++#define INVALID_IMM	0x80000000+static sljit_uw get_imm(sljit_uw imm)+{+	/* Thumb immediate form. */+	sljit_s32 counter;++	if (imm <= 0xff)+		return imm;++	if ((imm & 0xffff) == (imm >> 16)) {+		/* Some special cases. */+		if (!(imm & 0xff00))+			return (1 << 12) | (imm & 0xff);+		if (!(imm & 0xff))+			return (2 << 12) | ((imm >> 8) & 0xff);+		if ((imm & 0xff00) == ((imm & 0xff) << 8))+			return (3 << 12) | (imm & 0xff);+	}++	/* Assembly optimization: count leading zeroes? */+	counter = 8;+	if (!(imm & 0xffff0000)) {+		counter += 16;+		imm <<= 16;+	}+	if (!(imm & 0xff000000)) {+		counter += 8;+		imm <<= 8;+	}+	if (!(imm & 0xf0000000)) {+		counter += 4;+		imm <<= 4;+	}+	if (!(imm & 0xc0000000)) {+		counter += 2;+		imm <<= 2;+	}+	if (!(imm & 0x80000000)) {+		counter += 1;+		imm <<= 1;+	}+	/* Since imm >= 128, this must be true. */+	SLJIT_ASSERT(counter <= 31);++	if (imm & 0x00ffffff)+		return INVALID_IMM; /* Cannot be encoded. */++	return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);+}++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)+{+	sljit_uw tmp;++	/* MOVS cannot be used since it destroy flags. */++	if (imm >= 0x10000) {+		tmp = get_imm(imm);+		if (tmp != INVALID_IMM)+			return push_inst32(compiler, MOV_WI | RD4(dst) | tmp);+		tmp = get_imm(~imm);+		if (tmp != INVALID_IMM)+			return push_inst32(compiler, MVN_WI | RD4(dst) | tmp);+	}++	/* 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)));++	/* 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 SLJIT_SUCCESS;+}++#define ARG1_IMM	0x0010000+#define ARG2_IMM	0x0020000+/* 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++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, 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, no temporaries are used. */+		flags &= ~ARG1_IMM;+		FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));+		arg1 = TMP_REG1;+	}++	if (flags & (ARG1_IMM | ARG2_IMM)) {+		reg = (flags & ARG2_IMM) ? arg1 : arg2;+		imm = (flags & ARG2_IMM) ? arg2 : arg1;++		switch (flags & 0xffff) {+		case SLJIT_CLZ:+		case SLJIT_MUL:+			/* No form with immediate operand. */+			break;+		case SLJIT_MOV:+			SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG2);+			return load_immediate(compiler, dst, imm);+		case SLJIT_NOT:+			if (!(flags & SET_FLAGS))+				return load_immediate(compiler, dst, ~imm);+			/* Since the flags should be set, we just fallback to the register mode.+			   Although some clever things could be done here, "NOT IMM" does not worth the efforts. */+			break;+		case SLJIT_ADD:+			nimm = -(sljit_sw)imm;+			if (IS_2_LO_REGS(reg, dst)) {+				if (imm <= 0x7)+					return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));+				if (nimm <= 0x7)+					return push_inst16(compiler, SUBSI3 | IMM3(nimm) | RD3(dst) | RN3(reg));+				if (reg == dst) {+					if (imm <= 0xff)+						return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst));+					if (nimm <= 0xff)+						return push_inst16(compiler, SUBSI8 | IMM8(nimm) | RDN3(dst));+				}+			}+			if (!(flags & SET_FLAGS)) {+				if (imm <= 0xfff)+					return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm));+				if (nimm <= 0xfff)+					return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm));+			}+			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(-(sljit_sw)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);+			if (imm != INVALID_IMM)+				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 (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(-(sljit_sw)imm);+				if (nimm != INVALID_IMM)+					return push_inst32(compiler, CMNI_W | RN4(reg) | nimm);+			}+			nimm = -(sljit_sw)imm;+			if (IS_2_LO_REGS(reg, dst)) {+				if (imm <= 0x7)+					return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));+				if (nimm <= 0x7)+					return push_inst16(compiler, ADDSI3 | IMM3(nimm) | RD3(dst) | RN3(reg));+				if (reg == dst) {+					if (imm <= 0xff)+						return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst));+					if (nimm <= 0xff)+						return push_inst16(compiler, ADDSI8 | IMM8(nimm) | RDN3(dst));+				}+			}+			if (!(flags & SET_FLAGS)) {+				if (imm <= 0xfff)+					return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm));+				if (nimm <= 0xfff)+					return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(nimm));+			}+			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(-(sljit_sw)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)+				break;+			imm = get_imm(imm);+			if (imm != INVALID_IMM)+				return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);+			break;+		case SLJIT_AND:+			nimm = get_imm(imm);+			if (nimm != INVALID_IMM)+				return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);+			imm = get_imm(imm);+			if (imm != INVALID_IMM)+				return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);+			break;+		case SLJIT_OR:+			nimm = get_imm(imm);+			if (nimm != INVALID_IMM)+				return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);+			imm = get_imm(imm);+			if (imm != INVALID_IMM)+				return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);+			break;+		case SLJIT_XOR:+			imm = get_imm(imm);+			if (imm != INVALID_IMM)+				return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);+			break;+		case SLJIT_SHL:+		case SLJIT_LSHR:+		case SLJIT_ASHR:+			if (flags & ARG1_IMM)+				break;+			imm &= 0x1f;+			if (imm == 0) {+				if (!(flags & SET_FLAGS))+					return push_inst16(compiler, MOV | SET_REGS44(dst, reg));+				if (IS_2_LO_REGS(dst, reg))+					return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));+				return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));+			}+			switch (flags & 0xffff) {+			case SLJIT_SHL:+				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 (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 (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_UNREACHABLE();+			break;+		}++		if (flags & ARG2_IMM) {+			imm = arg2;+			arg2 = (arg1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;+			FAIL_IF(load_immediate(compiler, arg2, imm));+		}+		else {+			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. */+	switch (flags & 0xffff) {+	case SLJIT_MOV:+	case SLJIT_MOV_U32:+	case SLJIT_MOV_S32:+	case SLJIT_MOV_P:+		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:+		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:+		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:+		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:+		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_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_REG2);+		FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)));+		return SLJIT_SUCCESS;+	case SLJIT_ADD:+		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 && 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 & 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 && 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(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 (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 && 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 && 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 && 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 && 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 && 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_UNREACHABLE();+	return SLJIT_SUCCESS;+}++#define STORE		0x01+#define SIGNED		0x02++#define WORD_SIZE	0x00+#define BYTE_SIZE	0x04+#define HALF_SIZE	0x08+#define PRELOAD		0x0c++#define IS_WORD_SIZE(flags)		(!(flags & (BYTE_SIZE | HALF_SIZE)))+#define OFFSET_CHECK(imm, shift)	(!(argw & ~(imm << shift)))++/*+  1st letter:+  w = word+  b = byte+  h = half++  2nd letter:+  s = signed+  u = unsigned++  3rd letter:+  l = load+  s = store+*/++static const sljit_ins sljit_mem16[12] = {+/* w u l */ 0x5800 /* ldr */,+/* w u s */ 0x5000 /* str */,+/* w s l */ 0x5800 /* ldr */,+/* w s s */ 0x5000 /* str */,++/* b u l */ 0x5c00 /* ldrb */,+/* b u s */ 0x5400 /* strb */,+/* b s l */ 0x5600 /* ldrsb */,+/* b s s */ 0x5400 /* strb */,++/* h u l */ 0x5a00 /* ldrh */,+/* h u s */ 0x5200 /* strh */,+/* h s l */ 0x5e00 /* ldrsh */,+/* h s s */ 0x5200 /* strh */,+};++static const sljit_ins sljit_mem16_imm5[12] = {+/* w u l */ 0x6800 /* ldr imm5 */,+/* w u s */ 0x6000 /* str imm5 */,+/* w s l */ 0x6800 /* ldr imm5 */,+/* w s s */ 0x6000 /* str imm5 */,++/* b u l */ 0x7800 /* ldrb imm5 */,+/* b u s */ 0x7000 /* strb imm5 */,+/* b s l */ 0x0000 /* not allowed */,+/* b s s */ 0x7000 /* strb imm5 */,++/* h u l */ 0x8800 /* ldrh imm5 */,+/* h u s */ 0x8000 /* strh imm5 */,+/* h s l */ 0x0000 /* not allowed */,+/* h s s */ 0x8000 /* strh imm5 */,+};++#define MEM_IMM8	0xc00+#define MEM_IMM12	0x800000+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 */,+/* w s s */ 0xf8400000 /* str.w */,++/* b u l */ 0xf8100000 /* ldrb.w */,+/* b u s */ 0xf8000000 /* strb.w */,+/* b s l */ 0xf9100000 /* ldrsb.w */,+/* b s s */ 0xf8000000 /* strb.w */,++/* h u l */ 0xf8300000 /* ldrh.w */,+/* 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. */+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_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value));+		value = get_imm(value);+		if (value != INVALID_IMM)+			return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value);+	}+	else {+		value = -value;+		if (value <= 0xfff)+			return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value));+		value = get_imm(value);+		if (value != INVALID_IMM)+			return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value);+	}+	return SLJIT_ERR_UNSUPPORTED;+}++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;+	sljit_uw tmp;++	SLJIT_ASSERT(arg & SLJIT_MEM);+	SLJIT_ASSERT((arg & REG_MASK) != tmp_reg);+	arg &= ~SLJIT_MEM;++	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));+		}++		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)) {+		argw &= 0x3;+		other_r = OFFS_REG(arg);+		arg &= 0xf;++		if (!argw && IS_3_LO_REGS(reg, arg, other_r))+			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 (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 (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {+		tmp = 3;+		if (IS_WORD_SIZE(flags)) {+			if (OFFSET_CHECK(0x1f, 2))+				tmp = 2;+		}+		else if (flags & BYTE_SIZE)+		{+			if (OFFSET_CHECK(0x1f, 0))+				tmp = 0;+		}+		else {+			SLJIT_ASSERT(flags & HALF_SIZE);+			if (OFFSET_CHECK(0x1f, 1))+				tmp = 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));+	}++	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);++	SLJIT_ASSERT(arg != tmp_reg);++	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));+}++/* --------------------------------------------------------------------- */+/*  Entry, exit                                                          */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 args, size, i, tmp;+	sljit_ins push = 0;+#ifdef _WIN32+	sljit_uw imm;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--)+		push |= 1 << reg_map[i];++	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--)+		push |= 1 << reg_map[i];++	FAIL_IF((push & 0xff00)+		? push_inst32(compiler, PUSH_W | (1 << 14) | push)+		: push_inst16(compiler, PUSH | (1 << 8) | push));++	/* Stack must be aligned to 8 bytes: (LR, R4) */+	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);+	local_size = ((size + local_size + 7) & ~7) - size;+	compiler->local_size = local_size;++#ifdef _WIN32+	if (local_size >= 256) {+		if (local_size > 4096)+			imm = get_imm(4096);+		else+			imm = get_imm(local_size & ~0xff);++		SLJIT_ASSERT(imm != INVALID_IMM);+		FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(SLJIT_SP) | imm));+	}+#else+	if (local_size > 0) {+		if (local_size <= (127 << 2))+			FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2)));+		else+			FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size));+	}+#endif++	args = get_arg_count(arg_types);++	if (args >= 1)+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0)));+	if (args >= 2)+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S1, SLJIT_R1)));+	if (args >= 3)+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2)));++#ifdef _WIN32+	if (local_size >= 256) {+		if (local_size > 4096) {+			imm = get_imm(4096);+			SLJIT_ASSERT(imm != INVALID_IMM);++			if (local_size < 4 * 4096) {+				if (local_size > 2 * 4096) {+					FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));+					FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));+					local_size -= 4096;+				}++				if (local_size > 2 * 4096) {+					FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));+					FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));+					local_size -= 4096;+				}++				FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));+				local_size -= 4096;++				SLJIT_ASSERT(local_size > 0);+			}+			else {+				FAIL_IF(load_immediate(compiler, SLJIT_R3, (local_size >> 12) - 1));+				FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));+				FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));+				SLJIT_ASSERT(reg_map[SLJIT_R3] < 7);+				FAIL_IF(push_inst16(compiler, SUBSI8 | RDN3(SLJIT_R3) | 1));+				FAIL_IF(push_inst16(compiler, BCC | (0x1 << 8) /* not-equal */ | (-7 & 0xff)));++				local_size &= 0xfff;++				if (local_size != 0)+					FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));+			}++			if (local_size >= 256) {+				imm = get_imm(local_size & ~0xff);+				SLJIT_ASSERT(imm != INVALID_IMM);++				FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));+			}+		}++		local_size &= 0xff;+		FAIL_IF(push_inst32(compiler, LDRI | 0x400 | (local_size > 0 ? 0x100 : 0) | RT4(TMP_REG2) | RN4(TMP_REG1) | local_size));++		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SP, TMP_REG1)));+	}+	else if (local_size > 0)+		FAIL_IF(push_inst32(compiler, LDRI | 0x500 | RT4(TMP_REG1) | RN4(SLJIT_SP) | local_size));+#endif++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 size;++	CHECK_ERROR();+	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);+	compiler->local_size = ((size + local_size + 7) & ~7) - size;+	return SLJIT_SUCCESS;+}++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 = 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	if (compiler->local_size > 0) {+		if (compiler->local_size <= (127 << 2))+			FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2)));+		else+			FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_SP, SLJIT_SP, compiler->local_size));+	}++	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];++	for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--)+		pop |= 1 << reg_map[i];++	return (pop & 0xff00)+		? push_inst32(compiler, POP_W | (1 << 15) | pop)+		: push_inst16(compiler, POP | (1 << 8) | pop);+}++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)++#ifdef __cplusplus+extern "C" {+#endif++#ifdef _WIN32+extern unsigned long long __rt_udiv(unsigned int denominator, unsigned int numerator);+extern long long __rt_sdiv(int denominator, int numerator);+#elif defined(__GNUC__)+extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator);+extern int __aeabi_idivmod(int numerator, int denominator);+#else+#error "Software divmod functions are needed"+#endif++#ifdef __cplusplus+}+#endif++#endif /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)+	sljit_sw saved_reg_list[3];+	sljit_sw saved_reg_count;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_BREAKPOINT:+		return push_inst16(compiler, BKPT);+	case SLJIT_NOP:+		return push_inst16(compiler, NOP);+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+		return push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)+			| (reg_map[SLJIT_R1] << 8)+			| (reg_map[SLJIT_R0] << 12)+			| (reg_map[SLJIT_R0] << 16)+			| reg_map[SLJIT_R1]);+#if (defined __ARM_FEATURE_IDIV) || (defined __ARM_ARCH_EXT_IDIV__)+	case SLJIT_DIVMOD_UW:+	case SLJIT_DIVMOD_SW:+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));+		FAIL_IF(push_inst32(compiler, (op == SLJIT_DIVMOD_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));+		FAIL_IF(push_inst32(compiler, MUL | RD4(SLJIT_R1) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));+		return push_inst32(compiler, SUB_W | RD4(SLJIT_R1) | RN4(TMP_REG1) | RM4(SLJIT_R1));+	case SLJIT_DIV_UW:+	case SLJIT_DIV_SW:+		return push_inst32(compiler, (op == SLJIT_DIV_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1));+#else /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */+	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_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++] = 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_inst32(compiler, 0xf84d0d00 | (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_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));+			}+			if (saved_reg_count >= 3) {+				SLJIT_ASSERT(saved_reg_list[2] < 8);+				FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));+			}+		}++#ifdef _WIN32+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R0, SLJIT_R1)));+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R1, TMP_REG1)));+		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,+			((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__rt_udiv) : SLJIT_FUNC_OFFSET(__rt_sdiv))));+#elif defined(__GNUC__)+		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,+			((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));+#else+#error "Software divmod functions are needed"+#endif++		if (saved_reg_count > 0) {+			if (saved_reg_count >= 3) {+				SLJIT_ASSERT(saved_reg_list[2] < 8);+				FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));+			}+			if (saved_reg_count >= 2) {+				SLJIT_ASSERT(saved_reg_list[1] < 8);+				FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));+			}+			return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)+						| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);+		}+		return SLJIT_SUCCESS;+#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++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)+{+	sljit_s32 dst_r, flags;+	sljit_s32 op_flags = GET_ALL_FLAGS(op);++	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src, srcw);++	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;++	op = GET_OPCODE(op);+	if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {+		switch (op) {+		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;+			if (src & SLJIT_IMM)+				srcw = (sljit_u8)srcw;+			break;+		case SLJIT_MOV_S8:+			flags = BYTE_SIZE | SIGNED;+			if (src & SLJIT_IMM)+				srcw = (sljit_s8)srcw;+			break;+		case SLJIT_MOV_U16:+			flags = HALF_SIZE;+			if (src & SLJIT_IMM)+				srcw = (sljit_u16)srcw;+			break;+		case SLJIT_MOV_S16:+			flags = HALF_SIZE | SIGNED;+			if (src & SLJIT_IMM)+				srcw = (sljit_s16)srcw;+			break;+		default:+			SLJIT_UNREACHABLE();+			flags = 0;+			break;+		}++		if (src & SLJIT_IMM)+			FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, srcw));+		else if (src & SLJIT_MEM) {+			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_REG2, src);+			dst_r = src;+		}++		if (!(dst & SLJIT_MEM))+			return SLJIT_SUCCESS;++		return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);+	}++	if (op == SLJIT_NEG) {+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \+			|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)+		compiler->skip_checks = 1;+#endif+		return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw);+	}++	flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;++	if (src & SLJIT_MEM) {+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));+		src = TMP_REG1;+	}++	emit_op_imm(compiler, flags | op, dst_r, TMP_REG2, src);++	if (SLJIT_UNLIKELY(dst & SLJIT_MEM))+		return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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_s32 dst_reg, flags, src2_reg;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))+		return SLJIT_SUCCESS;++	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_reg, src1w, src2w);++	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_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		SLJIT_ASSERT(reg_map[TMP_REG2] == 14);++		if (FAST_IS_REG(src))+			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));+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		return SLJIT_SUCCESS;+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+		return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++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 (freg_map[reg] << 1);+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	if (size == 2)+		return push_inst16(compiler, *(sljit_u16*)instruction);+	return push_inst32(compiler, *(sljit_ins*)instruction);+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */++#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_uw imm;+	sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD));++	SLJIT_ASSERT(arg & SLJIT_MEM);++	/* Fast loads and stores. */+	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {+		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;+	}++	if ((arg & REG_MASK) && (argw & 0x3) == 0) {+		if (!(argw & ~0x3fc))+			return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | (argw >> 2));+		if (!(-argw & ~0x3fc))+			return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2));+	}++	if (arg & REG_MASK) {+		if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {+			FAIL_IF(compiler->error);+			return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg));+		}+		imm = get_imm(argw & ~0x3fc);+		if (imm != INVALID_IMM) {+			FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));+			return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2));+		}+		imm = get_imm(-argw & ~0x3fc);+		if (imm != INVALID_IMM) {+			argw = -argw;+			FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm));+			return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2));+		}+	}++	FAIL_IF(load_immediate(compiler, TMP_REG1, argw));+	if (arg & REG_MASK)+		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;+	}++	FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_F32_OP) | DD4(TMP_FREG1) | DM4(src)));++	if (FAST_IS_REG(dst))+		return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1));++	/* Store the integer value from a VFP register. */+	return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	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) {+		/* 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_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1)));+	}++	FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(TMP_FREG1)));++	if (dst & SLJIT_MEM)+		return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	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;+	}++	if (src2 & SLJIT_MEM) {+		emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);+		src2 = TMP_FREG2;+	}++	FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_F32_OP) | DD4(src1) | DM4(src2)));+	return push_inst32(compiler, VMRS);+}++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_s32 dst_r;++	CHECK_ERROR();++	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;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV_F64:+		if (src != dst_r) {+			if (dst_r != TMP_FREG1)+				FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));+			else+				dst_r = src;+		}+		break;+	case SLJIT_NEG_F64:+		FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));+		break;+	case SLJIT_ABS_F64:+		FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));+		break;+	case SLJIT_CONV_F64_FROM_F32:+		FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));+		op ^= SLJIT_F32_OP;+		break;+	}++	if (dst & SLJIT_MEM)+		return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw);+	return SLJIT_SUCCESS;+}++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_s32 dst_r;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	op ^= SLJIT_F32_OP;++	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;+	if (src1 & SLJIT_MEM) {+		emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);+		src1 = TMP_FREG1;+	}+	if (src2 & SLJIT_MEM) {+		emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);+		src2 = TMP_FREG2;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));+		break;+	case SLJIT_SUB_F64:+		FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));+		break;+	case SLJIT_MUL_F64:+		FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));+		break;+	case SLJIT_DIV_F64:+		FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));+		break;+	}++	if (!(dst & SLJIT_MEM))+		return SLJIT_SUCCESS;+	return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);+}++#undef FPU_LOAD++/* --------------------------------------------------------------------- */+/*  Other instructions                                                   */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	SLJIT_ASSERT(reg_map[TMP_REG2] == 14);++	if (FAST_IS_REG(dst))+		return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));++	/* Memory. */+	return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1);+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++static sljit_uw get_cc(sljit_s32 type)+{+	switch (type) {+	case SLJIT_EQUAL:+	case SLJIT_MUL_NOT_OVERFLOW:+	case SLJIT_EQUAL_F64:+		return 0x0;++	case SLJIT_NOT_EQUAL:+	case SLJIT_MUL_OVERFLOW:+	case SLJIT_NOT_EQUAL_F64:+		return 0x1;++	case SLJIT_LESS:+	case SLJIT_LESS_F64:+		return 0x3;++	case SLJIT_GREATER_EQUAL:+	case SLJIT_GREATER_EQUAL_F64:+		return 0x2;++	case SLJIT_GREATER:+	case SLJIT_GREATER_F64:+		return 0x8;++	case SLJIT_LESS_EQUAL:+	case SLJIT_LESS_EQUAL_F64:+		return 0x9;++	case SLJIT_SIG_LESS:+		return 0xb;++	case SLJIT_SIG_GREATER_EQUAL:+		return 0xa;++	case SLJIT_SIG_GREATER:+		return 0xc;++	case SLJIT_SIG_LESS_EQUAL:+		return 0xd;++	case SLJIT_OVERFLOW:+	case SLJIT_UNORDERED_F64:+		return 0x6;++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_ORDERED_F64:+		return 0x7;++	default: /* SLJIT_JUMP */+		SLJIT_UNREACHABLE();+		return 0xe;+	}+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	return label;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;+	sljit_ins cc;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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(emit_imm32_const(compiler, TMP_REG1, 0));+	if (type < SLJIT_JUMP) {+		jump->flags |= IS_COND;+		cc = get_cc(type);+		jump->flags |= cc << 8;+		PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));+	}++	jump->addr = compiler->size;+	if (type <= SLJIT_JUMP)+		PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));+	else {+		jump->flags |= IS_BL;+		PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));+	}++	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;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	SLJIT_ASSERT(reg_map[TMP_REG1] != 14);++	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));+	jump->u.target = srcw;++	FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));+	jump->addr = compiler->size;+	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 type)+{+	sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);+	sljit_ins cc;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	op = GET_OPCODE(op);+	cc = get_cc(type & 0xff);+	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));+		if (reg_map[dst_r] > 7) {+			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 & SLJIT_MEM))+			return SLJIT_SUCCESS;+		return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2);+	}++	if (dst & SLJIT_MEM)+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));++	if (op == SLJIT_AND) {+		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));+		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, ((op == SLJIT_OR) ? ORRI : EORI) | RN4(dst_r) | RD4(dst_r) | 1));+	}++	if (dst & SLJIT_MEM)+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2));++	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));+	}++	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)+{+	struct sljit_const *const_;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	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, TMP_REG2));+	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 0);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;+	PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0));++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));+	return put_label;+}++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;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);+	modify_imm32_const(inst, new_target);+	SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}
+ src/c/pcre2/src/sljit/sljitNativeMIPS_32.c view
@@ -0,0 +1,671 @@+/*+ *    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.+ */++/* mips 32-bit arch dependent functions. */++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)+{+	if (!(imm & ~0xffff))+		return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);++	if (imm < 0 && imm >= SIMM_MIN)+		return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);++	FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));+	return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;+}++#define EMIT_LOGICAL(op_imm, op_norm) \+	if (flags & SRC2_IMM) { \+		if (op & SLJIT_SET_Z) \+			FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \+		if (!(flags & UNUSED_DEST)) \+			FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \+	} \+	else { \+		if (op & SLJIT_SET_Z) \+			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \+		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_Z) \+			FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \+		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_Z) \+			FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \+		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:+	case SLJIT_MOV_S32:+	case SLJIT_MOV_P:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (dst != src2)+			return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U8:+	case SLJIT_MOV_S8:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S8) {+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+				return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));+#else /* SLJIT_MIPS_REV < 1 */+				FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));+				return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));+#endif /* SLJIT_MIPS_REV >= 1 */+			}+			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U16:+	case SLJIT_MOV_S16:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S16) {+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+				return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));+#else /* SLJIT_MIPS_REV < 1 */+				FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));+				return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));+#endif /* SLJIT_MIPS_REV >= 1 */+			}+			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_NOT:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (op & SLJIT_SET_Z)+			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));+		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_REV && SLJIT_MIPS_REV >= 1)+		if (op & SLJIT_SET_Z)+			FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));+		if (!(flags & UNUSED_DEST))+			FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));+#else /* SLJIT_MIPS_REV < 1 */+		if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {+			FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));+			return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);+		}+		/* Nearly all instructions are unmovable in the following sequence. */+		FAIL_IF(push_inst(compiler, ADDU | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));+		/* Check zero. */+		FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));+		FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));+		FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst) | IMM(-1), DR(dst)));+		/* Loop for searching the highest bit. */+		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));+#endif /* SLJIT_MIPS_REV >= 1 */+		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 (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 (is_overflow || is_carry) {+				if (src2 >= 0)+					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(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 (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))+				FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));+		}+		else {+			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 (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 (!(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 (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(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 (is_carry) {+				if (src2 >= 0)+					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(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 (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 (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(OTHER_FLAG) | D(dst), DR(dst)));+		if (!is_carry)+			return SLJIT_SUCCESS;++		/* 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(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);++	case SLJIT_SUB:+		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 (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;+			}+			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 (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 (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))+				FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));+		}+		else {+			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 (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 (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))+				FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));+		}++		if (!is_overflow)+			return SLJIT_SUCCESS;+		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) {+			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));+			src2 = TMP_REG2;+			flags &= ~SRC2_IMM;+		}++		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);++		if (flags & SRC2_IMM) {+			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 (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 (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(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 (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+			return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));+#else /* SLJIT_MIPS_REV < 1 */+			FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));+			return push_inst(compiler, MFLO | D(dst), DR(dst));+#endif /* SLJIT_MIPS_REV >= 1 */+		}++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+		FAIL_IF(push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)));+		FAIL_IF(push_inst(compiler, MUH | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));+#else /* SLJIT_MIPS_REV < 6 */+		FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));+		FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));+		FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));+#endif /* SLJIT_MIPS_REV >= 6 */+		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);+		return SLJIT_SUCCESS;++	case SLJIT_OR:+		EMIT_LOGICAL(ORI, OR);+		return SLJIT_SUCCESS;++	case SLJIT_XOR:+		EMIT_LOGICAL(XORI, XOR);+		return SLJIT_SUCCESS;++	case SLJIT_SHL:+		EMIT_SHIFT(SLL, SLLV);+		return SLJIT_SUCCESS;++	case SLJIT_LSHR:+		EMIT_SHIFT(SRL, SRLV);+		return SLJIT_SUCCESS;++	case SLJIT_ASHR:+		EMIT_SHIFT(SRA, SRAV);+		return SLJIT_SUCCESS;+	}++	SLJIT_UNREACHABLE();+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)+{+	FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));+	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_target, sljit_sw executable_offset)+{+	sljit_ins *inst = (sljit_ins *)addr;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);+	SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);+	inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);+	inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);+	SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}++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_REG1] == 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) | DA(4);++			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);+}
+ src/c/pcre2/src/sljit/sljitNativeMIPS_64.c view
@@ -0,0 +1,672 @@+/*+ *    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.+ */++/* mips 64-bit arch dependent functions. */++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)+{+	sljit_s32 shift = 32;+	sljit_s32 shift2;+	sljit_s32 inv = 0;+	sljit_ins ins;+	sljit_uw uimm;++	if (!(imm & ~0xffff))+		return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);++	if (imm < 0 && imm >= SIMM_MIN)+		return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);++	if (imm <= 0x7fffffffl && imm >= -0x80000000l) {+		FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));+		return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;+	}++	/* Zero extended number. */+	uimm = imm;+	if (imm < 0) {+		uimm = ~imm;+		inv = 1;+	}++	while (!(uimm & 0xff00000000000000l)) {+		shift -= 8;+		uimm <<= 8;+	}++	if (!(uimm & 0xf000000000000000l)) {+		shift -= 4;+		uimm <<= 4;+	}++	if (!(uimm & 0xc000000000000000l)) {+		shift -= 2;+		uimm <<= 2;+	}++	if ((sljit_sw)uimm < 0) {+		uimm >>= 1;+		shift += 1;+	}+	SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32));++	if (inv)+		uimm = ~uimm;++	FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar));+	if (uimm & 0x0000ffff00000000l)+		FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar));++	imm &= (1l << shift) - 1;+	if (!(imm & ~0xffff)) {+		ins = (shift == 32) ? DSLL32 : DSLL;+		if (shift < 32)+			ins |= SH_IMM(shift);+		FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar));+		return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);+	}++	/* Double shifts needs to be performed. */+	uimm <<= 32;+	shift2 = shift - 16;++	while (!(uimm & 0xf000000000000000l)) {+		shift2 -= 4;+		uimm <<= 4;+	}++	if (!(uimm & 0xc000000000000000l)) {+		shift2 -= 2;+		uimm <<= 2;+	}++	if (!(uimm & 0x8000000000000000l)) {+		shift2--;+		uimm <<= 1;+	}++	SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16));++	FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar));+	FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar));+	FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar));++	imm &= (1l << shift2) - 1;+	return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);+}++#define SELECT_OP(a, b) \+	(!(op & SLJIT_I32_OP) ? a : b)++#define EMIT_LOGICAL(op_imm, op_norm) \+	if (flags & SRC2_IMM) { \+		if (op & SLJIT_SET_Z) \+			FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \+		if (!(flags & UNUSED_DEST)) \+			FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \+	} \+	else { \+		if (op & SLJIT_SET_Z) \+			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \+		if (!(flags & UNUSED_DEST)) \+			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \+	}++#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \+	if (flags & SRC2_IMM) { \+		if (src2 >= 32) { \+			SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \+			ins = op_dimm32; \+			src2 -= 32; \+		} \+		else \+			ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \+		if (op & SLJIT_SET_Z) \+			FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \+		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_Z) \+			FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \+		if (!(flags & UNUSED_DEST)) \+			FAIL_IF(push_inst(compiler, ins | 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_ins ins;+	sljit_s32 is_overflow, is_carry, is_handled;++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV:+	case SLJIT_MOV_P:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (dst != src2)+			return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U8:+	case SLJIT_MOV_S8:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S8) {+				FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));+				return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));+			}+			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U16:+	case SLJIT_MOV_S16:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S16) {+				FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));+				return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));+			}+			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U32:+		SLJIT_ASSERT(!(op & SLJIT_I32_OP));+		FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));+		return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));++	case SLJIT_MOV_S32:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));++	case SLJIT_NOT:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (op & SLJIT_SET_Z)+			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));+		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_REV && SLJIT_MIPS_REV >= 1)+		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 (!(flags & UNUSED_DEST))+			FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst)));+#else /* SLJIT_MIPS_REV < 1 */+		if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {+			FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));+			return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);+		}+		/* Nearly all instructions are unmovable in the following sequence. */+		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));+		/* Check zero. */+		FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));+		FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS));+		FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst)));+		/* Loop for searching the highest bit. */+		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));+#endif /* SLJIT_MIPS_REV >= 1 */+		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 (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 (is_overflow || is_carry) {+				if (src2 >= 0)+					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(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 (!(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 (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 (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 (!(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 (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(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 (is_carry) {+				if (src2 >= 0)+					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(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 (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 (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(OTHER_FLAG) | D(dst), DR(dst)));+		if (!is_carry)+			return SLJIT_SUCCESS;++		/* 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(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);++	case SLJIT_SUB:+		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 (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;+			}+			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 (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 (!(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 (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 (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 (!(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 (!is_overflow)+			return SLJIT_SUCCESS;+		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) {+			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));+			src2 = TMP_REG2;+			flags &= ~SRC2_IMM;+		}++		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);++		if (flags & SRC2_IMM) {+			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 (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 (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(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 (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+			return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));+#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+			if (op & SLJIT_I32_OP)+				return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));+			FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));+			return push_inst(compiler, MFLO | D(dst), DR(dst));+#else /* SLJIT_MIPS_REV < 1 */+			FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));+			return push_inst(compiler, MFLO | D(dst), DR(dst));+#endif /* SLJIT_MIPS_REV >= 6 */+		}++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+		FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));+		FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));+#else /* SLJIT_MIPS_REV < 6 */+		FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));+		FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));+		FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));+#endif /* SLJIT_MIPS_REV >= 6 */+		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);+		return SLJIT_SUCCESS;++	case SLJIT_OR:+		EMIT_LOGICAL(ORI, OR);+		return SLJIT_SUCCESS;++	case SLJIT_XOR:+		EMIT_LOGICAL(XORI, XOR);+		return SLJIT_SUCCESS;++	case SLJIT_SHL:+		EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);+		return SLJIT_SUCCESS;++	case SLJIT_LSHR:+		EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);+		return SLJIT_SUCCESS;++	case SLJIT_ASHR:+		EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);+		return SLJIT_SUCCESS;+	}++	SLJIT_UNREACHABLE();+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)+{+	FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst)));+	FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst)));+	FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));+	FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst)));+	FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));+	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_target, sljit_sw executable_offset)+{+	sljit_ins *inst = (sljit_ins *)addr;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);+	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);+	SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}++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_REG1] == 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) | DA(4);+			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);+}
+ src/c/pcre2/src/sljit/sljitNativeMIPS_common.c view
@@ -0,0 +1,2305 @@+/*+ *    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.+ */++/* Latest MIPS architecture. */++#ifndef __mips_hard_float+/* Disable automatic detection, covers both -msoft-float and -mno-float */+#undef SLJIT_IS_FPU_AVAILABLE+#define SLJIT_IS_FPU_AVAILABLE 0+#endif++SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)+{+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	return "MIPS32-R6" SLJIT_CPUINFO;+#else /* !SLJIT_CONFIG_MIPS_32 */+	return "MIPS64-R6" SLJIT_CPUINFO;+#endif /* SLJIT_CONFIG_MIPS_32 */++#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	return "MIPS32-R1" SLJIT_CPUINFO;+#else /* !SLJIT_CONFIG_MIPS_32 */+	return "MIPS64-R1" SLJIT_CPUINFO;+#endif /* SLJIT_CONFIG_MIPS_32 */++#else /* SLJIT_MIPS_REV < 1 */+	return "MIPS III" SLJIT_CPUINFO;+#endif /* SLJIT_MIPS_REV >= 6 */+}++/* Length of an instruction word+   Both for mips-32 and mips-64 */+typedef sljit_u32 sljit_ins;++#define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)+#define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)+#define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)++/* For position independent code, t9 must contain the function address. */+#define PIC_ADDR_REG	TMP_REG2++/* Floating point status register. */+#define FCSR_REG	31+/* Return address register. */+#define RETURN_ADDR_REG	31++/* Flags are kept in volatile registers. */+#define EQUAL_FLAG	3+#define OTHER_FLAG	1++#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)+#define TMP_FREG3	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)++static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {+	0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31+};++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)++static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {+	0, 0, 14, 2, 4, 6, 8, 12, 10, 16+};++#else++static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {+	0, 0, 13, 14, 15, 16, 17, 12, 18, 10+};++#endif++/* --------------------------------------------------------------------- */+/*  Instrucion forms                                                     */+/* --------------------------------------------------------------------- */++#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 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)+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+/* CMP.cond.fmt */+/* S = (20 << 21) D = (21 << 21) */+#define CMP_FMT_S	(20 << 21)+#endif /* SLJIT_MIPS_REV >= 6 */+/* 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))+#define ADDIU		(HI(9))+#define ADDU		(HI(0) | LO(33))+#define AND		(HI(0) | LO(36))+#define ANDI		(HI(12))+#define B		(HI(4))+#define BAL		(HI(1) | (17 << 16))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define BC1EQZ		(HI(17) | (9 << 21) | FT(TMP_FREG3))+#define BC1NEZ		(HI(17) | (13 << 21) | FT(TMP_FREG3))+#else /* SLJIT_MIPS_REV < 6 */+#define BC1F		(HI(17) | (8 << 21))+#define BC1T		(HI(17) | (8 << 21) | (1 << 16))+#endif /* SLJIT_MIPS_REV >= 6 */+#define BEQ		(HI(4))+#define BGEZ		(HI(1) | (1 << 16))+#define BGTZ		(HI(7))+#define BLEZ		(HI(6))+#define BLTZ		(HI(1) | (0 << 16))+#define BNE		(HI(5))+#define BREAK		(HI(0) | LO(13))+#define CFC1		(HI(17) | (2 << 21))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define C_UEQ_S		(HI(17) | CMP_FMT_S | LO(3))+#define C_ULE_S		(HI(17) | CMP_FMT_S | LO(7))+#define C_ULT_S		(HI(17) | CMP_FMT_S | LO(5))+#define C_UN_S		(HI(17) | CMP_FMT_S | LO(1))+#define C_FD		(FD(TMP_FREG3))+#else /* SLJIT_MIPS_REV < 6 */+#define C_UEQ_S		(HI(17) | FMT_S | LO(51))+#define C_ULE_S		(HI(17) | FMT_S | LO(55))+#define C_ULT_S		(HI(17) | FMT_S | LO(53))+#define C_UN_S		(HI(17) | FMT_S | LO(49))+#define C_FD		(0)+#endif /* SLJIT_MIPS_REV >= 6 */+#define CVT_S_S		(HI(17) | FMT_S | LO(32))+#define DADDIU		(HI(25))+#define DADDU		(HI(0) | LO(45))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define DDIV		(HI(0) | (2 << 6) | LO(30))+#define DDIVU		(HI(0) | (2 << 6) | LO(31))+#define DMOD		(HI(0) | (3 << 6) | LO(30))+#define DMODU		(HI(0) | (3 << 6) | LO(31))+#define DIV		(HI(0) | (2 << 6) | LO(26))+#define DIVU		(HI(0) | (2 << 6) | LO(27))+#define DMUH		(HI(0) | (3 << 6) | LO(28))+#define DMUHU		(HI(0) | (3 << 6) | LO(29))+#define DMUL		(HI(0) | (2 << 6) | LO(28))+#define DMULU		(HI(0) | (2 << 6) | LO(29))+#else /* SLJIT_MIPS_REV < 6 */+#define DDIV		(HI(0) | LO(30))+#define DDIVU		(HI(0) | LO(31))+#define DIV		(HI(0) | LO(26))+#define DIVU		(HI(0) | LO(27))+#define DMULT		(HI(0) | LO(28))+#define DMULTU		(HI(0) | LO(29))+#endif /* SLJIT_MIPS_REV >= 6 */+#define DIV_S		(HI(17) | FMT_S | LO(3))+#define DSLL		(HI(0) | LO(56))+#define DSLL32		(HI(0) | LO(60))+#define DSLLV		(HI(0) | LO(20))+#define DSRA		(HI(0) | LO(59))+#define DSRA32		(HI(0) | LO(63))+#define DSRAV		(HI(0) | LO(23))+#define DSRL		(HI(0) | LO(58))+#define DSRL32		(HI(0) | LO(62))+#define DSRLV		(HI(0) | LO(22))+#define DSUBU		(HI(0) | LO(47))+#define J		(HI(2))+#define JAL		(HI(3))+#define JALR		(HI(0) | LO(9))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define JR		(HI(0) | LO(9))+#else /* SLJIT_MIPS_REV < 6 */+#define JR		(HI(0) | LO(8))+#endif /* SLJIT_MIPS_REV >= 6 */+#define LD		(HI(55))+#define LUI		(HI(15))+#define LW		(HI(35))+#define MFC1		(HI(17))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define MOD		(HI(0) | (3 << 6) | LO(26))+#define MODU		(HI(0) | (3 << 6) | LO(27))+#else /* SLJIT_MIPS_REV < 6 */+#define MFHI		(HI(0) | LO(16))+#define MFLO		(HI(0) | LO(18))+#endif /* SLJIT_MIPS_REV >= 6 */+#define MOV_S		(HI(17) | FMT_S | LO(6))+#define MTC1		(HI(17) | (4 << 21))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define MUH		(HI(0) | (3 << 6) | LO(24))+#define MUHU		(HI(0) | (3 << 6) | LO(25))+#define MUL		(HI(0) | (2 << 6) | LO(24))+#define MULU		(HI(0) | (2 << 6) | LO(25))+#else /* SLJIT_MIPS_REV < 6 */+#define MULT		(HI(0) | LO(24))+#define MULTU		(HI(0) | LO(25))+#endif /* SLJIT_MIPS_REV >= 6 */+#define MUL_S		(HI(17) | FMT_S | LO(2))+#define NEG_S		(HI(17) | FMT_S | LO(7))+#define NOP		(HI(0) | LO(0))+#define NOR		(HI(0) | LO(39))+#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))+#define SLTU		(HI(0) | LO(43))+#define SLL		(HI(0) | LO(0))+#define SLLV		(HI(0) | LO(4))+#define SRL		(HI(0) | LO(2))+#define SRLV		(HI(0) | LO(6))+#define SRA		(HI(0) | LO(3))+#define SRAV		(HI(0) | LO(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))++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+#define CLZ		(HI(28) | LO(32))+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#define DCLZ		(LO(18))+#else /* SLJIT_MIPS_REV < 6 */+#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))+#endif /* SLJIT_MIPS_REV >= 6 */+#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 /* SLJIT_MIPS_REV >= 1 */++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#define ADDU_W		ADDU+#define ADDIU_W		ADDIU+#define SLL_W		SLL+#define SUBU_W		SUBU+#else+#define ADDU_W		DADDU+#define ADDIU_W		DADDIU+#define SLL_W		DSLL+#define SUBU_W		DSUBU+#endif++#define SIMM_MAX	(0x7fff)+#define SIMM_MIN	(-0x8000)+#define UIMM_MAX	(0xffff)++/* dest_reg is the absolute name of the register+   Useful for reordering instructions in the delay slot. */+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)+{+	sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));+	SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS+		|| delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	compiler->delay_slot = delay_slot;+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)+{+	if (flags & IS_BIT26_COND)+		return (1 << 26);+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+	if (flags & IS_BIT23_COND)+		return (1 << 23);+#endif /* SLJIT_MIPS_REV >= 6 */+	return (1 << 16);+}++static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)+{+	sljit_sw diff;+	sljit_uw target_addr;+	sljit_ins *inst;+	sljit_ins saved_inst;++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))+		return code_ptr;+#else+	if (jump->flags & SLJIT_REWRITABLE_JUMP)+		return code_ptr;+#endif++	if (jump->flags & JUMP_ADDR)+		target_addr = jump->u.target;+	else {+		SLJIT_ASSERT(jump->flags & JUMP_LABEL);+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;+	}++	inst = (sljit_ins *)jump->addr;+	if (jump->flags & IS_COND)+		inst--;++#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+	if (jump->flags & IS_CALL)+		goto keep_address;+#endif++	/* B instructions. */+	if (jump->flags & IS_MOVABLE) {+		diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;+		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {+			jump->flags |= PATCH_B;++			if (!(jump->flags & IS_COND)) {+				inst[0] = inst[-1];+				inst[-1] = (jump->flags & IS_JAL) ? BAL : B;+				jump->addr -= sizeof(sljit_ins);+				return inst;+			}+			saved_inst = inst[0];+			inst[0] = inst[-1];+			inst[-1] = saved_inst ^ invert_branch(jump->flags);+			jump->addr -= 2 * sizeof(sljit_ins);+			return inst;+		}+	}+	else {+		diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;+		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {+			jump->flags |= PATCH_B;++			if (!(jump->flags & IS_COND)) {+				inst[0] = (jump->flags & IS_JAL) ? BAL : B;+				inst[1] = NOP;+				return inst + 1;+			}+			inst[0] = inst[0] ^ invert_branch(jump->flags);+			inst[1] = NOP;+			jump->addr -= sizeof(sljit_ins);+			return inst + 1;+		}+	}++	if (jump->flags & IS_COND) {+		if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~0xfffffff)) {+			jump->flags |= PATCH_J;+			saved_inst = inst[0];+			inst[0] = inst[-1];+			inst[-1] = (saved_inst & 0xffff0000) | 3;+			inst[1] = J;+			inst[2] = NOP;+			return inst + 2;+		}+		else if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) {+			jump->flags |= PATCH_J;+			inst[0] = (inst[0] & 0xffff0000) | 3;+			inst[1] = NOP;+			inst[2] = J;+			inst[3] = NOP;+			jump->addr += sizeof(sljit_ins);+			return inst + 3;+		}+	}+	else {+		/* J instuctions. */+		if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) {+			jump->flags |= PATCH_J;+			inst[0] = inst[-1];+			inst[-1] = (jump->flags & IS_JAL) ? JAL : J;+			jump->addr -= sizeof(sljit_ins);+			return inst;+		}++		if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) {+			jump->flags |= PATCH_J;+			inst[0] = (jump->flags & IS_JAL) ? JAL : J;+			inst[1] = NOP;+			return inst + 1;+		}+	}++#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+keep_address:+	if (target_addr <= 0x7fffffff) {+		jump->flags |= PATCH_ABS32;+		if (jump->flags & IS_COND) {+			inst[0] -= 4;+			inst++;+		}+		inst[2] = inst[6];+		inst[3] = inst[7];+		return inst + 3;+	}+	if (target_addr <= 0x7fffffffffffl) {+		jump->flags |= PATCH_ABS48;+		if (jump->flags & IS_COND) {+			inst[0] -= 2;+			inst++;+		}+		inst[4] = inst[6];+		inst[5] = inst[7];+		return inst + 5;+	}+#endif++	return code_ptr;+}++#ifdef __GNUC__+static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)+{+	SLJIT_CACHE_FLUSH(code, code_ptr);+}+#endif++#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)++static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)+{+	if (max_label < 0x80000000l) {+		put_label->flags = 0;+		return 1;+	}++	if (max_label < 0x800000000000l) {+		put_label->flags = 1;+		return 3;+	}++	put_label->flags = 2;+	return 5;+}++static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)+{+	sljit_uw addr = put_label->label->addr;+	sljit_ins *inst = (sljit_ins *)put_label->addr;+	sljit_s32 reg = *inst;++	if (put_label->flags == 0) {+		SLJIT_ASSERT(addr < 0x80000000l);+		inst[0] = LUI | T(reg) | IMM(addr >> 16);+	}+	else if (put_label->flags == 1) {+		SLJIT_ASSERT(addr < 0x800000000000l);+		inst[0] = LUI | T(reg) | IMM(addr >> 32);+		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);+		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);+		inst += 2;+	}+	else {+		inst[0] = LUI | T(reg) | IMM(addr >> 48);+		inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);+		inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);+		inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);+		inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);+		inst += 4;+	}++	inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);+}++#endif++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_ins *code;+	sljit_ins *code_ptr;+	sljit_ins *buf_ptr;+	sljit_ins *buf_end;+	sljit_uw word_count;+	sljit_uw next_addr;+	sljit_sw executable_offset;+	sljit_uw addr;++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	word_count = 0;+	next_addr = 0;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;++	do {+		buf_ptr = (sljit_ins*)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 2);+		do {+			*code_ptr = *buf_ptr++;+			if (next_addr == word_count) {+				SLJIT_ASSERT(!label || label->size >= word_count);+				SLJIT_ASSERT(!jump || jump->addr >= word_count);+				SLJIT_ASSERT(!const_ || const_->addr >= word_count);+				SLJIT_ASSERT(!put_label || put_label->addr >= word_count);++				/* These structures are ordered by their address. */+				if (label && label->size == word_count) {+					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) {+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+					jump->addr = (sljit_uw)(code_ptr - 3);+#else+					jump->addr = (sljit_uw)(code_ptr - 7);+#endif+					code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);+					jump = jump->next;+				}+				if (const_ && const_->addr == word_count) {+					const_->addr = (sljit_uw)code_ptr;+					const_ = const_->next;+				}+				if (put_label && put_label->addr == word_count) {+					SLJIT_ASSERT(put_label->label);+					put_label->addr = (sljit_uw)code_ptr;+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+					code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));+					word_count += 5;+#endif+					put_label = put_label->next;+				}+				next_addr = compute_next_addr(label, jump, const_, put_label);+			}+			code_ptr ++;+			word_count ++;+		} while (buf_ptr < buf_end);++		buf = buf->next;+	} while (buf);++	if (label && label->size == word_count) {+		label->addr = (sljit_uw)code_ptr;+		label->size = code_ptr - code;+		label = label->next;+	}++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);+	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);++	jump = compiler->jumps;+	while (jump) {+		do {+			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;+			buf_ptr = (sljit_ins *)jump->addr;++			if (jump->flags & PATCH_B) {+				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) == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~0xfffffff));+				buf_ptr[0] |= (addr >> 2) & 0x03ffffff;+				break;+			}++			/* Set the fields of immediate loads. */+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+			buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);+			buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);+#else+			if (jump->flags & PATCH_ABS32) {+				SLJIT_ASSERT(addr <= 0x7fffffff);+				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);+				buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);+			}+			else if (jump->flags & PATCH_ABS48) {+				SLJIT_ASSERT(addr <= 0x7fffffffffffl);+				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);+				buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);+				buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);+			}+			else {+				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);+				buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);+				buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);+				buf_ptr[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff);+			}+#endif+		} while (0);+		jump = jump->next;+	}++	put_label = compiler->put_labels;+	while (put_label) {+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+		addr = put_label->label->addr;+		buf_ptr = (sljit_ins *)put_label->addr;++		SLJIT_ASSERT((buf_ptr[0] & 0xffe00000) == LUI && (buf_ptr[1] & 0xfc000000) == ORI);+		buf_ptr[0] |= (addr >> 16) & 0xffff;+		buf_ptr[1] |= addr & 0xffff;+#else+		put_label_set(put_label);+#endif+		put_label = put_label->next;+	}++	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+	/* GCC workaround for invalid code generation with -O2. */+	sljit_cache_flush(code, code_ptr);+#endif+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);+	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+	case SLJIT_HAS_ZERO_REGISTER:+		return 1;++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+	case SLJIT_HAS_CLZ:+	case SLJIT_HAS_CMOV:+	case SLJIT_HAS_PREFETCH:+		return 1;+#endif /* SLJIT_MIPS_REV >= 1 */++	default:+		return fir;+	}+}++/* --------------------------------------------------------------------- */+/*  Entry, exit                                                          */+/* --------------------------------------------------------------------- */++/* Creates an index in data_transfer_insts array. */+#define LOAD_DATA	0x01+#define WORD_DATA	0x00+#define BYTE_DATA	0x02+#define HALF_DATA	0x04+#define INT_DATA	0x06+#define SIGNED_DATA	0x08+/* Separates integer and floating point registers */+#define GPR_REG		0x0f+#define DOUBLE_DATA	0x10+#define SINGLE_DATA	0x12++#define MEM_MASK	0x1f++#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	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+#define STACK_LOAD	LW+#else+#define STACK_STORE	SD+#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+#include "sljitNativeMIPS_64.c"+#endif++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_ins base;+	sljit_s32 args, i, tmp, offs;++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	local_size = (local_size + 15) & ~0xf;+#else+	local_size = (local_size + 31) & ~0x1f;+#endif+	compiler->local_size = local_size;++	if (local_size <= SIMM_MAX) {+		/* Frequent case. */+		FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));+		base = S(SLJIT_SP);+		offs = local_size - (sljit_sw)sizeof(sljit_sw);+	}+	else {+		FAIL_IF(load_immediate(compiler, DR(OTHER_FLAG), local_size));+		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));+		FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));+		base = S(TMP_REG2);+		local_size = 0;+		offs = -(sljit_sw)sizeof(sljit_sw);+	}++	FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS));++	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--) {+		offs -= (sljit_s32)(sizeof(sljit_sw));+		FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));+	}++	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		offs -= (sljit_s32)(sizeof(sljit_sw));+		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)+		FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_S1), DR(SLJIT_S1)));+	if (args >= 3)+		FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_S2), DR(SLJIT_S2)));++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	CHECK_ERROR();+	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	compiler->local_size = (local_size + 15) & ~0xf;+#else+	compiler->local_size = (local_size + 31) & ~0x1f;+#endif+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 local_size, i, tmp, offs;+	sljit_ins base;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	local_size = compiler->local_size;+	if (local_size <= SIMM_MAX)+		base = S(SLJIT_SP);+	else {+		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));+		FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1)));+		base = S(TMP_REG1);+		local_size = 0;+	}++	FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_s32)sizeof(sljit_sw)), RETURN_ADDR_REG));+	offs = local_size - (sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);++	tmp = compiler->scratches;+	for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {+		FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i)));+		offs += (sljit_s32)(sizeof(sljit_sw));+	}++	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = tmp; i <= SLJIT_S0; i++) {+		FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i)));+		offs += (sljit_s32)(sizeof(sljit_sw));+	}++	SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw)));++	FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));+	if (compiler->local_size <= SIMM_MAX)+		return push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(compiler->local_size), UNMOVABLE_INS);+	else+		return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_SP), UNMOVABLE_INS);+}++#undef STACK_STORE+#undef STACK_LOAD++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#define ARCH_32_64(a, b)	a+#else+#define ARCH_32_64(a, b)	b+#endif++static const sljit_ins data_transfer_insts[16 + 4] = {+/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),+/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),+/* u b s */ HI(40) /* sb */,+/* u b l */ HI(36) /* lbu */,+/* u h s */ HI(41) /* sh */,+/* u h l */ HI(37) /* lhu */,+/* u i s */ HI(43) /* sw */,+/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),++/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),+/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),+/* s b s */ HI(40) /* sb */,+/* s b l */ HI(32) /* lb */,+/* s h s */ HI(41) /* sh */,+/* s h l */ HI(33) /* lh */,+/* s i s */ HI(43) /* sw */,+/* s i l */ HI(35) /* lw */,++/* d   s */ HI(61) /* sdc1 */,+/* d   l */ HI(53) /* ldc1 */,+/* s   s */ HI(57) /* swc1 */,+/* s   l */ HI(49) /* lwc1 */,+};++#undef ARCH_32_64++/* reg_ar is an absoulute register! */++/* 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_ar, sljit_s32 arg, sljit_sw argw)+{+	SLJIT_ASSERT(arg & SLJIT_MEM);++	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;+		FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)+			| TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));+		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)+{+	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));++	/* Simple operation except for updates. */+	if (arg & OFFS_REG_MASK) {+		argw &= 0x3;+		next_argw &= 0x3;+		if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))+			return 1;+		return 0;+	}++	if (arg == next_arg) {+		if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))+			return 1;+		return 0;+	}++	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_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)+{+	sljit_s32 tmp_ar, base, delay_slot;++	SLJIT_ASSERT(arg & SLJIT_MEM);+	if (!(next_arg & SLJIT_MEM)) {+		next_arg = 0;+		next_argw = 0;+	}++	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {+		tmp_ar = reg_ar;+		delay_slot = reg_ar;+	}+	else {+		tmp_ar = DR(TMP_REG1);+		delay_slot = MOVABLE_INS;+	}+	base = arg & REG_MASK;++	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {+		argw &= 0x3;++		/* Using the cache. */+		if (argw == compiler->cache_argw) {+			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);+				}+				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);+			}+		}++		if (SLJIT_UNLIKELY(argw)) {+			compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);+			compiler->cache_argw = argw;+			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));+		}++		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 (compiler->cache_arg == arg && 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;+		}+		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);+	}++	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)));+	}+	else {+		compiler->cache_arg = SLJIT_MEM;+		FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));+	}+	compiler->cache_argw = argw;++	if (!base)+		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);++	if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {+		compiler->cache_arg = arg;+		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | 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(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));+	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);+}++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)+{+	sljit_s32 tmp_ar, base, delay_slot;++	if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))+		return compiler->error;++	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {+		tmp_ar = reg_ar;+		delay_slot = reg_ar;+	}+	else {+		tmp_ar = DR(TMP_REG1);+		delay_slot = MOVABLE_INS;+	}+	base = arg & REG_MASK;++	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {+		argw &= 0x3;++		if (SLJIT_UNLIKELY(argw)) {+			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));+			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));+		}+		else+			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));+		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);+	}++	FAIL_IF(load_immediate(compiler, tmp_ar, argw));++	if (base != 0)+		FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));++	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);+}++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 flags,+	sljit_s32 dst, sljit_sw dstw,+	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. */+	sljit_s32 dst_r = TMP_REG2;+	sljit_s32 src1_r;+	sljit_sw src2_r = 0;+	sljit_s32 sugg_src2_r = TMP_REG2;++	if (!(flags & ALT_KEEP_CACHE)) {+		compiler->cache_arg = 0;+		compiler->cache_argw = 0;+	}++	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {+		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_MOV_P)+			sugg_src2_r = dst_r;+	}+	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))+		flags |= SLOW_DEST;++	if (flags & IMM_OP) {+		if ((src2 & SLJIT_IMM) && src2w) {+			if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN))+				|| ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) {+				flags |= SRC2_IMM;+				src2_r = src2w;+			}+		}+		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {+			if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN))+				|| ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) {+				flags |= SRC2_IMM;+				src2_r = src1w;++				/* And swap arguments. */+				src1 = src2;+				src1w = src2w;+				src2 = SLJIT_IMM;+				/* src2w = src2_r unneeded. */+			}+		}+	}++	/* Source 1. */+	if (FAST_IS_REG(src1)) {+		src1_r = src1;+		flags |= REG1_SOURCE;+	}+	else if (src1 & SLJIT_IMM) {+		if (src1w) {+			FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));+			src1_r = TMP_REG1;+		}+		else+			src1_r = 0;+	}+	else {+		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))+			FAIL_IF(compiler->error);+		else+			flags |= SLOW_SRC1;+		src1_r = TMP_REG1;+	}++	/* Source 2. */+	if (FAST_IS_REG(src2)) {+		src2_r = src2;+		flags |= REG2_SOURCE;+		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)+			dst_r = src2_r;+	}+	else if (src2 & SLJIT_IMM) {+		if (!(flags & SRC2_IMM)) {+			if (src2w) {+				FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));+				src2_r = sugg_src2_r;+			}+			else {+				src2_r = 0;+				if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))+					dst_r = 0;+			}+		}+	}+	else {+		if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))+			FAIL_IF(compiler->error);+		else+			flags |= SLOW_SRC2;+		src2_r = sugg_src2_r;+	}++	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {+		SLJIT_ASSERT(src2_r == TMP_REG2);+		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));+		}+		else {+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));+		}+	}+	else if (flags & SLOW_SRC1)+		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));+	else if (flags & SLOW_SRC2)+		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));++	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));++	if (dst & SLJIT_MEM) {+		if (!(flags & SLOW_DEST)) {+			getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);+			return compiler->error;+		}+		return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+	sljit_s32 int_op = op & SLJIT_I32_OP;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_BREAKPOINT:+		return push_inst(compiler, BREAK, UNMOVABLE_INS);+	case SLJIT_NOP:+		return push_inst(compiler, NOP, UNMOVABLE_INS);+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));+#else /* !SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));+#endif /* SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));+		return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));+#else /* SLJIT_MIPS_REV < 6 */+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));+#else /* !SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));+#endif /* SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));+		return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));+#endif /* SLJIT_MIPS_REV >= 6 */+	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);+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+		if (int_op) {+			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));+			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));+		}+		else {+			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));+			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));+		}+#else /* !SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));+		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));+#endif /* SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));+		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));+#else /* SLJIT_MIPS_REV < 6 */+#if !(defined SLJIT_MIPS_REV)+		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));+		FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));+#endif /* !SLJIT_MIPS_REV */+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+		if (int_op)+			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));+		else+			FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));+#else /* !SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));+#endif /* SLJIT_CONFIG_MIPS_64 */+		FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));+		return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));+#endif /* SLJIT_MIPS_REV >= 6 */+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+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_MIPS_REV >= 1 */++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)+{+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#	define flags 0+#else+	sljit_s32 flags = 0;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	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;+#endif++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV:+	case SLJIT_MOV_P:+		return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_U32:+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);+#else+		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);+#endif++	case SLJIT_MOV_S32:+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);+#else+		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);+#endif++	case SLJIT_MOV_U8:+		return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);++	case SLJIT_MOV_S8:+		return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);++	case SLJIT_MOV_U16:+		return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);++	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_NOT:+		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_NEG:+		return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);++	case SLJIT_CLZ:+		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)+#	undef flags+#endif+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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)+{+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#	define flags 0+#else+	sljit_s32 flags = 0;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	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;+		if (src1 & SLJIT_IMM)+			src1w = (sljit_s32)src1w;+		if (src2 & SLJIT_IMM)+			src2w = (sljit_s32)src2w;+	}+#endif++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD:+	case SLJIT_ADDC:+		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SUB:+	case SLJIT_SUBC:+		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_MUL:+		return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_AND:+	case SLJIT_OR:+	case SLJIT_XOR:+		return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SHL:+	case SLJIT_LSHR:+	case SLJIT_ASHR:+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+		if (src2 & SLJIT_IMM)+			src2w &= 0x1f;+#else+		if (src2 & SLJIT_IMM) {+			if (op & SLJIT_I32_OP)+				src2w &= 0x1f;+			else+				src2w &= 0x3f;+		}+#endif+		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)+#	undef flags+#endif+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		if (FAST_IS_REG(src))+			FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));+		else+			FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));++		FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));+		return push_inst(compiler, NOP, UNMOVABLE_INS);+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		return SLJIT_SUCCESS;+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)+		return emit_prefetch(compiler, src, srcw);+#else /* SLJIT_MIPS_REV < 1 */+		return SLJIT_SUCCESS;+#endif /* SLJIT_MIPS_REV >= 1 */+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++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 FR(reg);+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */++#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))+#define FMT(op) (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) << (21 - 8))++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)+{+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#	define flags 0+#else+	sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) << 21;+#endif++	if (src & SLJIT_MEM) {+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));+		src = TMP_FREG1;+	}++	FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));++	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, FR(TMP_FREG1), dst, dstw, 0, 0);++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#	undef is_long+#endif+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#	define flags 0+#else+	sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21;+#endif++	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, FR(TMP_FREG1), src, srcw, dst, dstw));+	}+	else {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)+			srcw = (sljit_s32)srcw;+#endif+		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));+		FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));+	}++	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), FR(TMP_FREG1), dst, dstw, 0, 0);+	return SLJIT_SUCCESS;++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#	undef flags+#endif+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	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, FR(TMP_FREG1), src1, src1w, src2, src2w));+		src1 = TMP_FREG1;+	}++	if (src2 & SLJIT_MEM) {+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));+		src2 = TMP_FREG2;+	}++	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;+	}+	return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);+}++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_s32 dst_r;++	CHECK_ERROR();+	compiler->cache_arg = 0;+	compiler->cache_argw = 0;++	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);+	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);++	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)+		op ^= SLJIT_F32_OP;++	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;++	if (src & SLJIT_MEM) {+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));+		src = dst_r;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV_F64:+		if (src != dst_r) {+			if (dst_r != TMP_FREG1)+				FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));+			else+				dst_r = src;+		}+		break;+	case SLJIT_NEG_F64:+		FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));+		break;+	case SLJIT_ABS_F64:+		FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));+		break;+	case SLJIT_CONV_F64_FROM_F32:+		FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_F32_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));+		op ^= SLJIT_F32_OP;+		break;+	}++	if (dst & SLJIT_MEM)+		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);+	return SLJIT_SUCCESS;+}++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_s32 dst_r, flags = 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	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, FR(TMP_FREG1), src1, src1w)) {+			FAIL_IF(compiler->error);+			src1 = TMP_FREG1;+		} else+			flags |= SLOW_SRC1;+	}++	if (src2 & SLJIT_MEM) {+		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;+	}++	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, 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, 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, FR(TMP_FREG1), src1, src1w, dst, dstw));+	else if (flags & SLOW_SRC2)+		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));++	if (flags & SLOW_SRC1)+		src1 = TMP_FREG1;+	if (flags & SLOW_SRC2)+		src2 = TMP_FREG2;++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));+		break;++	case SLJIT_SUB_F64:+		FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));+		break;++	case SLJIT_MUL_F64:+		FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));+		break;++	case SLJIT_DIV_F64:+		FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));+		break;+	}++	if (dst_r == TMP_FREG2)+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));++	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Other instructions                                                   */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	if (FAST_IS_REG(dst))+		return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);++	/* Memory. */+	FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw));+	compiler->delay_slot = UNMOVABLE_INS;+	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	compiler->delay_slot = UNMOVABLE_INS;+	return label;+}++#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+#define JUMP_LENGTH	4+#else+#define JUMP_LENGTH	8+#endif++#define BR_Z(src) \+	inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \+	flags = IS_BIT26_COND; \+	delay_check = src;++#define BR_NZ(src) \+	inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \+	flags = IS_BIT26_COND; \+	delay_check = src;++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)++#define BR_T() \+	inst = BC1NEZ; \+	flags = IS_BIT23_COND; \+	delay_check = FCSR_FCC;+#define BR_F() \+	inst = BC1EQZ; \+	flags = IS_BIT23_COND; \+	delay_check = FCSR_FCC;++#else /* SLJIT_MIPS_REV < 6 */++#define BR_T() \+	inst = BC1T | JUMP_LENGTH; \+	flags = IS_BIT16_COND; \+	delay_check = FCSR_FCC;+#define BR_F() \+	inst = BC1F | JUMP_LENGTH; \+	flags = IS_BIT16_COND; \+	delay_check = FCSR_FCC;++#endif /* SLJIT_MIPS_REV >= 6 */++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;+	sljit_ins inst;+	sljit_s32 flags = 0;+	sljit_s32 delay_check = UNMOVABLE_INS;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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;++	switch (type) {+	case SLJIT_EQUAL:+		BR_NZ(EQUAL_FLAG);+		break;+	case SLJIT_NOT_EQUAL:+		BR_Z(EQUAL_FLAG);+		break;+	case SLJIT_LESS:+	case SLJIT_GREATER:+	case SLJIT_SIG_LESS:+	case SLJIT_SIG_GREATER:+	case SLJIT_OVERFLOW:+	case SLJIT_MUL_OVERFLOW:+		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(OTHER_FLAG);+		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;+		break;+	}++	jump->flags |= flags;+	if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))+		jump->flags |= IS_MOVABLE;++	if (inst)+		PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));++	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));++	if (type <= SLJIT_JUMP)+		PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));+	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;+	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));+	return jump;+}++#define RESOLVE_IMM1() \+	if (src1 & SLJIT_IMM) { \+		if (src1w) { \+			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \+			src1 = TMP_REG1; \+		} \+		else \+			src1 = 0; \+	}++#define RESOLVE_IMM2() \+	if (src2 & SLJIT_IMM) { \+		if (src2w) { \+			PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \+			src2 = TMP_REG2; \+		} \+		else \+			src2 = 0; \+	}++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)+{+	struct sljit_jump *jump;+	sljit_s32 flags;+	sljit_ins inst;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	compiler->cache_arg = 0;+	compiler->cache_argw = 0;+	flags = ((type & SLJIT_I32_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA;+	if (src1 & SLJIT_MEM) {+		PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));+		src1 = TMP_REG1;+	}+	if (src2 & SLJIT_MEM) {+		PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));+		src2 = TMP_REG2;+	}++	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;++	if (type <= SLJIT_NOT_EQUAL) {+		RESOLVE_IMM1();+		RESOLVE_IMM2();+		jump->flags |= IS_BIT26_COND;+		if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))+			jump->flags |= IS_MOVABLE;+		PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS));+	}+	else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {+		inst = NOP;+		if ((src1 & SLJIT_IMM) && (src1w == 0)) {+			RESOLVE_IMM2();+			switch (type) {+			case SLJIT_SIG_LESS:+				inst = BLEZ;+				jump->flags |= IS_BIT26_COND;+				break;+			case SLJIT_SIG_GREATER_EQUAL:+				inst = BGTZ;+				jump->flags |= IS_BIT26_COND;+				break;+			case SLJIT_SIG_GREATER:+				inst = BGEZ;+				jump->flags |= IS_BIT16_COND;+				break;+			case SLJIT_SIG_LESS_EQUAL:+				inst = BLTZ;+				jump->flags |= IS_BIT16_COND;+				break;+			}+			src1 = src2;+		}+		else {+			RESOLVE_IMM1();+			switch (type) {+			case SLJIT_SIG_LESS:+				inst = BGEZ;+				jump->flags |= IS_BIT16_COND;+				break;+			case SLJIT_SIG_GREATER_EQUAL:+				inst = BLTZ;+				jump->flags |= IS_BIT16_COND;+				break;+			case SLJIT_SIG_GREATER:+				inst = BLEZ;+				jump->flags |= IS_BIT26_COND;+				break;+			case SLJIT_SIG_LESS_EQUAL:+				inst = BGTZ;+				jump->flags |= IS_BIT26_COND;+				break;+			}+		}+		PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS));+	}+	else {+		if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {+			RESOLVE_IMM1();+			if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)+				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));+			else {+				RESOLVE_IMM2();+				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));+			}+			type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;+		}+		else {+			RESOLVE_IMM2();+			if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)+				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));+			else {+				RESOLVE_IMM1();+				PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));+			}+			type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;+		}++		jump->flags |= IS_BIT26_COND;+		PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | 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 RESOLVE_IMM1+#undef RESOLVE_IMM2++#undef JUMP_LENGTH+#undef BR_Z+#undef BR_NZ+#undef BR_T+#undef BR_F++#undef FLOAT_DATA+#undef FMT++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;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	if (src & SLJIT_IMM) {+		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_JAL : 0));+		jump->u.target = srcw;++		if (compiler->delay_slot != UNMOVABLE_INS)+			jump->flags |= IS_MOVABLE;++		FAIL_IF(emit_const(compiler, TMP_REG2, 0));+		src = TMP_REG2;+	}+	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), UNMOVABLE_INS));+	if (jump)+		jump->addr = compiler->size;+	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));+	return SLJIT_SUCCESS;+}++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 type)+{+	sljit_s32 src_ar, dst_ar;+	sljit_s32 saved_op = op;+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	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, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	op = GET_OPCODE(op);+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)+	if (op == SLJIT_MOV_S32)+		mem_type = INT_DATA | SIGNED_DATA;+#endif+	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 && (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(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(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:+	case SLJIT_LESS_F64:+	case SLJIT_GREATER_EQUAL_F64:+	case SLJIT_UNORDERED_F64:+	case SLJIT_ORDERED_F64:+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)+		FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));+#else /* SLJIT_MIPS_REV < 6 */+		FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));+#endif /* SLJIT_MIPS_REV >= 6 */+		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:+		src_ar = OTHER_FLAG;+		break;+	}++	if (type & 0x1) {+		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 (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(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);+}++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_REV && SLJIT_MIPS_REV >= 1)+	sljit_ins ins;+#endif /* SLJIT_MIPS_REV >= 1 */++	CHECK_ERROR();+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));++#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)++	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 /* SLJIT_MIPS_REV < 1 */+	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);+#endif /* SLJIT_MIPS_REV >= 1 */+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)+{+	struct sljit_const *const_;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;+	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));++	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 0);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)+	PTR_FAIL_IF(emit_const(compiler, dst_r, 0));+#else+	PTR_FAIL_IF(push_inst(compiler, dst_r, UNMOVABLE_INS));+	compiler->size += 5;+#endif++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));++	return put_label;+}
+ src/c/pcre2/src/sljit/sljitNativePPC_32.c view
@@ -0,0 +1,275 @@+/*+ *    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.+ */++/* ppc 32-bit arch dependent functions. */++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)+{+	if (imm <= SIMM_MAX && imm >= SIMM_MIN)+		return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));++	if (!(imm & ~0xffff))+		return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));++	FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));+	return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;+}++#define INS_CLEAR_LEFT(dst, src, from) \+	(RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))++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)+{+	switch (op) {+	case SLJIT_MOV:+	case SLJIT_MOV_U32:+	case SLJIT_MOV_S32:+	case SLJIT_MOV_P:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if (dst != src2)+			return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U8:+	case SLJIT_MOV_S8:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S8)+				return push_inst(compiler, EXTSB | S(src2) | A(dst));+			return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));+		}+		else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)+			return push_inst(compiler, EXTSB | S(src2) | A(dst));+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U16:+	case SLJIT_MOV_S16:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S16)+				return push_inst(compiler, EXTSH | S(src2) | A(dst));+			return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_NOT:+		SLJIT_ASSERT(src1 == TMP_REG1);+		return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));++	case SLJIT_NEG:+		SLJIT_ASSERT(src1 == TMP_REG1);+		/* 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 | S(src2) | A(dst));++	case SLJIT_ADD:+		if (flags & ALT_FORM1) {+			/* 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);++			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_SET_FLAGS))+			return push_inst(compiler, ADD | 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:+		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_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_SET_FLAGS))+			return push_inst(compiler, SUBF | 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:+		return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));++	case SLJIT_MUL:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);+		}+		return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));++	case SLJIT_AND:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM2) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);+		}+		return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_OR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM2) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM3) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));+			return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));+		}+		return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_XOR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM2) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM3) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));+			return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));+		}+		return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_SHL:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			compiler->imm &= 0x1f;+			return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));+		}+		return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_LSHR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			compiler->imm &= 0x1f;+			return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));+		}+		return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_ASHR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			compiler->imm &= 0x1f;+			return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));+		}+		return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));+	}++	SLJIT_UNREACHABLE();+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)+{+	FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));+	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_target, sljit_sw executable_offset)+{+	sljit_ins *inst = (sljit_ins *)addr;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);+	SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);+	inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);+	inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);+	SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}
+ src/c/pcre2/src/sljit/sljitNativePPC_64.c view
@@ -0,0 +1,495 @@+/*+ *    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.+ */++/* ppc 64-bit arch dependent functions. */++#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)+#define ASM_SLJIT_CLZ(src, dst) \+	__asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )+#elif defined(__xlc__)+#error "Please enable GCC syntax for inline assembly statements"+#else+#error "Must implement count leading zeroes"+#endif++#define PUSH_RLDICR(reg, shift) \+	push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)+{+	sljit_uw tmp;+	sljit_uw shift;+	sljit_uw tmp2;+	sljit_uw shift2;++	if (imm <= SIMM_MAX && imm >= SIMM_MIN)+		return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));++	if (!(imm & ~0xffff))+		return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));++	if (imm <= 0x7fffffffl && imm >= -0x80000000l) {+		FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));+		return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;+	}++	/* Count leading zeroes. */+	tmp = (imm >= 0) ? imm : ~imm;+	ASM_SLJIT_CLZ(tmp, shift);+	SLJIT_ASSERT(shift > 0);+	shift--;+	tmp = (imm << shift);++	if ((tmp & ~0xffff000000000000ul) == 0) {+		FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));+		shift += 15;+		return PUSH_RLDICR(reg, shift);+	}++	if ((tmp & ~0xffffffff00000000ul) == 0) {+		FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48)));+		FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));+		shift += 31;+		return PUSH_RLDICR(reg, shift);+	}++	/* Cut out the 16 bit from immediate. */+	shift += 15;+	tmp2 = imm & ((1ul << (63 - shift)) - 1);++	if (tmp2 <= 0xffff) {+		FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));+		FAIL_IF(PUSH_RLDICR(reg, shift));+		return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2);+	}++	if (tmp2 <= 0xffffffff) {+		FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));+		FAIL_IF(PUSH_RLDICR(reg, shift));+		FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16)));+		return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;+	}++	ASM_SLJIT_CLZ(tmp2, shift2);+	tmp2 <<= shift2;++	if ((tmp2 & ~0xffff000000000000ul) == 0) {+		FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));+		shift2 += 15;+		shift += (63 - shift2);+		FAIL_IF(PUSH_RLDICR(reg, shift));+		FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48)));+		return PUSH_RLDICR(reg, shift2);+	}++	/* The general version. */+	FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48)));+	FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));+	FAIL_IF(PUSH_RLDICR(reg, 31));+	FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));+	return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));+}++/* Simplified mnemonics: clrldi. */+#define INS_CLEAR_LEFT(dst, src, from) \+	(RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5))++/* Sign extension for integer operations. */+#define UN_EXTS() \+	if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \+		FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \+		src2 = TMP_REG2; \+	}++#define BIN_EXTS() \+	if (flags & ALT_SIGN_EXT) { \+		if (flags & REG1_SOURCE) { \+			FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \+			src1 = TMP_REG1; \+		} \+		if (flags & REG2_SOURCE) { \+			FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \+			src2 = TMP_REG2; \+		} \+	}++#define BIN_IMM_EXTS() \+	if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \+		FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \+		src1 = TMP_REG1; \+	}++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)+{+	switch (op) {+	case SLJIT_MOV:+	case SLJIT_MOV_P:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if (dst != src2)+			return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U32:+	case SLJIT_MOV_S32:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S32)+				return push_inst(compiler, EXTSW | S(src2) | A(dst));+			return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U8:+	case SLJIT_MOV_S8:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S8)+				return push_inst(compiler, EXTSB | S(src2) | A(dst));+			return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));+		}+		else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)+			return push_inst(compiler, EXTSB | S(src2) | A(dst));+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U16:+	case SLJIT_MOV_S16:+		SLJIT_ASSERT(src1 == TMP_REG1);+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S16)+				return push_inst(compiler, EXTSH | S(src2) | A(dst));+			return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));+		}+		else {+			SLJIT_ASSERT(dst == src2);+		}+		return SLJIT_SUCCESS;++	case SLJIT_NOT:+		SLJIT_ASSERT(src1 == TMP_REG1);+		UN_EXTS();+		return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));++	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();+		/* 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 | S(src2) | A(dst));+		return push_inst(compiler, CNTLZD | S(src2) | A(dst));++	case SLJIT_ADD:+		if (flags & ALT_FORM1) {+			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);++			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_SET_FLAGS))+			return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));+		BIN_EXTS();+		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:+		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_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_SET_FLAGS))+			return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));+		BIN_EXTS();+		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:+		BIN_EXTS();+		return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));++	case SLJIT_MUL:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);+		}+		BIN_EXTS();+		if (flags & ALT_FORM2)+			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) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM2) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);+		}+		return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_OR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM2) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM3) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));+			return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));+		}+		return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_XOR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM2) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);+		}+		if (flags & ALT_FORM3) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));+			return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));+		}+		return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));++	case SLJIT_SHL:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			if (flags & ALT_FORM2) {+				compiler->imm &= 0x1f;+				return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));+			}+			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));++	case SLJIT_LSHR:+		if (flags & ALT_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			if (flags & ALT_FORM2) {+				compiler->imm &= 0x1f;+				return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));+			}+			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_FORM1) {+			SLJIT_ASSERT(src2 == TMP_REG2);+			if (flags & ALT_FORM2) {+				compiler->imm &= 0x1f;+				return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));+			}+			compiler->imm &= 0x3f;+			return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));+		}+		return push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2));+	}++	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;+}++static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)+{+	FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));+	FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));+	FAIL_IF(PUSH_RLDICR(reg, 31));+	FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));+	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_target, sljit_sw executable_offset)+{+	sljit_ins *inst = (sljit_ins*)addr;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);+	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);+	SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}
+ src/c/pcre2/src/sljit/sljitNativePPC_common.c view
@@ -0,0 +1,2408 @@+/*+ *    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.+ */++SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)+{+	return "PowerPC" SLJIT_CPUINFO;+}++/* Length of an instruction word.+   Both for ppc-32 and ppc-64. */+typedef sljit_u32 sljit_ins;++#if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \+	|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define SLJIT_PPC_STACK_FRAME_V2 1+#endif++#ifdef _AIX+#include <sys/cache.h>+#endif++#if (defined _CALL_ELF && _CALL_ELF == 2)+#define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1+#endif++#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)++static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)+{+#ifdef _AIX+	_sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));+#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)+#	if defined(_ARCH_PWR) || defined(_ARCH_PWR2)+	/* Cache flush for POWER architecture. */+	while (from < to) {+		__asm__ volatile (+			"clf 0, %0\n"+			"dcs\n"+			: : "r"(from)+		);+		from++;+	}+	__asm__ volatile ( "ics" );+#	elif defined(_ARCH_COM) && !defined(_ARCH_PPC)+#	error "Cache flush is not implemented for PowerPC/POWER common mode."+#	else+	/* Cache flush for PowerPC architecture. */+	while (from < to) {+		__asm__ volatile (+			"dcbf 0, %0\n"+			"sync\n"+			"icbi 0, %0\n"+			: : "r"(from)+		);+		from++;+	}+	__asm__ volatile ( "isync" );+#	endif+#	ifdef __xlc__+#	warning "This file may fail to compile if -qfuncsect is used"+#	endif+#elif defined(__xlc__)+#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"+#else+#error "This platform requires a cache flush implementation."+#endif /* _AIX */+}++#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */++#define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)+#define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)+#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 + 5)+#else+#define TMP_CALL_REG	TMP_REG2+#endif++#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, 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+};++/* --------------------------------------------------------------------- */+/*  Instrucion forms                                                     */+/* --------------------------------------------------------------------- */+#define D(d)		(reg_map[d] << 21)+#define S(s)		(reg_map[s] << 21)+#define A(a)		(reg_map[a] << 16)+#define B(b)		(reg_map[b] << 11)+#define C(c)		(reg_map[c] << 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 OE(flags)	((flags) & ALT_SET_FLAGS)+/* Rc flag (see ALT_SET_FLAGS). */+#define RC(flags)	(((flags) & ALT_SET_FLAGS) >> 10)+#define HI(opcode)	((opcode) << 26)+#define LO(opcode)	((opcode) << 1)++#define ADD		(HI(31) | LO(266))+#define ADDC		(HI(31) | LO(10))+#define ADDE		(HI(31) | LO(138))+#define ADDI		(HI(14))+#define ADDIC		(HI(13))+#define ADDIS		(HI(15))+#define ADDME		(HI(31) | LO(234))+#define AND		(HI(31) | LO(28))+#define ANDI		(HI(28))+#define ANDIS		(HI(29))+#define Bx		(HI(18))+#define BCx		(HI(16))+#define BCCTR		(HI(19) | LO(528) | (3 << 11))+#define BLR		(HI(19) | LO(16) | (0x14 << 21))+#define CNTLZD		(HI(31) | LO(58))+#define CNTLZW		(HI(31) | LO(26))+#define CMP		(HI(31) | LO(0))+#define CMPI		(HI(11))+#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))+#define DIVWU		(HI(31) | LO(459))+#define EXTSB		(HI(31) | LO(954))+#define EXTSH		(HI(31) | LO(922))+#define EXTSW		(HI(31) | LO(986))+#define FABS		(HI(63) | LO(264))+#define FADD		(HI(63) | LO(21))+#define FADDS		(HI(59) | LO(21))+#define FCFID		(HI(63) | LO(846))+#define FCMPU		(HI(63) | LO(0))+#define FCTIDZ		(HI(63) | LO(815))+#define FCTIWZ		(HI(63) | LO(15))+#define FDIV		(HI(63) | LO(18))+#define FDIVS		(HI(59) | LO(18))+#define FMR		(HI(63) | LO(72))+#define FMUL		(HI(63) | LO(25))+#define FMULS		(HI(59) | LO(25))+#define FNEG		(HI(63) | LO(40))+#define FRSP		(HI(63) | LO(12))+#define FSUB		(HI(63) | LO(20))+#define FSUBS		(HI(59) | LO(20))+#define LD		(HI(58) | 0)+#define LWZ		(HI(32))+#define MFCR		(HI(31) | LO(19))+#define MFLR		(HI(31) | LO(339) | 0x80000)+#define MFXER		(HI(31) | LO(339) | 0x10000)+#define MTCTR		(HI(31) | LO(467) | 0x90000)+#define MTLR		(HI(31) | LO(467) | 0x80000)+#define MTXER		(HI(31) | LO(467) | 0x10000)+#define MULHD		(HI(31) | LO(73))+#define MULHDU		(HI(31) | LO(9))+#define MULHW		(HI(31) | LO(75))+#define MULHWU		(HI(31) | LO(11))+#define MULLD		(HI(31) | LO(233))+#define MULLI		(HI(7))+#define MULLW		(HI(31) | LO(235))+#define NEG		(HI(31) | LO(104))+#define NOP		(HI(24))+#define NOR		(HI(31) | LO(124))+#define OR		(HI(31) | LO(444))+#define ORI		(HI(24))+#define ORIS		(HI(25))+#define RLDICL		(HI(30))+#define RLWINM		(HI(21))+#define SLD		(HI(31) | LO(27))+#define SLW		(HI(31) | LO(24))+#define SRAD		(HI(31) | LO(794))+#define SRADI		(HI(31) | LO(413 << 1))+#define SRAW		(HI(31) | LO(792))+#define SRAWI		(HI(31) | LO(824))+#define SRD		(HI(31) | LO(539))+#define SRW		(HI(31) | LO(536))+#define STD		(HI(62) | 0)+#define STDU		(HI(62) | 1)+#define STDUX		(HI(31) | LO(181))+#define STFIWX		(HI(31) | LO(983))+#define STW		(HI(36))+#define STWU		(HI(37))+#define STWUX		(HI(31) | LO(183))+#define SUBF		(HI(31) | LO(40))+#define SUBFC		(HI(31) | LO(8))+#define SUBFE		(HI(31) | LO(136))+#define SUBFIC		(HI(8))+#define XOR		(HI(31) | LO(316))+#define XORI		(HI(26))+#define XORIS		(HI(27))++#define SIMM_MAX	(0x7fff)+#define SIMM_MIN	(-0x8000)+#define UIMM_MAX	(0xffff)++#define RLDI(dst, src, sh, mb, type) \+	(HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))++#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)+{+	sljit_sw* ptrs;+	if (func_ptr)+		*func_ptr = (void*)context;+	ptrs = (sljit_sw*)func;+	context->addr = addr ? addr : ptrs[0];+	context->r2 = ptrs[1];+	context->r11 = ptrs[2];+}+#endif++static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)+{+	sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	return SLJIT_SUCCESS;+}++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;+	sljit_sw extra_jump_flags;++#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+	if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))+		return 0;+#else+	if (jump->flags & SLJIT_REWRITABLE_JUMP)+		return 0;+#endif++	if (jump->flags & JUMP_ADDR)+		target_addr = jump->u.target;+	else {+		SLJIT_ASSERT(jump->flags & JUMP_LABEL);+		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)+	if (jump->flags & IS_CALL)+		goto keep_address;+#endif++	diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;++	extra_jump_flags = 0;+	if (jump->flags & IS_COND) {+		if (diff <= 0x7fff && diff >= -0x8000) {+			jump->flags |= PATCH_B;+			return 1;+		}+		if (target_addr <= 0xffff) {+			jump->flags |= PATCH_B | PATCH_ABS_B;+			return 1;+		}+		extra_jump_flags = REMOVE_COND;++		diff -= sizeof(sljit_ins);+	}++	if (diff <= 0x01ffffff && diff >= -0x02000000) {+		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;+	}++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)+keep_address:+#endif+	if (target_addr <= 0x7fffffff) {+		jump->flags |= PATCH_ABS32;+		return 1;+	}++	if (target_addr <= 0x7fffffffffffl) {+		jump->flags |= PATCH_ABS48;+		return 1;+	}+#endif++	return 0;+}++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)++static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)+{+	if (max_label < 0x100000000l) {+		put_label->flags = 0;+		return 1;+	}++	if (max_label < 0x1000000000000l) {+		put_label->flags = 1;+		return 3;+	}++	put_label->flags = 2;+	return 4;+}++static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)+{+	sljit_uw addr = put_label->label->addr;+	sljit_ins *inst = (sljit_ins *)put_label->addr;+	sljit_s32 reg = *inst;++	if (put_label->flags == 0) {+		SLJIT_ASSERT(addr < 0x100000000l);+		inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16);+	}+	else {+		if (put_label->flags == 1) {+			SLJIT_ASSERT(addr < 0x1000000000000l);+			inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32);+		}+		else {+			inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48);+			inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff);+			inst ++;+		}++		inst[1] = RLDI(reg, reg, 32, 31, 1);+		inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff);+		inst += 2;+	}++	inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff);+}++#endif++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_ins *code;+	sljit_ins *code_ptr;+	sljit_ins *buf_ptr;+	sljit_ins *buf_end;+	sljit_uw word_count;+	sljit_uw next_addr;+	sljit_sw executable_offset;+	sljit_uw addr;++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+	compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));+#else+	compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));+#endif+#endif+	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	word_count = 0;+	next_addr = 0;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;++	do {+		buf_ptr = (sljit_ins*)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 2);+		do {+			*code_ptr = *buf_ptr++;+			if (next_addr == word_count) {+				SLJIT_ASSERT(!label || label->size >= word_count);+				SLJIT_ASSERT(!jump || jump->addr >= word_count);+				SLJIT_ASSERT(!const_ || const_->addr >= word_count);+				SLJIT_ASSERT(!put_label || put_label->addr >= word_count);++				/* These structures are ordered by their address. */+				if (label && label->size == word_count) {+					/* Just recording the address. */+					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) {+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+					jump->addr = (sljit_uw)(code_ptr - 3);+#else+					jump->addr = (sljit_uw)(code_ptr - 6);+#endif+					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;+#else+						if (jump->flags & PATCH_ABS32) {+							code_ptr -= 3;+							code_ptr[-1] = code_ptr[2];+							code_ptr[0] = code_ptr[3];+						}+						else if (jump->flags & PATCH_ABS48) {+							code_ptr--;+							code_ptr[-1] = code_ptr[0];+							code_ptr[0] = code_ptr[1];+							/* rldicr rX,rX,32,31 -> rX,rX,16,47 */+							SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);+							code_ptr[-3] ^= 0x8422;+							/* oris -> ori */+							code_ptr[-2] ^= 0x4000000;+						}+						else {+							code_ptr[-6] = code_ptr[0];+							code_ptr -= 6;+						}+#endif+						if (jump->flags & REMOVE_COND) {+							code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);+							code_ptr++;+							jump->addr += sizeof(sljit_ins);+							code_ptr[0] = Bx;+							jump->flags -= IS_COND;+						}+					}+					jump = jump->next;+				}+				if (const_ && const_->addr == word_count) {+					const_->addr = (sljit_uw)code_ptr;+					const_ = const_->next;+				}+				if (put_label && put_label->addr == word_count) {+					SLJIT_ASSERT(put_label->label);+					put_label->addr = (sljit_uw)code_ptr;+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+					code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));+					word_count += 4;+#endif+					put_label = put_label->next;+				}+				next_addr = compute_next_addr(label, jump, const_, put_label);+			}+			code_ptr ++;+			word_count ++;+		} while (buf_ptr < buf_end);++		buf = buf->next;+	} while (buf);++	if (label && label->size == word_count) {+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);+		label->size = code_ptr - code;+		label = label->next;+	}++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);++#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)+	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));+#else+	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);+#endif++	jump = compiler->jumps;+	while (jump) {+		do {+			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;+			buf_ptr = (sljit_ins *)jump->addr;++			if (jump->flags & PATCH_B) {+				if (jump->flags & IS_COND) {+					if (!(jump->flags & PATCH_ABS_B)) {+						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);+					}+					else {+						SLJIT_ASSERT(addr <= 0xffff);+						*buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);+					}+				}+				else {+					if (!(jump->flags & PATCH_ABS_B)) {+						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);+					}+					else {+						SLJIT_ASSERT(addr <= 0x03ffffff);+						*buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);+					}+				}+				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);+			buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);+#else+			if (jump->flags & PATCH_ABS32) {+				SLJIT_ASSERT(addr <= 0x7fffffff);+				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);+				buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);+				break;+			}+			if (jump->flags & PATCH_ABS48) {+				SLJIT_ASSERT(addr <= 0x7fffffffffff);+				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);+				buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);+				buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);+				break;+			}+			buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);+			buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);+			buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);+			buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);+#endif+		} while (0);+		jump = jump->next;+	}++	put_label = compiler->put_labels;+	while (put_label) {+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+		addr = put_label->label->addr;+		buf_ptr = (sljit_ins *)put_label->addr;++		SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI);+		buf_ptr[0] |= (addr >> 16) & 0xffff;+		buf_ptr[1] |= addr & 0xffff;+#else+		put_label_set(put_label);+#endif+		put_label = put_label->next;+	}++	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);++#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++;+#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);+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);++#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++	/* A saved register is set to a zero value. */+	case SLJIT_HAS_ZERO_REGISTER:+	case SLJIT_HAS_CLZ:+	case SLJIT_HAS_PREFETCH:+		return 1;++	default:+		return 0;+	}+}++/* --------------------------------------------------------------------- */+/*  Entry, exit                                                          */+/* --------------------------------------------------------------------- */++/* inp_flags: */++/* Creates an index in data_transfer_insts array. */+#define LOAD_DATA	0x01+#define INDEXED		0x02+#define SIGNED_DATA	0x04++#define WORD_DATA	0x00+#define BYTE_DATA	0x08+#define HALF_DATA	0x10+#define INT_DATA	0x18+/* Separates integer and floating point registers */+#define GPR_REG		0x1f+#define DOUBLE_DATA	0x20++#define MEM_MASK	0x7f++/* Other inp_flags. */++/* Integer opertion and set flags -> requires exts on 64 bit systems. */+#define ALT_SIGN_EXT	0x000100+/* This flag affects the RC() and OERC() macros. */+#define ALT_SET_FLAGS	0x000400+#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+/*+ALT_SIGN_EXT		0x000100+ALT_SET_FLAGS		0x000200+ALT_FORM1		0x001000+...+ALT_FORM5		0x010000 */++#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+#include "sljitNativePPC_32.c"+#else+#include "sljitNativePPC_64.c"+#endif++#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+#define STACK_STORE	STW+#define STACK_LOAD	LWZ+#else+#define STACK_STORE	STD+#define STACK_LOAD	LD+#endif++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 args, i, tmp, offs;++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	FAIL_IF(push_inst(compiler, MFLR | D(0)));+	offs = -(sljit_s32)(sizeof(sljit_sw));+	FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));++	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--) {+		offs -= (sljit_s32)(sizeof(sljit_sw));+		FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));+	}++	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		offs -= (sljit_s32)(sizeof(sljit_sw));+		FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs)));+	}++	SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1));++#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)+	FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));+#else+	FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));+#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)+		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1)));+	if (args >= 3)+		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2)));++	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;+	local_size = (local_size + 15) & ~0xf;+	compiler->local_size = local_size;++#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+	if (local_size <= SIMM_MAX)+		FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));+	else {+		FAIL_IF(load_immediate(compiler, 0, -local_size));+		FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));+	}+#else+	if (local_size <= SIMM_MAX)+		FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size)));+	else {+		FAIL_IF(load_immediate(compiler, 0, -local_size));+		FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0)));+	}+#endif++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	CHECK_ERROR();+	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;+	compiler->local_size = (local_size + 15) & ~0xf;+	return SLJIT_SUCCESS;+}++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, offs;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	if (compiler->local_size <= SIMM_MAX)+		FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size)));+	else {+		FAIL_IF(load_immediate(compiler, 0, compiler->local_size));+		FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0)));+	}++#if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2)+	FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw))));+#else+	FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw))));+#endif++	offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);++	tmp = compiler->scratches;+	for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {+		FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));+		offs += (sljit_s32)(sizeof(sljit_sw));+	}++	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = tmp; i <= SLJIT_S0; i++) {+		FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs)));+		offs += (sljit_s32)(sizeof(sljit_sw));+	}++	FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs)));+	SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw)));++	FAIL_IF(push_inst(compiler, MTLR | S(0)));+	FAIL_IF(push_inst(compiler, BLR));++	return SLJIT_SUCCESS;+}++#undef STACK_STORE+#undef STACK_LOAD++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++/* 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)++   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+#endif++#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+#define ARCH_32_64(a, b)	a+#define INST_CODE_AND_DST(inst, flags, reg) \+	((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))+#else+#define ARCH_32_64(a, b)	b+#define INST_CODE_AND_DST(inst, flags, reg) \+	(((inst) & ~INT_ALIGNED) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))+#endif++static const sljit_ins data_transfer_insts[64 + 16] = {++/* -------- Integer -------- */++/* Word. */++/* 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 */),++/* 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. */++/* 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 */,++/* 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. */++/* 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 */,++/* 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. */++/* 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 */,++/* 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 */),++/* -------- 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. */++/* 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 */),++/* 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. */++/* 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 */,++/* 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. */++/* 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 */,++/* 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. */++/* 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 */,++/* 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 */),++/* -------- Floating point -------- */++/* 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   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 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_ASSERT(A(0) == 0);+	SLJIT_ASSERT(arg & SLJIT_MEM);++	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {+		argw &= 0x3;+		offs_reg = OFFS_REG(arg);++		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_reg) | (argw << 11) | ((31 - argw) << 1)));+#else+			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];++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+		SLJIT_ASSERT(!(inst & INT_ALIGNED));+#endif++		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;++#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);+#endif++		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)+	}++	/* The rest is PPC-64 only. */++	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+}++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,+	sljit_s32 src2, sljit_sw src2w)+{+	/* arg1 goes to TMP_REG1 or src reg+	   arg2 goes to TMP_REG2, imm or src reg+	   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_SIGN_EXT | ALT_SET_FLAGS);++	/* Destination check. */+	if (SLOW_IS_REG(dst)) {+		dst_r = dst;+		flags |= REG_DEST;++		if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)+			sugg_src2_r = dst_r;+	}++	/* Source 1. */+	if (FAST_IS_REG(src1)) {+		src1_r = src1;+		flags |= REG1_SOURCE;+	}+	else if (src1 & SLJIT_IMM) {+		FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));+		src1_r = TMP_REG1;+	}+	else {+		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));+		src1_r = TMP_REG1;+	}++	/* Source 2. */+	if (FAST_IS_REG(src2)) {+		src2_r = src2;+		flags |= REG2_SOURCE;++		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 {+		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 (!(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)+{+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+	sljit_s32 int_op = op & SLJIT_I32_OP;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_BREAKPOINT:+	case SLJIT_NOP:+		return push_inst(compiler, NOP);+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+		FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));+		return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));+#else+		FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));+		return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));+#endif+	case SLJIT_DIVMOD_UW:+	case SLJIT_DIVMOD_SW:+		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+		FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));+		FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));+#else+		FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));+		FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));+#endif+		return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));+	case SLJIT_DIV_UW:+	case SLJIT_DIV_SW:+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+		return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));+#else+		return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));+#endif+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	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)++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)+{+	sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;+	sljit_s32 op_flags = GET_ALL_FLAGS(op);++	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src, srcw);++	op = GET_OPCODE(op);+	if ((src & SLJIT_IMM) && srcw == 0)+		src = TMP_ZERO;++	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 (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;+			}+		}+		else {+			/* Most operations expect sign extended arguments. */+			flags |= INT_DATA | SIGNED_DATA;+			if (HAS_FLAGS(op_flags))+				flags |= ALT_SIGN_EXT;+		}+	}+#endif++	switch (op) {+	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+		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+	case SLJIT_MOV_U32:+		return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32));++	case SLJIT_MOV_S32:+		return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32));+#endif++	case SLJIT_MOV_U8:+		return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8));++	case SLJIT_MOV_S8:+		return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8));++	case SLJIT_MOV_U16:+		return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16));++	case SLJIT_MOV_S16:+		return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (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 | (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)+		return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);+#else+		return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);+#endif+	}++	return SLJIT_SUCCESS;+}++#undef EMIT_MOV++#define TEST_SL_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)++#define TEST_UL_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && !((srcw) & ~0xffff))++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define TEST_SH_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l)+#else+#define TEST_SH_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && !((srcw) & 0xffff))+#endif++#define TEST_UH_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define TEST_ADD_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l)+#else+#define TEST_ADD_IMM(src, srcw) \+	((src) & SLJIT_IMM)+#endif++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define TEST_UI_IMM(src, srcw) \+	(((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))+#else+#define TEST_UI_IMM(src, srcw) \+	((src) & SLJIT_IMM)+#endif++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	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)+		src2 = TMP_ZERO;++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+	if (op & SLJIT_I32_OP) {+		/* Most operations expect sign extended arguments. */+		flags |= INT_DATA | SIGNED_DATA;+		if (src1 & SLJIT_IMM)+			src1w = (sljit_s32)(src1w);+		if (src2 & SLJIT_IMM)+			src2w = (sljit_s32)(src2w);+		if (HAS_FLAGS(op))+			flags |= ALT_SIGN_EXT;+	}+#endif+	if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)+		FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD:+		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_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_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 | 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 | 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_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_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);+			}+		}+		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);+			}+			if (TEST_SL_IMM(src1, src1w)) {+				compiler->imm = src1w & 0xffff;+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);+			}+		}+		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, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SUB:+		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_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_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 | 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_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, 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);+			}+			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);+		}++		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 | ((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, 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 (!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);+			}+			if (TEST_SL_IMM(src1, src1w)) {+				compiler->imm = src1w & 0xffff;+				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 (!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);+			}+			if (TEST_UL_IMM(src1, src1w)) {+				compiler->imm = src1w;+				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);+			}+			if (TEST_UH_IMM(src2, src2w)) {+				compiler->imm = (src2w >> 16) & 0xffff;+				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);+			}+			if (TEST_UH_IMM(src1, src1w)) {+				compiler->imm = (src1w >> 16) & 0xffff;+				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);+			}+		}+		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);+			}+			if (TEST_UI_IMM(src1, src1w)) {+				compiler->imm = src1w;+				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);+			}+		}+		return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);++	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;+#endif+		if (src2 & SLJIT_IMM) {+			compiler->imm = src2w;+			return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);+		}+		return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		if (FAST_IS_REG(src))+			FAIL_IF(push_inst(compiler, MTLR | S(src)));+		else {+			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);+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		return SLJIT_SUCCESS;+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+		return emit_prefetch(compiler, src, srcw);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++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 freg_map[reg];+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	return push_inst(compiler, *(sljit_ins*)instruction);+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */++#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))+#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw))+#else+#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw))++#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)+#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw))+#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw))+#else+#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw))+#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw))+#endif++#endif /* SLJIT_CONFIG_PPC_64 */++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)+{+	if (src & SLJIT_MEM) {+		/* We can ignore the temporary data store on the stack from caching point of view. */+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));+		src = TMP_FREG1;+	}++#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)+	op = GET_OPCODE(op);+	FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));++	if (op == SLJIT_CONV_SW_FROM_F64) {+		if (FAST_IS_REG(dst)) {+			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_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);+	}+#else+	FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));+#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_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);+	}++	SLJIT_ASSERT(dst & SLJIT_MEM);++	if (dst & OFFS_REG_MASK) {+		dstw &= 0x3;+		if (dstw) {+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+			FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1)));+#else+			FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1)));+#endif+			dstw = TMP_REG1;+		}+		else+			dstw = OFFS_REG(dst);+	}+	else {+		if ((dst & REG_MASK) && !dstw) {+			dstw = dst & REG_MASK;+			dst = 0;+		}+		else {+			/* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */+			FAIL_IF(load_immediate(compiler, TMP_REG1, dstw));+			dstw = TMP_REG1;+		}+	}++	return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw));+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)++	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;++	if (src & SLJIT_IMM) {+		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)+			srcw = (sljit_s32)srcw;+		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));+		src = TMP_REG1;+	}+	else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {+		if (FAST_IS_REG(src))+			FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));+		else+			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_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_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_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;++#else++	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;+	sljit_s32 invert_sign = 1;++	if (src & SLJIT_IMM) {+		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000));+		src = TMP_REG1;+		invert_sign = 0;+	}+	else if (!FAST_IS_REG(src)) {+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));+		src = TMP_REG1;+	}++	/* First, a special double floating point value is constructed: (2^53 + (input xor (2^31)))+	   The double precision format has exactly 53 bit precision, so the lower 32 bit represents+	   the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000+	   to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating+	   point value, we need to substract 2^53 + 2^31 from the constructed value. */+	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_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_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_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;++#endif+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	if (src1 & SLJIT_MEM) {+		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_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));+		src2 = TMP_FREG2;+	}++	return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2));+}++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_s32 dst_r;++	CHECK_ERROR();++	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);++	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)+		op ^= SLJIT_F32_OP;++	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;++	if (src & SLJIT_MEM) {+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));+		src = dst_r;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_CONV_F64_FROM_F32:+		op ^= SLJIT_F32_OP;+		if (op & SLJIT_F32_OP) {+			FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));+			break;+		}+		/* Fall through. */+	case SLJIT_MOV_F64:+		if (src != dst_r) {+			if (dst_r != TMP_FREG1)+				FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));+			else+				dst_r = src;+		}+		break;+	case SLJIT_NEG_F64:+		FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src)));+		break;+	case SLJIT_ABS_F64:+		FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src)));+		break;+	}++	if (dst & SLJIT_MEM)+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));+	return SLJIT_SUCCESS;+}++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_s32 dst_r;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;++	if (src1 & SLJIT_MEM) {+		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_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));+		src2 = TMP_FREG2;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2)));+		break;++	case SLJIT_SUB_F64:+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2)));+		break;++	case SLJIT_MUL_F64:+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));+		break;++	case SLJIT_DIV_F64:+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2)));+		break;+	}++	if (dst & SLJIT_MEM)+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));++	return SLJIT_SUCCESS;+}++#undef SELECT_FOP++/* --------------------------------------------------------------------- */+/*  Other instructions                                                   */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	if (FAST_IS_REG(dst))+		return push_inst(compiler, MFLR | D(dst));++	/* Memory. */+	FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));+	return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	return label;+}++static sljit_ins get_bo_bi_flags(sljit_s32 type)+{+	switch (type) {+	case SLJIT_EQUAL:+		return (12 << 21) | (2 << 16);++	case SLJIT_NOT_EQUAL:+		return (4 << 21) | (2 << 16);++	case SLJIT_LESS:+	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);++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_MUL_NOT_OVERFLOW:+		return (4 << 21) | (3 << 16);++	case SLJIT_EQUAL_F64:+		return (12 << 21) | ((4 + 2) << 16);++	case SLJIT_NOT_EQUAL_F64:+		return (4 << 21) | ((4 + 2) << 16);++	case SLJIT_UNORDERED_F64:+		return (12 << 21) | ((4 + 3) << 16);++	case SLJIT_ORDERED_F64:+		return (4 << 21) | ((4 + 3) << 16);++	default:+		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);+		return (20 << 21);+	}+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;+	sljit_ins bo_bi_flags;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	bo_bi_flags = get_bo_bi_flags(type & 0xff);+	if (!bo_bi_flags)+		return NULL;++	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;++	/* In PPC, we don't need to touch the arguments. */+	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_CALL)+		jump->flags |= IS_CALL;+#endif++	PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));+	PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));+	jump->addr = compiler->size;+	PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));+	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;+	sljit_s32 src_r;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	if (FAST_IS_REG(src)) {+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)+		if (type >= SLJIT_CALL) {+			FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));+			src_r = TMP_CALL_REG;+		}+		else+			src_r = src;+#else+		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_CALL)+			jump->flags |= IS_CALL;+#endif+		FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));+		src_r = TMP_CALL_REG;+	}+	else {+		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));+		src_r = TMP_CALL_REG;+	}++	FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));+	if (jump)+		jump->addr = compiler->size;+	return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));+}++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_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 type)+{+	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, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++#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;++	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_LESS:+	case SLJIT_SIG_LESS:+		break;++	case SLJIT_GREATER_EQUAL:+	case SLJIT_SIG_GREATER_EQUAL:+		invert = 1;+		break;++	case SLJIT_GREATER:+	case SLJIT_SIG_GREATER:+		cr_bit = 1;+		break;++	case SLJIT_LESS_EQUAL:+	case SLJIT_SIG_LESS_EQUAL:+		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:+		cr_bit = 3;+		break;++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_MUL_NOT_OVERFLOW:+		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:+		cr_bit = 4 + 2;+		break;++	case SLJIT_NOT_EQUAL_F64:+		cr_bit = 4 + 2;+		invert = 1;+		break;++	case SLJIT_UNORDERED_F64:+		cr_bit = 4 + 3;+		break;++	case SLJIT_ORDERED_F64:+		cr_bit = 4 + 3;+		invert = 1;+		break;++	default:+		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 (!(dst & SLJIT_MEM))+			return SLJIT_SUCCESS;+		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+	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)+{+	struct sljit_const *const_;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;+	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));++	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 0);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)+	PTR_FAIL_IF(emit_const(compiler, dst_r, 0));+#else+	PTR_FAIL_IF(push_inst(compiler, dst_r));+	compiler->size += 4;+#endif++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));++	return put_label;+}
+ src/c/pcre2/src/sljit/sljitNativeSPARC_32.c view
@@ -0,0 +1,283 @@+/*+ *    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.+ */++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw imm)+{+	if (imm <= SIMM_MAX && imm >= SIMM_MIN)+		return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst));++	FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((imm >> 10) & 0x3fffff), DR(dst)));+	return (imm & 0x3ff) ? push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (imm & 0x3ff), DR(dst)) : SLJIT_SUCCESS;+}++#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2))++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_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same);++	switch (op) {+	case SLJIT_MOV:+	case SLJIT_MOV_U32:+	case SLJIT_MOV_S32:+	case SLJIT_MOV_P:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (dst != src2)+			return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst));+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U8:+	case SLJIT_MOV_S8:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_U8)+				return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst));+			FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst)));+			return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst));+		}+		else if (dst != src2)+			SLJIT_UNREACHABLE();+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U16:+	case SLJIT_MOV_S16:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst)));+			return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));+		}+		else if (dst != src2)+			SLJIT_UNREACHABLE();+		return SLJIT_SUCCESS;++	case SLJIT_NOT:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_CLZ:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		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 | 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 | 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));++	case SLJIT_ADDC:+		return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_SUB:+		return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_SUBC:+		return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_MUL:+		FAIL_IF(push_inst(compiler, SMUL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));+		if (!(flags & SET_FLAGS))+			return SLJIT_SUCCESS;+		FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1)));+		FAIL_IF(push_inst(compiler, RDY | D(TMP_LINK), DR(TMP_LINK)));+		return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS);++	case SLJIT_AND:+		return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_OR:+		return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_XOR:+		return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));++	case SLJIT_SHL:+		FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));+		return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);++	case SLJIT_LSHR:+		FAIL_IF(push_inst(compiler, SRL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));+		return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);++	case SLJIT_ASHR:+		FAIL_IF(push_inst(compiler, SRA | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));+		return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);+	}++	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;+}++static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)+{+	FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst)));+	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_target, sljit_sw executable_offset)+{+	sljit_ins *inst = (sljit_ins *)addr;+	SLJIT_UNUSED_ARG(executable_offset);++	SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);+	SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));+	inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);+	inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);+	SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);+	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_sw executable_offset)+{+	sljit_set_jump_addr(addr, new_constant, executable_offset);+}
+ src/c/pcre2/src/sljit/sljitNativeSPARC_common.c view
@@ -0,0 +1,1554 @@+/*+ *    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.+ */++SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)+{+	return "SPARC" SLJIT_CPUINFO;+}++/* Length of an instruction word+   Both for sparc-32 and sparc-64 */+typedef sljit_u32 sljit_ins;++#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)++static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)+{+#if defined(__SUNPRO_C) && __SUNPRO_C < 0x590+	__asm (+		/* if (from == to) return */+		"cmp %i0, %i1\n"+		"be .leave\n"+		"nop\n"++		/* loop until from >= to */+		".mainloop:\n"+		"flush %i0\n"+		"add %i0, 8, %i0\n"+		"cmp %i0, %i1\n"+		"bcs .mainloop\n"+		"nop\n"++		/* The comparison was done above. */+		"bne .leave\n"+		/* nop is not necessary here, since the+		   sub operation has no side effect. */+		"sub %i0, 4, %i0\n"+		"flush %i0\n"+		".leave:"+	);+#else+	if (SLJIT_UNLIKELY(from == to))+		return;++	do {+		__asm__ volatile (+			"flush %0\n"+			: : "r"(from)+		);+		/* Operates at least on doubleword. */+		from += 2;+	} while (from < to);++	if (from == to) {+		/* Flush the last word. */+		from --;+		__asm__ volatile (+			"flush %0\n"+			: : "r"(from)+		);+	}+#endif+}++#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */++/* TMP_REG2 is not used by getput_arg */+#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	(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, 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+};++/* --------------------------------------------------------------------- */+/*  Instrucion forms                                                     */+/* --------------------------------------------------------------------- */++#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 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)+#define IMM(imm)	(((imm) & 0x1fff) | IMM_ARG)++#define DR(dr)		(reg_map[dr])+#define OPC1(opcode)	((opcode) << 30)+#define OPC2(opcode)	((opcode) << 22)+#define OPC3(opcode)	((opcode) << 19)+#define SET_FLAGS	OPC3(0x10)++#define ADD		(OPC1(0x2) | OPC3(0x00))+#define ADDC		(OPC1(0x2) | OPC3(0x08))+#define AND		(OPC1(0x2) | OPC3(0x01))+#define ANDN		(OPC1(0x2) | OPC3(0x05))+#define CALL		(OPC1(0x1))+#define FABSS		(OPC1(0x2) | OPC3(0x34) | DOP(0x09))+#define FADDD		(OPC1(0x2) | OPC3(0x34) | DOP(0x42))+#define FADDS		(OPC1(0x2) | OPC3(0x34) | DOP(0x41))+#define FCMPD		(OPC1(0x2) | OPC3(0x35) | DOP(0x52))+#define FCMPS		(OPC1(0x2) | OPC3(0x35) | DOP(0x51))+#define FDIVD		(OPC1(0x2) | OPC3(0x34) | DOP(0x4e))+#define FDIVS		(OPC1(0x2) | OPC3(0x34) | DOP(0x4d))+#define FDTOI		(OPC1(0x2) | OPC3(0x34) | DOP(0xd2))+#define FDTOS		(OPC1(0x2) | OPC3(0x34) | DOP(0xc6))+#define FITOD		(OPC1(0x2) | OPC3(0x34) | DOP(0xc8))+#define FITOS		(OPC1(0x2) | OPC3(0x34) | DOP(0xc4))+#define FMOVS		(OPC1(0x2) | OPC3(0x34) | DOP(0x01))+#define FMULD		(OPC1(0x2) | OPC3(0x34) | DOP(0x4a))+#define FMULS		(OPC1(0x2) | OPC3(0x34) | DOP(0x49))+#define FNEGS		(OPC1(0x2) | OPC3(0x34) | DOP(0x05))+#define FSTOD		(OPC1(0x2) | OPC3(0x34) | DOP(0xc9))+#define FSTOI		(OPC1(0x2) | OPC3(0x34) | DOP(0xd1))+#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))+#define RDY		(OPC1(0x2) | OPC3(0x28) | S1A(0))+#define RESTORE		(OPC1(0x2) | OPC3(0x3d))+#define SAVE		(OPC1(0x2) | OPC3(0x3c))+#define SETHI		(OPC1(0x0) | OPC2(0x04))+#define SLL		(OPC1(0x2) | OPC3(0x25))+#define SLLX		(OPC1(0x2) | OPC3(0x25) | (1 << 12))+#define SRA		(OPC1(0x2) | OPC3(0x27))+#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))+#define WRY		(OPC1(0x2) | OPC3(0x30) | DA(0))+#define XOR		(OPC1(0x2) | OPC3(0x03))+#define XNOR		(OPC1(0x2) | OPC3(0x07))++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+#define MAX_DISP	(0x1fffff)+#define MIN_DISP	(-0x200000)+#define DISP_MASK	(0x3fffff)++#define BICC		(OPC1(0x0) | OPC2(0x2))+#define FBFCC		(OPC1(0x0) | OPC2(0x6))+#define SLL_W		SLL+#define SDIV		(OPC1(0x2) | OPC3(0x0f))+#define SMUL		(OPC1(0x2) | OPC3(0x0b))+#define UDIV		(OPC1(0x2) | OPC3(0x0e))+#define UMUL		(OPC1(0x2) | OPC3(0x0a))+#else+#define SLL_W		SLLX+#endif++#define SIMM_MAX	(0x0fff)+#define SIMM_MIN	(-0x1000)++/* dest_reg is the absolute name of the register+   Useful for reordering instructions in the delay slot. */+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)+{+	sljit_ins *ptr;+	SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS+		|| (delay_slot & DST_INS_MASK) == MOVABLE_INS+		|| (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));+	ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	compiler->delay_slot = delay_slot;+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)+{+	sljit_sw diff;+	sljit_uw target_addr;+	sljit_ins *inst;+	sljit_ins saved_inst;++	if (jump->flags & SLJIT_REWRITABLE_JUMP)+		return code_ptr;++	if (jump->flags & JUMP_ADDR)+		target_addr = jump->u.target;+	else {+		SLJIT_ASSERT(jump->flags & JUMP_LABEL);+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;+	}+	inst = (sljit_ins*)jump->addr;++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+	if (jump->flags & IS_CALL) {+		/* Call is always patchable on sparc 32. */+		jump->flags |= PATCH_CALL;+		if (jump->flags & IS_MOVABLE) {+			inst[0] = inst[-1];+			inst[-1] = CALL;+			jump->addr -= sizeof(sljit_ins);+			return inst;+		}+		inst[0] = CALL;+		inst[1] = NOP;+		return inst + 1;+	}+#else+	/* Both calls and BPr instructions shall not pass this point. */+#error "Implementation required"+#endif++	if (jump->flags & IS_COND)+		inst--;++	diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2;++	if (jump->flags & IS_MOVABLE) {+		if (diff <= MAX_DISP && diff >= MIN_DISP) {+			jump->flags |= PATCH_B;+			inst--;+			if (jump->flags & IS_COND) {+				saved_inst = inst[0];+				inst[0] = inst[1] ^ (1 << 28);+				inst[1] = saved_inst;+			} else {+				inst[1] = inst[0];+				inst[0] = BICC | DA(0x8);+			}+			jump->addr = (sljit_uw)inst;+			return inst + 1;+		}+	}++	diff += sizeof(sljit_ins);++	if (diff <= MAX_DISP && diff >= MIN_DISP) {+		jump->flags |= PATCH_B;+		if (jump->flags & IS_COND)+			inst[0] ^= (1 << 28);+		else+			inst[0] = BICC | DA(0x8);+		inst[1] = NOP;+		jump->addr = (sljit_uw)inst;+		return inst + 1;+	}++	return code_ptr;+}++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_ins *code;+	sljit_ins *code_ptr;+	sljit_ins *buf_ptr;+	sljit_ins *buf_end;+	sljit_uw word_count;+	sljit_uw next_addr;+	sljit_sw executable_offset;+	sljit_uw addr;++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	word_count = 0;+	next_addr = 0;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;++	do {+		buf_ptr = (sljit_ins*)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 2);+		do {+			*code_ptr = *buf_ptr++;+			if (next_addr == word_count) {+				SLJIT_ASSERT(!label || label->size >= word_count);+				SLJIT_ASSERT(!jump || jump->addr >= word_count);+				SLJIT_ASSERT(!const_ || const_->addr >= word_count);+				SLJIT_ASSERT(!put_label || put_label->addr >= word_count);++				/* These structures are ordered by their address. */+				if (label && label->size == word_count) {+					/* Just recording the address. */+					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) {+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+					jump->addr = (sljit_uw)(code_ptr - 3);+#else+					jump->addr = (sljit_uw)(code_ptr - 6);+#endif+					code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);+					jump = jump->next;+				}+				if (const_ && const_->addr == word_count) {+					/* Just recording the address. */+					const_->addr = (sljit_uw)code_ptr;+					const_ = const_->next;+				}+				if (put_label && put_label->addr == word_count) {+					SLJIT_ASSERT(put_label->label);+					put_label->addr = (sljit_uw)code_ptr;+					put_label = put_label->next;+				}+				next_addr = compute_next_addr(label, jump, const_, put_label);+			}+			code_ptr ++;+			word_count ++;+		} while (buf_ptr < buf_end);++		buf = buf->next;+	} while (buf);++	if (label && label->size == word_count) {+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);+		label->size = code_ptr - code;+		label = label->next;+	}++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);+	SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);++	jump = compiler->jumps;+	while (jump) {+		do {+			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;+			buf_ptr = (sljit_ins *)jump->addr;++			if (jump->flags & PATCH_CALL) {+				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 - (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;+			}++			/* Set the fields of immediate loads. */+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+			SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));+			buf_ptr[0] |= (addr >> 10) & 0x3fffff;+			buf_ptr[1] |= addr & 0x3ff;+#else+#error "Implementation required"+#endif+		} while (0);+		jump = jump->next;+	}++	put_label = compiler->put_labels;+	while (put_label) {+		addr = put_label->label->addr;+		buf_ptr = (sljit_ins *)put_label->addr;++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+		SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));+		buf_ptr[0] |= (addr >> 10) & 0x3fffff;+		buf_ptr[1] |= addr & 0x3ff;+#else+#error "Implementation required"+#endif+		put_label = put_label->next;+	}++	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);+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);+	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_ZERO_REGISTER:+		return 1;++#if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)+	case SLJIT_HAS_CMOV:+		return 1;+#endif++	default:+		return 0;+	}+}++/* --------------------------------------------------------------------- */+/*  Entry, exit                                                          */+/* --------------------------------------------------------------------- */++/* Creates an index in data_transfer_insts array. */+#define LOAD_DATA	0x01+#define WORD_DATA	0x00+#define BYTE_DATA	0x02+#define HALF_DATA	0x04+#define INT_DATA	0x06+#define SIGNED_DATA	0x08+/* Separates integer and floating point registers */+#define GPR_REG		0x0f+#define DOUBLE_DATA	0x10+#define SINGLE_DATA	0x12++#define MEM_MASK	0x1f++#define ARG_TEST	0x00020+#define ALT_KEEP_CACHE	0x00040+#define CUMULATIVE_OP	0x00080+#define IMM_OP		0x00100+#define SRC2_IMM	0x00200++#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! */++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+#include "sljitNativeSPARC_32.c"+#else+#include "sljitNativeSPARC_64.c"+#endif++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;+	compiler->local_size = local_size;++	if (local_size <= SIMM_MAX) {+		FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));+	}+	else {+		FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));+		FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));+	}++	/* Arguments are in their appropriate registers. */++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	CHECK_ERROR();+	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	if (op != SLJIT_MOV || !FAST_IS_REG(src)) {+		FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));+		src = SLJIT_R0;+	}++	FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));+	return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS);+}++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+#define ARCH_32_64(a, b)	a+#else+#define ARCH_32_64(a, b)	b+#endif++static const sljit_ins data_transfer_insts[16 + 4] = {+/* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),+/* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),+/* u b s */ OPC1(3) | OPC3(0x05) /* stb */,+/* u b l */ OPC1(3) | OPC3(0x01) /* ldub */,+/* u h s */ OPC1(3) | OPC3(0x06) /* sth */,+/* u h l */ OPC1(3) | OPC3(0x02) /* lduh */,+/* u i s */ OPC1(3) | OPC3(0x04) /* stw */,+/* u i l */ OPC1(3) | OPC3(0x00) /* lduw */,++/* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),+/* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),+/* s b s */ OPC1(3) | OPC3(0x05) /* stb */,+/* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */,+/* s h s */ OPC1(3) | OPC3(0x06) /* sth */,+/* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */,+/* s i s */ OPC1(3) | OPC3(0x04) /* stw */,+/* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */),++/* d   s */ OPC1(3) | OPC3(0x27),+/* d   l */ OPC1(3) | OPC3(0x23),+/* s   s */ OPC1(3) | OPC3(0x24),+/* s   l */ OPC1(3) | OPC3(0x20),+};++#undef ARCH_32_64++/* 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)+{+	SLJIT_ASSERT(arg & SLJIT_MEM);++	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;+}++/* 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_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));++	/* Simple operation except for updates. */+	if (arg & OFFS_REG_MASK) {+		argw &= 0x3;+		SLJIT_ASSERT(argw);+		next_argw &= 0x3;+		if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw)+			return 1;+		return 0;+	}++	if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))+		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 base, arg2, delay_slot;+	sljit_ins dest;++	SLJIT_ASSERT(arg & SLJIT_MEM);+	if (!(next_arg & SLJIT_MEM)) {+		next_arg = 0;+		next_argw = 0;+	}++	base = arg & REG_MASK;+	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {+		argw &= 0x3;++		/* Using the cache. */+		if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw))+			arg2 = 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;+				arg2 = TMP_REG3;+			}+			else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg))+				arg2 = reg;+			else /* It must be a mov operation, so tmp1 must be free to use. */+				arg2 = TMP_REG1;+			FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2)));+		}+	}+	else {+		/* Using the cache. */+		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, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));+				compiler->cache_argw = argw;+			}+			arg2 = TMP_REG3;+		} else {+			if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) {+				compiler->cache_arg = SLJIT_MEM;+				compiler->cache_argw = argw;+				arg2 = TMP_REG3;+			}+			else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base)+				arg2 = reg;+			else /* It must be a mov operation, so tmp1 must be free to use. */+				arg2 = TMP_REG1;+			FAIL_IF(load_immediate(compiler, arg2, argw));+		}+	}++	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);+	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)+{+	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);+}++static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,+	sljit_s32 dst, sljit_sw dstw,+	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. */+	sljit_s32 dst_r = TMP_REG2;+	sljit_s32 src1_r;+	sljit_sw src2_r = 0;+	sljit_s32 sugg_src2_r = TMP_REG2;++	if (!(flags & ALT_KEEP_CACHE)) {+		compiler->cache_arg = 0;+		compiler->cache_argw = 0;+	}++	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;+	}++	if (flags & IMM_OP) {+		if ((src2 & SLJIT_IMM) && src2w) {+			if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) {+				flags |= SRC2_IMM;+				src2_r = src2w;+			}+		}+		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {+			if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) {+				flags |= SRC2_IMM;+				src2_r = src1w;++				/* And swap arguments. */+				src1 = src2;+				src1w = src2w;+				src2 = SLJIT_IMM;+				/* src2w = src2_r unneeded. */+			}+		}+	}++	/* Source 1. */+	if (FAST_IS_REG(src1))+		src1_r = src1;+	else if (src1 & SLJIT_IMM) {+		if (src1w) {+			FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));+			src1_r = TMP_REG1;+		}+		else+			src1_r = 0;+	}+	else {+		if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))+			FAIL_IF(compiler->error);+		else+			flags |= SLOW_SRC1;+		src1_r = TMP_REG1;+	}++	/* Source 2. */+	if (FAST_IS_REG(src2)) {+		src2_r = src2;+		flags |= REG2_SOURCE;+		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)+			dst_r = src2_r;+	}+	else if (src2 & SLJIT_IMM) {+		if (!(flags & SRC2_IMM)) {+			if (src2w) {+				FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));+				src2_r = sugg_src2_r;+			}+			else {+				src2_r = 0;+				if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))+					dst_r = 0;+			}+		}+	}+	else {+		if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))+			FAIL_IF(compiler->error);+		else+			flags |= SLOW_SRC2;+		src2_r = sugg_src2_r;+	}++	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {+		SLJIT_ASSERT(src2_r == TMP_REG2);+		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));+		}+		else {+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));+		}+	}+	else if (flags & SLOW_SRC1)+		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));+	else if (flags & SLOW_SRC2)+		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));++	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));++	if (dst & SLJIT_MEM) {+		if (!(flags & SLOW_DEST)) {+			getput_arg_fast(compiler, flags, dst_r, dst, dstw);+			return compiler->error;+		}+		return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_BREAKPOINT:+		return push_inst(compiler, TA, UNMOVABLE_INS);+	case SLJIT_NOP:+		return push_inst(compiler, NOP, UNMOVABLE_INS);+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+		FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));+		return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));+#else+#error "Implementation required"+#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);+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+		if ((op | 0x2) == SLJIT_DIV_UW)+			FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));+		else {+			FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));+			FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));+		}+		if (op <= SLJIT_DIVMOD_SW)+			FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));+		FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));+		if (op >= SLJIT_DIV_UW)+			return SLJIT_SUCCESS;+		FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));+		return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));+#else+#error "Implementation required"+#endif+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++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)+{+	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);++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_MOV:+	case SLJIT_MOV_P:+		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_U32:+		return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_S32:+		return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_U8:+		return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);++	case SLJIT_MOV_S8:+		return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);++	case SLJIT_MOV_U16:+		return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);++	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_NOT:+	case SLJIT_CLZ:+		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_NEG:+		return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	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:+	case SLJIT_ADDC:+	case SLJIT_MUL:+	case SLJIT_AND:+	case SLJIT_OR:+	case SLJIT_XOR:+		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SUB:+	case SLJIT_SUBC:+		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SHL:+	case SLJIT_LSHR:+	case SLJIT_ASHR:+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+		if (src2 & SLJIT_IMM)+			src2w &= 0x1f;+#else+		SLJIT_UNREACHABLE();+#endif+		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		if (FAST_IS_REG(src))+			FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));+		else+			FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));++		FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));+		return push_inst(compiler, NOP, UNMOVABLE_INS);+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++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 freg_map[reg];+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */++#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))++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)+{+	if (src & SLJIT_MEM) {+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));+		src = TMP_FREG1;+	}++	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));+		return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET);+	}++	/* Store the integer value from a VFP register. */+	return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	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)+		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)+			srcw = (sljit_s32)srcw;+#endif+		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));+		src = TMP_REG1;+		srcw = 0;+	}++	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));+		src = SLJIT_MEM1(SLJIT_SP);+		srcw = FLOAT_TMP_MEM_OFFSET;+	}++	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) | 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);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src1, sljit_sw src1w,+	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));+		src1 = TMP_FREG1;+	}++	if (src2 & SLJIT_MEM) {+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));+		src2 = TMP_FREG2;+	}++	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,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 dst_r;++	CHECK_ERROR();+	compiler->cache_arg = 0;+	compiler->cache_argw = 0;++	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);+	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);++	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)+		op ^= SLJIT_F32_OP;++	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;+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV_F64:+		if (src != dst_r) {+			if (dst_r != TMP_FREG1) {+				FAIL_IF(push_inst(compiler, FMOVS | FD(dst_r) | FS2(src), MOVABLE_INS));+				if (!(op & SLJIT_F32_OP))+					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 | FD(dst_r) | FS2(src), MOVABLE_INS));+		if (dst_r != src && !(op & SLJIT_F32_OP))+			FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));+		break;+	case SLJIT_ABS_F64:+		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 | FDN(dst_r) | FS2N(src), MOVABLE_INS));+		break;+	case SLJIT_CONV_F64_FROM_F32:+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | FD(dst_r) | FS2(src), MOVABLE_INS));+		op ^= SLJIT_F32_OP;+		break;+	}++	if (dst & SLJIT_MEM)+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));+	return SLJIT_SUCCESS;+}++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_s32 dst_r, flags = 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	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 |= SLOW_SRC1;+	}++	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 |= 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, 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 & SLOW_SRC1)+		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, 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));++	if (flags & SLOW_SRC1)+		src1 = TMP_FREG1;+	if (flags & SLOW_SRC2)+		src2 = TMP_FREG2;++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		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) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));+		break;++	case SLJIT_MUL_F64:+		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) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));+		break;+	}++	if (dst_r == TMP_FREG2)+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));++	return SLJIT_SUCCESS;+}++#undef FLOAT_DATA+#undef SELECT_FOP++/* --------------------------------------------------------------------- */+/*  Other instructions                                                   */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	if (FAST_IS_REG(dst))+		return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), UNMOVABLE_INS);++	/* Memory. */+	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw));+	compiler->delay_slot = UNMOVABLE_INS;+	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	compiler->delay_slot = UNMOVABLE_INS;+	return label;+}++static sljit_ins get_cc(sljit_s32 type)+{+	switch (type) {+	case SLJIT_EQUAL:+	case SLJIT_MUL_NOT_OVERFLOW:+	case SLJIT_NOT_EQUAL_F64: /* Unordered. */+		return DA(0x1);++	case SLJIT_NOT_EQUAL:+	case SLJIT_MUL_OVERFLOW:+	case SLJIT_EQUAL_F64:+		return DA(0x9);++	case SLJIT_LESS:+	case SLJIT_GREATER_F64: /* Unordered. */+		return DA(0x5);++	case SLJIT_GREATER_EQUAL:+	case SLJIT_LESS_EQUAL_F64:+		return DA(0xd);++	case SLJIT_GREATER:+	case SLJIT_GREATER_EQUAL_F64: /* Unordered. */+		return DA(0xc);++	case SLJIT_LESS_EQUAL:+	case SLJIT_LESS_F64:+		return DA(0x4);++	case SLJIT_SIG_LESS:+		return DA(0x3);++	case SLJIT_SIG_GREATER_EQUAL:+		return DA(0xb);++	case SLJIT_SIG_GREATER:+		return DA(0xa);++	case SLJIT_SIG_LESS_EQUAL:+		return DA(0x2);++	case SLJIT_OVERFLOW:+	case SLJIT_UNORDERED_F64:+		return DA(0x7);++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_ORDERED_F64:+		return DA(0xf);++	default:+		SLJIT_UNREACHABLE();+		return DA(0x8);+	}+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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;++	if (type < SLJIT_EQUAL_F64) {+		jump->flags |= IS_COND;+		if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))+			jump->flags |= IS_MOVABLE;+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+		PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));+#else+#error "Implementation required"+#endif+	}+	else if (type < SLJIT_JUMP) {+		jump->flags |= IS_COND;+		if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET))+			jump->flags |= IS_MOVABLE;+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)+		PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));+#else+#error "Implementation required"+#endif+	}+	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_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;+	sljit_s32 src_r;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	if (FAST_IS_REG(src))+		src_r = src;+	else if (src & SLJIT_IMM) {+		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 ((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_REG1, 0));+		src_r = TMP_REG1;+	}+	else {+		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));+	if (jump)+		jump->addr = compiler->size;+	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 type)+{+	sljit_s32 reg, flags = HAS_FLAGS(op) ? SET_FLAGS : 0;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++#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 && (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)+		FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));+	else+		FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));++	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) {+		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);+	}++	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+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)+{+	struct sljit_const *const_;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;+	PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));+	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_s32 dst_r;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 0);++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;+	PTR_FAIL_IF(emit_const(compiler, dst_r, 0));++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));+	return put_label;+}
+ src/c/pcre2/src/sljit/sljitNativeTILEGX-encoder.c view
@@ -0,0 +1,10159 @@+/*+ *    Stack-less Just-In-Time compiler+ *+ *    Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). 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:+ *+ *   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 code is owned by Tilera Corporation, and distributed as part+   of multiple projects. In sljit, the code is under BSD licence.  */++#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#define BFD_RELOC(x) R_##x++/* Special registers. */+#define TREG_LR 55+#define TREG_SN 56+#define TREG_ZERO 63++/* Canonical name of each register. */+const char *const tilegx_register_names[] =+{+  "r0",   "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",+  "r8",   "r9",  "r10", "r11", "r12", "r13", "r14", "r15",+  "r16",  "r17", "r18", "r19", "r20", "r21", "r22", "r23",+  "r24",  "r25", "r26", "r27", "r28", "r29", "r30", "r31",+  "r32",  "r33", "r34", "r35", "r36", "r37", "r38", "r39",+  "r40",  "r41", "r42", "r43", "r44", "r45", "r46", "r47",+  "r48",  "r49", "r50", "r51", "r52", "tp",  "sp",  "lr",+  "sn",  "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero"+};++enum+{+  R_NONE = 0,+  R_TILEGX_NONE = 0,+  R_TILEGX_64 = 1,+  R_TILEGX_32 = 2,+  R_TILEGX_16 = 3,+  R_TILEGX_8 = 4,+  R_TILEGX_64_PCREL = 5,+  R_TILEGX_32_PCREL = 6,+  R_TILEGX_16_PCREL = 7,+  R_TILEGX_8_PCREL = 8,+  R_TILEGX_HW0 = 9,+  R_TILEGX_HW1 = 10,+  R_TILEGX_HW2 = 11,+  R_TILEGX_HW3 = 12,+  R_TILEGX_HW0_LAST = 13,+  R_TILEGX_HW1_LAST = 14,+  R_TILEGX_HW2_LAST = 15,+  R_TILEGX_COPY = 16,+  R_TILEGX_GLOB_DAT = 17,+  R_TILEGX_JMP_SLOT = 18,+  R_TILEGX_RELATIVE = 19,+  R_TILEGX_BROFF_X1 = 20,+  R_TILEGX_JUMPOFF_X1 = 21,+  R_TILEGX_JUMPOFF_X1_PLT = 22,+  R_TILEGX_IMM8_X0 = 23,+  R_TILEGX_IMM8_Y0 = 24,+  R_TILEGX_IMM8_X1 = 25,+  R_TILEGX_IMM8_Y1 = 26,+  R_TILEGX_DEST_IMM8_X1 = 27,+  R_TILEGX_MT_IMM14_X1 = 28,+  R_TILEGX_MF_IMM14_X1 = 29,+  R_TILEGX_MMSTART_X0 = 30,+  R_TILEGX_MMEND_X0 = 31,+  R_TILEGX_SHAMT_X0 = 32,+  R_TILEGX_SHAMT_X1 = 33,+  R_TILEGX_SHAMT_Y0 = 34,+  R_TILEGX_SHAMT_Y1 = 35,+  R_TILEGX_IMM16_X0_HW0 = 36,+  R_TILEGX_IMM16_X1_HW0 = 37,+  R_TILEGX_IMM16_X0_HW1 = 38,+  R_TILEGX_IMM16_X1_HW1 = 39,+  R_TILEGX_IMM16_X0_HW2 = 40,+  R_TILEGX_IMM16_X1_HW2 = 41,+  R_TILEGX_IMM16_X0_HW3 = 42,+  R_TILEGX_IMM16_X1_HW3 = 43,+  R_TILEGX_IMM16_X0_HW0_LAST = 44,+  R_TILEGX_IMM16_X1_HW0_LAST = 45,+  R_TILEGX_IMM16_X0_HW1_LAST = 46,+  R_TILEGX_IMM16_X1_HW1_LAST = 47,+  R_TILEGX_IMM16_X0_HW2_LAST = 48,+  R_TILEGX_IMM16_X1_HW2_LAST = 49,+  R_TILEGX_IMM16_X0_HW0_PCREL = 50,+  R_TILEGX_IMM16_X1_HW0_PCREL = 51,+  R_TILEGX_IMM16_X0_HW1_PCREL = 52,+  R_TILEGX_IMM16_X1_HW1_PCREL = 53,+  R_TILEGX_IMM16_X0_HW2_PCREL = 54,+  R_TILEGX_IMM16_X1_HW2_PCREL = 55,+  R_TILEGX_IMM16_X0_HW3_PCREL = 56,+  R_TILEGX_IMM16_X1_HW3_PCREL = 57,+  R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58,+  R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59,+  R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60,+  R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61,+  R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62,+  R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63,+  R_TILEGX_IMM16_X0_HW0_GOT = 64,+  R_TILEGX_IMM16_X1_HW0_GOT = 65,++  R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66,+  R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67,+  R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68,+  R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69,+  R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70,+  R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71,++  R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72,+  R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73,+  R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74,+  R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75,+  R_TILEGX_IMM16_X0_HW0_TLS_GD = 78,+  R_TILEGX_IMM16_X1_HW0_TLS_GD = 79,+  R_TILEGX_IMM16_X0_HW0_TLS_LE = 80,+  R_TILEGX_IMM16_X1_HW0_TLS_LE = 81,+  R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82,+  R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83,+  R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84,+  R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85,+  R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86,+  R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87,+  R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88,+  R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89,+  R_TILEGX_IMM16_X0_HW0_TLS_IE = 92,+  R_TILEGX_IMM16_X1_HW0_TLS_IE = 93,++  R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94,+  R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95,+  R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96,+  R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97,+  R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98,+  R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99,++  R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100,+  R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101,+  R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102,+  R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103,+  R_TILEGX_TLS_DTPMOD64 = 106,+  R_TILEGX_TLS_DTPOFF64 = 107,+  R_TILEGX_TLS_TPOFF64 = 108,+  R_TILEGX_TLS_DTPMOD32 = 109,+  R_TILEGX_TLS_DTPOFF32 = 110,+  R_TILEGX_TLS_TPOFF32 = 111,+  R_TILEGX_TLS_GD_CALL = 112,+  R_TILEGX_IMM8_X0_TLS_GD_ADD = 113,+  R_TILEGX_IMM8_X1_TLS_GD_ADD = 114,+  R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115,+  R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116,+  R_TILEGX_TLS_IE_LOAD = 117,+  R_TILEGX_IMM8_X0_TLS_ADD = 118,+  R_TILEGX_IMM8_X1_TLS_ADD = 119,+  R_TILEGX_IMM8_Y0_TLS_ADD = 120,+  R_TILEGX_IMM8_Y1_TLS_ADD = 121,+  R_TILEGX_GNU_VTINHERIT = 128,+  R_TILEGX_GNU_VTENTRY = 129,+  R_TILEGX_IRELATIVE = 130,+  R_TILEGX_NUM = 131+};++typedef enum+{+  TILEGX_PIPELINE_X0,+  TILEGX_PIPELINE_X1,+  TILEGX_PIPELINE_Y0,+  TILEGX_PIPELINE_Y1,+  TILEGX_PIPELINE_Y2,+} tilegx_pipeline;++typedef unsigned long long tilegx_bundle_bits;++/* These are the bits that determine if a bundle is in the X encoding. */+#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)++enum+{+  /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */+  TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,++  /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */+  TILEGX_NUM_PIPELINE_ENCODINGS = 5,++  /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */+  TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,++  /* Instructions take this many bytes. */+  TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,++  /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,++  /* Bundles should be aligned modulo this number of bytes. */+  TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =+    (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),++  /* Number of registers (some are magic, such as network I/O). */+  TILEGX_NUM_REGISTERS = 64,+};++/* Make a few "tile_" variables to simplify common code between+   architectures.  */++typedef tilegx_bundle_bits tile_bundle_bits;+#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES+#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES+#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES++/* 64-bit pattern for a { bpt ; nop } bundle. */+#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL++typedef enum+{+  TILEGX_OP_TYPE_REGISTER,+  TILEGX_OP_TYPE_IMMEDIATE,+  TILEGX_OP_TYPE_ADDRESS,+  TILEGX_OP_TYPE_SPR+} tilegx_operand_type;++struct tilegx_operand+{+  /* Is this operand a register, immediate or address? */+  tilegx_operand_type type;++  /* The default relocation type for this operand.  */+  signed int default_reloc : 16;++  /* How many bits is this value? (used for range checking) */+  unsigned int num_bits : 5;++  /* Is the value signed? (used for range checking) */+  unsigned int is_signed : 1;++  /* Is this operand a source register? */+  unsigned int is_src_reg : 1;++  /* Is this operand written? (i.e. is it a destination register) */+  unsigned int is_dest_reg : 1;++  /* Is this operand PC-relative? */+  unsigned int is_pc_relative : 1;++  /* By how many bits do we right shift the value before inserting? */+  unsigned int rightshift : 2;++  /* Return the bits for this operand to be ORed into an existing bundle. */+  tilegx_bundle_bits (*insert) (int op);++  /* Extract this operand and return it. */+  unsigned int (*extract) (tilegx_bundle_bits bundle);+};++typedef enum+{+  TILEGX_OPC_BPT,+  TILEGX_OPC_INFO,+  TILEGX_OPC_INFOL,+  TILEGX_OPC_LD4S_TLS,+  TILEGX_OPC_LD_TLS,+  TILEGX_OPC_MOVE,+  TILEGX_OPC_MOVEI,+  TILEGX_OPC_MOVELI,+  TILEGX_OPC_PREFETCH,+  TILEGX_OPC_PREFETCH_ADD_L1,+  TILEGX_OPC_PREFETCH_ADD_L1_FAULT,+  TILEGX_OPC_PREFETCH_ADD_L2,+  TILEGX_OPC_PREFETCH_ADD_L2_FAULT,+  TILEGX_OPC_PREFETCH_ADD_L3,+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  TILEGX_OPC_PREFETCH_L1,+  TILEGX_OPC_PREFETCH_L1_FAULT,+  TILEGX_OPC_PREFETCH_L2,+  TILEGX_OPC_PREFETCH_L2_FAULT,+  TILEGX_OPC_PREFETCH_L3,+  TILEGX_OPC_PREFETCH_L3_FAULT,+  TILEGX_OPC_RAISE,+  TILEGX_OPC_ADD,+  TILEGX_OPC_ADDI,+  TILEGX_OPC_ADDLI,+  TILEGX_OPC_ADDX,+  TILEGX_OPC_ADDXI,+  TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXSC,+  TILEGX_OPC_AND,+  TILEGX_OPC_ANDI,+  TILEGX_OPC_BEQZ,+  TILEGX_OPC_BEQZT,+  TILEGX_OPC_BFEXTS,+  TILEGX_OPC_BFEXTU,+  TILEGX_OPC_BFINS,+  TILEGX_OPC_BGEZ,+  TILEGX_OPC_BGEZT,+  TILEGX_OPC_BGTZ,+  TILEGX_OPC_BGTZT,+  TILEGX_OPC_BLBC,+  TILEGX_OPC_BLBCT,+  TILEGX_OPC_BLBS,+  TILEGX_OPC_BLBST,+  TILEGX_OPC_BLEZ,+  TILEGX_OPC_BLEZT,+  TILEGX_OPC_BLTZ,+  TILEGX_OPC_BLTZT,+  TILEGX_OPC_BNEZ,+  TILEGX_OPC_BNEZT,+  TILEGX_OPC_CLZ,+  TILEGX_OPC_CMOVEQZ,+  TILEGX_OPC_CMOVNEZ,+  TILEGX_OPC_CMPEQ,+  TILEGX_OPC_CMPEQI,+  TILEGX_OPC_CMPEXCH,+  TILEGX_OPC_CMPEXCH4,+  TILEGX_OPC_CMPLES,+  TILEGX_OPC_CMPLEU,+  TILEGX_OPC_CMPLTS,+  TILEGX_OPC_CMPLTSI,+  TILEGX_OPC_CMPLTU,+  TILEGX_OPC_CMPLTUI,+  TILEGX_OPC_CMPNE,+  TILEGX_OPC_CMUL,+  TILEGX_OPC_CMULA,+  TILEGX_OPC_CMULAF,+  TILEGX_OPC_CMULF,+  TILEGX_OPC_CMULFR,+  TILEGX_OPC_CMULH,+  TILEGX_OPC_CMULHR,+  TILEGX_OPC_CRC32_32,+  TILEGX_OPC_CRC32_8,+  TILEGX_OPC_CTZ,+  TILEGX_OPC_DBLALIGN,+  TILEGX_OPC_DBLALIGN2,+  TILEGX_OPC_DBLALIGN4,+  TILEGX_OPC_DBLALIGN6,+  TILEGX_OPC_DRAIN,+  TILEGX_OPC_DTLBPR,+  TILEGX_OPC_EXCH,+  TILEGX_OPC_EXCH4,+  TILEGX_OPC_FDOUBLE_ADD_FLAGS,+  TILEGX_OPC_FDOUBLE_ADDSUB,+  TILEGX_OPC_FDOUBLE_MUL_FLAGS,+  TILEGX_OPC_FDOUBLE_PACK1,+  TILEGX_OPC_FDOUBLE_PACK2,+  TILEGX_OPC_FDOUBLE_SUB_FLAGS,+  TILEGX_OPC_FDOUBLE_UNPACK_MAX,+  TILEGX_OPC_FDOUBLE_UNPACK_MIN,+  TILEGX_OPC_FETCHADD,+  TILEGX_OPC_FETCHADD4,+  TILEGX_OPC_FETCHADDGEZ,+  TILEGX_OPC_FETCHADDGEZ4,+  TILEGX_OPC_FETCHAND,+  TILEGX_OPC_FETCHAND4,+  TILEGX_OPC_FETCHOR,+  TILEGX_OPC_FETCHOR4,+  TILEGX_OPC_FINV,+  TILEGX_OPC_FLUSH,+  TILEGX_OPC_FLUSHWB,+  TILEGX_OPC_FNOP,+  TILEGX_OPC_FSINGLE_ADD1,+  TILEGX_OPC_FSINGLE_ADDSUB2,+  TILEGX_OPC_FSINGLE_MUL1,+  TILEGX_OPC_FSINGLE_MUL2,+  TILEGX_OPC_FSINGLE_PACK1,+  TILEGX_OPC_FSINGLE_PACK2,+  TILEGX_OPC_FSINGLE_SUB1,+  TILEGX_OPC_ICOH,+  TILEGX_OPC_ILL,+  TILEGX_OPC_INV,+  TILEGX_OPC_IRET,+  TILEGX_OPC_J,+  TILEGX_OPC_JAL,+  TILEGX_OPC_JALR,+  TILEGX_OPC_JALRP,+  TILEGX_OPC_JR,+  TILEGX_OPC_JRP,+  TILEGX_OPC_LD,+  TILEGX_OPC_LD1S,+  TILEGX_OPC_LD1S_ADD,+  TILEGX_OPC_LD1U,+  TILEGX_OPC_LD1U_ADD,+  TILEGX_OPC_LD2S,+  TILEGX_OPC_LD2S_ADD,+  TILEGX_OPC_LD2U,+  TILEGX_OPC_LD2U_ADD,+  TILEGX_OPC_LD4S,+  TILEGX_OPC_LD4S_ADD,+  TILEGX_OPC_LD4U,+  TILEGX_OPC_LD4U_ADD,+  TILEGX_OPC_LD_ADD,+  TILEGX_OPC_LDNA,+  TILEGX_OPC_LDNA_ADD,+  TILEGX_OPC_LDNT,+  TILEGX_OPC_LDNT1S,+  TILEGX_OPC_LDNT1S_ADD,+  TILEGX_OPC_LDNT1U,+  TILEGX_OPC_LDNT1U_ADD,+  TILEGX_OPC_LDNT2S,+  TILEGX_OPC_LDNT2S_ADD,+  TILEGX_OPC_LDNT2U,+  TILEGX_OPC_LDNT2U_ADD,+  TILEGX_OPC_LDNT4S,+  TILEGX_OPC_LDNT4S_ADD,+  TILEGX_OPC_LDNT4U,+  TILEGX_OPC_LDNT4U_ADD,+  TILEGX_OPC_LDNT_ADD,+  TILEGX_OPC_LNK,+  TILEGX_OPC_MF,+  TILEGX_OPC_MFSPR,+  TILEGX_OPC_MM,+  TILEGX_OPC_MNZ,+  TILEGX_OPC_MTSPR,+  TILEGX_OPC_MUL_HS_HS,+  TILEGX_OPC_MUL_HS_HU,+  TILEGX_OPC_MUL_HS_LS,+  TILEGX_OPC_MUL_HS_LU,+  TILEGX_OPC_MUL_HU_HU,+  TILEGX_OPC_MUL_HU_LS,+  TILEGX_OPC_MUL_HU_LU,+  TILEGX_OPC_MUL_LS_LS,+  TILEGX_OPC_MUL_LS_LU,+  TILEGX_OPC_MUL_LU_LU,+  TILEGX_OPC_MULA_HS_HS,+  TILEGX_OPC_MULA_HS_HU,+  TILEGX_OPC_MULA_HS_LS,+  TILEGX_OPC_MULA_HS_LU,+  TILEGX_OPC_MULA_HU_HU,+  TILEGX_OPC_MULA_HU_LS,+  TILEGX_OPC_MULA_HU_LU,+  TILEGX_OPC_MULA_LS_LS,+  TILEGX_OPC_MULA_LS_LU,+  TILEGX_OPC_MULA_LU_LU,+  TILEGX_OPC_MULAX,+  TILEGX_OPC_MULX,+  TILEGX_OPC_MZ,+  TILEGX_OPC_NAP,+  TILEGX_OPC_NOP,+  TILEGX_OPC_NOR,+  TILEGX_OPC_OR,+  TILEGX_OPC_ORI,+  TILEGX_OPC_PCNT,+  TILEGX_OPC_REVBITS,+  TILEGX_OPC_REVBYTES,+  TILEGX_OPC_ROTL,+  TILEGX_OPC_ROTLI,+  TILEGX_OPC_SHL,+  TILEGX_OPC_SHL16INSLI,+  TILEGX_OPC_SHL1ADD,+  TILEGX_OPC_SHL1ADDX,+  TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL2ADDX,+  TILEGX_OPC_SHL3ADD,+  TILEGX_OPC_SHL3ADDX,+  TILEGX_OPC_SHLI,+  TILEGX_OPC_SHLX,+  TILEGX_OPC_SHLXI,+  TILEGX_OPC_SHRS,+  TILEGX_OPC_SHRSI,+  TILEGX_OPC_SHRU,+  TILEGX_OPC_SHRUI,+  TILEGX_OPC_SHRUX,+  TILEGX_OPC_SHRUXI,+  TILEGX_OPC_SHUFFLEBYTES,+  TILEGX_OPC_ST,+  TILEGX_OPC_ST1,+  TILEGX_OPC_ST1_ADD,+  TILEGX_OPC_ST2,+  TILEGX_OPC_ST2_ADD,+  TILEGX_OPC_ST4,+  TILEGX_OPC_ST4_ADD,+  TILEGX_OPC_ST_ADD,+  TILEGX_OPC_STNT,+  TILEGX_OPC_STNT1,+  TILEGX_OPC_STNT1_ADD,+  TILEGX_OPC_STNT2,+  TILEGX_OPC_STNT2_ADD,+  TILEGX_OPC_STNT4,+  TILEGX_OPC_STNT4_ADD,+  TILEGX_OPC_STNT_ADD,+  TILEGX_OPC_SUB,+  TILEGX_OPC_SUBX,+  TILEGX_OPC_SUBXSC,+  TILEGX_OPC_SWINT0,+  TILEGX_OPC_SWINT1,+  TILEGX_OPC_SWINT2,+  TILEGX_OPC_SWINT3,+  TILEGX_OPC_TBLIDXB0,+  TILEGX_OPC_TBLIDXB1,+  TILEGX_OPC_TBLIDXB2,+  TILEGX_OPC_TBLIDXB3,+  TILEGX_OPC_V1ADD,+  TILEGX_OPC_V1ADDI,+  TILEGX_OPC_V1ADDUC,+  TILEGX_OPC_V1ADIFFU,+  TILEGX_OPC_V1AVGU,+  TILEGX_OPC_V1CMPEQ,+  TILEGX_OPC_V1CMPEQI,+  TILEGX_OPC_V1CMPLES,+  TILEGX_OPC_V1CMPLEU,+  TILEGX_OPC_V1CMPLTS,+  TILEGX_OPC_V1CMPLTSI,+  TILEGX_OPC_V1CMPLTU,+  TILEGX_OPC_V1CMPLTUI,+  TILEGX_OPC_V1CMPNE,+  TILEGX_OPC_V1DDOTPU,+  TILEGX_OPC_V1DDOTPUA,+  TILEGX_OPC_V1DDOTPUS,+  TILEGX_OPC_V1DDOTPUSA,+  TILEGX_OPC_V1DOTP,+  TILEGX_OPC_V1DOTPA,+  TILEGX_OPC_V1DOTPU,+  TILEGX_OPC_V1DOTPUA,+  TILEGX_OPC_V1DOTPUS,+  TILEGX_OPC_V1DOTPUSA,+  TILEGX_OPC_V1INT_H,+  TILEGX_OPC_V1INT_L,+  TILEGX_OPC_V1MAXU,+  TILEGX_OPC_V1MAXUI,+  TILEGX_OPC_V1MINU,+  TILEGX_OPC_V1MINUI,+  TILEGX_OPC_V1MNZ,+  TILEGX_OPC_V1MULTU,+  TILEGX_OPC_V1MULU,+  TILEGX_OPC_V1MULUS,+  TILEGX_OPC_V1MZ,+  TILEGX_OPC_V1SADAU,+  TILEGX_OPC_V1SADU,+  TILEGX_OPC_V1SHL,+  TILEGX_OPC_V1SHLI,+  TILEGX_OPC_V1SHRS,+  TILEGX_OPC_V1SHRSI,+  TILEGX_OPC_V1SHRU,+  TILEGX_OPC_V1SHRUI,+  TILEGX_OPC_V1SUB,+  TILEGX_OPC_V1SUBUC,+  TILEGX_OPC_V2ADD,+  TILEGX_OPC_V2ADDI,+  TILEGX_OPC_V2ADDSC,+  TILEGX_OPC_V2ADIFFS,+  TILEGX_OPC_V2AVGS,+  TILEGX_OPC_V2CMPEQ,+  TILEGX_OPC_V2CMPEQI,+  TILEGX_OPC_V2CMPLES,+  TILEGX_OPC_V2CMPLEU,+  TILEGX_OPC_V2CMPLTS,+  TILEGX_OPC_V2CMPLTSI,+  TILEGX_OPC_V2CMPLTU,+  TILEGX_OPC_V2CMPLTUI,+  TILEGX_OPC_V2CMPNE,+  TILEGX_OPC_V2DOTP,+  TILEGX_OPC_V2DOTPA,+  TILEGX_OPC_V2INT_H,+  TILEGX_OPC_V2INT_L,+  TILEGX_OPC_V2MAXS,+  TILEGX_OPC_V2MAXSI,+  TILEGX_OPC_V2MINS,+  TILEGX_OPC_V2MINSI,+  TILEGX_OPC_V2MNZ,+  TILEGX_OPC_V2MULFSC,+  TILEGX_OPC_V2MULS,+  TILEGX_OPC_V2MULTS,+  TILEGX_OPC_V2MZ,+  TILEGX_OPC_V2PACKH,+  TILEGX_OPC_V2PACKL,+  TILEGX_OPC_V2PACKUC,+  TILEGX_OPC_V2SADAS,+  TILEGX_OPC_V2SADAU,+  TILEGX_OPC_V2SADS,+  TILEGX_OPC_V2SADU,+  TILEGX_OPC_V2SHL,+  TILEGX_OPC_V2SHLI,+  TILEGX_OPC_V2SHLSC,+  TILEGX_OPC_V2SHRS,+  TILEGX_OPC_V2SHRSI,+  TILEGX_OPC_V2SHRU,+  TILEGX_OPC_V2SHRUI,+  TILEGX_OPC_V2SUB,+  TILEGX_OPC_V2SUBSC,+  TILEGX_OPC_V4ADD,+  TILEGX_OPC_V4ADDSC,+  TILEGX_OPC_V4INT_H,+  TILEGX_OPC_V4INT_L,+  TILEGX_OPC_V4PACKSC,+  TILEGX_OPC_V4SHL,+  TILEGX_OPC_V4SHLSC,+  TILEGX_OPC_V4SHRS,+  TILEGX_OPC_V4SHRU,+  TILEGX_OPC_V4SUB,+  TILEGX_OPC_V4SUBSC,+  TILEGX_OPC_WH64,+  TILEGX_OPC_XOR,+  TILEGX_OPC_XORI,+  TILEGX_OPC_NONE+} tilegx_mnemonic;++enum+{+  TILEGX_MAX_OPERANDS = 4 /* bfexts */+};++struct tilegx_opcode+{+  /* The opcode mnemonic, e.g. "add" */+  const char *name;++  /* The enum value for this mnemonic. */+  tilegx_mnemonic mnemonic;++  /* A bit mask of which of the five pipes this instruction+     is compatible with:+     X0  0x01+     X1  0x02+     Y0  0x04+     Y1  0x08+     Y2  0x10 */+  unsigned char pipes;++  /* How many operands are there? */+  unsigned char num_operands;++  /* Which register does this write implicitly, or TREG_ZERO if none? */+  unsigned char implicitly_written_register;++  /* Can this be bundled with other instructions (almost always true). */+  unsigned char can_bundle;++  /* The description of the operands. Each of these is an+   * index into the tilegx_operands[] table. */+  unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];++  /* A mask of which bits have predefined values for each pipeline.+   * This is useful for disassembly. */+  tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS];++  /* For each bit set in fixed_bit_masks, what the value is for this+   * instruction. */+  tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS];+};++/* Used for non-textual disassembly into structs. */+struct tilegx_decoded_instruction+{+  const struct tilegx_opcode *opcode;+  const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];+  long long operand_values[TILEGX_MAX_OPERANDS];+};++enum+{+  ADDI_IMM8_OPCODE_X0 = 1,+  ADDI_IMM8_OPCODE_X1 = 1,+  ADDI_OPCODE_Y0 = 0,+  ADDI_OPCODE_Y1 = 1,+  ADDLI_OPCODE_X0 = 1,+  ADDLI_OPCODE_X1 = 0,+  ADDXI_IMM8_OPCODE_X0 = 2,+  ADDXI_IMM8_OPCODE_X1 = 2,+  ADDXI_OPCODE_Y0 = 1,+  ADDXI_OPCODE_Y1 = 2,+  ADDXLI_OPCODE_X0 = 2,+  ADDXLI_OPCODE_X1 = 1,+  ADDXSC_RRR_0_OPCODE_X0 = 1,+  ADDXSC_RRR_0_OPCODE_X1 = 1,+  ADDX_RRR_0_OPCODE_X0 = 2,+  ADDX_RRR_0_OPCODE_X1 = 2,+  ADDX_RRR_0_OPCODE_Y0 = 0,+  ADDX_SPECIAL_0_OPCODE_Y1 = 0,+  ADD_RRR_0_OPCODE_X0 = 3,+  ADD_RRR_0_OPCODE_X1 = 3,+  ADD_RRR_0_OPCODE_Y0 = 1,+  ADD_SPECIAL_0_OPCODE_Y1 = 1,+  ANDI_IMM8_OPCODE_X0 = 3,+  ANDI_IMM8_OPCODE_X1 = 3,+  ANDI_OPCODE_Y0 = 2,+  ANDI_OPCODE_Y1 = 3,+  AND_RRR_0_OPCODE_X0 = 4,+  AND_RRR_0_OPCODE_X1 = 4,+  AND_RRR_5_OPCODE_Y0 = 0,+  AND_RRR_5_OPCODE_Y1 = 0,+  BEQZT_BRANCH_OPCODE_X1 = 16,+  BEQZ_BRANCH_OPCODE_X1 = 17,+  BFEXTS_BF_OPCODE_X0 = 4,+  BFEXTU_BF_OPCODE_X0 = 5,+  BFINS_BF_OPCODE_X0 = 6,+  BF_OPCODE_X0 = 3,+  BGEZT_BRANCH_OPCODE_X1 = 18,+  BGEZ_BRANCH_OPCODE_X1 = 19,+  BGTZT_BRANCH_OPCODE_X1 = 20,+  BGTZ_BRANCH_OPCODE_X1 = 21,+  BLBCT_BRANCH_OPCODE_X1 = 22,+  BLBC_BRANCH_OPCODE_X1 = 23,+  BLBST_BRANCH_OPCODE_X1 = 24,+  BLBS_BRANCH_OPCODE_X1 = 25,+  BLEZT_BRANCH_OPCODE_X1 = 26,+  BLEZ_BRANCH_OPCODE_X1 = 27,+  BLTZT_BRANCH_OPCODE_X1 = 28,+  BLTZ_BRANCH_OPCODE_X1 = 29,+  BNEZT_BRANCH_OPCODE_X1 = 30,+  BNEZ_BRANCH_OPCODE_X1 = 31,+  BRANCH_OPCODE_X1 = 2,+  CMOVEQZ_RRR_0_OPCODE_X0 = 5,+  CMOVEQZ_RRR_4_OPCODE_Y0 = 0,+  CMOVNEZ_RRR_0_OPCODE_X0 = 6,+  CMOVNEZ_RRR_4_OPCODE_Y0 = 1,+  CMPEQI_IMM8_OPCODE_X0 = 4,+  CMPEQI_IMM8_OPCODE_X1 = 4,+  CMPEQI_OPCODE_Y0 = 3,+  CMPEQI_OPCODE_Y1 = 4,+  CMPEQ_RRR_0_OPCODE_X0 = 7,+  CMPEQ_RRR_0_OPCODE_X1 = 5,+  CMPEQ_RRR_3_OPCODE_Y0 = 0,+  CMPEQ_RRR_3_OPCODE_Y1 = 2,+  CMPEXCH4_RRR_0_OPCODE_X1 = 6,+  CMPEXCH_RRR_0_OPCODE_X1 = 7,+  CMPLES_RRR_0_OPCODE_X0 = 8,+  CMPLES_RRR_0_OPCODE_X1 = 8,+  CMPLES_RRR_2_OPCODE_Y0 = 0,+  CMPLES_RRR_2_OPCODE_Y1 = 0,+  CMPLEU_RRR_0_OPCODE_X0 = 9,+  CMPLEU_RRR_0_OPCODE_X1 = 9,+  CMPLEU_RRR_2_OPCODE_Y0 = 1,+  CMPLEU_RRR_2_OPCODE_Y1 = 1,+  CMPLTSI_IMM8_OPCODE_X0 = 5,+  CMPLTSI_IMM8_OPCODE_X1 = 5,+  CMPLTSI_OPCODE_Y0 = 4,+  CMPLTSI_OPCODE_Y1 = 5,+  CMPLTS_RRR_0_OPCODE_X0 = 10,+  CMPLTS_RRR_0_OPCODE_X1 = 10,+  CMPLTS_RRR_2_OPCODE_Y0 = 2,+  CMPLTS_RRR_2_OPCODE_Y1 = 2,+  CMPLTUI_IMM8_OPCODE_X0 = 6,+  CMPLTUI_IMM8_OPCODE_X1 = 6,+  CMPLTU_RRR_0_OPCODE_X0 = 11,+  CMPLTU_RRR_0_OPCODE_X1 = 11,+  CMPLTU_RRR_2_OPCODE_Y0 = 3,+  CMPLTU_RRR_2_OPCODE_Y1 = 3,+  CMPNE_RRR_0_OPCODE_X0 = 12,+  CMPNE_RRR_0_OPCODE_X1 = 12,+  CMPNE_RRR_3_OPCODE_Y0 = 1,+  CMPNE_RRR_3_OPCODE_Y1 = 3,+  CMULAF_RRR_0_OPCODE_X0 = 13,+  CMULA_RRR_0_OPCODE_X0 = 14,+  CMULFR_RRR_0_OPCODE_X0 = 15,+  CMULF_RRR_0_OPCODE_X0 = 16,+  CMULHR_RRR_0_OPCODE_X0 = 17,+  CMULH_RRR_0_OPCODE_X0 = 18,+  CMUL_RRR_0_OPCODE_X0 = 19,+  CNTLZ_UNARY_OPCODE_X0 = 1,+  CNTLZ_UNARY_OPCODE_Y0 = 1,+  CNTTZ_UNARY_OPCODE_X0 = 2,+  CNTTZ_UNARY_OPCODE_Y0 = 2,+  CRC32_32_RRR_0_OPCODE_X0 = 20,+  CRC32_8_RRR_0_OPCODE_X0 = 21,+  DBLALIGN2_RRR_0_OPCODE_X0 = 22,+  DBLALIGN2_RRR_0_OPCODE_X1 = 13,+  DBLALIGN4_RRR_0_OPCODE_X0 = 23,+  DBLALIGN4_RRR_0_OPCODE_X1 = 14,+  DBLALIGN6_RRR_0_OPCODE_X0 = 24,+  DBLALIGN6_RRR_0_OPCODE_X1 = 15,+  DBLALIGN_RRR_0_OPCODE_X0 = 25,+  DRAIN_UNARY_OPCODE_X1 = 1,+  DTLBPR_UNARY_OPCODE_X1 = 2,+  EXCH4_RRR_0_OPCODE_X1 = 16,+  EXCH_RRR_0_OPCODE_X1 = 17,+  FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26,+  FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27,+  FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28,+  FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29,+  FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30,+  FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31,+  FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32,+  FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33,+  FETCHADD4_RRR_0_OPCODE_X1 = 18,+  FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19,+  FETCHADDGEZ_RRR_0_OPCODE_X1 = 20,+  FETCHADD_RRR_0_OPCODE_X1 = 21,+  FETCHAND4_RRR_0_OPCODE_X1 = 22,+  FETCHAND_RRR_0_OPCODE_X1 = 23,+  FETCHOR4_RRR_0_OPCODE_X1 = 24,+  FETCHOR_RRR_0_OPCODE_X1 = 25,+  FINV_UNARY_OPCODE_X1 = 3,+  FLUSHWB_UNARY_OPCODE_X1 = 4,+  FLUSH_UNARY_OPCODE_X1 = 5,+  FNOP_UNARY_OPCODE_X0 = 3,+  FNOP_UNARY_OPCODE_X1 = 6,+  FNOP_UNARY_OPCODE_Y0 = 3,+  FNOP_UNARY_OPCODE_Y1 = 8,+  FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34,+  FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35,+  FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36,+  FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37,+  FSINGLE_PACK1_UNARY_OPCODE_X0 = 4,+  FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4,+  FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38,+  FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39,+  ICOH_UNARY_OPCODE_X1 = 7,+  ILL_UNARY_OPCODE_X1 = 8,+  ILL_UNARY_OPCODE_Y1 = 9,+  IMM8_OPCODE_X0 = 4,+  IMM8_OPCODE_X1 = 3,+  INV_UNARY_OPCODE_X1 = 9,+  IRET_UNARY_OPCODE_X1 = 10,+  JALRP_UNARY_OPCODE_X1 = 11,+  JALRP_UNARY_OPCODE_Y1 = 10,+  JALR_UNARY_OPCODE_X1 = 12,+  JALR_UNARY_OPCODE_Y1 = 11,+  JAL_JUMP_OPCODE_X1 = 0,+  JRP_UNARY_OPCODE_X1 = 13,+  JRP_UNARY_OPCODE_Y1 = 12,+  JR_UNARY_OPCODE_X1 = 14,+  JR_UNARY_OPCODE_Y1 = 13,+  JUMP_OPCODE_X1 = 4,+  J_JUMP_OPCODE_X1 = 1,+  LD1S_ADD_IMM8_OPCODE_X1 = 7,+  LD1S_OPCODE_Y2 = 0,+  LD1S_UNARY_OPCODE_X1 = 15,+  LD1U_ADD_IMM8_OPCODE_X1 = 8,+  LD1U_OPCODE_Y2 = 1,+  LD1U_UNARY_OPCODE_X1 = 16,+  LD2S_ADD_IMM8_OPCODE_X1 = 9,+  LD2S_OPCODE_Y2 = 2,+  LD2S_UNARY_OPCODE_X1 = 17,+  LD2U_ADD_IMM8_OPCODE_X1 = 10,+  LD2U_OPCODE_Y2 = 3,+  LD2U_UNARY_OPCODE_X1 = 18,+  LD4S_ADD_IMM8_OPCODE_X1 = 11,+  LD4S_OPCODE_Y2 = 1,+  LD4S_UNARY_OPCODE_X1 = 19,+  LD4U_ADD_IMM8_OPCODE_X1 = 12,+  LD4U_OPCODE_Y2 = 2,+  LD4U_UNARY_OPCODE_X1 = 20,+  LDNA_UNARY_OPCODE_X1 = 21,+  LDNT1S_ADD_IMM8_OPCODE_X1 = 13,+  LDNT1S_UNARY_OPCODE_X1 = 22,+  LDNT1U_ADD_IMM8_OPCODE_X1 = 14,+  LDNT1U_UNARY_OPCODE_X1 = 23,+  LDNT2S_ADD_IMM8_OPCODE_X1 = 15,+  LDNT2S_UNARY_OPCODE_X1 = 24,+  LDNT2U_ADD_IMM8_OPCODE_X1 = 16,+  LDNT2U_UNARY_OPCODE_X1 = 25,+  LDNT4S_ADD_IMM8_OPCODE_X1 = 17,+  LDNT4S_UNARY_OPCODE_X1 = 26,+  LDNT4U_ADD_IMM8_OPCODE_X1 = 18,+  LDNT4U_UNARY_OPCODE_X1 = 27,+  LDNT_ADD_IMM8_OPCODE_X1 = 19,+  LDNT_UNARY_OPCODE_X1 = 28,+  LD_ADD_IMM8_OPCODE_X1 = 20,+  LD_OPCODE_Y2 = 3,+  LD_UNARY_OPCODE_X1 = 29,+  LNK_UNARY_OPCODE_X1 = 30,+  LNK_UNARY_OPCODE_Y1 = 14,+  LWNA_ADD_IMM8_OPCODE_X1 = 21,+  MFSPR_IMM8_OPCODE_X1 = 22,+  MF_UNARY_OPCODE_X1 = 31,+  MM_BF_OPCODE_X0 = 7,+  MNZ_RRR_0_OPCODE_X0 = 40,+  MNZ_RRR_0_OPCODE_X1 = 26,+  MNZ_RRR_4_OPCODE_Y0 = 2,+  MNZ_RRR_4_OPCODE_Y1 = 2,+  MODE_OPCODE_YA2 = 1,+  MODE_OPCODE_YB2 = 2,+  MODE_OPCODE_YC2 = 3,+  MTSPR_IMM8_OPCODE_X1 = 23,+  MULAX_RRR_0_OPCODE_X0 = 41,+  MULAX_RRR_3_OPCODE_Y0 = 2,+  MULA_HS_HS_RRR_0_OPCODE_X0 = 42,+  MULA_HS_HS_RRR_9_OPCODE_Y0 = 0,+  MULA_HS_HU_RRR_0_OPCODE_X0 = 43,+  MULA_HS_LS_RRR_0_OPCODE_X0 = 44,+  MULA_HS_LU_RRR_0_OPCODE_X0 = 45,+  MULA_HU_HU_RRR_0_OPCODE_X0 = 46,+  MULA_HU_HU_RRR_9_OPCODE_Y0 = 1,+  MULA_HU_LS_RRR_0_OPCODE_X0 = 47,+  MULA_HU_LU_RRR_0_OPCODE_X0 = 48,+  MULA_LS_LS_RRR_0_OPCODE_X0 = 49,+  MULA_LS_LS_RRR_9_OPCODE_Y0 = 2,+  MULA_LS_LU_RRR_0_OPCODE_X0 = 50,+  MULA_LU_LU_RRR_0_OPCODE_X0 = 51,+  MULA_LU_LU_RRR_9_OPCODE_Y0 = 3,+  MULX_RRR_0_OPCODE_X0 = 52,+  MULX_RRR_3_OPCODE_Y0 = 3,+  MUL_HS_HS_RRR_0_OPCODE_X0 = 53,+  MUL_HS_HS_RRR_8_OPCODE_Y0 = 0,+  MUL_HS_HU_RRR_0_OPCODE_X0 = 54,+  MUL_HS_LS_RRR_0_OPCODE_X0 = 55,+  MUL_HS_LU_RRR_0_OPCODE_X0 = 56,+  MUL_HU_HU_RRR_0_OPCODE_X0 = 57,+  MUL_HU_HU_RRR_8_OPCODE_Y0 = 1,+  MUL_HU_LS_RRR_0_OPCODE_X0 = 58,+  MUL_HU_LU_RRR_0_OPCODE_X0 = 59,+  MUL_LS_LS_RRR_0_OPCODE_X0 = 60,+  MUL_LS_LS_RRR_8_OPCODE_Y0 = 2,+  MUL_LS_LU_RRR_0_OPCODE_X0 = 61,+  MUL_LU_LU_RRR_0_OPCODE_X0 = 62,+  MUL_LU_LU_RRR_8_OPCODE_Y0 = 3,+  MZ_RRR_0_OPCODE_X0 = 63,+  MZ_RRR_0_OPCODE_X1 = 27,+  MZ_RRR_4_OPCODE_Y0 = 3,+  MZ_RRR_4_OPCODE_Y1 = 3,+  NAP_UNARY_OPCODE_X1 = 32,+  NOP_UNARY_OPCODE_X0 = 5,+  NOP_UNARY_OPCODE_X1 = 33,+  NOP_UNARY_OPCODE_Y0 = 5,+  NOP_UNARY_OPCODE_Y1 = 15,+  NOR_RRR_0_OPCODE_X0 = 64,+  NOR_RRR_0_OPCODE_X1 = 28,+  NOR_RRR_5_OPCODE_Y0 = 1,+  NOR_RRR_5_OPCODE_Y1 = 1,+  ORI_IMM8_OPCODE_X0 = 7,+  ORI_IMM8_OPCODE_X1 = 24,+  OR_RRR_0_OPCODE_X0 = 65,+  OR_RRR_0_OPCODE_X1 = 29,+  OR_RRR_5_OPCODE_Y0 = 2,+  OR_RRR_5_OPCODE_Y1 = 2,+  PCNT_UNARY_OPCODE_X0 = 6,+  PCNT_UNARY_OPCODE_Y0 = 6,+  REVBITS_UNARY_OPCODE_X0 = 7,+  REVBITS_UNARY_OPCODE_Y0 = 7,+  REVBYTES_UNARY_OPCODE_X0 = 8,+  REVBYTES_UNARY_OPCODE_Y0 = 8,+  ROTLI_SHIFT_OPCODE_X0 = 1,+  ROTLI_SHIFT_OPCODE_X1 = 1,+  ROTLI_SHIFT_OPCODE_Y0 = 0,+  ROTLI_SHIFT_OPCODE_Y1 = 0,+  ROTL_RRR_0_OPCODE_X0 = 66,+  ROTL_RRR_0_OPCODE_X1 = 30,+  ROTL_RRR_6_OPCODE_Y0 = 0,+  ROTL_RRR_6_OPCODE_Y1 = 0,+  RRR_0_OPCODE_X0 = 5,+  RRR_0_OPCODE_X1 = 5,+  RRR_0_OPCODE_Y0 = 5,+  RRR_0_OPCODE_Y1 = 6,+  RRR_1_OPCODE_Y0 = 6,+  RRR_1_OPCODE_Y1 = 7,+  RRR_2_OPCODE_Y0 = 7,+  RRR_2_OPCODE_Y1 = 8,+  RRR_3_OPCODE_Y0 = 8,+  RRR_3_OPCODE_Y1 = 9,+  RRR_4_OPCODE_Y0 = 9,+  RRR_4_OPCODE_Y1 = 10,+  RRR_5_OPCODE_Y0 = 10,+  RRR_5_OPCODE_Y1 = 11,+  RRR_6_OPCODE_Y0 = 11,+  RRR_6_OPCODE_Y1 = 12,+  RRR_7_OPCODE_Y0 = 12,+  RRR_7_OPCODE_Y1 = 13,+  RRR_8_OPCODE_Y0 = 13,+  RRR_9_OPCODE_Y0 = 14,+  SHIFT_OPCODE_X0 = 6,+  SHIFT_OPCODE_X1 = 6,+  SHIFT_OPCODE_Y0 = 15,+  SHIFT_OPCODE_Y1 = 14,+  SHL16INSLI_OPCODE_X0 = 7,+  SHL16INSLI_OPCODE_X1 = 7,+  SHL1ADDX_RRR_0_OPCODE_X0 = 67,+  SHL1ADDX_RRR_0_OPCODE_X1 = 31,+  SHL1ADDX_RRR_7_OPCODE_Y0 = 1,+  SHL1ADDX_RRR_7_OPCODE_Y1 = 1,+  SHL1ADD_RRR_0_OPCODE_X0 = 68,+  SHL1ADD_RRR_0_OPCODE_X1 = 32,+  SHL1ADD_RRR_1_OPCODE_Y0 = 0,+  SHL1ADD_RRR_1_OPCODE_Y1 = 0,+  SHL2ADDX_RRR_0_OPCODE_X0 = 69,+  SHL2ADDX_RRR_0_OPCODE_X1 = 33,+  SHL2ADDX_RRR_7_OPCODE_Y0 = 2,+  SHL2ADDX_RRR_7_OPCODE_Y1 = 2,+  SHL2ADD_RRR_0_OPCODE_X0 = 70,+  SHL2ADD_RRR_0_OPCODE_X1 = 34,+  SHL2ADD_RRR_1_OPCODE_Y0 = 1,+  SHL2ADD_RRR_1_OPCODE_Y1 = 1,+  SHL3ADDX_RRR_0_OPCODE_X0 = 71,+  SHL3ADDX_RRR_0_OPCODE_X1 = 35,+  SHL3ADDX_RRR_7_OPCODE_Y0 = 3,+  SHL3ADDX_RRR_7_OPCODE_Y1 = 3,+  SHL3ADD_RRR_0_OPCODE_X0 = 72,+  SHL3ADD_RRR_0_OPCODE_X1 = 36,+  SHL3ADD_RRR_1_OPCODE_Y0 = 2,+  SHL3ADD_RRR_1_OPCODE_Y1 = 2,+  SHLI_SHIFT_OPCODE_X0 = 2,+  SHLI_SHIFT_OPCODE_X1 = 2,+  SHLI_SHIFT_OPCODE_Y0 = 1,+  SHLI_SHIFT_OPCODE_Y1 = 1,+  SHLXI_SHIFT_OPCODE_X0 = 3,+  SHLXI_SHIFT_OPCODE_X1 = 3,+  SHLX_RRR_0_OPCODE_X0 = 73,+  SHLX_RRR_0_OPCODE_X1 = 37,+  SHL_RRR_0_OPCODE_X0 = 74,+  SHL_RRR_0_OPCODE_X1 = 38,+  SHL_RRR_6_OPCODE_Y0 = 1,+  SHL_RRR_6_OPCODE_Y1 = 1,+  SHRSI_SHIFT_OPCODE_X0 = 4,+  SHRSI_SHIFT_OPCODE_X1 = 4,+  SHRSI_SHIFT_OPCODE_Y0 = 2,+  SHRSI_SHIFT_OPCODE_Y1 = 2,+  SHRS_RRR_0_OPCODE_X0 = 75,+  SHRS_RRR_0_OPCODE_X1 = 39,+  SHRS_RRR_6_OPCODE_Y0 = 2,+  SHRS_RRR_6_OPCODE_Y1 = 2,+  SHRUI_SHIFT_OPCODE_X0 = 5,+  SHRUI_SHIFT_OPCODE_X1 = 5,+  SHRUI_SHIFT_OPCODE_Y0 = 3,+  SHRUI_SHIFT_OPCODE_Y1 = 3,+  SHRUXI_SHIFT_OPCODE_X0 = 6,+  SHRUXI_SHIFT_OPCODE_X1 = 6,+  SHRUX_RRR_0_OPCODE_X0 = 76,+  SHRUX_RRR_0_OPCODE_X1 = 40,+  SHRU_RRR_0_OPCODE_X0 = 77,+  SHRU_RRR_0_OPCODE_X1 = 41,+  SHRU_RRR_6_OPCODE_Y0 = 3,+  SHRU_RRR_6_OPCODE_Y1 = 3,+  SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78,+  ST1_ADD_IMM8_OPCODE_X1 = 25,+  ST1_OPCODE_Y2 = 0,+  ST1_RRR_0_OPCODE_X1 = 42,+  ST2_ADD_IMM8_OPCODE_X1 = 26,+  ST2_OPCODE_Y2 = 1,+  ST2_RRR_0_OPCODE_X1 = 43,+  ST4_ADD_IMM8_OPCODE_X1 = 27,+  ST4_OPCODE_Y2 = 2,+  ST4_RRR_0_OPCODE_X1 = 44,+  STNT1_ADD_IMM8_OPCODE_X1 = 28,+  STNT1_RRR_0_OPCODE_X1 = 45,+  STNT2_ADD_IMM8_OPCODE_X1 = 29,+  STNT2_RRR_0_OPCODE_X1 = 46,+  STNT4_ADD_IMM8_OPCODE_X1 = 30,+  STNT4_RRR_0_OPCODE_X1 = 47,+  STNT_ADD_IMM8_OPCODE_X1 = 31,+  STNT_RRR_0_OPCODE_X1 = 48,+  ST_ADD_IMM8_OPCODE_X1 = 32,+  ST_OPCODE_Y2 = 3,+  ST_RRR_0_OPCODE_X1 = 49,+  SUBXSC_RRR_0_OPCODE_X0 = 79,+  SUBXSC_RRR_0_OPCODE_X1 = 50,+  SUBX_RRR_0_OPCODE_X0 = 80,+  SUBX_RRR_0_OPCODE_X1 = 51,+  SUBX_RRR_0_OPCODE_Y0 = 2,+  SUBX_RRR_0_OPCODE_Y1 = 2,+  SUB_RRR_0_OPCODE_X0 = 81,+  SUB_RRR_0_OPCODE_X1 = 52,+  SUB_RRR_0_OPCODE_Y0 = 3,+  SUB_RRR_0_OPCODE_Y1 = 3,+  SWINT0_UNARY_OPCODE_X1 = 34,+  SWINT1_UNARY_OPCODE_X1 = 35,+  SWINT2_UNARY_OPCODE_X1 = 36,+  SWINT3_UNARY_OPCODE_X1 = 37,+  TBLIDXB0_UNARY_OPCODE_X0 = 9,+  TBLIDXB0_UNARY_OPCODE_Y0 = 9,+  TBLIDXB1_UNARY_OPCODE_X0 = 10,+  TBLIDXB1_UNARY_OPCODE_Y0 = 10,+  TBLIDXB2_UNARY_OPCODE_X0 = 11,+  TBLIDXB2_UNARY_OPCODE_Y0 = 11,+  TBLIDXB3_UNARY_OPCODE_X0 = 12,+  TBLIDXB3_UNARY_OPCODE_Y0 = 12,+  UNARY_RRR_0_OPCODE_X0 = 82,+  UNARY_RRR_0_OPCODE_X1 = 53,+  UNARY_RRR_1_OPCODE_Y0 = 3,+  UNARY_RRR_1_OPCODE_Y1 = 3,+  V1ADDI_IMM8_OPCODE_X0 = 8,+  V1ADDI_IMM8_OPCODE_X1 = 33,+  V1ADDUC_RRR_0_OPCODE_X0 = 83,+  V1ADDUC_RRR_0_OPCODE_X1 = 54,+  V1ADD_RRR_0_OPCODE_X0 = 84,+  V1ADD_RRR_0_OPCODE_X1 = 55,+  V1ADIFFU_RRR_0_OPCODE_X0 = 85,+  V1AVGU_RRR_0_OPCODE_X0 = 86,+  V1CMPEQI_IMM8_OPCODE_X0 = 9,+  V1CMPEQI_IMM8_OPCODE_X1 = 34,+  V1CMPEQ_RRR_0_OPCODE_X0 = 87,+  V1CMPEQ_RRR_0_OPCODE_X1 = 56,+  V1CMPLES_RRR_0_OPCODE_X0 = 88,+  V1CMPLES_RRR_0_OPCODE_X1 = 57,+  V1CMPLEU_RRR_0_OPCODE_X0 = 89,+  V1CMPLEU_RRR_0_OPCODE_X1 = 58,+  V1CMPLTSI_IMM8_OPCODE_X0 = 10,+  V1CMPLTSI_IMM8_OPCODE_X1 = 35,+  V1CMPLTS_RRR_0_OPCODE_X0 = 90,+  V1CMPLTS_RRR_0_OPCODE_X1 = 59,+  V1CMPLTUI_IMM8_OPCODE_X0 = 11,+  V1CMPLTUI_IMM8_OPCODE_X1 = 36,+  V1CMPLTU_RRR_0_OPCODE_X0 = 91,+  V1CMPLTU_RRR_0_OPCODE_X1 = 60,+  V1CMPNE_RRR_0_OPCODE_X0 = 92,+  V1CMPNE_RRR_0_OPCODE_X1 = 61,+  V1DDOTPUA_RRR_0_OPCODE_X0 = 161,+  V1DDOTPUSA_RRR_0_OPCODE_X0 = 93,+  V1DDOTPUS_RRR_0_OPCODE_X0 = 94,+  V1DDOTPU_RRR_0_OPCODE_X0 = 162,+  V1DOTPA_RRR_0_OPCODE_X0 = 95,+  V1DOTPUA_RRR_0_OPCODE_X0 = 163,+  V1DOTPUSA_RRR_0_OPCODE_X0 = 96,+  V1DOTPUS_RRR_0_OPCODE_X0 = 97,+  V1DOTPU_RRR_0_OPCODE_X0 = 164,+  V1DOTP_RRR_0_OPCODE_X0 = 98,+  V1INT_H_RRR_0_OPCODE_X0 = 99,+  V1INT_H_RRR_0_OPCODE_X1 = 62,+  V1INT_L_RRR_0_OPCODE_X0 = 100,+  V1INT_L_RRR_0_OPCODE_X1 = 63,+  V1MAXUI_IMM8_OPCODE_X0 = 12,+  V1MAXUI_IMM8_OPCODE_X1 = 37,+  V1MAXU_RRR_0_OPCODE_X0 = 101,+  V1MAXU_RRR_0_OPCODE_X1 = 64,+  V1MINUI_IMM8_OPCODE_X0 = 13,+  V1MINUI_IMM8_OPCODE_X1 = 38,+  V1MINU_RRR_0_OPCODE_X0 = 102,+  V1MINU_RRR_0_OPCODE_X1 = 65,+  V1MNZ_RRR_0_OPCODE_X0 = 103,+  V1MNZ_RRR_0_OPCODE_X1 = 66,+  V1MULTU_RRR_0_OPCODE_X0 = 104,+  V1MULUS_RRR_0_OPCODE_X0 = 105,+  V1MULU_RRR_0_OPCODE_X0 = 106,+  V1MZ_RRR_0_OPCODE_X0 = 107,+  V1MZ_RRR_0_OPCODE_X1 = 67,+  V1SADAU_RRR_0_OPCODE_X0 = 108,+  V1SADU_RRR_0_OPCODE_X0 = 109,+  V1SHLI_SHIFT_OPCODE_X0 = 7,+  V1SHLI_SHIFT_OPCODE_X1 = 7,+  V1SHL_RRR_0_OPCODE_X0 = 110,+  V1SHL_RRR_0_OPCODE_X1 = 68,+  V1SHRSI_SHIFT_OPCODE_X0 = 8,+  V1SHRSI_SHIFT_OPCODE_X1 = 8,+  V1SHRS_RRR_0_OPCODE_X0 = 111,+  V1SHRS_RRR_0_OPCODE_X1 = 69,+  V1SHRUI_SHIFT_OPCODE_X0 = 9,+  V1SHRUI_SHIFT_OPCODE_X1 = 9,+  V1SHRU_RRR_0_OPCODE_X0 = 112,+  V1SHRU_RRR_0_OPCODE_X1 = 70,+  V1SUBUC_RRR_0_OPCODE_X0 = 113,+  V1SUBUC_RRR_0_OPCODE_X1 = 71,+  V1SUB_RRR_0_OPCODE_X0 = 114,+  V1SUB_RRR_0_OPCODE_X1 = 72,+  V2ADDI_IMM8_OPCODE_X0 = 14,+  V2ADDI_IMM8_OPCODE_X1 = 39,+  V2ADDSC_RRR_0_OPCODE_X0 = 115,+  V2ADDSC_RRR_0_OPCODE_X1 = 73,+  V2ADD_RRR_0_OPCODE_X0 = 116,+  V2ADD_RRR_0_OPCODE_X1 = 74,+  V2ADIFFS_RRR_0_OPCODE_X0 = 117,+  V2AVGS_RRR_0_OPCODE_X0 = 118,+  V2CMPEQI_IMM8_OPCODE_X0 = 15,+  V2CMPEQI_IMM8_OPCODE_X1 = 40,+  V2CMPEQ_RRR_0_OPCODE_X0 = 119,+  V2CMPEQ_RRR_0_OPCODE_X1 = 75,+  V2CMPLES_RRR_0_OPCODE_X0 = 120,+  V2CMPLES_RRR_0_OPCODE_X1 = 76,+  V2CMPLEU_RRR_0_OPCODE_X0 = 121,+  V2CMPLEU_RRR_0_OPCODE_X1 = 77,+  V2CMPLTSI_IMM8_OPCODE_X0 = 16,+  V2CMPLTSI_IMM8_OPCODE_X1 = 41,+  V2CMPLTS_RRR_0_OPCODE_X0 = 122,+  V2CMPLTS_RRR_0_OPCODE_X1 = 78,+  V2CMPLTUI_IMM8_OPCODE_X0 = 17,+  V2CMPLTUI_IMM8_OPCODE_X1 = 42,+  V2CMPLTU_RRR_0_OPCODE_X0 = 123,+  V2CMPLTU_RRR_0_OPCODE_X1 = 79,+  V2CMPNE_RRR_0_OPCODE_X0 = 124,+  V2CMPNE_RRR_0_OPCODE_X1 = 80,+  V2DOTPA_RRR_0_OPCODE_X0 = 125,+  V2DOTP_RRR_0_OPCODE_X0 = 126,+  V2INT_H_RRR_0_OPCODE_X0 = 127,+  V2INT_H_RRR_0_OPCODE_X1 = 81,+  V2INT_L_RRR_0_OPCODE_X0 = 128,+  V2INT_L_RRR_0_OPCODE_X1 = 82,+  V2MAXSI_IMM8_OPCODE_X0 = 18,+  V2MAXSI_IMM8_OPCODE_X1 = 43,+  V2MAXS_RRR_0_OPCODE_X0 = 129,+  V2MAXS_RRR_0_OPCODE_X1 = 83,+  V2MINSI_IMM8_OPCODE_X0 = 19,+  V2MINSI_IMM8_OPCODE_X1 = 44,+  V2MINS_RRR_0_OPCODE_X0 = 130,+  V2MINS_RRR_0_OPCODE_X1 = 84,+  V2MNZ_RRR_0_OPCODE_X0 = 131,+  V2MNZ_RRR_0_OPCODE_X1 = 85,+  V2MULFSC_RRR_0_OPCODE_X0 = 132,+  V2MULS_RRR_0_OPCODE_X0 = 133,+  V2MULTS_RRR_0_OPCODE_X0 = 134,+  V2MZ_RRR_0_OPCODE_X0 = 135,+  V2MZ_RRR_0_OPCODE_X1 = 86,+  V2PACKH_RRR_0_OPCODE_X0 = 136,+  V2PACKH_RRR_0_OPCODE_X1 = 87,+  V2PACKL_RRR_0_OPCODE_X0 = 137,+  V2PACKL_RRR_0_OPCODE_X1 = 88,+  V2PACKUC_RRR_0_OPCODE_X0 = 138,+  V2PACKUC_RRR_0_OPCODE_X1 = 89,+  V2SADAS_RRR_0_OPCODE_X0 = 139,+  V2SADAU_RRR_0_OPCODE_X0 = 140,+  V2SADS_RRR_0_OPCODE_X0 = 141,+  V2SADU_RRR_0_OPCODE_X0 = 142,+  V2SHLI_SHIFT_OPCODE_X0 = 10,+  V2SHLI_SHIFT_OPCODE_X1 = 10,+  V2SHLSC_RRR_0_OPCODE_X0 = 143,+  V2SHLSC_RRR_0_OPCODE_X1 = 90,+  V2SHL_RRR_0_OPCODE_X0 = 144,+  V2SHL_RRR_0_OPCODE_X1 = 91,+  V2SHRSI_SHIFT_OPCODE_X0 = 11,+  V2SHRSI_SHIFT_OPCODE_X1 = 11,+  V2SHRS_RRR_0_OPCODE_X0 = 145,+  V2SHRS_RRR_0_OPCODE_X1 = 92,+  V2SHRUI_SHIFT_OPCODE_X0 = 12,+  V2SHRUI_SHIFT_OPCODE_X1 = 12,+  V2SHRU_RRR_0_OPCODE_X0 = 146,+  V2SHRU_RRR_0_OPCODE_X1 = 93,+  V2SUBSC_RRR_0_OPCODE_X0 = 147,+  V2SUBSC_RRR_0_OPCODE_X1 = 94,+  V2SUB_RRR_0_OPCODE_X0 = 148,+  V2SUB_RRR_0_OPCODE_X1 = 95,+  V4ADDSC_RRR_0_OPCODE_X0 = 149,+  V4ADDSC_RRR_0_OPCODE_X1 = 96,+  V4ADD_RRR_0_OPCODE_X0 = 150,+  V4ADD_RRR_0_OPCODE_X1 = 97,+  V4INT_H_RRR_0_OPCODE_X0 = 151,+  V4INT_H_RRR_0_OPCODE_X1 = 98,+  V4INT_L_RRR_0_OPCODE_X0 = 152,+  V4INT_L_RRR_0_OPCODE_X1 = 99,+  V4PACKSC_RRR_0_OPCODE_X0 = 153,+  V4PACKSC_RRR_0_OPCODE_X1 = 100,+  V4SHLSC_RRR_0_OPCODE_X0 = 154,+  V4SHLSC_RRR_0_OPCODE_X1 = 101,+  V4SHL_RRR_0_OPCODE_X0 = 155,+  V4SHL_RRR_0_OPCODE_X1 = 102,+  V4SHRS_RRR_0_OPCODE_X0 = 156,+  V4SHRS_RRR_0_OPCODE_X1 = 103,+  V4SHRU_RRR_0_OPCODE_X0 = 157,+  V4SHRU_RRR_0_OPCODE_X1 = 104,+  V4SUBSC_RRR_0_OPCODE_X0 = 158,+  V4SUBSC_RRR_0_OPCODE_X1 = 105,+  V4SUB_RRR_0_OPCODE_X0 = 159,+  V4SUB_RRR_0_OPCODE_X1 = 106,+  WH64_UNARY_OPCODE_X1 = 38,+  XORI_IMM8_OPCODE_X0 = 20,+  XORI_IMM8_OPCODE_X1 = 45,+  XOR_RRR_0_OPCODE_X0 = 160,+  XOR_RRR_0_OPCODE_X1 = 107,+  XOR_RRR_5_OPCODE_Y0 = 3,+  XOR_RRR_5_OPCODE_Y1 = 3+};++static __inline unsigned int+get_BFEnd_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_BFOpcodeExtension_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 24)) & 0xf);+}++static __inline unsigned int+get_BFStart_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 18)) & 0x3f);+}++static __inline unsigned int+get_BrOff_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 31)) & 0x0000003f) |+         (((unsigned int)(n >> 37)) & 0x0001ffc0);+}++static __inline unsigned int+get_BrType_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 54)) & 0x1f);+}++static __inline unsigned int+get_Dest_Imm8_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 31)) & 0x0000003f) |+         (((unsigned int)(n >> 43)) & 0x000000c0);+}++static __inline unsigned int+get_Dest_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 0)) & 0x3f);+}++static __inline unsigned int+get_Dest_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 31)) & 0x3f);+}++static __inline unsigned int+get_Dest_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 0)) & 0x3f);+}++static __inline unsigned int+get_Dest_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 31)) & 0x3f);+}++static __inline unsigned int+get_Imm16_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0xffff);+}++static __inline unsigned int+get_Imm16_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0xffff);+}++static __inline unsigned int+get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 20)) & 0xff);+}++static __inline unsigned int+get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 51)) & 0xff);+}++static __inline unsigned int+get_Imm8_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0xff);+}++static __inline unsigned int+get_Imm8_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0xff);+}++static __inline unsigned int+get_Imm8_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0xff);+}++static __inline unsigned int+get_Imm8_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0xff);+}++static __inline unsigned int+get_JumpOff_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 31)) & 0x7ffffff);+}++static __inline unsigned int+get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 58)) & 0x1);+}++static __inline unsigned int+get_MF_Imm14_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 37)) & 0x3fff);+}++static __inline unsigned int+get_MT_Imm14_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 31)) & 0x0000003f) |+         (((unsigned int)(n >> 37)) & 0x00003fc0);+}++static __inline unsigned int+get_Mode(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 62)) & 0x3);+}++static __inline unsigned int+get_Opcode_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 28)) & 0x7);+}++static __inline unsigned int+get_Opcode_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 59)) & 0x7);+}++static __inline unsigned int+get_Opcode_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 27)) & 0xf);+}++static __inline unsigned int+get_Opcode_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 58)) & 0xf);+}++static __inline unsigned int+get_Opcode_Y2(tilegx_bundle_bits n)+{+  return (((n >> 26)) & 0x00000001) |+         (((unsigned int)(n >> 56)) & 0x00000002);+}++static __inline unsigned int+get_RRROpcodeExtension_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 18)) & 0x3ff);+}++static __inline unsigned int+get_RRROpcodeExtension_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 49)) & 0x3ff);+}++static __inline unsigned int+get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 18)) & 0x3);+}++static __inline unsigned int+get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 49)) & 0x3);+}++static __inline unsigned int+get_ShAmt_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_ShAmt_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0x3f);+}++static __inline unsigned int+get_ShAmt_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_ShAmt_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0x3f);+}++static __inline unsigned int+get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 18)) & 0x3ff);+}++static __inline unsigned int+get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 49)) & 0x3ff);+}++static __inline unsigned int+get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 18)) & 0x3);+}++static __inline unsigned int+get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 49)) & 0x3);+}++static __inline unsigned int+get_SrcA_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 6)) & 0x3f);+}++static __inline unsigned int+get_SrcA_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 37)) & 0x3f);+}++static __inline unsigned int+get_SrcA_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 6)) & 0x3f);+}++static __inline unsigned int+get_SrcA_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 37)) & 0x3f);+}++static __inline unsigned int+get_SrcA_Y2(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 20)) & 0x3f);+}++static __inline unsigned int+get_SrcBDest_Y2(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 51)) & 0x3f);+}++static __inline unsigned int+get_SrcB_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_SrcB_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0x3f);+}++static __inline unsigned int+get_SrcB_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_SrcB_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0x3f);+}++static __inline unsigned int+get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0x3f);+}++static __inline unsigned int+get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)+{+  const unsigned int n = (unsigned int)num;+  return (((n >> 12)) & 0x3f);+}++static __inline unsigned int+get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)+{+  return (((unsigned int)(n >> 43)) & 0x3f);+}++static __inline int+sign_extend(int n, int num_bits)+{+  int shift = (int)(sizeof(int) * 8 - num_bits);+  return (n << shift) >> shift;+}++static __inline tilegx_bundle_bits+create_BFEnd_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_BFOpcodeExtension_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0xf) << 24);+}++static __inline tilegx_bundle_bits+create_BFStart_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 18);+}++static __inline tilegx_bundle_bits+create_BrOff_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |+         (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);+}++static __inline tilegx_bundle_bits+create_BrType_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x1f)) << 54);+}++static __inline tilegx_bundle_bits+create_Dest_Imm8_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |+         (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);+}++static __inline tilegx_bundle_bits+create_Dest_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 0);+}++static __inline tilegx_bundle_bits+create_Dest_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);+}++static __inline tilegx_bundle_bits+create_Dest_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 0);+}++static __inline tilegx_bundle_bits+create_Dest_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);+}++static __inline tilegx_bundle_bits+create_Imm16_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0xffff) << 12);+}++static __inline tilegx_bundle_bits+create_Imm16_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0xffff)) << 43);+}++static __inline tilegx_bundle_bits+create_Imm8OpcodeExtension_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0xff) << 20);+}++static __inline tilegx_bundle_bits+create_Imm8OpcodeExtension_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0xff)) << 51);+}++static __inline tilegx_bundle_bits+create_Imm8_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0xff) << 12);+}++static __inline tilegx_bundle_bits+create_Imm8_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0xff)) << 43);+}++static __inline tilegx_bundle_bits+create_Imm8_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0xff) << 12);+}++static __inline tilegx_bundle_bits+create_Imm8_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0xff)) << 43);+}++static __inline tilegx_bundle_bits+create_JumpOff_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);+}++static __inline tilegx_bundle_bits+create_JumpOpcodeExtension_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x1)) << 58);+}++static __inline tilegx_bundle_bits+create_MF_Imm14_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);+}++static __inline tilegx_bundle_bits+create_MT_Imm14_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |+         (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);+}++static __inline tilegx_bundle_bits+create_Mode(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3)) << 62);+}++static __inline tilegx_bundle_bits+create_Opcode_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x7) << 28);+}++static __inline tilegx_bundle_bits+create_Opcode_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x7)) << 59);+}++static __inline tilegx_bundle_bits+create_Opcode_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0xf) << 27);+}++static __inline tilegx_bundle_bits+create_Opcode_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0xf)) << 58);+}++static __inline tilegx_bundle_bits+create_Opcode_Y2(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x00000001) << 26) |+         (((tilegx_bundle_bits)(n & 0x00000002)) << 56);+}++static __inline tilegx_bundle_bits+create_RRROpcodeExtension_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3ff) << 18);+}++static __inline tilegx_bundle_bits+create_RRROpcodeExtension_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);+}++static __inline tilegx_bundle_bits+create_RRROpcodeExtension_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3) << 18);+}++static __inline tilegx_bundle_bits+create_RRROpcodeExtension_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3)) << 49);+}++static __inline tilegx_bundle_bits+create_ShAmt_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_ShAmt_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);+}++static __inline tilegx_bundle_bits+create_ShAmt_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_ShAmt_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);+}++static __inline tilegx_bundle_bits+create_ShiftOpcodeExtension_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3ff) << 18);+}++static __inline tilegx_bundle_bits+create_ShiftOpcodeExtension_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);+}++static __inline tilegx_bundle_bits+create_ShiftOpcodeExtension_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3) << 18);+}++static __inline tilegx_bundle_bits+create_ShiftOpcodeExtension_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3)) << 49);+}++static __inline tilegx_bundle_bits+create_SrcA_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 6);+}++static __inline tilegx_bundle_bits+create_SrcA_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);+}++static __inline tilegx_bundle_bits+create_SrcA_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 6);+}++static __inline tilegx_bundle_bits+create_SrcA_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);+}++static __inline tilegx_bundle_bits+create_SrcA_Y2(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 20);+}++static __inline tilegx_bundle_bits+create_SrcBDest_Y2(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 51);+}++static __inline tilegx_bundle_bits+create_SrcB_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_SrcB_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);+}++static __inline tilegx_bundle_bits+create_SrcB_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_SrcB_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);+}++static __inline tilegx_bundle_bits+create_UnaryOpcodeExtension_X0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_UnaryOpcodeExtension_X1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);+}++static __inline tilegx_bundle_bits+create_UnaryOpcodeExtension_Y0(int num)+{+  const unsigned int n = (unsigned int)num;+  return ((n & 0x3f) << 12);+}++static __inline tilegx_bundle_bits+create_UnaryOpcodeExtension_Y1(int num)+{+  const unsigned int n = (unsigned int)num;+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);+}++const struct tilegx_opcode tilegx_opcodes[336] =+{+ { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffffffff80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a44ae00000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1,+    { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00fffULL,+      0xfff807ff80000000ULL,+      0x0000000078000fffULL,+      0x3c0007ff80000000ULL,+      0ULL+    },+    {+      0x0000000040300fffULL,+      0x181807ff80000000ULL,+      0x0000000010000fffULL,+      0x0c0007ff80000000ULL,+      -1ULL+    }+#endif+  },+  { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,+    { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc000000070000fffULL,+      0xf80007ff80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000070000fffULL,+      0x380007ff80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1858000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18a0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0xfffff80000000000ULL,+      0x00000000780ff000ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      0x000000005107f000ULL,+      0x283bf80000000000ULL,+      0x00000000500bf000ULL,+      0x2c05f80000000000ULL,+      -1ULL+    }+#endif+  },+  { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,+    { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00fc0ULL,+      0xfff807e000000000ULL,+      0x0000000078000fc0ULL,+      0x3c0007e000000000ULL,+      0ULL+    },+    {+      0x0000000040100fc0ULL,+      0x180807e000000000ULL,+      0x0000000000000fc0ULL,+      0x040007e000000000ULL,+      -1ULL+    }+#endif+  },+  { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,+    { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc000000070000fc0ULL,+      0xf80007e000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000010000fc0ULL,+      0x000007e000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286a801f80000000ULL,+      -1ULL,+      -1ULL,+      0x41f8000004000000ULL+    }+#endif+  },+  { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8001f80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1840001f80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8001f80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1838001f80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8001f80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1850001f80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8001f80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1848001f80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8001f80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1860001f80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8001f80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1858001f80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286a801f80000000ULL,+      -1ULL,+      -1ULL,+      0x41f8000004000000ULL+    }+#endif+  },+  { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286a781f80000000ULL,+      -1ULL,+      -1ULL,+      0x41f8000000000000ULL+    }+#endif+  },+  { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286a901f80000000ULL,+      -1ULL,+      -1ULL,+      0x43f8000004000000ULL+    }+#endif+  },+  { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286a881f80000000ULL,+      -1ULL,+      -1ULL,+      0x43f8000000000000ULL+    }+#endif+  },+  { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286aa01f80000000ULL,+      -1ULL,+      -1ULL,+      0x83f8000000000000ULL+    }+#endif+  },+  { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff81f80000000ULL,+      0ULL,+      0ULL,+      0xc3f8000004000000ULL+    },+    {+      -1ULL,+      0x286a981f80000000ULL,+      -1ULL,+      -1ULL,+      0x81f8000004000000ULL+    }+#endif+  },+  { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffffffff80000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a44ae80000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x00000000500c0000ULL,+      0x2806000000000000ULL,+      0x0000000028040000ULL,+      0x1802000000000000ULL,+      -1ULL+    }+#endif+  },+  { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0x0000000078000000ULL,+      0x3c00000000000000ULL,+      0ULL+    },+    {+      0x0000000040100000ULL,+      0x1808000000000000ULL,+      0ULL,+      0x0400000000000000ULL,+      -1ULL+    }+#endif+  },+  { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc000000070000000ULL,+      0xf800000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000010000000ULL,+      0ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050080000ULL,+      0x2804000000000000ULL,+      0x0000000028000000ULL,+      0x1800000000000000ULL,+      -1ULL+    }+#endif+  },+  { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0x0000000078000000ULL,+      0x3c00000000000000ULL,+      0ULL+    },+    {+      0x0000000040200000ULL,+      0x1810000000000000ULL,+      0x0000000008000000ULL,+      0x0800000000000000ULL,+      -1ULL+    }+#endif+  },+  { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc000000070000000ULL,+      0xf800000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000020000000ULL,+      0x0800000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050040000ULL,+      0x2802000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050100000ULL,+      0x2808000000000000ULL,+      0x0000000050000000ULL,+      0x2c00000000000000ULL,+      -1ULL+    }+#endif+  },+  { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0x0000000078000000ULL,+      0x3c00000000000000ULL,+      0ULL+    },+    {+      0x0000000040300000ULL,+      0x1818000000000000ULL,+      0x0000000010000000ULL,+      0x0c00000000000000ULL,+      -1ULL+    }+#endif+  },+  { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1440000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1400000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1,+    { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007f000000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000034000000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1,+    { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007f000000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000035000000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1,+    { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007f000000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000036000000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x14c0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1480000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1540000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1500000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x15c0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1580000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1640000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1600000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x16c0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1680000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1740000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1700000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x17c0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xffc0000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1780000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051481000ULL,+      -1ULL,+      0x00000000300c1000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050140000ULL,+      -1ULL,+      0x0000000048000000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050180000ULL,+      -1ULL,+      0x0000000048040000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x00000000501c0000ULL,+      0x280a000000000000ULL,+      0x0000000040000000ULL,+      0x2404000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0x0000000078000000ULL,+      0x3c00000000000000ULL,+      0ULL+    },+    {+      0x0000000040400000ULL,+      0x1820000000000000ULL,+      0x0000000018000000ULL,+      0x1000000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x280e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x280c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050200000ULL,+      0x2810000000000000ULL,+      0x0000000038000000ULL,+      0x2000000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050240000ULL,+      0x2812000000000000ULL,+      0x0000000038040000ULL,+      0x2002000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050280000ULL,+      0x2814000000000000ULL,+      0x0000000038080000ULL,+      0x2004000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0x0000000078000000ULL,+      0x3c00000000000000ULL,+      0ULL+    },+    {+      0x0000000040500000ULL,+      0x1828000000000000ULL,+      0x0000000020000000ULL,+      0x1400000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x00000000502c0000ULL,+      0x2816000000000000ULL,+      0x00000000380c0000ULL,+      0x2006000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040600000ULL,+      0x1830000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050300000ULL,+      0x2818000000000000ULL,+      0x0000000040040000ULL,+      0x2406000000000000ULL,+      -1ULL+    }+#endif+  },+  { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000504c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050380000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050340000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050400000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000503c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050480000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050440000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050500000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050540000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051482000ULL,+      -1ULL,+      0x00000000300c2000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050640000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050580000ULL,+      0x281a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000505c0000ULL,+      0x281c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050600000ULL,+      0x281e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a080000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a100000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2822000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2820000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000506c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050680000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050700000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050740000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050780000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000507c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050800000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050840000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x282a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2824000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2828000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2826000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x282e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x282c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2832000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2830000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a180000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a280000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a200000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,+    { {  }, {  }, {  }, {  }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0xfffff80000000000ULL,+      0x00000000780ff000ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      0x0000000051483000ULL,+      0x286a300000000000ULL,+      0x00000000300c3000ULL,+      0x1c06400000000000ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050880000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000508c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050900000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050940000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051484000ULL,+      -1ULL,+      0x00000000300c4000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050980000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000509c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a380000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1,+    { { 0, }, {  }, { 0, }, {  }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a400000000000ULL,+      -1ULL,+      0x1c06480000000000ULL,+      -1ULL+    }+#endif+  },+  { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a480000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a500000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfc00000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2400000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1,+    { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfc00000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2000000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1,+    { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a600000000000ULL,+      -1ULL,+      0x1c06580000000000ULL,+      -1ULL+    }+#endif+  },+  { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1,+    { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a580000000000ULL,+      -1ULL,+      0x1c06500000000000ULL,+      -1ULL+    }+#endif+  },+  { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a700000000000ULL,+      -1ULL,+      0x1c06680000000000ULL,+      -1ULL+    }+#endif+  },+  { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      -1ULL,+      0x286a680000000000ULL,+      -1ULL,+      0x1c06600000000000ULL,+      -1ULL+    }+#endif+  },+  { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286ae80000000000ULL,+      -1ULL,+      -1ULL,+      0x8200000004000000ULL+    }+#endif+  },+  { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286a780000000000ULL,+      -1ULL,+      -1ULL,+      0x4000000000000000ULL+    }+#endif+  },+  { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1838000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286a800000000000ULL,+      -1ULL,+      -1ULL,+      0x4000000004000000ULL+    }+#endif+  },+  { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1840000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286a880000000000ULL,+      -1ULL,+      -1ULL,+      0x4200000000000000ULL+    }+#endif+  },+  { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1848000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286a900000000000ULL,+      -1ULL,+      -1ULL,+      0x4200000004000000ULL+    }+#endif+  },+  { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1850000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286a980000000000ULL,+      -1ULL,+      -1ULL,+      0x8000000004000000ULL+    }+#endif+  },+  { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1858000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x286aa00000000000ULL,+      -1ULL,+      -1ULL,+      0x8200000000000000ULL+    }+#endif+  },+  { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1860000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18a0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286aa80000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18a8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ae00000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ab00000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1868000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ab80000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1870000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ac00000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1878000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ac80000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1880000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ad00000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1888000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286ad80000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1890000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1898000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1,+    { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      -1ULL,+      0x286af00000000000ULL,+      -1ULL,+      0x1c06700000000000ULL,+      -1ULL+    }+#endif+  },+  { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286af80000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18b0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1,+    { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007f000000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000037000000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050a00000ULL,+      0x2834000000000000ULL,+      0x0000000048080000ULL,+      0x2804000000000000ULL,+      -1ULL+    }+#endif+  },+  { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18b8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050d40000ULL,+      -1ULL,+      0x0000000068000000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050d80000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050dc0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050e00000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050e40000ULL,+      -1ULL,+      0x0000000068040000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050e80000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050ec0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050f00000ULL,+      -1ULL,+      0x0000000068080000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050f40000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050f80000ULL,+      -1ULL,+      0x00000000680c0000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050a80000ULL,+      -1ULL,+      0x0000000070000000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050ac0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050b00000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050b40000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050b80000ULL,+      -1ULL,+      0x0000000070040000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050bc0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050c00000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050c40000ULL,+      -1ULL,+      0x0000000070080000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050c80000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050cc0000ULL,+      -1ULL,+      0x00000000700c0000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050a40000ULL,+      -1ULL,+      0x0000000040080000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0x00000000780c0000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000050d00000ULL,+      -1ULL,+      0x00000000400c0000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000050fc0000ULL,+      0x2836000000000000ULL,+      0x00000000480c0000ULL,+      0x2806000000000000ULL,+      -1ULL+    }+#endif+  },+  { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286b000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1,+    { {  }, {  }, {  }, {  }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0xfffff80000000000ULL,+      0x00000000780ff000ULL,+      0x3c07f80000000000ULL,+      0ULL+    },+    {+      0x0000000051485000ULL,+      0x286b080000000000ULL,+      0x00000000300c5000ULL,+      0x1c06780000000000ULL,+      -1ULL+    }+#endif+  },+  { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051000000ULL,+      0x2838000000000000ULL,+      0x0000000050040000ULL,+      0x2c02000000000000ULL,+      -1ULL+    }+#endif+  },+  { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051040000ULL,+      0x283a000000000000ULL,+      0x0000000050080000ULL,+      0x2c04000000000000ULL,+      -1ULL+    }+#endif+  },+  { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040700000ULL,+      0x18c0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051486000ULL,+      -1ULL,+      0x00000000300c6000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051487000ULL,+      -1ULL,+      0x00000000300c7000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1,+    { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051488000ULL,+      -1ULL,+      0x00000000300c8000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051080000ULL,+      0x283c000000000000ULL,+      0x0000000058000000ULL,+      0x3000000000000000ULL,+      -1ULL+    }+#endif+  },+  { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000060040000ULL,+      0x3002000000000000ULL,+      0x0000000078000000ULL,+      0x3800000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051280000ULL,+      0x284c000000000000ULL,+      0x0000000058040000ULL,+      0x3002000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc000000070000000ULL,+      0xf800000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000070000000ULL,+      0x3800000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051100000ULL,+      0x2840000000000000ULL,+      0x0000000030000000ULL,+      0x1c00000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x00000000510c0000ULL,+      0x283e000000000000ULL,+      0x0000000060040000ULL,+      0x3402000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051180000ULL,+      0x2844000000000000ULL,+      0x0000000030040000ULL,+      0x1c02000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051140000ULL,+      0x2842000000000000ULL,+      0x0000000060080000ULL,+      0x3404000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051200000ULL,+      0x2848000000000000ULL,+      0x0000000030080000ULL,+      0x1c04000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x00000000511c0000ULL,+      0x2846000000000000ULL,+      0x00000000600c0000ULL,+      0x3406000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000060080000ULL,+      0x3004000000000000ULL,+      0x0000000078040000ULL,+      0x3802000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051240000ULL,+      0x284a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000600c0000ULL,+      0x3006000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x00000000512c0000ULL,+      0x284e000000000000ULL,+      0x0000000058080000ULL,+      0x3004000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000060100000ULL,+      0x3008000000000000ULL,+      0x0000000078080000ULL,+      0x3804000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051340000ULL,+      0x2852000000000000ULL,+      0x00000000580c0000ULL,+      0x3006000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000060140000ULL,+      0x300a000000000000ULL,+      0x00000000780c0000ULL,+      0x3806000000000000ULL,+      -1ULL+    }+#endif+  },+  { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051300000ULL,+      0x2850000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000060180000ULL,+      0x300c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051380000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x2862000000000000ULL,+      -1ULL,+      -1ULL,+      0xc200000004000000ULL+    }+#endif+  },+  { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x2854000000000000ULL,+      -1ULL,+      -1ULL,+      0xc000000000000000ULL+    }+#endif+  },+  { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18c8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x2856000000000000ULL,+      -1ULL,+      -1ULL,+      0xc000000004000000ULL+    }+#endif+  },+  { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18d0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0xc200000004000000ULL+    },+    {+      -1ULL,+      0x2858000000000000ULL,+      -1ULL,+      -1ULL,+      0xc200000000000000ULL+    }+#endif+  },+  { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18d8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x1900000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x2860000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x285a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18e0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x285c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18e8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1,+    { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x285e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18f0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1,+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x18f8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051440000ULL,+      0x2868000000000000ULL,+      0x00000000280c0000ULL,+      0x1806000000000000ULL,+      -1ULL+    }+#endif+  },+  { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000051400000ULL,+      0x2866000000000000ULL,+      0x0000000028080000ULL,+      0x1804000000000000ULL,+      -1ULL+    }+#endif+  },+  { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000513c0000ULL,+      0x2864000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286b100000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286b180000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286b200000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286b280000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,+    { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051489000ULL,+      -1ULL,+      0x00000000300c9000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,+    { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x000000005148a000ULL,+      -1ULL,+      0x00000000300ca000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,+    { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x000000005148b000ULL,+      -1ULL,+      0x00000000300cb000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,+    { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffff000ULL,+      0ULL,+      0x00000000780ff000ULL,+      0ULL,+      0ULL+    },+    {+      0x000000005148c000ULL,+      -1ULL,+      0x00000000300cc000ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051500000ULL,+      0x286e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040800000ULL,+      0x1908000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000514c0000ULL,+      0x286c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051540000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051580000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000515c0000ULL,+      0x2870000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040900000ULL,+      0x1910000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051600000ULL,+      0x2872000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051640000ULL,+      0x2874000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051680000ULL,+      0x2876000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040a00000ULL,+      0x1918000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000516c0000ULL,+      0x2878000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040b00000ULL,+      0x1920000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051700000ULL,+      0x287a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052880000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052840000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051780000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051740000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051880000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000517c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052900000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000528c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051840000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051800000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000518c0000ULL,+      0x287c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051900000ULL,+      0x287e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051940000ULL,+      0x2880000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040c00000ULL,+      0x1928000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051980000ULL,+      0x2882000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040d00000ULL,+      0x1930000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000519c0000ULL,+      0x2884000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051a00000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051a80000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051a40000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051ac0000ULL,+      0x2886000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051b00000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051b40000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051b80000ULL,+      0x2888000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000601c0000ULL,+      0x300e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051bc0000ULL,+      0x288a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000060200000ULL,+      0x3010000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051c00000ULL,+      0x288c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000060240000ULL,+      0x3012000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051c80000ULL,+      0x2890000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051c40000ULL,+      0x288e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051d00000ULL,+      0x2894000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040e00000ULL,+      0x1938000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051cc0000ULL,+      0x2892000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051d40000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051d80000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051dc0000ULL,+      0x2896000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000040f00000ULL,+      0x1940000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051e00000ULL,+      0x2898000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051e40000ULL,+      0x289a000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051e80000ULL,+      0x289c000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000041000000ULL,+      0x1948000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051ec0000ULL,+      0x289e000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000041100000ULL,+      0x1950000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051f00000ULL,+      0x28a0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051f80000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051f40000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000051fc0000ULL,+      0x28a2000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052000000ULL,+      0x28a4000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052040000ULL,+      0x28a6000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000041200000ULL,+      0x1958000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052080000ULL,+      0x28a8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000041300000ULL,+      0x1960000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000520c0000ULL,+      0x28aa000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052100000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052140000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052180000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000521c0000ULL,+      0x28ac000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052200000ULL,+      0x28ae000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052240000ULL,+      0x28b0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052280000ULL,+      0x28b2000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000522c0000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1,+    { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052300000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052340000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052380000ULL,+      -1ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052400000ULL,+      0x28b6000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000060280000ULL,+      0x3014000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000523c0000ULL,+      0x28b4000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052440000ULL,+      0x28b8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000602c0000ULL,+      0x3016000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052480000ULL,+      0x28ba000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000060300000ULL,+      0x3018000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052500000ULL,+      0x28be000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000524c0000ULL,+      0x28bc000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052580000ULL,+      0x28c2000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052540000ULL,+      0x28c0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000525c0000ULL,+      0x28c4000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052600000ULL,+      0x28c6000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052640000ULL,+      0x28c8000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000526c0000ULL,+      0x28cc000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052680000ULL,+      0x28ca000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052700000ULL,+      0x28ce000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052740000ULL,+      0x28d0000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x00000000527c0000ULL,+      0x28d4000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000052780000ULL,+      0x28d2000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1,+    { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0ULL,+      0xfffff80000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      -1ULL,+      0x286b300000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1,+    { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ffc0000ULL,+      0xfffe000000000000ULL,+      0x00000000780c0000ULL,+      0x3c06000000000000ULL,+      0ULL+    },+    {+      0x0000000052800000ULL,+      0x28d6000000000000ULL,+      0x00000000500c0000ULL,+      0x2c06000000000000ULL,+      -1ULL+    }+#endif+  },+  { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1,+    { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },+#ifndef DISASM_ONLY+    {+      0xc00000007ff00000ULL,+      0xfff8000000000000ULL,+      0ULL,+      0ULL,+      0ULL+    },+    {+      0x0000000041400000ULL,+      0x1968000000000000ULL,+      -1ULL,+      -1ULL,+      -1ULL+    }+#endif+  },+  { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },+#ifndef DISASM_ONLY+    { 0, }, { 0, }+#endif+  }+};++#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))+#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index))++static const unsigned short decode_X0_fsm[936] =+{+  BITFIELD(22, 9) /* index 0 */,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS,+  TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU,+  TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS,+  TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM,+  TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578),+  CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671),+  CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865),+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),+  BITFIELD(6, 2) /* index 513 */,+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),+  BITFIELD(8, 2) /* index 518 */,+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),+  BITFIELD(10, 2) /* index 523 */,+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,+  BITFIELD(20, 2) /* index 528 */,+  TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),+  BITFIELD(6, 2) /* index 533 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),+  BITFIELD(8, 2) /* index 538 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),+  BITFIELD(10, 2) /* index 543 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,+  BITFIELD(0, 2) /* index 548 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),+  BITFIELD(2, 2) /* index 553 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),+  BITFIELD(4, 2) /* index 558 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),+  BITFIELD(6, 2) /* index 563 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),+  BITFIELD(8, 2) /* index 568 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),+  BITFIELD(10, 2) /* index 573 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,+  BITFIELD(20, 2) /* index 578 */,+  TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI,+  BITFIELD(20, 2) /* index 583 */,+  TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI,+  TILEGX_OPC_V1CMPLTUI,+  BITFIELD(20, 2) /* index 588 */,+  TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI,+  TILEGX_OPC_V2CMPEQI,+  BITFIELD(20, 2) /* index 593 */,+  TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI,+  TILEGX_OPC_V2MINSI,+  BITFIELD(20, 2) /* index 598 */,+  TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(18, 4) /* index 603 */,+  TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,+  TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ,+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,+  TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR,+  BITFIELD(18, 4) /* index 620 */,+  TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL,+  TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2,+  TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN,+  TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS,+  TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1,+  TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS,+  BITFIELD(18, 4) /* index 637 */,+  TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN,+  TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2,+  TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2,+  TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX,+  TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS,+  TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS,+  BITFIELD(18, 4) /* index 654 */,+  TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU,+  TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS,+  TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU,+  TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU,+  TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU,+  TILEGX_OPC_MZ,+  BITFIELD(18, 4) /* index 671 */,+  TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,+  TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES,+  TILEGX_OPC_SUBXSC,+  BITFIELD(12, 2) /* index 688 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693),+  BITFIELD(14, 2) /* index 693 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698),+  BITFIELD(16, 2) /* index 698 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,+  BITFIELD(18, 4) /* index 703 */,+  TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC,+  TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU,+  TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,+  TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,+  TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA,+  BITFIELD(12, 4) /* index 720 */,+  TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757),+  CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787),+  CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 737 */,+  TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 742 */,+  TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 747 */,+  TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 752 */,+  TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 757 */,+  TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 762 */,+  TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 767 */,+  TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 772 */,+  TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 777 */,+  TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 782 */,+  TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 787 */,+  TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(16, 2) /* index 792 */,+  TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(18, 4) /* index 797 */,+  TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP,+  TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU,+  TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS,+  TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU,+  TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS,+  BITFIELD(18, 4) /* index 814 */,+  TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC,+  TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS,+  TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU,+  TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE,+  TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H,+  BITFIELD(18, 4) /* index 831 */,+  TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ,+  TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ,+  TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,+  TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS,+  TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC,+  BITFIELD(18, 4) /* index 848 */,+  TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC,+  TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,+  TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,+  TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,+  TILEGX_OPC_V4SUB,+  BITFIELD(18, 3) /* index 865 */,+  CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(21, 1) /* index 874 */,+  TILEGX_OPC_XOR, TILEGX_OPC_NONE,+  BITFIELD(21, 1) /* index 877 */,+  TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE,+  BITFIELD(21, 1) /* index 880 */,+  TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE,+  BITFIELD(21, 1) /* index 883 */,+  TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE,+  BITFIELD(21, 1) /* index 886 */,+  TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE,+  BITFIELD(18, 4) /* index 889 */,+  TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,+  TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,+  TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,+  TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE,+  BITFIELD(0, 2) /* index 906 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(911),+  BITFIELD(2, 2) /* index 911 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(916),+  BITFIELD(4, 2) /* index 916 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(921),+  BITFIELD(6, 2) /* index 921 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(926),+  BITFIELD(8, 2) /* index 926 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(931),+  BITFIELD(10, 2) /* index 931 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  TILEGX_OPC_INFOL,+};++static const unsigned short decode_X1_fsm[1266] =+{+  BITFIELD(53, 9) /* index 0 */,+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT,+  TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT,+  TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT,+  TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT,+  TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST,+  TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT,+  TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT,+  TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT,+  TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578),+  CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758),+  CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J,+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,+  CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185),+  CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),+  CHILD(1236),+  BITFIELD(37, 2) /* index 513 */,+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),+  BITFIELD(39, 2) /* index 518 */,+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),+  BITFIELD(41, 2) /* index 523 */,+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,+  BITFIELD(51, 2) /* index 528 */,+  TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),+  BITFIELD(37, 2) /* index 533 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),+  BITFIELD(39, 2) /* index 538 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),+  BITFIELD(41, 2) /* index 543 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,+  BITFIELD(31, 2) /* index 548 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),+  BITFIELD(33, 2) /* index 553 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),+  BITFIELD(35, 2) /* index 558 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),+  BITFIELD(37, 2) /* index 563 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),+  BITFIELD(39, 2) /* index 568 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),+  BITFIELD(41, 2) /* index 573 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,+  BITFIELD(51, 2) /* index 578 */,+  TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583),+  BITFIELD(31, 2) /* index 583 */,+  TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588),+  BITFIELD(33, 2) /* index 588 */,+  TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593),+  BITFIELD(35, 2) /* index 593 */,+  TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD,+  TILEGX_OPC_PREFETCH_ADD_L1_FAULT,+  BITFIELD(51, 2) /* index 598 */,+  CHILD(603), CHILD(618), CHILD(633), CHILD(648),+  BITFIELD(31, 2) /* index 603 */,+  TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608),+  BITFIELD(33, 2) /* index 608 */,+  TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613),+  BITFIELD(35, 2) /* index 613 */,+  TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD,+  TILEGX_OPC_PREFETCH_ADD_L1,+  BITFIELD(31, 2) /* index 618 */,+  TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623),+  BITFIELD(33, 2) /* index 623 */,+  TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628),+  BITFIELD(35, 2) /* index 628 */,+  TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD,+  TILEGX_OPC_PREFETCH_ADD_L2_FAULT,+  BITFIELD(31, 2) /* index 633 */,+  TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638),+  BITFIELD(33, 2) /* index 638 */,+  TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643),+  BITFIELD(35, 2) /* index 643 */,+  TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD,+  TILEGX_OPC_PREFETCH_ADD_L2,+  BITFIELD(31, 2) /* index 648 */,+  CHILD(653), CHILD(653), CHILD(653), CHILD(673),+  BITFIELD(43, 2) /* index 653 */,+  CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,+  BITFIELD(45, 2) /* index 658 */,+  CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,+  BITFIELD(47, 2) /* index 663 */,+  CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,+  BITFIELD(49, 2) /* index 668 */,+  TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,+  TILEGX_OPC_LD4S_ADD,+  BITFIELD(33, 2) /* index 673 */,+  CHILD(653), CHILD(653), CHILD(653), CHILD(678),+  BITFIELD(35, 2) /* index 678 */,+  CHILD(653), CHILD(653), CHILD(653), CHILD(683),+  BITFIELD(43, 2) /* index 683 */,+  CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  BITFIELD(45, 2) /* index 688 */,+  CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  BITFIELD(47, 2) /* index 693 */,+  CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  BITFIELD(49, 2) /* index 698 */,+  TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,+  BITFIELD(51, 2) /* index 703 */,+  CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD,+  TILEGX_OPC_LDNT2S_ADD,+  BITFIELD(31, 2) /* index 708 */,+  TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713),+  BITFIELD(33, 2) /* index 713 */,+  TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718),+  BITFIELD(35, 2) /* index 718 */,+  TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD,+  TILEGX_OPC_PREFETCH_ADD_L3,+  BITFIELD(51, 2) /* index 723 */,+  TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD,+  TILEGX_OPC_LDNT_ADD,+  BITFIELD(51, 2) /* index 728 */,+  CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR,+  BITFIELD(43, 2) /* index 733 */,+  CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,+  BITFIELD(45, 2) /* index 738 */,+  CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,+  BITFIELD(47, 2) /* index 743 */,+  CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,+  BITFIELD(49, 2) /* index 748 */,+  TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,+  BITFIELD(51, 2) /* index 753 */,+  TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD,+  BITFIELD(51, 2) /* index 758 */,+  TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD,+  TILEGX_OPC_STNT_ADD,+  BITFIELD(51, 2) /* index 763 */,+  TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI,+  TILEGX_OPC_V1CMPLTSI,+  BITFIELD(51, 2) /* index 768 */,+  TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI,+  TILEGX_OPC_V2ADDI,+  BITFIELD(51, 2) /* index 773 */,+  TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI,+  TILEGX_OPC_V2MAXSI,+  BITFIELD(51, 2) /* index 778 */,+  TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(49, 4) /* index 783 */,+  TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,+  TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH,+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,+  TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4,+  TILEGX_OPC_DBLALIGN6,+  BITFIELD(49, 4) /* index 800 */,+  TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4,+  TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD,+  TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4,+  TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR,+  CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,+  BITFIELD(43, 2) /* index 817 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822),+  BITFIELD(45, 2) /* index 822 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827),+  BITFIELD(47, 2) /* index 827 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,+  BITFIELD(49, 4) /* index 832 */,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,+  TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1,+  TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2,+  TILEGX_OPC_STNT4,+  BITFIELD(46, 7) /* index 849 */,+  TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,+  TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,+  TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST,+  TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC,+  TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC,+  TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX,+  TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX,+  TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,+  TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB,+  TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987),+  CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,+  TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,+  TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,+  TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,+  TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,+  TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,+  TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,+  TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,+  TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,+  TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,+  TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,+  TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,+  TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,+  TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,+  TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,+  TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,+  TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,+  TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,+  TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,+  TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,+  TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,+  TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,+  TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,+  TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,+  TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,+  TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,+  BITFIELD(43, 3) /* index 978 */,+  TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV,+  TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH,+  BITFIELD(43, 3) /* index 987 */,+  CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP,+  TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051),+  BITFIELD(31, 2) /* index 996 */,+  CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(33, 2) /* index 1001 */,+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006),+  BITFIELD(35, 2) /* index 1006 */,+  TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(37, 2) /* index 1011 */,+  TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(39, 2) /* index 1016 */,+  TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(41, 2) /* index 1021 */,+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL,+  BITFIELD(33, 2) /* index 1026 */,+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031),+  BITFIELD(35, 2) /* index 1031 */,+  TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(37, 2) /* index 1036 */,+  TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(39, 2) /* index 1041 */,+  TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL,+  BITFIELD(41, 2) /* index 1046 */,+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL,+  BITFIELD(31, 2) /* index 1051 */,+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056),+  BITFIELD(33, 2) /* index 1056 */,+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061),+  BITFIELD(35, 2) /* index 1061 */,+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,+  TILEGX_OPC_PREFETCH_L1_FAULT,+  BITFIELD(43, 3) /* index 1066 */,+  CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135),+  TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U,+  BITFIELD(31, 2) /* index 1075 */,+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080),+  BITFIELD(33, 2) /* index 1080 */,+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085),+  BITFIELD(35, 2) /* index 1085 */,+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,+  BITFIELD(31, 2) /* index 1090 */,+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095),+  BITFIELD(33, 2) /* index 1095 */,+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100),+  BITFIELD(35, 2) /* index 1100 */,+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,+  TILEGX_OPC_PREFETCH_L2_FAULT,+  BITFIELD(31, 2) /* index 1105 */,+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110),+  BITFIELD(33, 2) /* index 1110 */,+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115),+  BITFIELD(35, 2) /* index 1115 */,+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,+  BITFIELD(31, 2) /* index 1120 */,+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125),+  BITFIELD(33, 2) /* index 1125 */,+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130),+  BITFIELD(35, 2) /* index 1130 */,+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S,+  TILEGX_OPC_PREFETCH_L3_FAULT,+  BITFIELD(31, 2) /* index 1135 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140),+  BITFIELD(33, 2) /* index 1140 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145),+  BITFIELD(35, 2) /* index 1145 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,+  BITFIELD(43, 3) /* index 1150 */,+  TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U,+  TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF,+  BITFIELD(43, 3) /* index 1159 */,+  TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1,+  TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE,+  BITFIELD(49, 4) /* index 1168 */,+  TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ,+  TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC,+  TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ,+  TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS,+  TILEGX_OPC_V2CMPLTU,+  BITFIELD(49, 4) /* index 1185 */,+  TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L,+  TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ,+  TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,+  TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU,+  TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB,+  BITFIELD(49, 4) /* index 1202 */,+  TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,+  TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,+  TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,+  TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(49, 4) /* index 1219 */,+  TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,+  TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,+  TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,+  TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE,+  BITFIELD(31, 2) /* index 1236 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(1241),+  BITFIELD(33, 2) /* index 1241 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(1246),+  BITFIELD(35, 2) /* index 1246 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(1251),+  BITFIELD(37, 2) /* index 1251 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(1256),+  BITFIELD(39, 2) /* index 1256 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  CHILD(1261),+  BITFIELD(41, 2) /* index 1261 */,+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,+  TILEGX_OPC_INFOL,+};++static const unsigned short decode_Y0_fsm[178] =+{+  BITFIELD(27, 4) /* index 0 */,+  CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,+  TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123),+  CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168),+  CHILD(173),+  BITFIELD(6, 2) /* index 17 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),+  BITFIELD(8, 2) /* index 22 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),+  BITFIELD(10, 2) /* index 27 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,+  BITFIELD(0, 2) /* index 32 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),+  BITFIELD(2, 2) /* index 37 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),+  BITFIELD(4, 2) /* index 42 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),+  BITFIELD(6, 2) /* index 47 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),+  BITFIELD(8, 2) /* index 52 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),+  BITFIELD(10, 2) /* index 57 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,+  BITFIELD(18, 2) /* index 62 */,+  TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,+  BITFIELD(15, 5) /* index 67 */,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,+  TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,+  TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100),+  CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(12, 3) /* index 100 */,+  TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP,+  TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT,+  TILEGX_OPC_REVBITS,+  BITFIELD(12, 3) /* index 109 */,+  TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1,+  TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  TILEGX_OPC_NONE,+  BITFIELD(18, 2) /* index 118 */,+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,+  BITFIELD(18, 2) /* index 123 */,+  TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX,+  BITFIELD(18, 2) /* index 128 */,+  TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,+  BITFIELD(18, 2) /* index 133 */,+  TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR,+  BITFIELD(12, 2) /* index 138 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143),+  BITFIELD(14, 2) /* index 143 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148),+  BITFIELD(16, 2) /* index 148 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,+  BITFIELD(18, 2) /* index 153 */,+  TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,+  BITFIELD(18, 2) /* index 158 */,+  TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,+  TILEGX_OPC_SHL3ADDX,+  BITFIELD(18, 2) /* index 163 */,+  TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS,+  TILEGX_OPC_MUL_LU_LU,+  BITFIELD(18, 2) /* index 168 */,+  TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS,+  TILEGX_OPC_MULA_LU_LU,+  BITFIELD(18, 2) /* index 173 */,+  TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,+};++static const unsigned short decode_Y1_fsm[167] =+{+  BITFIELD(58, 4) /* index 0 */,+  TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,+  TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122),+  CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE,+  BITFIELD(37, 2) /* index 17 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),+  BITFIELD(39, 2) /* index 22 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),+  BITFIELD(41, 2) /* index 27 */,+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,+  BITFIELD(31, 2) /* index 32 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),+  BITFIELD(33, 2) /* index 37 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),+  BITFIELD(35, 2) /* index 42 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),+  BITFIELD(37, 2) /* index 47 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),+  BITFIELD(39, 2) /* index 52 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),+  BITFIELD(41, 2) /* index 57 */,+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,+  BITFIELD(49, 2) /* index 62 */,+  TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,+  BITFIELD(47, 4) /* index 67 */,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD,+  TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84),+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,+  BITFIELD(43, 3) /* index 84 */,+  CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108),+  CHILD(111), CHILD(114),+  BITFIELD(46, 1) /* index 93 */,+  TILEGX_OPC_NONE, TILEGX_OPC_FNOP,+  BITFIELD(46, 1) /* index 96 */,+  TILEGX_OPC_NONE, TILEGX_OPC_ILL,+  BITFIELD(46, 1) /* index 99 */,+  TILEGX_OPC_NONE, TILEGX_OPC_JALRP,+  BITFIELD(46, 1) /* index 102 */,+  TILEGX_OPC_NONE, TILEGX_OPC_JALR,+  BITFIELD(46, 1) /* index 105 */,+  TILEGX_OPC_NONE, TILEGX_OPC_JRP,+  BITFIELD(46, 1) /* index 108 */,+  TILEGX_OPC_NONE, TILEGX_OPC_JR,+  BITFIELD(46, 1) /* index 111 */,+  TILEGX_OPC_NONE, TILEGX_OPC_LNK,+  BITFIELD(46, 1) /* index 114 */,+  TILEGX_OPC_NONE, TILEGX_OPC_NOP,+  BITFIELD(49, 2) /* index 117 */,+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,+  BITFIELD(49, 2) /* index 122 */,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE,+  BITFIELD(49, 2) /* index 127 */,+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,+  BITFIELD(49, 2) /* index 132 */,+  TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR,+  BITFIELD(43, 2) /* index 137 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142),+  BITFIELD(45, 2) /* index 142 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147),+  BITFIELD(47, 2) /* index 147 */,+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,+  BITFIELD(49, 2) /* index 152 */,+  TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,+  BITFIELD(49, 2) /* index 157 */,+  TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,+  TILEGX_OPC_SHL3ADDX,+  BITFIELD(49, 2) /* index 162 */,+  TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,+};++static const unsigned short decode_Y2_fsm[118] =+{+  BITFIELD(62, 2) /* index 0 */,+  TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109),+  BITFIELD(55, 3) /* index 5 */,+  CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40),+  CHILD(43),+  BITFIELD(26, 1) /* index 14 */,+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1U,+  BITFIELD(26, 1) /* index 17 */,+  CHILD(20), CHILD(30),+  BITFIELD(51, 2) /* index 20 */,+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25),+  BITFIELD(53, 2) /* index 25 */,+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,+  TILEGX_OPC_PREFETCH_L1_FAULT,+  BITFIELD(51, 2) /* index 30 */,+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35),+  BITFIELD(53, 2) /* index 35 */,+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,+  BITFIELD(26, 1) /* index 40 */,+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2U,+  BITFIELD(26, 1) /* index 43 */,+  CHILD(46), CHILD(56),+  BITFIELD(51, 2) /* index 46 */,+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51),+  BITFIELD(53, 2) /* index 51 */,+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,+  TILEGX_OPC_PREFETCH_L2_FAULT,+  BITFIELD(51, 2) /* index 56 */,+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61),+  BITFIELD(53, 2) /* index 61 */,+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,+  BITFIELD(56, 2) /* index 66 */,+  CHILD(71), CHILD(74), CHILD(90), CHILD(93),+  BITFIELD(26, 1) /* index 71 */,+  TILEGX_OPC_NONE, TILEGX_OPC_LD4S,+  BITFIELD(26, 1) /* index 74 */,+  TILEGX_OPC_NONE, CHILD(77),+  BITFIELD(51, 2) /* index 77 */,+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82),+  BITFIELD(53, 2) /* index 82 */,+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87),+  BITFIELD(55, 1) /* index 87 */,+  TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT,+  BITFIELD(26, 1) /* index 90 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_LD,+  BITFIELD(26, 1) /* index 93 */,+  CHILD(96), TILEGX_OPC_LD,+  BITFIELD(51, 2) /* index 96 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101),+  BITFIELD(53, 2) /* index 101 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106),+  BITFIELD(55, 1) /* index 106 */,+  TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,+  BITFIELD(26, 1) /* index 109 */,+  CHILD(112), CHILD(115),+  BITFIELD(57, 1) /* index 112 */,+  TILEGX_OPC_ST1, TILEGX_OPC_ST4,+  BITFIELD(57, 1) /* index 115 */,+  TILEGX_OPC_ST2, TILEGX_OPC_ST,+};++#undef BITFIELD+#undef CHILD++const unsigned short * const+tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] =+{+  decode_X0_fsm,+  decode_X1_fsm,+  decode_Y0_fsm,+  decode_Y1_fsm,+  decode_Y2_fsm+};++const struct tilegx_operand tilegx_operands[35] =+{+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0),+    8, 1, 0, 0, 0, 0,+    create_Imm8_X0, get_Imm8_X0+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1),+    8, 1, 0, 0, 0, 0,+    create_Imm8_X1, get_Imm8_X1+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0),+    8, 1, 0, 0, 0, 0,+    create_Imm8_Y0, get_Imm8_Y0+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1),+    8, 1, 0, 0, 0, 0,+    create_Imm8_Y1, get_Imm8_Y1+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST),+    16, 1, 0, 0, 0, 0,+    create_Imm16_X0, get_Imm16_X0+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST),+    16, 1, 0, 0, 0, 0,+    create_Imm16_X1, get_Imm16_X1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 0, 1, 0, 0,+    create_Dest_X1, get_Dest_X1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcA_X1, get_SrcA_X1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 0, 1, 0, 0,+    create_Dest_X0, get_Dest_X0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcA_X0, get_SrcA_X0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 0, 1, 0, 0,+    create_Dest_Y0, get_Dest_Y0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcA_Y0, get_SrcA_Y0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 0, 1, 0, 0,+    create_Dest_Y1, get_Dest_Y1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcA_Y1, get_SrcA_Y1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcA_Y2, get_SrcA_Y2+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 1, 0, 0,+    create_SrcA_X1, get_SrcA_X1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcB_X0, get_SrcB_X0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcB_X1, get_SrcB_X1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcB_Y0, get_SrcB_Y0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcB_Y1, get_SrcB_Y1+  },+  {+    TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1),+    17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,+    create_BrOff_X1, get_BrOff_X1+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0),+    6, 0, 0, 0, 0, 0,+    create_BFStart_X0, get_BFStart_X0+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0),+    6, 0, 0, 0, 0, 0,+    create_BFEnd_X0, get_BFEnd_X0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 1, 0, 0,+    create_Dest_X0, get_Dest_X0+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 1, 0, 0,+    create_Dest_Y0, get_Dest_Y0+  },+  {+    TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1),+    27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,+    create_JumpOff_X1, get_JumpOff_X1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 0, 1, 0, 0,+    create_SrcBDest_Y2, get_SrcBDest_Y2+  },+  {+    TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1),+    14, 0, 0, 0, 0, 0,+    create_MF_Imm14_X1, get_MF_Imm14_X1+  },+  {+    TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1),+    14, 0, 0, 0, 0, 0,+    create_MT_Imm14_X1, get_MT_Imm14_X1+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0),+    6, 0, 0, 0, 0, 0,+    create_ShAmt_X0, get_ShAmt_X0+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1),+    6, 0, 0, 0, 0, 0,+    create_ShAmt_X1, get_ShAmt_X1+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0),+    6, 0, 0, 0, 0, 0,+    create_ShAmt_Y0, get_ShAmt_Y0+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1),+    6, 0, 0, 0, 0, 0,+    create_ShAmt_Y1, get_ShAmt_Y1+  },+  {+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),+    6, 0, 1, 0, 0, 0,+    create_SrcBDest_Y2, get_SrcBDest_Y2+  },+  {+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1),+    8, 1, 0, 0, 0, 0,+    create_Dest_Imm8_X1, get_Dest_Imm8_X1+  }+};++/* Given a set of bundle bits and a specific pipe, returns which+ * instruction the bundle contains in that pipe.+ */+const struct tilegx_opcode *+find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe)+{+  const unsigned short *table = tilegx_bundle_decoder_fsms[pipe];+  int index = 0;++  while (1)+  {+    unsigned short bitspec = table[index];+    unsigned int bitfield =+      ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);++    unsigned short next = table[index + 1 + bitfield];+    if (next <= TILEGX_OPC_NONE)+      return &tilegx_opcodes[next];++    index = next - TILEGX_OPC_NONE;+  }+}++int+parse_insn_tilegx(tilegx_bundle_bits bits,+                  unsigned long long pc,+                  struct tilegx_decoded_instruction+                  decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE])+{+  int num_instructions = 0;+  int pipe;++  int min_pipe, max_pipe;+  if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0)+  {+    min_pipe = TILEGX_PIPELINE_X0;+    max_pipe = TILEGX_PIPELINE_X1;+  }+  else+  {+    min_pipe = TILEGX_PIPELINE_Y0;+    max_pipe = TILEGX_PIPELINE_Y2;+  }++  /* For each pipe, find an instruction that fits. */+  for (pipe = min_pipe; pipe <= max_pipe; pipe++)+  {+    const struct tilegx_opcode *opc;+    struct tilegx_decoded_instruction *d;+    int i;++    d = &decoded[num_instructions++];+    opc = find_opcode (bits, (tilegx_pipeline)pipe);+    d->opcode = opc;++    /* Decode each operand, sign extending, etc. as appropriate. */+    for (i = 0; i < opc->num_operands; i++)+    {+      const struct tilegx_operand *op =+        &tilegx_operands[opc->operands[pipe][i]];+      int raw_opval = op->extract (bits);+      long long opval;++      if (op->is_signed)+      {+        /* Sign-extend the operand. */+        int shift = (int)((sizeof(int) * 8) - op->num_bits);+        raw_opval = (raw_opval << shift) >> shift;+      }++      /* Adjust PC-relative scaled branch offsets. */+      if (op->type == TILEGX_OP_TYPE_ADDRESS)+        opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc;+      else+        opval = raw_opval;++      /* Record the final value. */+      d->operands[i] = op;+      d->operand_values[i] = opval;+    }+  }++  return num_instructions;+}++struct tilegx_spr+{+  /* The number */+  int number;++  /* The name */+  const char *name;+};++static int+tilegx_spr_compare (const void *a_ptr, const void *b_ptr)+{+  const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr;+  const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr;+  return (a->number - b->number);+}++const struct tilegx_spr tilegx_sprs[] = {+  { 0, "MPL_MEM_ERROR_SET_0" },+  { 1, "MPL_MEM_ERROR_SET_1" },+  { 2, "MPL_MEM_ERROR_SET_2" },+  { 3, "MPL_MEM_ERROR_SET_3" },+  { 4, "MPL_MEM_ERROR" },+  { 5, "MEM_ERROR_CBOX_ADDR" },+  { 6, "MEM_ERROR_CBOX_STATUS" },+  { 7, "MEM_ERROR_ENABLE" },+  { 8, "MEM_ERROR_MBOX_ADDR" },+  { 9, "MEM_ERROR_MBOX_STATUS" },+  { 10, "SBOX_ERROR" },+  { 11, "XDN_DEMUX_ERROR" },+  { 256, "MPL_SINGLE_STEP_3_SET_0" },+  { 257, "MPL_SINGLE_STEP_3_SET_1" },+  { 258, "MPL_SINGLE_STEP_3_SET_2" },+  { 259, "MPL_SINGLE_STEP_3_SET_3" },+  { 260, "MPL_SINGLE_STEP_3" },+  { 261, "SINGLE_STEP_CONTROL_3" },+  { 512, "MPL_SINGLE_STEP_2_SET_0" },+  { 513, "MPL_SINGLE_STEP_2_SET_1" },+  { 514, "MPL_SINGLE_STEP_2_SET_2" },+  { 515, "MPL_SINGLE_STEP_2_SET_3" },+  { 516, "MPL_SINGLE_STEP_2" },+  { 517, "SINGLE_STEP_CONTROL_2" },+  { 768, "MPL_SINGLE_STEP_1_SET_0" },+  { 769, "MPL_SINGLE_STEP_1_SET_1" },+  { 770, "MPL_SINGLE_STEP_1_SET_2" },+  { 771, "MPL_SINGLE_STEP_1_SET_3" },+  { 772, "MPL_SINGLE_STEP_1" },+  { 773, "SINGLE_STEP_CONTROL_1" },+  { 1024, "MPL_SINGLE_STEP_0_SET_0" },+  { 1025, "MPL_SINGLE_STEP_0_SET_1" },+  { 1026, "MPL_SINGLE_STEP_0_SET_2" },+  { 1027, "MPL_SINGLE_STEP_0_SET_3" },+  { 1028, "MPL_SINGLE_STEP_0" },+  { 1029, "SINGLE_STEP_CONTROL_0" },+  { 1280, "MPL_IDN_COMPLETE_SET_0" },+  { 1281, "MPL_IDN_COMPLETE_SET_1" },+  { 1282, "MPL_IDN_COMPLETE_SET_2" },+  { 1283, "MPL_IDN_COMPLETE_SET_3" },+  { 1284, "MPL_IDN_COMPLETE" },+  { 1285, "IDN_COMPLETE_PENDING" },+  { 1536, "MPL_UDN_COMPLETE_SET_0" },+  { 1537, "MPL_UDN_COMPLETE_SET_1" },+  { 1538, "MPL_UDN_COMPLETE_SET_2" },+  { 1539, "MPL_UDN_COMPLETE_SET_3" },+  { 1540, "MPL_UDN_COMPLETE" },+  { 1541, "UDN_COMPLETE_PENDING" },+  { 1792, "MPL_ITLB_MISS_SET_0" },+  { 1793, "MPL_ITLB_MISS_SET_1" },+  { 1794, "MPL_ITLB_MISS_SET_2" },+  { 1795, "MPL_ITLB_MISS_SET_3" },+  { 1796, "MPL_ITLB_MISS" },+  { 1797, "ITLB_TSB_BASE_ADDR_0" },+  { 1798, "ITLB_TSB_BASE_ADDR_1" },+  { 1920, "ITLB_CURRENT_ATTR" },+  { 1921, "ITLB_CURRENT_PA" },+  { 1922, "ITLB_CURRENT_VA" },+  { 1923, "ITLB_INDEX" },+  { 1924, "ITLB_MATCH_0" },+  { 1925, "ITLB_PERF" },+  { 1926, "ITLB_PR" },+  { 1927, "ITLB_TSB_ADDR_0" },+  { 1928, "ITLB_TSB_ADDR_1" },+  { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" },+  { 1930, "ITLB_TSB_FILL_MATCH" },+  { 1931, "NUMBER_ITLB" },+  { 1932, "REPLACEMENT_ITLB" },+  { 1933, "WIRED_ITLB" },+  { 2048, "MPL_ILL_SET_0" },+  { 2049, "MPL_ILL_SET_1" },+  { 2050, "MPL_ILL_SET_2" },+  { 2051, "MPL_ILL_SET_3" },+  { 2052, "MPL_ILL" },+  { 2304, "MPL_GPV_SET_0" },+  { 2305, "MPL_GPV_SET_1" },+  { 2306, "MPL_GPV_SET_2" },+  { 2307, "MPL_GPV_SET_3" },+  { 2308, "MPL_GPV" },+  { 2309, "GPV_REASON" },+  { 2560, "MPL_IDN_ACCESS_SET_0" },+  { 2561, "MPL_IDN_ACCESS_SET_1" },+  { 2562, "MPL_IDN_ACCESS_SET_2" },+  { 2563, "MPL_IDN_ACCESS_SET_3" },+  { 2564, "MPL_IDN_ACCESS" },+  { 2565, "IDN_DEMUX_COUNT_0" },+  { 2566, "IDN_DEMUX_COUNT_1" },+  { 2567, "IDN_FLUSH_EGRESS" },+  { 2568, "IDN_PENDING" },+  { 2569, "IDN_ROUTE_ORDER" },+  { 2570, "IDN_SP_FIFO_CNT" },+  { 2688, "IDN_DATA_AVAIL" },+  { 2816, "MPL_UDN_ACCESS_SET_0" },+  { 2817, "MPL_UDN_ACCESS_SET_1" },+  { 2818, "MPL_UDN_ACCESS_SET_2" },+  { 2819, "MPL_UDN_ACCESS_SET_3" },+  { 2820, "MPL_UDN_ACCESS" },+  { 2821, "UDN_DEMUX_COUNT_0" },+  { 2822, "UDN_DEMUX_COUNT_1" },+  { 2823, "UDN_DEMUX_COUNT_2" },+  { 2824, "UDN_DEMUX_COUNT_3" },+  { 2825, "UDN_FLUSH_EGRESS" },+  { 2826, "UDN_PENDING" },+  { 2827, "UDN_ROUTE_ORDER" },+  { 2828, "UDN_SP_FIFO_CNT" },+  { 2944, "UDN_DATA_AVAIL" },+  { 3072, "MPL_SWINT_3_SET_0" },+  { 3073, "MPL_SWINT_3_SET_1" },+  { 3074, "MPL_SWINT_3_SET_2" },+  { 3075, "MPL_SWINT_3_SET_3" },+  { 3076, "MPL_SWINT_3" },+  { 3328, "MPL_SWINT_2_SET_0" },+  { 3329, "MPL_SWINT_2_SET_1" },+  { 3330, "MPL_SWINT_2_SET_2" },+  { 3331, "MPL_SWINT_2_SET_3" },+  { 3332, "MPL_SWINT_2" },+  { 3584, "MPL_SWINT_1_SET_0" },+  { 3585, "MPL_SWINT_1_SET_1" },+  { 3586, "MPL_SWINT_1_SET_2" },+  { 3587, "MPL_SWINT_1_SET_3" },+  { 3588, "MPL_SWINT_1" },+  { 3840, "MPL_SWINT_0_SET_0" },+  { 3841, "MPL_SWINT_0_SET_1" },+  { 3842, "MPL_SWINT_0_SET_2" },+  { 3843, "MPL_SWINT_0_SET_3" },+  { 3844, "MPL_SWINT_0" },+  { 4096, "MPL_ILL_TRANS_SET_0" },+  { 4097, "MPL_ILL_TRANS_SET_1" },+  { 4098, "MPL_ILL_TRANS_SET_2" },+  { 4099, "MPL_ILL_TRANS_SET_3" },+  { 4100, "MPL_ILL_TRANS" },+  { 4101, "ILL_TRANS_REASON" },+  { 4102, "ILL_VA_PC" },+  { 4352, "MPL_UNALIGN_DATA_SET_0" },+  { 4353, "MPL_UNALIGN_DATA_SET_1" },+  { 4354, "MPL_UNALIGN_DATA_SET_2" },+  { 4355, "MPL_UNALIGN_DATA_SET_3" },+  { 4356, "MPL_UNALIGN_DATA" },+  { 4608, "MPL_DTLB_MISS_SET_0" },+  { 4609, "MPL_DTLB_MISS_SET_1" },+  { 4610, "MPL_DTLB_MISS_SET_2" },+  { 4611, "MPL_DTLB_MISS_SET_3" },+  { 4612, "MPL_DTLB_MISS" },+  { 4613, "DTLB_TSB_BASE_ADDR_0" },+  { 4614, "DTLB_TSB_BASE_ADDR_1" },+  { 4736, "AAR" },+  { 4737, "CACHE_PINNED_WAYS" },+  { 4738, "DTLB_BAD_ADDR" },+  { 4739, "DTLB_BAD_ADDR_REASON" },+  { 4740, "DTLB_CURRENT_ATTR" },+  { 4741, "DTLB_CURRENT_PA" },+  { 4742, "DTLB_CURRENT_VA" },+  { 4743, "DTLB_INDEX" },+  { 4744, "DTLB_MATCH_0" },+  { 4745, "DTLB_PERF" },+  { 4746, "DTLB_TSB_ADDR_0" },+  { 4747, "DTLB_TSB_ADDR_1" },+  { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" },+  { 4749, "DTLB_TSB_FILL_MATCH" },+  { 4750, "NUMBER_DTLB" },+  { 4751, "REPLACEMENT_DTLB" },+  { 4752, "WIRED_DTLB" },+  { 4864, "MPL_DTLB_ACCESS_SET_0" },+  { 4865, "MPL_DTLB_ACCESS_SET_1" },+  { 4866, "MPL_DTLB_ACCESS_SET_2" },+  { 4867, "MPL_DTLB_ACCESS_SET_3" },+  { 4868, "MPL_DTLB_ACCESS" },+  { 5120, "MPL_IDN_FIREWALL_SET_0" },+  { 5121, "MPL_IDN_FIREWALL_SET_1" },+  { 5122, "MPL_IDN_FIREWALL_SET_2" },+  { 5123, "MPL_IDN_FIREWALL_SET_3" },+  { 5124, "MPL_IDN_FIREWALL" },+  { 5125, "IDN_DIRECTION_PROTECT" },+  { 5376, "MPL_UDN_FIREWALL_SET_0" },+  { 5377, "MPL_UDN_FIREWALL_SET_1" },+  { 5378, "MPL_UDN_FIREWALL_SET_2" },+  { 5379, "MPL_UDN_FIREWALL_SET_3" },+  { 5380, "MPL_UDN_FIREWALL" },+  { 5381, "UDN_DIRECTION_PROTECT" },+  { 5632, "MPL_TILE_TIMER_SET_0" },+  { 5633, "MPL_TILE_TIMER_SET_1" },+  { 5634, "MPL_TILE_TIMER_SET_2" },+  { 5635, "MPL_TILE_TIMER_SET_3" },+  { 5636, "MPL_TILE_TIMER" },+  { 5637, "TILE_TIMER_CONTROL" },+  { 5888, "MPL_AUX_TILE_TIMER_SET_0" },+  { 5889, "MPL_AUX_TILE_TIMER_SET_1" },+  { 5890, "MPL_AUX_TILE_TIMER_SET_2" },+  { 5891, "MPL_AUX_TILE_TIMER_SET_3" },+  { 5892, "MPL_AUX_TILE_TIMER" },+  { 5893, "AUX_TILE_TIMER_CONTROL" },+  { 6144, "MPL_IDN_TIMER_SET_0" },+  { 6145, "MPL_IDN_TIMER_SET_1" },+  { 6146, "MPL_IDN_TIMER_SET_2" },+  { 6147, "MPL_IDN_TIMER_SET_3" },+  { 6148, "MPL_IDN_TIMER" },+  { 6149, "IDN_DEADLOCK_COUNT" },+  { 6150, "IDN_DEADLOCK_TIMEOUT" },+  { 6400, "MPL_UDN_TIMER_SET_0" },+  { 6401, "MPL_UDN_TIMER_SET_1" },+  { 6402, "MPL_UDN_TIMER_SET_2" },+  { 6403, "MPL_UDN_TIMER_SET_3" },+  { 6404, "MPL_UDN_TIMER" },+  { 6405, "UDN_DEADLOCK_COUNT" },+  { 6406, "UDN_DEADLOCK_TIMEOUT" },+  { 6656, "MPL_IDN_AVAIL_SET_0" },+  { 6657, "MPL_IDN_AVAIL_SET_1" },+  { 6658, "MPL_IDN_AVAIL_SET_2" },+  { 6659, "MPL_IDN_AVAIL_SET_3" },+  { 6660, "MPL_IDN_AVAIL" },+  { 6661, "IDN_AVAIL_EN" },+  { 6912, "MPL_UDN_AVAIL_SET_0" },+  { 6913, "MPL_UDN_AVAIL_SET_1" },+  { 6914, "MPL_UDN_AVAIL_SET_2" },+  { 6915, "MPL_UDN_AVAIL_SET_3" },+  { 6916, "MPL_UDN_AVAIL" },+  { 6917, "UDN_AVAIL_EN" },+  { 7168, "MPL_IPI_3_SET_0" },+  { 7169, "MPL_IPI_3_SET_1" },+  { 7170, "MPL_IPI_3_SET_2" },+  { 7171, "MPL_IPI_3_SET_3" },+  { 7172, "MPL_IPI_3" },+  { 7173, "IPI_EVENT_3" },+  { 7174, "IPI_EVENT_RESET_3" },+  { 7175, "IPI_EVENT_SET_3" },+  { 7176, "IPI_MASK_3" },+  { 7177, "IPI_MASK_RESET_3" },+  { 7178, "IPI_MASK_SET_3" },+  { 7424, "MPL_IPI_2_SET_0" },+  { 7425, "MPL_IPI_2_SET_1" },+  { 7426, "MPL_IPI_2_SET_2" },+  { 7427, "MPL_IPI_2_SET_3" },+  { 7428, "MPL_IPI_2" },+  { 7429, "IPI_EVENT_2" },+  { 7430, "IPI_EVENT_RESET_2" },+  { 7431, "IPI_EVENT_SET_2" },+  { 7432, "IPI_MASK_2" },+  { 7433, "IPI_MASK_RESET_2" },+  { 7434, "IPI_MASK_SET_2" },+  { 7680, "MPL_IPI_1_SET_0" },+  { 7681, "MPL_IPI_1_SET_1" },+  { 7682, "MPL_IPI_1_SET_2" },+  { 7683, "MPL_IPI_1_SET_3" },+  { 7684, "MPL_IPI_1" },+  { 7685, "IPI_EVENT_1" },+  { 7686, "IPI_EVENT_RESET_1" },+  { 7687, "IPI_EVENT_SET_1" },+  { 7688, "IPI_MASK_1" },+  { 7689, "IPI_MASK_RESET_1" },+  { 7690, "IPI_MASK_SET_1" },+  { 7936, "MPL_IPI_0_SET_0" },+  { 7937, "MPL_IPI_0_SET_1" },+  { 7938, "MPL_IPI_0_SET_2" },+  { 7939, "MPL_IPI_0_SET_3" },+  { 7940, "MPL_IPI_0" },+  { 7941, "IPI_EVENT_0" },+  { 7942, "IPI_EVENT_RESET_0" },+  { 7943, "IPI_EVENT_SET_0" },+  { 7944, "IPI_MASK_0" },+  { 7945, "IPI_MASK_RESET_0" },+  { 7946, "IPI_MASK_SET_0" },+  { 8192, "MPL_PERF_COUNT_SET_0" },+  { 8193, "MPL_PERF_COUNT_SET_1" },+  { 8194, "MPL_PERF_COUNT_SET_2" },+  { 8195, "MPL_PERF_COUNT_SET_3" },+  { 8196, "MPL_PERF_COUNT" },+  { 8197, "PERF_COUNT_0" },+  { 8198, "PERF_COUNT_1" },+  { 8199, "PERF_COUNT_CTL" },+  { 8200, "PERF_COUNT_DN_CTL" },+  { 8201, "PERF_COUNT_STS" },+  { 8202, "WATCH_MASK" },+  { 8203, "WATCH_VAL" },+  { 8448, "MPL_AUX_PERF_COUNT_SET_0" },+  { 8449, "MPL_AUX_PERF_COUNT_SET_1" },+  { 8450, "MPL_AUX_PERF_COUNT_SET_2" },+  { 8451, "MPL_AUX_PERF_COUNT_SET_3" },+  { 8452, "MPL_AUX_PERF_COUNT" },+  { 8453, "AUX_PERF_COUNT_0" },+  { 8454, "AUX_PERF_COUNT_1" },+  { 8455, "AUX_PERF_COUNT_CTL" },+  { 8456, "AUX_PERF_COUNT_STS" },+  { 8704, "MPL_INTCTRL_3_SET_0" },+  { 8705, "MPL_INTCTRL_3_SET_1" },+  { 8706, "MPL_INTCTRL_3_SET_2" },+  { 8707, "MPL_INTCTRL_3_SET_3" },+  { 8708, "MPL_INTCTRL_3" },+  { 8709, "INTCTRL_3_STATUS" },+  { 8710, "INTERRUPT_MASK_3" },+  { 8711, "INTERRUPT_MASK_RESET_3" },+  { 8712, "INTERRUPT_MASK_SET_3" },+  { 8713, "INTERRUPT_VECTOR_BASE_3" },+  { 8714, "SINGLE_STEP_EN_0_3" },+  { 8715, "SINGLE_STEP_EN_1_3" },+  { 8716, "SINGLE_STEP_EN_2_3" },+  { 8717, "SINGLE_STEP_EN_3_3" },+  { 8832, "EX_CONTEXT_3_0" },+  { 8833, "EX_CONTEXT_3_1" },+  { 8834, "SYSTEM_SAVE_3_0" },+  { 8835, "SYSTEM_SAVE_3_1" },+  { 8836, "SYSTEM_SAVE_3_2" },+  { 8837, "SYSTEM_SAVE_3_3" },+  { 8960, "MPL_INTCTRL_2_SET_0" },+  { 8961, "MPL_INTCTRL_2_SET_1" },+  { 8962, "MPL_INTCTRL_2_SET_2" },+  { 8963, "MPL_INTCTRL_2_SET_3" },+  { 8964, "MPL_INTCTRL_2" },+  { 8965, "INTCTRL_2_STATUS" },+  { 8966, "INTERRUPT_MASK_2" },+  { 8967, "INTERRUPT_MASK_RESET_2" },+  { 8968, "INTERRUPT_MASK_SET_2" },+  { 8969, "INTERRUPT_VECTOR_BASE_2" },+  { 8970, "SINGLE_STEP_EN_0_2" },+  { 8971, "SINGLE_STEP_EN_1_2" },+  { 8972, "SINGLE_STEP_EN_2_2" },+  { 8973, "SINGLE_STEP_EN_3_2" },+  { 9088, "EX_CONTEXT_2_0" },+  { 9089, "EX_CONTEXT_2_1" },+  { 9090, "SYSTEM_SAVE_2_0" },+  { 9091, "SYSTEM_SAVE_2_1" },+  { 9092, "SYSTEM_SAVE_2_2" },+  { 9093, "SYSTEM_SAVE_2_3" },+  { 9216, "MPL_INTCTRL_1_SET_0" },+  { 9217, "MPL_INTCTRL_1_SET_1" },+  { 9218, "MPL_INTCTRL_1_SET_2" },+  { 9219, "MPL_INTCTRL_1_SET_3" },+  { 9220, "MPL_INTCTRL_1" },+  { 9221, "INTCTRL_1_STATUS" },+  { 9222, "INTERRUPT_MASK_1" },+  { 9223, "INTERRUPT_MASK_RESET_1" },+  { 9224, "INTERRUPT_MASK_SET_1" },+  { 9225, "INTERRUPT_VECTOR_BASE_1" },+  { 9226, "SINGLE_STEP_EN_0_1" },+  { 9227, "SINGLE_STEP_EN_1_1" },+  { 9228, "SINGLE_STEP_EN_2_1" },+  { 9229, "SINGLE_STEP_EN_3_1" },+  { 9344, "EX_CONTEXT_1_0" },+  { 9345, "EX_CONTEXT_1_1" },+  { 9346, "SYSTEM_SAVE_1_0" },+  { 9347, "SYSTEM_SAVE_1_1" },+  { 9348, "SYSTEM_SAVE_1_2" },+  { 9349, "SYSTEM_SAVE_1_3" },+  { 9472, "MPL_INTCTRL_0_SET_0" },+  { 9473, "MPL_INTCTRL_0_SET_1" },+  { 9474, "MPL_INTCTRL_0_SET_2" },+  { 9475, "MPL_INTCTRL_0_SET_3" },+  { 9476, "MPL_INTCTRL_0" },+  { 9477, "INTCTRL_0_STATUS" },+  { 9478, "INTERRUPT_MASK_0" },+  { 9479, "INTERRUPT_MASK_RESET_0" },+  { 9480, "INTERRUPT_MASK_SET_0" },+  { 9481, "INTERRUPT_VECTOR_BASE_0" },+  { 9482, "SINGLE_STEP_EN_0_0" },+  { 9483, "SINGLE_STEP_EN_1_0" },+  { 9484, "SINGLE_STEP_EN_2_0" },+  { 9485, "SINGLE_STEP_EN_3_0" },+  { 9600, "EX_CONTEXT_0_0" },+  { 9601, "EX_CONTEXT_0_1" },+  { 9602, "SYSTEM_SAVE_0_0" },+  { 9603, "SYSTEM_SAVE_0_1" },+  { 9604, "SYSTEM_SAVE_0_2" },+  { 9605, "SYSTEM_SAVE_0_3" },+  { 9728, "MPL_BOOT_ACCESS_SET_0" },+  { 9729, "MPL_BOOT_ACCESS_SET_1" },+  { 9730, "MPL_BOOT_ACCESS_SET_2" },+  { 9731, "MPL_BOOT_ACCESS_SET_3" },+  { 9732, "MPL_BOOT_ACCESS" },+  { 9733, "BIG_ENDIAN_CONFIG" },+  { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" },+  { 9735, "CACHE_INVALIDATION_MASK_0" },+  { 9736, "CACHE_INVALIDATION_MASK_1" },+  { 9737, "CACHE_INVALIDATION_MASK_2" },+  { 9738, "CBOX_CACHEASRAM_CONFIG" },+  { 9739, "CBOX_CACHE_CONFIG" },+  { 9740, "CBOX_HOME_MAP_ADDR" },+  { 9741, "CBOX_HOME_MAP_DATA" },+  { 9742, "CBOX_MMAP_0" },+  { 9743, "CBOX_MMAP_1" },+  { 9744, "CBOX_MMAP_2" },+  { 9745, "CBOX_MMAP_3" },+  { 9746, "CBOX_MSR" },+  { 9747, "DIAG_BCST_CTL" },+  { 9748, "DIAG_BCST_MASK" },+  { 9749, "DIAG_BCST_TRIGGER" },+  { 9750, "DIAG_MUX_CTL" },+  { 9751, "DIAG_TRACE_CTL" },+  { 9752, "DIAG_TRACE_DATA" },+  { 9753, "DIAG_TRACE_STS" },+  { 9754, "IDN_DEMUX_BUF_THRESH" },+  { 9755, "L1_I_PIN_WAY_0" },+  { 9756, "MEM_ROUTE_ORDER" },+  { 9757, "MEM_STRIPE_CONFIG" },+  { 9758, "PERF_COUNT_PLS" },+  { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" },+  { 9760, "QUIESCE_CTL" },+  { 9761, "RSHIM_COORD" },+  { 9762, "SBOX_CONFIG" },+  { 9763, "UDN_DEMUX_BUF_THRESH" },+  { 9764, "XDN_CORE_STARVATION_COUNT" },+  { 9765, "XDN_ROUND_ROBIN_ARB_CTL" },+  { 9856, "CYCLE_MODIFY" },+  { 9857, "I_AAR" },+  { 9984, "MPL_WORLD_ACCESS_SET_0" },+  { 9985, "MPL_WORLD_ACCESS_SET_1" },+  { 9986, "MPL_WORLD_ACCESS_SET_2" },+  { 9987, "MPL_WORLD_ACCESS_SET_3" },+  { 9988, "MPL_WORLD_ACCESS" },+  { 9989, "DONE" },+  { 9990, "DSTREAM_PF" },+  { 9991, "FAIL" },+  { 9992, "INTERRUPT_CRITICAL_SECTION" },+  { 9993, "PASS" },+  { 9994, "PSEUDO_RANDOM_NUMBER" },+  { 9995, "TILE_COORD" },+  { 9996, "TILE_RTF_HWM" },+  { 10112, "CMPEXCH_VALUE" },+  { 10113, "CYCLE" },+  { 10114, "EVENT_BEGIN" },+  { 10115, "EVENT_END" },+  { 10116, "PROC_STATUS" },+  { 10117, "SIM_CONTROL" },+  { 10118, "SIM_SOCKET" },+  { 10119, "STATUS_SATURATE" },+  { 10240, "MPL_I_ASID_SET_0" },+  { 10241, "MPL_I_ASID_SET_1" },+  { 10242, "MPL_I_ASID_SET_2" },+  { 10243, "MPL_I_ASID_SET_3" },+  { 10244, "MPL_I_ASID" },+  { 10245, "I_ASID" },+  { 10496, "MPL_D_ASID_SET_0" },+  { 10497, "MPL_D_ASID_SET_1" },+  { 10498, "MPL_D_ASID_SET_2" },+  { 10499, "MPL_D_ASID_SET_3" },+  { 10500, "MPL_D_ASID" },+  { 10501, "D_ASID" },+  { 10752, "MPL_DOUBLE_FAULT_SET_0" },+  { 10753, "MPL_DOUBLE_FAULT_SET_1" },+  { 10754, "MPL_DOUBLE_FAULT_SET_2" },+  { 10755, "MPL_DOUBLE_FAULT_SET_3" },+  { 10756, "MPL_DOUBLE_FAULT" },+  { 10757, "LAST_INTERRUPT_REASON" },+};++const int tilegx_num_sprs = 441;++const char *+get_tilegx_spr_name (int num)+{+  void *result;+  struct tilegx_spr key;++  key.number = num;+  result = bsearch((const void *) &key, (const void *) tilegx_sprs,+                   tilegx_num_sprs, sizeof (struct tilegx_spr),+                   tilegx_spr_compare);++  if (result == NULL)+  {+    return (NULL);+  }+  else+  {+    struct tilegx_spr *result_ptr = (struct tilegx_spr *) result;+    return (result_ptr->name);+  }+}++int+print_insn_tilegx (unsigned char * memaddr)+{+  struct tilegx_decoded_instruction+    decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];+  unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES];+  int i, num_instructions, num_printed;+  tilegx_mnemonic padding_mnemonic;++  memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES);++  /* Parse the instructions in the bundle. */+  num_instructions =+    parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded);++  /* Print the instructions in the bundle. */+  printf("{ ");+  num_printed = 0;++  /* Determine which nop opcode is used for padding and should be skipped. */+  padding_mnemonic = TILEGX_OPC_FNOP;+  for (i = 0; i < num_instructions; i++)+  {+    if (!decoded[i].opcode->can_bundle)+    {+      /* Instructions that cannot be bundled are padded out with nops,+         rather than fnops. Displaying them is always clutter. */+      padding_mnemonic = TILEGX_OPC_NOP;+      break;+    }+  }++  for (i = 0; i < num_instructions; i++)+  {+    const struct tilegx_opcode *opcode = decoded[i].opcode;+    const char *name;+    int j;++    /* Do not print out fnops, unless everything is an fnop, in+       which case we will print out just the last one. */+    if (opcode->mnemonic == padding_mnemonic+        && (num_printed > 0 || i + 1 < num_instructions))+      continue;++    if (num_printed > 0)+      printf(" ; ");+    ++num_printed;++    name = opcode->name;+    if (name == NULL)+      name = "<invalid>";+    printf("%s", name);++    for (j = 0; j < opcode->num_operands; j++)+    {+      unsigned long long num;+      const struct tilegx_operand *op;+      const char *spr_name;++      if (j > 0)+        printf (",");+      printf (" ");++      num = decoded[i].operand_values[j];++      op = decoded[i].operands[j];+      switch (op->type)+      {+      case TILEGX_OP_TYPE_REGISTER:+        printf ("%s", tilegx_register_names[(int)num]);+        break;+      case TILEGX_OP_TYPE_SPR:+        spr_name = get_tilegx_spr_name(num);+        if (spr_name != NULL)+          printf ("%s", spr_name);+        else+          printf ("%d", (int)num);+        break;+      case TILEGX_OP_TYPE_IMMEDIATE:+        printf ("%d", (int)num);+        break;+      case TILEGX_OP_TYPE_ADDRESS:+        printf ("0x%016llx", num);+        break;+      default:+        abort ();+      }+    }+  }+  printf (" }\n");++  return TILEGX_BUNDLE_SIZE_IN_BYTES;+}
+ src/c/pcre2/src/sljit/sljitNativeTILEGX_64.c view
@@ -0,0 +1,2565 @@+/*+ *    Stack-less Just-In-Time compiler+ *+ *    Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). 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:+ *+ *   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.+ */++/* TileGX architecture. */+/* Contributed by Tilera Corporation. */+#include "sljitNativeTILEGX-encoder.c"++#define SIMM_8BIT_MAX (0x7f)+#define SIMM_8BIT_MIN (-0x80)+#define SIMM_16BIT_MAX (0x7fff)+#define SIMM_16BIT_MIN (-0x8000)+#define SIMM_17BIT_MAX (0xffff)+#define SIMM_17BIT_MIN (-0x10000)+#define SIMM_32BIT_MAX (0x7fffffff)+#define SIMM_32BIT_MIN (-0x7fffffff - 1)+#define SIMM_48BIT_MAX (0x7fffffff0000L)+#define SIMM_48BIT_MIN (-0x800000000000L)+#define IMM16(imm) ((imm) & 0xffff)++#define UIMM_16BIT_MAX (0xffff)++#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 ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5)+#define PIC_ADDR_REG TMP_REG2++static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {+	63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7+};++#define SLJIT_LOCALS_REG_mapped 54+#define TMP_REG1_mapped 5+#define TMP_REG2_mapped 16+#define TMP_REG3_mapped 6+#define ADDR_TMP_mapped 7++/* Flags are keept in volatile registers. */+#define EQUAL_FLAG 8+/* And carry flag as well. */+#define ULESS_FLAG 9+#define UGREATER_FLAG 10+#define LESS_FLAG 11+#define GREATER_FLAG 12+#define OVERFLOW_FLAG 13++#define ZERO 63+#define RA 55+#define TMP_EREG1 14+#define TMP_EREG2 15++#define LOAD_DATA 0x01+#define WORD_DATA 0x00+#define BYTE_DATA 0x02+#define HALF_DATA 0x04+#define INT_DATA 0x06+#define SIGNED_DATA 0x08+#define DOUBLE_DATA 0x10++/* Separates integer and floating point registers */+#define GPR_REG 0xf++#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 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))))++SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void)+{+	return "TileGX" SLJIT_CPUINFO;+}++/* Length of an instruction word */+typedef sljit_uw sljit_ins;++struct jit_instr {+	const struct tilegx_opcode* opcode; +	tilegx_pipeline pipe;+	unsigned long input_registers;+	unsigned long output_registers;+	int operand_value[4];+	int line;+};++/* Opcode Helper Macros */+#define TILEGX_X_MODE 0++#define X_MODE create_Mode(TILEGX_X_MODE)++#define FNOP_X0 \+	create_Opcode_X0(RRR_0_OPCODE_X0) | \+	create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \+	create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0)++#define FNOP_X1 \+	create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \+	create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1)++#define NOP \+	create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1++#define ANOP_X0 \+	create_Opcode_X0(RRR_0_OPCODE_X0) | \+	create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \+	create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0)++#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \+	create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \+	create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0++#define ADD_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0++#define ADDI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \+	create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0++#define SUB_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0++#define NOR_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0++#define OR_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0++#define AND_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0++#define XOR_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0++#define CMOVNEZ_X0 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \+	create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1++#define CMOVEQZ_X0 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \+	create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1++#define ADDLI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0++#define V4INT_L_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0++#define BFEXTU_X0 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \+	create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1++#define BFEXTS_X0 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \+	create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1++#define SHL16INSLI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0++#define ST_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0++#define LD_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \+	create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0++#define JR_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \+	create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0++#define JALR_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \+	create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0++#define CLZ_X0 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \+	create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \+	create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1++#define CMPLTUI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \+	create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0++#define CMPLTU_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0++#define CMPLTS_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0++#define XORI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \+	create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0++#define ORI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \+	create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0++#define ANDI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \+	create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0++#define SHLI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \+	create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0++#define SHL_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0++#define SHRSI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \+	create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0++#define SHRS_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0++#define SHRUI_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \+	create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0++#define SHRU_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \+	create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0++#define BEQZ_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \+	create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0++#define BNEZ_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \+	create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0++#define J_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \+	create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0++#define JAL_X1 \+	create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \+	create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0++#define DEST_X0(x) create_Dest_X0(x)+#define SRCA_X0(x) create_SrcA_X0(x)+#define SRCB_X0(x) create_SrcB_X0(x)+#define DEST_X1(x) create_Dest_X1(x)+#define SRCA_X1(x) create_SrcA_X1(x)+#define SRCB_X1(x) create_SrcB_X1(x)+#define IMM16_X1(x) create_Imm16_X1(x)+#define IMM8_X1(x) create_Imm8_X1(x)+#define BFSTART_X0(x) create_BFStart_X0(x)+#define BFEND_X0(x) create_BFEnd_X0(x)+#define SHIFTIMM_X1(x) create_ShAmt_X1(x)+#define JOFF_X1(x) create_JumpOff_X1(x)+#define BOFF_X1(x) create_BrOff_X1(x)++static const tilegx_mnemonic data_transfer_insts[16] = {+	/* u w s */ TILEGX_OPC_ST   /* st */,+	/* u w l */ TILEGX_OPC_LD   /* ld */,+	/* u b s */ TILEGX_OPC_ST1  /* st1 */,+	/* u b l */ TILEGX_OPC_LD1U /* ld1u */,+	/* u h s */ TILEGX_OPC_ST2  /* st2 */,+	/* u h l */ TILEGX_OPC_LD2U /* ld2u */,+	/* u i s */ TILEGX_OPC_ST4  /* st4 */,+	/* u i l */ TILEGX_OPC_LD4U /* ld4u */,+	/* s w s */ TILEGX_OPC_ST   /* st */,+	/* s w l */ TILEGX_OPC_LD   /* ld */,+	/* s b s */ TILEGX_OPC_ST1  /* st1 */,+	/* s b l */ TILEGX_OPC_LD1S /* ld1s */,+	/* s h s */ TILEGX_OPC_ST2  /* st2 */,+	/* s h l */ TILEGX_OPC_LD2S /* ld2s */,+	/* s i s */ TILEGX_OPC_ST4  /* st4 */,+	/* s i l */ TILEGX_OPC_LD4S /* ld4s */,+};++#ifdef TILEGX_JIT_DEBUG+static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line)+{+	sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	printf("|%04d|S0|:\t\t", line);+	print_insn_tilegx(ptr);+	return SLJIT_SUCCESS;+}++static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins)+{+	sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	return SLJIT_SUCCESS;+}++#define push_inst(a, b) push_inst_debug(a, b, __LINE__)+#else+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)+{+	sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));+	FAIL_IF(!ptr);+	*ptr = ins;+	compiler->size++;+	return SLJIT_SUCCESS;+}+#endif++#define BUNDLE_FORMAT_MASK(p0, p1, p2) \+	((p0) | ((p1) << 8) | ((p2) << 16))++#define BUNDLE_FORMAT(p0, p1, p2) \+	{ \+		{ \+			(tilegx_pipeline)(p0), \+			(tilegx_pipeline)(p1), \+			(tilegx_pipeline)(p2) \+		}, \+		BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \+	}++#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS++#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)++#define PI(encoding) \+	push_inst(compiler, encoding)++#define PB3(opcode, dst, srca, srcb) \+	push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__)++#define PB2(opcode, dst, src) \+	push_2_buffer(compiler, opcode, dst, src, __LINE__)++#define JR(reg) \+	push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__)++#define ADD(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__)++#define SUB(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)++#define MUL(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__)++#define NOR(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)++#define OR(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__)++#define XOR(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__)++#define AND(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__)++#define CLZ(dst, src) \+	push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__)++#define SHLI(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__)++#define SHRUI(dst, srca, imm) \+	push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__)++#define XORI(dst, srca, imm) \+	push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__)++#define ORI(dst, srca, imm) \+	push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__)++#define CMPLTU(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__)++#define CMPLTS(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__)++#define CMPLTUI(dst, srca, imm) \+	push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__)++#define CMOVNEZ(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__)++#define CMOVEQZ(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__)++#define ADDLI(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__)++#define SHL16INSLI(dst, srca, srcb) \+	push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__)++#define LD_ADD(dst, addr, adjust) \+	push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__)++#define ST_ADD(src, addr, adjust) \+	push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__)++#define LD(dst, addr) \+	push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__)++#define BFEXTU(dst, src, start, end) \+	push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__)++#define BFEXTS(dst, src, start, end) \+	push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__)++#define ADD_SOLO(dest, srca, srcb) \+	push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb))++#define ADDI_SOLO(dest, srca, imm) \+	push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm))++#define ADDLI_SOLO(dest, srca, imm) \+	push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))++#define SHL16INSLI_SOLO(dest, srca, imm) \+	push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))++#define JALR_SOLO(reg) \+	push_inst(compiler, JALR_X1 | SRCA_X1(reg))++#define JR_SOLO(reg) \+	push_inst(compiler, JR_X1 | SRCA_X1(reg))++struct Format {+	/* Mapping of bundle issue slot to assigned pipe. */+	tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];++	/* Mask of pipes used by this bundle. */+	unsigned int pipe_mask;+};++const struct Format formats[] =+{+	/* In Y format we must always have something in Y2, since it has+	* no fnop, so this conveys that Y2 must always be used. */+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE),++	/* Y format has three instructions. */+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1),+	BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0),++	/* X format has only two instructions. */+	BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE),+	BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE)+};+++struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];+unsigned long inst_buf_index;++tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode)+{+	/* FIXME: tile: we could pregenerate this. */+	int pipe;+	for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++)+		;+	return (tilegx_pipeline)(pipe);+}++void insert_nop(tilegx_mnemonic opc, int line)+{+	const struct tilegx_opcode* opcode = NULL;++	memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]);++	opcode = &tilegx_opcodes[opc];+	inst_buf[0].opcode = opcode;+	inst_buf[0].pipe = get_any_valid_pipe(opcode);+	inst_buf[0].input_registers = 0;+	inst_buf[0].output_registers = 0;+	inst_buf[0].line = line;+	++inst_buf_index;+}++const struct Format* compute_format()+{+	unsigned int compatible_pipes = BUNDLE_FORMAT_MASK(+		inst_buf[0].opcode->pipes,+		inst_buf[1].opcode->pipes,+		(inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE)));++	const struct Format* match = NULL;+	const struct Format *b = NULL;+	unsigned int i;+	for (i = 0; i < sizeof formats / sizeof formats[0]; i++) {+		b = &formats[i];+		if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {+			match = b;+			break;+		}+	}++	return match;+}++sljit_s32 assign_pipes()+{+	unsigned long output_registers = 0;+	unsigned int i = 0;++	if (inst_buf_index == 1) {+		tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle+					? TILEGX_OPC_FNOP : TILEGX_OPC_NOP;+		insert_nop(opc, __LINE__);+	}++	const struct Format* match = compute_format();++	if (match == NULL)+		return -1;++	for (i = 0; i < inst_buf_index; i++) {++		if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0))+			return -1;++		if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0))+			return -1;++		/* Don't include Rzero in the match set, to avoid triggering+		   needlessly on 'prefetch' instrs. */++		output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL;++		inst_buf[i].pipe = match->pipe[i];+	}++	/* If only 2 instrs, and in Y-mode, insert a nop. */+	if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) {+		insert_nop(TILEGX_OPC_FNOP, __LINE__);++		/* Select the yet unassigned pipe. */+		tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0+					+ TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2)+					- (inst_buf[1].pipe + inst_buf[2].pipe)));++		inst_buf[0].pipe = pipe;+	}++	return 0;+}++tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst)+{+	int i, val;+	const struct tilegx_opcode* opcode = inst->opcode;+	tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe];++	const struct tilegx_operand* operand = NULL;+	for (i = 0; i < opcode->num_operands; i++) {+		operand = &tilegx_operands[opcode->operands[inst->pipe][i]];+		val = inst->operand_value[i];++		bits |= operand->insert(val);+	}++	return bits;+}++static sljit_s32 update_buffer(struct sljit_compiler *compiler)+{+	int i;+	int orig_index = inst_buf_index;+	struct jit_instr inst0 = inst_buf[0];+	struct jit_instr inst1 = inst_buf[1];+	struct jit_instr inst2 = inst_buf[2];+	tilegx_bundle_bits bits = 0;++	/* If the bundle is valid as is, perform the encoding and return 1. */+	if (assign_pipes() == 0) {+		for (i = 0; i < inst_buf_index; i++) {+			bits |= get_bundle_bit(inst_buf + i);+#ifdef TILEGX_JIT_DEBUG+			printf("|%04d", inst_buf[i].line);+#endif+		}+#ifdef TILEGX_JIT_DEBUG+		if (inst_buf_index == 3)+			printf("|M0|:\t");+		else+			printf("|M0|:\t\t");+		print_insn_tilegx(&bits);+#endif++		inst_buf_index = 0;++#ifdef TILEGX_JIT_DEBUG+		return push_inst_nodebug(compiler, bits);+#else+		return push_inst(compiler, bits);+#endif+	}++	/* If the bundle is invalid, split it in two. First encode the first two+	   (or possibly 1) instructions, and then the last, separately. Note that+	   assign_pipes may have re-ordered the instrs (by inserting no-ops in+	   lower slots) so we need to reset them. */++	inst_buf_index = orig_index - 1;+	inst_buf[0] = inst0;+	inst_buf[1] = inst1;+	inst_buf[2] = inst2;+	if (assign_pipes() == 0) {+		for (i = 0; i < inst_buf_index; i++) {+			bits |= get_bundle_bit(inst_buf + i);+#ifdef TILEGX_JIT_DEBUG+			printf("|%04d", inst_buf[i].line);+#endif+		}++#ifdef TILEGX_JIT_DEBUG+		if (inst_buf_index == 3)+			printf("|M1|:\t");+		else+			printf("|M1|:\t\t");+		print_insn_tilegx(&bits);+#endif++		if ((orig_index - 1) == 2) {+			inst_buf[0] = inst2;+			inst_buf_index = 1;+		} else if ((orig_index - 1) == 1) {+			inst_buf[0] = inst1;+			inst_buf_index = 1;+		} else+			SLJIT_UNREACHABLE();++#ifdef TILEGX_JIT_DEBUG+		return push_inst_nodebug(compiler, bits);+#else+		return push_inst(compiler, bits);+#endif+	} else {+		/* We had 3 instrs of which the first 2 can't live in the same bundle.+		   Split those two. Note that we don't try to then combine the second+		   and third instr into a single bundle.  First instruction: */+		inst_buf_index = 1;+		inst_buf[0] = inst0;+		inst_buf[1] = inst1;+		inst_buf[2] = inst2;+		if (assign_pipes() == 0) {+			for (i = 0; i < inst_buf_index; i++) {+				bits |= get_bundle_bit(inst_buf + i);+#ifdef TILEGX_JIT_DEBUG+				printf("|%04d", inst_buf[i].line);+#endif+			}++#ifdef TILEGX_JIT_DEBUG+			if (inst_buf_index == 3)+				printf("|M2|:\t");+			else+				printf("|M2|:\t\t");+			print_insn_tilegx(&bits);+#endif++			inst_buf[0] = inst1;+			inst_buf[1] = inst2;+			inst_buf_index = orig_index - 1;+#ifdef TILEGX_JIT_DEBUG+			return push_inst_nodebug(compiler, bits);+#else+			return push_inst(compiler, bits);+#endif+		} else+			SLJIT_UNREACHABLE();+	}++	SLJIT_UNREACHABLE();+}++static sljit_s32 flush_buffer(struct sljit_compiler *compiler)+{+	while (inst_buf_index != 0) {+		FAIL_IF(update_buffer(compiler));+	}+	return SLJIT_SUCCESS;+}++static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)+{+	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)+		FAIL_IF(update_buffer(compiler));++	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];+	inst_buf[inst_buf_index].opcode = opcode;+	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);+	inst_buf[inst_buf_index].operand_value[0] = op0;+	inst_buf[inst_buf_index].operand_value[1] = op1;+	inst_buf[inst_buf_index].operand_value[2] = op2;+	inst_buf[inst_buf_index].operand_value[3] = op3;+	inst_buf[inst_buf_index].input_registers = 1L << op1;+	inst_buf[inst_buf_index].output_registers = 1L << op0;+	inst_buf[inst_buf_index].line = line;+	inst_buf_index++;++	return SLJIT_SUCCESS;+}++static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line)+{+	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)+		FAIL_IF(update_buffer(compiler));++	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];+	inst_buf[inst_buf_index].opcode = opcode;+	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);+	inst_buf[inst_buf_index].operand_value[0] = op0;+	inst_buf[inst_buf_index].operand_value[1] = op1;+	inst_buf[inst_buf_index].operand_value[2] = op2;+	inst_buf[inst_buf_index].line = line;++	switch (opc) {+	case TILEGX_OPC_ST_ADD:+		inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);+		inst_buf[inst_buf_index].output_registers = 1L << op0;+		break;+	case TILEGX_OPC_LD_ADD:+		inst_buf[inst_buf_index].input_registers = 1L << op1;+		inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1);+		break;+	case TILEGX_OPC_ADD:+	case TILEGX_OPC_AND:+	case TILEGX_OPC_SUB:+	case TILEGX_OPC_MULX:+	case TILEGX_OPC_OR:+	case TILEGX_OPC_XOR:+	case TILEGX_OPC_NOR:+	case TILEGX_OPC_SHL:+	case TILEGX_OPC_SHRU:+	case TILEGX_OPC_SHRS:+	case TILEGX_OPC_CMPLTU:+	case TILEGX_OPC_CMPLTS:+	case TILEGX_OPC_CMOVEQZ:+	case TILEGX_OPC_CMOVNEZ:+		inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2);+		inst_buf[inst_buf_index].output_registers = 1L << op0;+		break;+	case TILEGX_OPC_ADDLI:+	case TILEGX_OPC_XORI:+	case TILEGX_OPC_ORI:+	case TILEGX_OPC_SHLI:+	case TILEGX_OPC_SHRUI:+	case TILEGX_OPC_SHRSI:+	case TILEGX_OPC_SHL16INSLI:+	case TILEGX_OPC_CMPLTUI:+	case TILEGX_OPC_CMPLTSI:+		inst_buf[inst_buf_index].input_registers = 1L << op1;+		inst_buf[inst_buf_index].output_registers = 1L << op0;+		break;+	default:+		printf("unrecoginzed opc: %s\n", opcode->name);+		SLJIT_UNREACHABLE();+	}++	inst_buf_index++;++	return SLJIT_SUCCESS;+}++static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line)+{+	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)+		FAIL_IF(update_buffer(compiler));++	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];+	inst_buf[inst_buf_index].opcode = opcode;+	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);+	inst_buf[inst_buf_index].operand_value[0] = op0;+	inst_buf[inst_buf_index].operand_value[1] = op1;+	inst_buf[inst_buf_index].line = line;++	switch (opc) {+	case TILEGX_OPC_BEQZ:+	case TILEGX_OPC_BNEZ:+		inst_buf[inst_buf_index].input_registers = 1L << op0;+		break;+	case TILEGX_OPC_ST:+	case TILEGX_OPC_ST1:+	case TILEGX_OPC_ST2:+	case TILEGX_OPC_ST4:+		inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);+		inst_buf[inst_buf_index].output_registers = 0;+		break;+	case TILEGX_OPC_CLZ:+	case TILEGX_OPC_LD:+	case TILEGX_OPC_LD1U:+	case TILEGX_OPC_LD1S:+	case TILEGX_OPC_LD2U:+	case TILEGX_OPC_LD2S:+	case TILEGX_OPC_LD4U:+	case TILEGX_OPC_LD4S:+		inst_buf[inst_buf_index].input_registers = 1L << op1;+		inst_buf[inst_buf_index].output_registers = 1L << op0;+		break;+	default:+		printf("unrecoginzed opc: %s\n", opcode->name);+		SLJIT_UNREACHABLE();+	}++	inst_buf_index++;++	return SLJIT_SUCCESS;+}++static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line)+{+	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)+		FAIL_IF(update_buffer(compiler));++	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];+	inst_buf[inst_buf_index].opcode = opcode;+	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);+	inst_buf[inst_buf_index].input_registers = 0;+	inst_buf[inst_buf_index].output_registers = 0;+	inst_buf[inst_buf_index].line = line;+	inst_buf_index++;++	return SLJIT_SUCCESS;+}++static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line)+{+	if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)+		FAIL_IF(update_buffer(compiler));++	const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];+	inst_buf[inst_buf_index].opcode = opcode;+	inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);+	inst_buf[inst_buf_index].operand_value[0] = op0;+	inst_buf[inst_buf_index].input_registers = 1L << op0;+	inst_buf[inst_buf_index].output_registers = 0;+	inst_buf[inst_buf_index].line = line;+	inst_buf_index++;+ +	return flush_buffer(compiler);+}++static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)+{+	sljit_sw diff;+	sljit_uw target_addr;+	sljit_ins *inst;++	if (jump->flags & SLJIT_REWRITABLE_JUMP)+		return code_ptr;++	if (jump->flags & JUMP_ADDR)+		target_addr = jump->u.target;+	else {+		SLJIT_ASSERT(jump->flags & JUMP_LABEL);+		target_addr = (sljit_uw)(code + jump->u.label->size);+	}++	inst = (sljit_ins *)jump->addr;+	if (jump->flags & IS_COND)+		inst--;++	diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3;+	if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) {+		jump->flags |= PATCH_B;++		if (!(jump->flags & IS_COND)) {+			if (jump->flags & IS_JAL) {+				jump->flags &= ~(PATCH_B);+				jump->flags |= PATCH_J;+				inst[0] = JAL_X1;++#ifdef TILEGX_JIT_DEBUG+				printf("[runtime relocate]%04d:\t", __LINE__);+				print_insn_tilegx(inst);+#endif+			} else {+				inst[0] = BEQZ_X1 | SRCA_X1(ZERO);++#ifdef TILEGX_JIT_DEBUG+				printf("[runtime relocate]%04d:\t", __LINE__);+				print_insn_tilegx(inst);+#endif+			}++			return inst;+		}++		inst[0] = inst[0] ^ (0x7L << 55);++#ifdef TILEGX_JIT_DEBUG+		printf("[runtime relocate]%04d:\t", __LINE__);+		print_insn_tilegx(inst);+#endif+		jump->addr -= sizeof(sljit_ins);+		return inst;+	}++	if (jump->flags & IS_COND) {+		if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {+			jump->flags |= PATCH_J;+			inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2);+			inst[1] = J_X1;+			return inst + 1;+		}++		return code_ptr;+	}++	if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {+		jump->flags |= PATCH_J;++		if (jump->flags & IS_JAL) {+			inst[0] = JAL_X1;++#ifdef TILEGX_JIT_DEBUG+			printf("[runtime relocate]%04d:\t", __LINE__);+			print_insn_tilegx(inst);+#endif++		} else {+			inst[0] = J_X1;++#ifdef TILEGX_JIT_DEBUG+			printf("[runtime relocate]%04d:\t", __LINE__);+			print_insn_tilegx(inst);+#endif+		}++		return inst;+	}++	return code_ptr;+}++SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_ins *code;+	sljit_ins *code_ptr;+	sljit_ins *buf_ptr;+	sljit_ins *buf_end;+	sljit_uw word_count;+	sljit_uw addr;++	struct sljit_label *label;+	struct sljit_jump *jump;+	struct sljit_const *const_;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	word_count = 0;+	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	do {+		buf_ptr = (sljit_ins *)buf->memory;+		buf_end = buf_ptr + (buf->used_size >> 3);+		do {+			*code_ptr = *buf_ptr++;+			SLJIT_ASSERT(!label || label->size >= word_count);+			SLJIT_ASSERT(!jump || jump->addr >= word_count);+			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->size = code_ptr - code;+				label = label->next;+			}++			if (jump && jump->addr == word_count) {+				if (jump->flags & IS_JAL)+					jump->addr = (sljit_uw)(code_ptr - 4);+				else+					jump->addr = (sljit_uw)(code_ptr - 3);++				code_ptr = detect_jump_type(jump, code_ptr, code);+				jump = jump->next;+			}++			if (const_ && const_->addr == word_count) {+				/* Just recording the address. */+				const_->addr = (sljit_uw) code_ptr;+				const_ = const_->next;+			}++			code_ptr++;+			word_count++;+		} while (buf_ptr < buf_end);++		buf = buf->next;+	} while (buf);++	if (label && label->size == word_count) {+		label->addr = (sljit_uw) code_ptr;+		label->size = code_ptr - code;+		label = label->next;+	}++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);++	jump = compiler->jumps;+	while (jump) {+		do {+			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;+			buf_ptr = (sljit_ins *)jump->addr;++			if (jump->flags & PATCH_B) {+				addr = (sljit_sw)(addr - (jump->addr)) >> 3;+				SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN);+				buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr);++#ifdef TILEGX_JIT_DEBUG+				printf("[runtime relocate]%04d:\t", __LINE__);+				print_insn_tilegx(buf_ptr);+#endif+				break;+			}++			if (jump->flags & PATCH_J) {+				SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL));+				addr = (sljit_sw)(addr - (jump->addr)) >> 3;+				buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr);++#ifdef TILEGX_JIT_DEBUG+				printf("[runtime relocate]%04d:\t", __LINE__);+				print_insn_tilegx(buf_ptr);+#endif+				break;+			}++			SLJIT_ASSERT(!(jump->flags & IS_JAL));++			/* Set the fields of immediate loads. */+			buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43);+			buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43);+			buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43);+		} while (0);++		jump = jump->next;+	}++	compiler->error = SLJIT_ERR_COMPILED;+	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);++	SLJIT_CACHE_FLUSH(code, code_ptr);+	SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);+	return code;+}++static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)+{++	if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN)+		return ADDLI(dst_ar, ZERO, imm);++	if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) {+		FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16));+		return SHL16INSLI(dst_ar, dst_ar, imm);+	}++	if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) {+		FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));+		FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));+		return SHL16INSLI(dst_ar, dst_ar, imm);+	}++	FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48));+	FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32));+	FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));+	return SHL16INSLI(dst_ar, dst_ar, imm);+}++static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)+{+	/* Should *not* be optimized as load_immediate, as pcre relocation+	   mechanism will match this fixed 4-instruction pattern. */+	if (flush) {+		FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32));+		FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16));+		return SHL16INSLI_SOLO(dst_ar, dst_ar, imm);+	}++	FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));+	FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));+	return SHL16INSLI(dst_ar, dst_ar, imm);+}++static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)+{+	/* Should *not* be optimized as load_immediate, as pcre relocation+	   mechanism will match this fixed 4-instruction pattern. */+	if (flush) {+		FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48));+		FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));+		FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));+		return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm);+	}++	FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48));+	FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));+	FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));+	return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm);+}++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 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_ins base;+	sljit_s32 i, tmp;+ +	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);++	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);+	local_size = (local_size + 7) & ~7;+	compiler->local_size = local_size;++	if (local_size <= SIMM_16BIT_MAX) {+		/* Frequent case. */+		FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size));+		base = SLJIT_LOCALS_REG_mapped;+	} else {+		FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));+		FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO));+		FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));+		base = TMP_REG2_mapped;+		local_size = 0;+	}++	/* Save the return address. */+	FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));+	FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));++	/* Save the S registers. */+	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--) {+		FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));+	}++	/* Save the R registers that need to be reserved. */+	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));+	}++	/* Move the arguments to S registers. */+	for (i = 0; i < args; i++) {+		FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO));+	}++	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 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);++	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);+	compiler->local_size = (local_size + 7) & ~7;++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 local_size;+	sljit_ins base;+	sljit_s32 i, tmp;+	sljit_s32 saveds;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	local_size = compiler->local_size;+	if (local_size <= SIMM_16BIT_MAX)+		base = SLJIT_LOCALS_REG_mapped;+	else {+		FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));+		FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));+		base = TMP_REG1_mapped;+		local_size = 0;+	}++	/* Restore the return address. */+	FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));+	FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8));++	/* Restore the S registers. */+	saveds = compiler->saveds;+	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--) {+		FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));+	}++	/* Restore the R registers that need to be reserved. */+	for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));+	}++	if (compiler->local_size <= SIMM_16BIT_MAX)+		FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size));+	else+		FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO));++	return JR(RA);+}++/* reg_ar is an absoulute register! */++/* 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_ar, sljit_s32 arg, sljit_sw argw)+{+	SLJIT_ASSERT(arg & SLJIT_MEM);++	if ((!(flags & WRITE_BACK) || !(arg & REG_MASK))+			&& !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {+		/* Works for both absoulte and relative addresses. */+		if (SLJIT_UNLIKELY(flags & ARG_TEST))+			return 1;++		FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw));++		if (flags & LOAD_DATA)+			FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));+		else+			FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));++		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)+{+	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));++	/* Simple operation except for updates. */+	if (arg & OFFS_REG_MASK) {+		argw &= 0x3;+		next_argw &= 0x3;+		if (argw && argw == next_argw+				&& (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))+			return 1;+		return 0;+	}++	if (arg == next_arg) {+		if (((next_argw - argw) <= SIMM_16BIT_MAX+				&& (next_argw - argw) >= SIMM_16BIT_MIN))+			return 1;++		return 0;+	}++	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_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)+{+	sljit_s32 tmp_ar, base;++	SLJIT_ASSERT(arg & SLJIT_MEM);+	if (!(next_arg & SLJIT_MEM)) {+		next_arg = 0;+		next_argw = 0;+	}++	if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))+		tmp_ar = reg_ar;+	else+		tmp_ar = TMP_REG1_mapped;++	base = arg & REG_MASK;++	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {+		argw &= 0x3;++		if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) {+			SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar);+			FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));+			reg_ar = TMP_REG1_mapped;+		}++		/* Using the cache. */+		if (argw == compiler->cache_argw) {+			if (!(flags & WRITE_BACK)) {+				if (arg == compiler->cache_arg) {+					if (flags & LOAD_DATA)+						return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);+					else+						return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);+				}++				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(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped));+						if (flags & LOAD_DATA)+							return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);+						else+							return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);+					}++					FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped));+					if (flags & LOAD_DATA)+						return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);+					else+						return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);+				}+			} else {+				if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {+					FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));+					if (flags & LOAD_DATA)+						return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);+					else+						return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);+				}+			}+		}++		if (SLJIT_UNLIKELY(argw)) {+			compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);+			compiler->cache_argw = argw;+			FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw));+		}++		if (!(flags & WRITE_BACK)) {+			if (arg == next_arg && argw == (next_argw & 0x3)) {+				compiler->cache_arg = arg;+				compiler->cache_argw = argw;+				FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));+				tmp_ar = TMP_REG3_mapped;+			} else+				FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));++			if (flags & LOAD_DATA)+				return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);+			else+				return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);+		}++		FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));++		if (flags & LOAD_DATA)+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);+		else+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);+	}++	if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {+		/* Update only applies if a base register exists. */+		if (reg_ar == reg_map[base]) {+			SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar);+			if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {+				FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw));+				if (flags & LOAD_DATA)+					FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));+				else+					FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));++				if (argw)+					return ADDLI(reg_map[base], reg_map[base], argw);++				return SLJIT_SUCCESS;+			}++			FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));+			reg_ar = TMP_REG1_mapped;+		}++		if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {+			if (argw)+				FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw));+		} else {+			if (compiler->cache_arg == SLJIT_MEM+					&& argw - compiler->cache_argw <= SIMM_16BIT_MAX+					&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {+				if (argw != compiler->cache_argw) {+					FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));+					compiler->cache_argw = argw;+				}++				FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));+			} else {+				compiler->cache_arg = SLJIT_MEM;+				compiler->cache_argw = argw;+				FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));+				FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));+			}+		}++		if (flags & LOAD_DATA)+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);+		else+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);+	}++	if (compiler->cache_arg == arg+			&& argw - compiler->cache_argw <= SIMM_16BIT_MAX+			&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {+		if (argw != compiler->cache_argw) {+			FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));+			compiler->cache_argw = argw;+		}++		if (flags & LOAD_DATA)+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);+		else+			return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);+	}++	if (compiler->cache_arg == SLJIT_MEM+			&& argw - compiler->cache_argw <= SIMM_16BIT_MAX+			&& argw - compiler->cache_argw >= SIMM_16BIT_MIN) {+		if (argw != compiler->cache_argw)+			FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));+	} else {+		compiler->cache_arg = SLJIT_MEM;+		FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));+	}++	compiler->cache_argw = argw;++	if (!base) {+		if (flags & LOAD_DATA)+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);+		else+			return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);+	}++	if (arg == next_arg+			&& next_argw - argw <= SIMM_16BIT_MAX+			&& next_argw - argw >= SIMM_16BIT_MIN) {+		compiler->cache_arg = arg;+		FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base]));+		if (flags & LOAD_DATA)+			return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);+		else+			return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);+	}++	FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base]));++	if (flags & LOAD_DATA)+		return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);+	else+		return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);+}++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 (getput_arg_fast(compiler, flags, reg_ar, arg, argw))+		return compiler->error;++	compiler->cache_arg = 0;+	compiler->cache_argw = 0;+	return getput_arg(compiler, flags, reg_ar, 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);+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	CHECK_ERROR();+	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 ADD(reg_map[dst], RA, ZERO);++	/* Memory. */+	return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw);+}++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 overflow_ra = 0;++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV:+	case SLJIT_MOV_P:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (dst != src2)+			return ADD(reg_map[dst], reg_map[src2], ZERO);+		return SLJIT_SUCCESS;++	case SLJIT_MOV_U32:+	case SLJIT_MOV_S32:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S32)+				return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);++			return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);+		} else if (dst != src2) {+			SLJIT_ASSERT(src2 == 0);+			return ADD(reg_map[dst], reg_map[src2], ZERO);+		}++		return SLJIT_SUCCESS;++	case SLJIT_MOV_U8:+	case SLJIT_MOV_S8:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S8)+				return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);++			return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);+		} else if (dst != src2) {+			SLJIT_ASSERT(src2 == 0);+			return ADD(reg_map[dst], reg_map[src2], ZERO);+		}++		return SLJIT_SUCCESS;++	case SLJIT_MOV_U16:+	case SLJIT_MOV_S16:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {+			if (op == SLJIT_MOV_S16)+				return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);++			return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);+		} else if (dst != src2) {+			SLJIT_ASSERT(src2 == 0);+			return ADD(reg_map[dst], reg_map[src2], ZERO);+		}++		return SLJIT_SUCCESS;++	case SLJIT_NOT:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (op & SLJIT_SET_E)+			FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2]));+		if (CHECK_FLAGS(SLJIT_SET_E))+			FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2]));++		return SLJIT_SUCCESS;++	case SLJIT_CLZ:+		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));+		if (op & SLJIT_SET_E)+			FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2]));+		if (CHECK_FLAGS(SLJIT_SET_E))+			FAIL_IF(CLZ(reg_map[dst], reg_map[src2]));++		return SLJIT_SUCCESS;++	case SLJIT_ADD:+		if (flags & SRC2_IMM) {+			if (op & SLJIT_SET_O) {+				FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63));+				if (src2 < 0)+					FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));+			}++			if (op & SLJIT_SET_E)+				FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2));++			if (op & SLJIT_SET_C) {+				if (src2 >= 0)+					FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2));+				else {+					FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2));+					FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG));+				}+			}++			/* dst may be the same as src1 or src2. */+			if (CHECK_FLAGS(SLJIT_SET_E))+				FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));++			if (op & SLJIT_SET_O) {+				FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63));++				if (src2 < 0)+					FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1));+			}+		} else {+			if (op & SLJIT_SET_O) {+				FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));+				FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));++				if (src1 != dst)+					overflow_ra = reg_map[src1];+				else if (src2 != dst)+					overflow_ra = reg_map[src2];+				else {+					/* Rare ocasion. */+					FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));+					overflow_ra = TMP_EREG2;+				}+			}++			if (op & SLJIT_SET_E)+				FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2]));++			if (op & SLJIT_SET_C)+				FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2]));++			/* dst may be the same as src1 or src2. */+			if (CHECK_FLAGS(SLJIT_SET_E))+				FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2]));++			if (op & SLJIT_SET_O) {+				FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra));+				FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));+			}+		}++		/* a + b >= a | b (otherwise, the carry should be set to 1). */+		if (op & SLJIT_SET_C)+			FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG));++		if (op & SLJIT_SET_O)+			return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);++		return SLJIT_SUCCESS;++	case SLJIT_ADDC:+		if (flags & SRC2_IMM) {+			if (op & SLJIT_SET_C) {+				if (src2 >= 0)+					FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2));+				else {+					FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2));+					FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1));+				}+			}++			FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));++		} else {+			if (op & SLJIT_SET_C)+				FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2]));++			/* dst may be the same as src1 or src2. */+			FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2]));+		}++		if (op & SLJIT_SET_C)+			FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1));++		FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG));++		if (!(op & SLJIT_SET_C))+			return SLJIT_SUCCESS;++		/* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */+		FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1));+		FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG));+		/* Set carry flag. */+		return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1);++	case SLJIT_SUB:+		if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) {+			FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));+			src2 = TMP_REG2;+			flags &= ~SRC2_IMM;+		}++		if (flags & SRC2_IMM) {+			if (op & SLJIT_SET_O) {+				FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63));++				if (src2 < 0)+					FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));++				if (src1 != dst)+					overflow_ra = reg_map[src1];+				else {+					/* Rare ocasion. */+					FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));+					overflow_ra = TMP_EREG2;+				}+			}++			if (op & SLJIT_SET_E)+				FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2));++			if (op & SLJIT_SET_C) {+				FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2));+				FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped));+			}++			/* dst may be the same as src1 or src2. */+			if (CHECK_FLAGS(SLJIT_SET_E))+				FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));++		} else {++			if (op & SLJIT_SET_O) {+				FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));+				FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));++				if (src1 != dst)+					overflow_ra = reg_map[src1];+				else {+					/* Rare ocasion. */+					FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));+					overflow_ra = TMP_EREG2;+				}+			}++			if (op & SLJIT_SET_E)+				FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2]));++			if (op & (SLJIT_SET_U | SLJIT_SET_C))+				FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2]));++			if (op & SLJIT_SET_U)+				FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1]));++			if (op & SLJIT_SET_S) {+				FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2]));+				FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1]));+			}++			/* dst may be the same as src1 or src2. */+			if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))+				FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));+		}++		if (op & SLJIT_SET_O) {+			FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra));+			FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));+			return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);+		}++		return SLJIT_SUCCESS;++	case SLJIT_SUBC:+		if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) {+			FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));+			src2 = TMP_REG2;+			flags &= ~SRC2_IMM;+		}++		if (flags & SRC2_IMM) {+			if (op & SLJIT_SET_C) {+				FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2));+				FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped));+			}++			/* dst may be the same as src1 or src2. */+			FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));++		} else {+			if (op & SLJIT_SET_C)+				FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2]));+				/* dst may be the same as src1 or src2. */+			FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));+		}++		if (op & SLJIT_SET_C)+			FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG));++		FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG));++		if (op & SLJIT_SET_C)+			FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO));++		return SLJIT_SUCCESS;++	case SLJIT_MUL:+		if (flags & SRC2_IMM) {+			FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2));+			src2 = TMP_REG2;+			flags &= ~SRC2_IMM;+		}++		FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2]));++		return SLJIT_SUCCESS;++#define EMIT_LOGICAL(op_imm, op_norm) \+	if (flags & SRC2_IMM) { \+		FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \+		if (op & SLJIT_SET_E) \+			FAIL_IF(push_3_buffer( \+				compiler, op_norm, EQUAL_FLAG, reg_map[src1], \+				ADDR_TMP_mapped, __LINE__)); \+		if (CHECK_FLAGS(SLJIT_SET_E)) \+			FAIL_IF(push_3_buffer( \+				compiler, op_norm, reg_map[dst], reg_map[src1], \+				ADDR_TMP_mapped, __LINE__)); \+	} else { \+		if (op & SLJIT_SET_E) \+			FAIL_IF(push_3_buffer( \+				compiler, op_norm, EQUAL_FLAG, reg_map[src1], \+				reg_map[src2], __LINE__)); \+		if (CHECK_FLAGS(SLJIT_SET_E)) \+			FAIL_IF(push_3_buffer( \+				compiler, op_norm, reg_map[dst], reg_map[src1], \+				reg_map[src2], __LINE__)); \+	}++	case SLJIT_AND:+		EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND);+		return SLJIT_SUCCESS;++	case SLJIT_OR:+		EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR);+		return SLJIT_SUCCESS;++	case SLJIT_XOR:+		EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR);+		return SLJIT_SUCCESS;++#define EMIT_SHIFT(op_imm, op_norm) \+	if (flags & SRC2_IMM) { \+		if (op & SLJIT_SET_E) \+			FAIL_IF(push_3_buffer( \+				compiler, op_imm, EQUAL_FLAG, reg_map[src1], \+				src2 & 0x3F, __LINE__)); \+		if (CHECK_FLAGS(SLJIT_SET_E)) \+			FAIL_IF(push_3_buffer( \+				compiler, op_imm, reg_map[dst], reg_map[src1], \+				src2 & 0x3F, __LINE__)); \+	} else { \+		if (op & SLJIT_SET_E) \+			FAIL_IF(push_3_buffer( \+				compiler, op_norm, EQUAL_FLAG, reg_map[src1], \+				reg_map[src2], __LINE__)); \+		if (CHECK_FLAGS(SLJIT_SET_E)) \+			FAIL_IF(push_3_buffer( \+				compiler, op_norm, reg_map[dst], reg_map[src1], \+				reg_map[src2], __LINE__)); \+	}++	case SLJIT_SHL:+		EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL);+		return SLJIT_SUCCESS;++	case SLJIT_LSHR:+		EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU);+		return SLJIT_SUCCESS;++	case SLJIT_ASHR:+		EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS);+		return SLJIT_SUCCESS;+	}++	SLJIT_UNREACHABLE();+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, 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. */+	sljit_s32 dst_r = TMP_REG2;+	sljit_s32 src1_r;+	sljit_sw src2_r = 0;+	sljit_s32 sugg_src2_r = TMP_REG2;++	if (!(flags & ALT_KEEP_CACHE)) {+		compiler->cache_arg = 0;+		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 (GET_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)+			sugg_src2_r = dst_r;+	} else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw))+		flags |= SLOW_DEST;++	if (flags & IMM_OP) {+		if ((src2 & SLJIT_IMM) && src2w) {+			if ((!(flags & LOGICAL_OP)+					&& (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN))+					|| ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) {+				flags |= SRC2_IMM;+				src2_r = src2w;+			}+		}++		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {+			if ((!(flags & LOGICAL_OP)+					&& (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN))+					|| ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) {+				flags |= SRC2_IMM;+				src2_r = src1w;++				/* And swap arguments. */+				src1 = src2;+				src1w = src2w;+				src2 = SLJIT_IMM;+				/* src2w = src2_r unneeded. */+			}+		}+	}++	/* Source 1. */+	if (FAST_IS_REG(src1)) {+		src1_r = src1;+		flags |= REG1_SOURCE;+	} else if (src1 & SLJIT_IMM) {+		if (src1w) {+			FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w));+			src1_r = TMP_REG1;+		} else+			src1_r = 0;+	} else {+		if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w))+			FAIL_IF(compiler->error);+		else+			flags |= SLOW_SRC1;+		src1_r = TMP_REG1;+	}++	/* Source 2. */+	if (FAST_IS_REG(src2)) {+		src2_r = src2;+		flags |= REG2_SOURCE;+		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)+			dst_r = src2_r;+	} else if (src2 & SLJIT_IMM) {+		if (!(flags & SRC2_IMM)) {+			if (src2w) {+				FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w));+				src2_r = sugg_src2_r;+			} else {+				src2_r = 0;+				if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))+					dst_r = 0;+			}+		}+	} else {+		if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w))+			FAIL_IF(compiler->error);+		else+			flags |= SLOW_SRC2;+		src2_r = sugg_src2_r;+	}++	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {+		SLJIT_ASSERT(src2_r == TMP_REG2);+		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w));+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));+		} else {+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w));+			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw));+		}+	} else if (flags & SLOW_SRC1)+		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));+	else if (flags & SLOW_SRC2)+		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw));++	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));++	if (dst & SLJIT_MEM) {+		if (!(flags & SLOW_DEST)) {+			getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw);+			return compiler->error;+		}++		return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0);+	}++	return SLJIT_SUCCESS;+}++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 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	op = GET_OPCODE(op);+	if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)+		mem_type = INT_DATA | SIGNED_DATA;+	sugg_dst_ar = reg_map[(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, TMP_REG1_mapped, src, srcw, dst, dstw));+		src = TMP_REG1;+		srcw = 0;+	}++	switch (type & 0xff) {+	case SLJIT_EQUAL:+	case SLJIT_NOT_EQUAL:+		FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));+		dst_ar = sugg_dst_ar;+		break;+	case SLJIT_LESS:+	case SLJIT_GREATER_EQUAL:+		dst_ar = ULESS_FLAG;+		break;+	case SLJIT_GREATER:+	case SLJIT_LESS_EQUAL:+		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;+		break;+	case SLJIT_MUL_OVERFLOW:+	case SLJIT_MUL_NOT_OVERFLOW:+		FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));+		dst_ar = sugg_dst_ar;+		type ^= 0x1; /* Flip type bit for the XORI below. */+		break;++	default:+		SLJIT_UNREACHABLE();+		dst_ar = sugg_dst_ar;+		break;+	}++	if (type & 0x1) {+		FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1));+		dst_ar = sugg_dst_ar;+	}++	if (op >= SLJIT_ADD) {+		if (TMP_REG2_mapped != dst_ar)+			FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));+		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 (dst & SLJIT_MEM)+		return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);++	if (sugg_dst_ar != dst_ar)+		return ADD(sugg_dst_ar, dst_ar, ZERO);++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) {+	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	op = GET_OPCODE(op);+	switch (op) {+	case SLJIT_NOP:+		return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__);++	case SLJIT_BREAKPOINT:+		return PI(BPT);++	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+	case SLJIT_DIVMOD_UW:+	case SLJIT_DIVMOD_SW:+	case SLJIT_DIV_UW:+	case SLJIT_DIV_SW:+		SLJIT_UNREACHABLE();+	case SLJIT_ENDBR:+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++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)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (GET_OPCODE(op)) {+	case SLJIT_MOV:+	case SLJIT_MOV_P:+		return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_U32:+		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_S32:+		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOV_U8:+		return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);++	case SLJIT_MOV_S8:+		return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);++	case SLJIT_MOV_U16:+		return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);++	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:+		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_MOVU_S32:+		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);++	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, 0, dst, dstw, TMP_REG1, 0, src, srcw);++	case SLJIT_NEG:+		return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);++	case SLJIT_CLZ:+		return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD:+	case SLJIT_ADDC:+		return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SUB:+	case SLJIT_SUBC:+		return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_MUL:+		return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_AND:+	case SLJIT_OR:+	case SLJIT_XOR:+		return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);++	case SLJIT_SHL:+	case SLJIT_LSHR:+	case SLJIT_ASHR:+		if (src2 & SLJIT_IMM)+			src2w &= 0x3f;+		if (op & SLJIT_I32_OP)+			src2w &= 0x1f;++		return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	switch (op) {+	case SLJIT_FAST_RETURN:+		if (FAST_IS_REG(src))+			FAIL_IF(ADD(RA, reg_map[src], ZERO));++		else+			FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw));++		return JR(RA);+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		return SLJIT_SUCCESS;+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler)+{+	struct sljit_label *label;++	flush_buffer(compiler);++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);+	return label;+}++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;++	flush_buffer(compiler);++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	if (FAST_IS_REG(src)) {+		if (reg_map[src] != 0)+			src_r = src;+		else+			FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO));+	}++	if (type >= SLJIT_CALL0) {+		SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);+		if (src & (SLJIT_IMM | SLJIT_MEM)) {+			if (src & SLJIT_IMM)+				FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1));+			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(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));++			FAIL_IF(ADDI_SOLO(54, 54, -16));++			FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG]));++			return ADDI_SOLO(54, 54, 16);+		}++		/* Register input. */+		if (type >= SLJIT_CALL1)+			FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));++		FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO));++		FAIL_IF(ADDI_SOLO(54, 54, -16));++		FAIL_IF(JALR_SOLO(reg_map[src_r]));++		return ADDI_SOLO(54, 54, 16);+	}++	if (src & SLJIT_IMM) {+		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_JAL : 0));+		jump->u.target = srcw;+		FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));++		if (type >= SLJIT_FAST_CALL) {+			FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO));+			jump->addr = compiler->size;+			FAIL_IF(JR_SOLO(reg_map[src_r]));+		} else {+			jump->addr = compiler->size;+			FAIL_IF(JR_SOLO(reg_map[src_r]));+		}++		return SLJIT_SUCCESS;++	} else if (src & SLJIT_MEM) {+		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));+		flush_buffer(compiler);+	}++	FAIL_IF(JR_SOLO(reg_map[src_r]));++	if (jump)+		jump->addr = compiler->size;++	return SLJIT_SUCCESS;+}++#define BR_Z(src) \+	inst = BEQZ_X1 | SRCA_X1(src); \+	flags = IS_COND;++#define BR_NZ(src) \+	inst = BNEZ_X1 | SRCA_X1(src); \+	flags = IS_COND;++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	struct sljit_jump *jump;+	sljit_ins inst;+	sljit_s32 flags = 0;++	flush_buffer(compiler);++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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;++	switch (type) {+	case SLJIT_EQUAL:+		BR_NZ(EQUAL_FLAG);+		break;+	case SLJIT_NOT_EQUAL:+		BR_Z(EQUAL_FLAG);+		break;+	case SLJIT_LESS:+		BR_Z(ULESS_FLAG);+		break;+	case SLJIT_GREATER_EQUAL:+		BR_NZ(ULESS_FLAG);+		break;+	case SLJIT_GREATER:+		BR_Z(UGREATER_FLAG);+		break;+	case SLJIT_LESS_EQUAL:+		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);+		break;+	case SLJIT_NOT_OVERFLOW:+	case SLJIT_MUL_NOT_OVERFLOW:+		BR_NZ(OVERFLOW_FLAG);+		break;+	default:+		/* Not conditional branch. */+		inst = 0;+		break;+	}++	jump->flags |= flags;++	if (inst) {+		inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6));+		PTR_FAIL_IF(PI(inst));+	}++	PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));+	if (type <= SLJIT_JUMP) {+		jump->addr = compiler->size;+		PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped));+	} else {+		SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);+		/* Cannot be optimized out if type is >= CALL0. */+		jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);+		PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));+		jump->addr = compiler->size;+		PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped));+	}++	return jump;+}++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_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_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)+{+	struct sljit_const *const_;+	sljit_s32 reg;++	flush_buffer(compiler);++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++	reg = FAST_IS_REG(dst) ? dst : TMP_REG2;++	PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1));++	if (dst & SLJIT_MEM)+		PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));+	return const_;+}++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_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);+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)+{+	sljit_ins *inst = (sljit_ins *)addr;++	inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43);+	inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43);+	inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43);+	inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);+	SLJIT_CACHE_FLUSH(inst, inst + 4);+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	CHECK_REG_INDEX(check_sljit_get_register_index(reg));+	return reg_map[reg];+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,+	void *instruction, sljit_s32 size)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));+	return SLJIT_ERR_UNSUPPORTED;+}+
+ src/c/pcre2/src/sljit/sljitNativeX86_32.c view
@@ -0,0 +1,928 @@+/*+ *    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.+ */++/* x86 32-bit arch dependent functions. */++static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm)+{+	sljit_u8 *inst;++	inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));+	FAIL_IF(!inst);+	INC_SIZE(1 + sizeof(sljit_sw));+	*inst++ = opcode;+	sljit_unaligned_store_sw(inst, imm);+	return SLJIT_SUCCESS;+}++static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)+{+	sljit_s32 type = jump->flags >> TYPE_SHIFT;++	if (type == SLJIT_JUMP) {+		*code_ptr++ = JMP_i32;+		jump->addr++;+	}+	else if (type >= SLJIT_FAST_CALL) {+		*code_ptr++ = CALL_i32;+		jump->addr++;+	}+	else {+		*code_ptr++ = GROUP_0F;+		*code_ptr++ = get_jump_code(type);+		jump->addr += 2;+	}++	if (jump->flags & JUMP_LABEL)+		jump->flags |= PATCH_MW;+	else+		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 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 args, size;+	sljit_u8 *inst;++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	/* Emit ENDBR32 at function entry if needed.  */+	FAIL_IF(emit_endbranch(compiler));++	args = get_arg_count(arg_types);+	compiler->args = args;++	/* [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+	size += (args > 0 ? (2 + args * 3) : 0);+#endif+	inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+	FAIL_IF(!inst);++	INC_SIZE(size);+	PUSH_REG(reg_map[TMP_REG1]);+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)+	if (args > 0) {+		*inst++ = MOV_r_rm;+		*inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */;+	}+#endif+	if (saveds > 2 || scratches > 9)+		PUSH_REG(reg_map[SLJIT_S2]);+	if (saveds > 1 || scratches > 10)+		PUSH_REG(reg_map[SLJIT_S1]);+	if (saveds > 0 || scratches > 11)+		PUSH_REG(reg_map[SLJIT_S0]);++#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)+	if (args > 0) {+		inst[0] = MOV_r_rm;+		inst[1] = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2];+		inst += 2;+	}+	if (args > 1) {+		inst[0] = MOV_r_rm;+		inst[1] = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1];+		inst += 2;+	}+	if (args > 2) {+		inst[0] = MOV_r_rm;+		inst[1] = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */;+		inst[2] = 0x24;+		inst[3] = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */+	}+#else+	if (args > 0) {+		inst[0] = MOV_r_rm;+		inst[1] = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1];+		inst[2] = sizeof(sljit_sw) * 2;+		inst += 3;+	}+	if (args > 1) {+		inst[0] = MOV_r_rm;+		inst[1] = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1];+		inst[2] = sizeof(sljit_sw) * 3;+		inst += 3;+	}+	if (args > 2) {+		inst[0] = MOV_r_rm;+		inst[1] = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1];+		inst[2] = sizeof(sljit_sw) * 4;+	}+#endif++	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 > 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_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 + sizeof(sljit_sw) - 1) & ~(sizeof(sljit_sw) - 1));+#endif++	compiler->local_size = local_size;++#ifdef _WIN32+	if (local_size > 0) {+		if (local_size <= 4 * 4096) {+			if (local_size > 4096)+				EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096);+			if (local_size > 2 * 4096)+				EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);+			if (local_size > 3 * 4096)+				EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);+		}+		else {+			EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_SP, 0);+			EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_IMM, (local_size - 1) >> 12);++			SLJIT_ASSERT (reg_map[SLJIT_R0] == 0);++			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_R0), -4096);+			FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),+				SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 4096));+			FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),+				SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1));++			inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+			FAIL_IF(!inst);++			INC_SIZE(2);+			inst[0] = JNE_i8;+			inst[1] = (sljit_s8) -16;+		}++		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size);+	}+#endif++	SLJIT_ASSERT(local_size > 0);++#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 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, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	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 > 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_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 + sizeof(sljit_sw) - 1) & ~(sizeof(sljit_sw) - 1));+#endif+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 size;+	sljit_u8 *inst;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));+	SLJIT_ASSERT(compiler->args >= 0);++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++	SLJIT_ASSERT(compiler->local_size > 0);++#if !defined(__APPLE__)+	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 > 9 ? (compiler->scratches - 9) : 0) ++		(compiler->saveds <= 3 ? compiler->saveds : 3);+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)+	if (compiler->args > 2)+		size += 2;+#endif+	inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+	FAIL_IF(!inst);++	INC_SIZE(size);++	if (compiler->saveds > 0 || compiler->scratches > 11)+		POP_REG(reg_map[SLJIT_S0]);+	if (compiler->saveds > 1 || compiler->scratches > 10)+		POP_REG(reg_map[SLJIT_S1]);+	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)+	if (compiler->args > 2)+		RET_I16(sizeof(sljit_sw));+	else+		RET();+#else+	RET();+#endif++	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++/* Size contains the flags as well. */+static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,+	/* The register or immediate operand. */+	sljit_s32 a, sljit_sw imma,+	/* The general operand (not immediate). */+	sljit_s32 b, sljit_sw immb)+{+	sljit_u8 *inst;+	sljit_u8 *buf_ptr;+	sljit_s32 flags = size & ~0xf;+	sljit_s32 inst_size;++	/* Both cannot be switched on. */+	SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));+	/* Size flags not allowed for typed instructions. */+	SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);+	/* Both size flags cannot be switched on. */+	SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));+	/* SSE2 and immediate is not possible. */+	SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));+	SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)+		&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)+		&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));+	/* We don't support (%ebp). */+	SLJIT_ASSERT(!(b & SLJIT_MEM) || immb || reg_map[b & REG_MASK] != 5);++	size &= 0xf;+	inst_size = size;++	if (flags & (EX86_PREF_F2 | EX86_PREF_F3))+		inst_size++;+	if (flags & EX86_PREF_66)+		inst_size++;++	/* Calculate size of b. */+	inst_size += 1; /* mod r/m byte. */+	if (b & SLJIT_MEM) {+		if ((b & REG_MASK) == SLJIT_UNUSED)+			inst_size += sizeof(sljit_sw);+		else if (immb != 0 && !(b & OFFS_REG_MASK)) {+			/* Immediate operand. */+			if (immb <= 127 && immb >= -128)+				inst_size += sizeof(sljit_s8);+			else+				inst_size += sizeof(sljit_sw);+		}++		if ((b & REG_MASK) == SLJIT_SP && !(b & OFFS_REG_MASK))+			b |= TO_OFFS_REG(SLJIT_SP);++		if ((b & OFFS_REG_MASK) != SLJIT_UNUSED)+			inst_size += 1; /* SIB byte. */+	}++	/* Calculate size of a. */+	if (a & SLJIT_IMM) {+		if (flags & EX86_BIN_INS) {+			if (imma <= 127 && imma >= -128) {+				inst_size += 1;+				flags |= EX86_BYTE_ARG;+			} else+				inst_size += 4;+		}+		else if (flags & EX86_SHIFT_INS) {+			imma &= 0x1f;+			if (imma != 1) {+				inst_size ++;+				flags |= EX86_BYTE_ARG;+			}+		} else if (flags & EX86_BYTE_ARG)+			inst_size++;+		else if (flags & EX86_HALF_ARG)+			inst_size += sizeof(short);+		else+			inst_size += sizeof(sljit_sw);+	}+	else+		SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);++	inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);+	PTR_FAIL_IF(!inst);++	/* Encoding the byte. */+	INC_SIZE(inst_size);+	if (flags & EX86_PREF_F2)+		*inst++ = 0xf2;+	if (flags & EX86_PREF_F3)+		*inst++ = 0xf3;+	if (flags & EX86_PREF_66)+		*inst++ = 0x66;++	buf_ptr = inst + size;++	/* Encode mod/rm byte. */+	if (!(flags & EX86_SHIFT_INS)) {+		if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))+			*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;++		if (a & SLJIT_IMM)+			*buf_ptr = 0;+		else if (!(flags & EX86_SSE2_OP1))+			*buf_ptr = reg_map[a] << 3;+		else+			*buf_ptr = a << 3;+	}+	else {+		if (a & SLJIT_IMM) {+			if (imma == 1)+				*inst = GROUP_SHIFT_1;+			else+				*inst = GROUP_SHIFT_N;+		} else+			*inst = GROUP_SHIFT_CL;+		*buf_ptr = 0;+	}++	if (!(b & SLJIT_MEM))+		*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_map[b] : 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) {+				if (immb <= 127 && immb >= -128)+					*buf_ptr |= 0x40;+				else+					*buf_ptr |= 0x80;+			}++			if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)+				*buf_ptr++ |= reg_map[b & REG_MASK];+			else {+				*buf_ptr++ |= 0x04;+				*buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3);+			}++			if (immb != 0) {+				if (immb <= 127 && immb >= -128)+					*buf_ptr++ = immb; /* 8 bit displacement. */+				else {+					sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */+					buf_ptr += sizeof(sljit_sw);+				}+			}+		}+		else {+			*buf_ptr++ |= 0x04;+			*buf_ptr++ = reg_map[b & REG_MASK] | (reg_map[OFFS_REG(b)] << 3) | (immb << 6);+		}+	}+	else {+		*buf_ptr++ |= 0x05;+		sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */+		buf_ptr += sizeof(sljit_sw);+	}++	if (a & SLJIT_IMM) {+		if (flags & EX86_BYTE_ARG)+			*buf_ptr = imma;+		else if (flags & EX86_HALF_ARG)+			sljit_unaligned_store_s16(buf_ptr, imma);+		else if (!(flags & EX86_SHIFT_INS))+			sljit_unaligned_store_sw(buf_ptr, imma);+	}++	return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);+}++/* --------------------------------------------------------------------- */+/*  Call / return instructions                                           */+/* --------------------------------------------------------------------- */++#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)+	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 (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, 0));+		return jump;+	}+#endif++	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)+{+	sljit_u8 *inst;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	CHECK_EXTRA_REGS(dst, dstw, (void)0);++	/* For UNUSED dst. Uncommon, but possible. */+	if (dst == SLJIT_UNUSED)+		dst = TMP_REG1;++	if (FAST_IS_REG(dst)) {+		/* Unused dest is possible here. */+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+		FAIL_IF(!inst);++		INC_SIZE(1);+		POP_REG(reg_map[dst]);+		return SLJIT_SUCCESS;+	}++	/* Memory. */+	inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);+	FAIL_IF(!inst);+	*inst++ = POP_rm;+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)+{+	sljit_u8 *inst;++	CHECK_EXTRA_REGS(src, srcw, (void)0);++	if (FAST_IS_REG(src)) {+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);+		FAIL_IF(!inst);++		INC_SIZE(1 + 1);+		PUSH_REG(reg_map[src]);+	}+	else {+		inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);+		FAIL_IF(!inst);+		*inst++ = GROUP_FF;+		*inst |= PUSH_rm;++		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+		FAIL_IF(!inst);+		INC_SIZE(1);+	}++	RET();+	return SLJIT_SUCCESS;+}++static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)+{+	sljit_s32 size, saved_size;+	sljit_s32 has_f64_aligment;++	/* Don't adjust shadow stack if it isn't enabled.  */+	if (!cpu_has_shadow_stack ())+		return SLJIT_SUCCESS;++	SLJIT_ASSERT(compiler->args >= 0);+	SLJIT_ASSERT(compiler->local_size > 0);++#if !defined(__APPLE__)+	has_f64_aligment = compiler->options & SLJIT_F64_ALIGNMENT;+#else+	has_f64_aligment = 0;+#endif++	size = compiler->local_size;+	saved_size = (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) + (compiler->saveds <= 3 ? compiler->saveds : 3)) * sizeof(sljit_uw);+	if (has_f64_aligment) {+		/* mov TMP_REG1, [esp + local_size].  */+		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), size);+		/* mov TMP_REG1, [TMP_REG1+ saved_size].  */+		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), saved_size);+		/* Move return address to [esp]. */+		EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, TMP_REG1, 0);+		size = 0;+	} else+		size += saved_size;++	return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size);+}
+ src/c/pcre2/src/sljit/sljitNativeX86_64.c view
@@ -0,0 +1,918 @@+/*+ *    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.+ */++/* x86 64-bit arch dependent functions. */++static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)+{+	sljit_u8 *inst;++	inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));+	FAIL_IF(!inst);+	INC_SIZE(2 + sizeof(sljit_sw));+	*inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);+	*inst++ = MOV_r_i32 + (reg_map[reg] & 0x7);+	sljit_unaligned_store_sw(inst, imm);+	return SLJIT_SUCCESS;+}++static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr)+{+	sljit_s32 type = jump->flags >> TYPE_SHIFT;++	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++ = short_addr ? (6 + 3) : (10 + 3);+	}++	*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 += short_addr ? sizeof(sljit_s32) : sizeof(sljit_sw);++	*code_ptr++ = REX_B;+	*code_ptr++ = GROUP_FF;+	*code_ptr++ = MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2];++	return code_ptr;+}++static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label)+{+	if (max_label > HALFWORD_MAX) {+		put_label->addr -= put_label->flags;+		put_label->flags = PATCH_MD;+		return code_ptr;+	}++	if (put_label->flags == 0) {+		/* Destination is register. */+		code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw);++		SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);+		SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);++		if ((code_ptr[0] & 0x07) != 0) {+			code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x08);+			code_ptr += 2 + sizeof(sljit_s32);+		}+		else {+			code_ptr[0] = code_ptr[1];+			code_ptr += 1 + sizeof(sljit_s32);+		}++		put_label->addr = (sljit_uw)code_ptr;+		return code_ptr;+	}++	code_ptr -= put_label->flags + (2 + sizeof(sljit_uw));+	SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags);++	SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);++	if ((code_ptr[1] & 0xf8) == MOV_r_i32) {+		code_ptr += 2 + sizeof(sljit_uw);+		SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);+	}++	SLJIT_ASSERT(code_ptr[1] == MOV_rm_r);++	code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x4);+	code_ptr[1] = MOV_rm_i32;+	code_ptr[2] = (sljit_u8)(code_ptr[2] & ~(0x7 << 3));++	code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32));+	put_label->addr = (sljit_uw)code_ptr;+	put_label->flags = 0;+	return code_ptr;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 args, i, tmp, size, saved_register_size;+	sljit_u8 *inst;++	CHECK_ERROR();+	CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++	/* Emit ENDBR64 at function entry if needed.  */+	FAIL_IF(emit_endbranch(compiler));++	compiler->mode32 = 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);++	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = SLJIT_S0; i >= tmp; i--) {+		size = reg_map[i] >= 8 ? 2 : 1;+		inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+		FAIL_IF(!inst);+		INC_SIZE(size);+		if (reg_map[i] >= 8)+			*inst++ = REX_B;+		PUSH_REG(reg_lmap[i]);+	}++	for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {+		size = reg_map[i] >= 8 ? 2 : 1;+		inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+		FAIL_IF(!inst);+		INC_SIZE(size);+		if (reg_map[i] >= 8)+			*inst++ = REX_B;+		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);+		FAIL_IF(!inst);++		INC_SIZE(size);++#ifndef _WIN64+		if (args > 0) {+			inst[0] = REX_W;+			inst[1] = MOV_r_rm;+			inst[2] = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */;+			inst += 3;+		}+		if (args > 1) {+			inst[0] = REX_W | REX_R;+			inst[1] = MOV_r_rm;+			inst[2] = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */;+			inst += 3;+		}+		if (args > 2) {+			inst[0] = REX_W | REX_R;+			inst[1] = MOV_r_rm;+			inst[2] = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */;+		}+#else+		if (args > 0) {+			inst[0] = REX_W;+			inst[1] = MOV_r_rm;+			inst[2] = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */;+			inst += 3;+		}+		if (args > 1) {+			inst[0] = REX_W;+			inst[1] = MOV_r_rm;+			inst[2] = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */;+			inst += 3;+		}+		if (args > 2) {+			inst[0] = REX_W | REX_B;+			inst[1] = MOV_r_rm;+			inst[2] = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */;+		}+#endif+	}++	local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size;+	compiler->local_size = local_size;++#ifdef _WIN64+	if (local_size > 0) {+		if (local_size <= 4 * 4096) {+			if (local_size > 4096)+				EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096);+			if (local_size > 2 * 4096)+				EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);+			if (local_size > 3 * 4096)+				EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);+		}+		else {+			EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_SP, 0);+			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, (local_size - 1) >> 12);++			SLJIT_ASSERT (reg_map[SLJIT_R0] == 0);++			EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_MEM1(SLJIT_R0), -4096);+			FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),+				SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 4096));+			FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),+				TMP_REG1, 0, TMP_REG1, 0, SLJIT_IMM, 1));++			inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+			FAIL_IF(!inst);++			INC_SIZE(2);+			inst[0] = JNE_i8;+			inst[1] = (sljit_s8) -19;+		}++		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size);+	}+#endif++	if (local_size > 0) {+		FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));+	}++#ifdef _WIN64+	/* Save xmm6 register: movaps [rsp + 0x20], xmm6 */+	if (fscratches >= 6 || fsaveds >= 1) {+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);+		FAIL_IF(!inst);+		INC_SIZE(5);+		*inst++ = GROUP_0F;+		sljit_unaligned_store_s32(inst, 0x20247429);+	}+#endif++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,+	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)+{+	sljit_s32 saved_register_size;++	CHECK_ERROR();+	CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));+	set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);++#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);+	compiler->local_size = ((local_size + SLJIT_LOCALS_OFFSET + saved_register_size + 15) & ~15) - saved_register_size;+	return SLJIT_SUCCESS;+}++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, size;+	sljit_u8 *inst;++	CHECK_ERROR();+	CHECK(check_sljit_emit_return(compiler, op, src, srcw));++	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));++#ifdef _WIN64+	/* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */+	if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) {+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);+		FAIL_IF(!inst);+		INC_SIZE(5);+		*inst++ = GROUP_0F;+		sljit_unaligned_store_s32(inst, 0x20247428);+	}+#endif++	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;+	for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {+		size = reg_map[i] >= 8 ? 2 : 1;+		inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+		FAIL_IF(!inst);+		INC_SIZE(size);+		if (reg_map[i] >= 8)+			*inst++ = REX_B;+		POP_REG(reg_lmap[i]);+	}++	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;+	for (i = tmp; i <= SLJIT_S0; i++) {+		size = reg_map[i] >= 8 ? 2 : 1;+		inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+		FAIL_IF(!inst);+		INC_SIZE(size);+		if (reg_map[i] >= 8)+			*inst++ = REX_B;+		POP_REG(reg_lmap[i]);+	}++	inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+	FAIL_IF(!inst);+	INC_SIZE(1);+	RET();+	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Operators                                                            */+/* --------------------------------------------------------------------- */++static sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm)+{+	sljit_u8 *inst;+	sljit_s32 length = 1 + (rex ? 1 : 0) + sizeof(sljit_s32);++	inst = (sljit_u8*)ensure_buf(compiler, 1 + length);+	FAIL_IF(!inst);+	INC_SIZE(length);+	if (rex)+		*inst++ = rex;+	*inst++ = opcode;+	sljit_unaligned_store_s32(inst, imm);+	return SLJIT_SUCCESS;+}++static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,+	/* The register or immediate operand. */+	sljit_s32 a, sljit_sw imma,+	/* The general operand (not immediate). */+	sljit_s32 b, sljit_sw immb)+{+	sljit_u8 *inst;+	sljit_u8 *buf_ptr;+	sljit_u8 rex = 0;+	sljit_s32 flags = size & ~0xf;+	sljit_s32 inst_size;++	/* The immediate operand must be 32 bit. */+	SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));+	/* Both cannot be switched on. */+	SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));+	/* Size flags not allowed for typed instructions. */+	SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);+	/* Both size flags cannot be switched on. */+	SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));+	/* SSE2 and immediate is not possible. */+	SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));+	SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)+		&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)+		&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));++	size &= 0xf;+	inst_size = size;++	if (!compiler->mode32 && !(flags & EX86_NO_REXW))+		rex |= REX_W;+	else if (flags & EX86_REX)+		rex |= REX;++	if (flags & (EX86_PREF_F2 | EX86_PREF_F3))+		inst_size++;+	if (flags & EX86_PREF_66)+		inst_size++;++	/* Calculate size of b. */+	inst_size += 1; /* mod r/m byte. */+	if (b & SLJIT_MEM) {+		if (!(b & OFFS_REG_MASK)) {+			if (NOT_HALFWORD(immb)) {+				PTR_FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immb));+				immb = 0;+				if (b & REG_MASK)+					b |= TO_OFFS_REG(TMP_REG2);+				else+					b |= TMP_REG2;+			}+			else if (reg_lmap[b & REG_MASK] == 4)+				b |= TO_OFFS_REG(SLJIT_SP);+		}++		if ((b & REG_MASK) == SLJIT_UNUSED)+			inst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */+		else {+			if (reg_map[b & REG_MASK] >= 8)+				rex |= REX_B;++			if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) {+				/* Immediate operand. */+				if (immb <= 127 && immb >= -128)+					inst_size += sizeof(sljit_s8);+				else+					inst_size += sizeof(sljit_s32);+			}+			else if (reg_lmap[b & REG_MASK] == 5)+				inst_size += sizeof(sljit_s8);++			if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {+				inst_size += 1; /* SIB byte. */+				if (reg_map[OFFS_REG(b)] >= 8)+					rex |= REX_X;+			}+		}+	}+	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) {+		if (flags & EX86_BIN_INS) {+			if (imma <= 127 && imma >= -128) {+				inst_size += 1;+				flags |= EX86_BYTE_ARG;+			} else+				inst_size += 4;+		}+		else if (flags & EX86_SHIFT_INS) {+			imma &= compiler->mode32 ? 0x1f : 0x3f;+			if (imma != 1) {+				inst_size ++;+				flags |= EX86_BYTE_ARG;+			}+		} else if (flags & EX86_BYTE_ARG)+			inst_size++;+		else if (flags & EX86_HALF_ARG)+			inst_size += sizeof(short);+		else+			inst_size += sizeof(sljit_s32);+	}+	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)) {+			if (reg_map[a] >= 8)+				rex |= REX_R;+		}+		else if (freg_map[a] >= 8)+			rex |= REX_R;+	}++	if (rex)+		inst_size++;++	inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);+	PTR_FAIL_IF(!inst);++	/* Encoding the byte. */+	INC_SIZE(inst_size);+	if (flags & EX86_PREF_F2)+		*inst++ = 0xf2;+	if (flags & EX86_PREF_F3)+		*inst++ = 0xf3;+	if (flags & EX86_PREF_66)+		*inst++ = 0x66;+	if (rex)+		*inst++ = rex;+	buf_ptr = inst + size;++	/* Encode mod/rm byte. */+	if (!(flags & EX86_SHIFT_INS)) {+		if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))+			*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;++		if (a & SLJIT_IMM)+			*buf_ptr = 0;+		else if (!(flags & EX86_SSE2_OP1))+			*buf_ptr = reg_lmap[a] << 3;+		else+			*buf_ptr = freg_lmap[a] << 3;+	}+	else {+		if (a & SLJIT_IMM) {+			if (imma == 1)+				*inst = GROUP_SHIFT_1;+			else+				*inst = GROUP_SHIFT_N;+		} else+			*inst = GROUP_SHIFT_CL;+		*buf_ptr = 0;+	}++	if (!(b & SLJIT_MEM))+		*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) {+				if (immb <= 127 && immb >= -128)+					*buf_ptr |= 0x40;+				else+					*buf_ptr |= 0x80;+			}++			if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)+				*buf_ptr++ |= reg_lmap[b & REG_MASK];+			else {+				*buf_ptr++ |= 0x04;+				*buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3);+			}++			if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {+				if (immb <= 127 && immb >= -128)+					*buf_ptr++ = immb; /* 8 bit displacement. */+				else {+					sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */+					buf_ptr += sizeof(sljit_s32);+				}+			}+		}+		else {+			if (reg_lmap[b & REG_MASK] == 5)+				*buf_ptr |= 0x40;+			*buf_ptr++ |= 0x04;+			*buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6);+			if (reg_lmap[b & REG_MASK] == 5)+				*buf_ptr++ = 0;+		}+	}+	else {+		*buf_ptr++ |= 0x04;+		*buf_ptr++ = 0x25;+		sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */+		buf_ptr += sizeof(sljit_s32);+	}++	if (a & SLJIT_IMM) {+		if (flags & EX86_BYTE_ARG)+			*buf_ptr = imma;+		else if (flags & EX86_HALF_ARG)+			sljit_unaligned_store_s16(buf_ptr, imma);+		else if (!(flags & EX86_SHIFT_INS))+			sljit_unaligned_store_s32(buf_ptr, imma);+	}++	return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);+}++/* --------------------------------------------------------------------- */+/*  Call / return instructions                                           */+/* --------------------------------------------------------------------- */++#ifndef _WIN64++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;+	}++	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++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;+	}++	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;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	/* For UNUSED dst. Uncommon, but possible. */+	if (dst == SLJIT_UNUSED)+		dst = TMP_REG1;++	if (FAST_IS_REG(dst)) {+		if (reg_map[dst] < 8) {+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+			FAIL_IF(!inst);+			INC_SIZE(1);+			POP_REG(reg_lmap[dst]);+			return SLJIT_SUCCESS;+		}++		inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+		FAIL_IF(!inst);+		INC_SIZE(2);+		*inst++ = REX_B;+		POP_REG(reg_lmap[dst]);+		return SLJIT_SUCCESS;+	}++	/* REX_W is not necessary (src is not immediate). */+	compiler->mode32 = 1;+	inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);+	FAIL_IF(!inst);+	*inst++ = POP_rm;+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)+{+	sljit_u8 *inst;++	if (FAST_IS_REG(src)) {+		if (reg_map[src] < 8) {+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);+			FAIL_IF(!inst);++			INC_SIZE(1 + 1);+			PUSH_REG(reg_lmap[src]);+		}+		else {+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);+			FAIL_IF(!inst);++			INC_SIZE(2 + 1);+			*inst++ = REX_B;+			PUSH_REG(reg_lmap[src]);+		}+	}+	else {+		/* REX_W is not necessary (src is not immediate). */+		compiler->mode32 = 1;+		inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);+		FAIL_IF(!inst);+		*inst++ = GROUP_FF;+		*inst |= PUSH_rm;++		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+		FAIL_IF(!inst);+		INC_SIZE(1);+	}++	RET();+	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Extend input                                                         */+/* --------------------------------------------------------------------- */++static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_u8* inst;+	sljit_s32 dst_r;++	compiler->mode32 = 0;++	if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))+		return SLJIT_SUCCESS; /* Empty instruction. */++	if (src & SLJIT_IMM) {+		if (FAST_IS_REG(dst)) {+			if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {+				inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);+				FAIL_IF(!inst);+				*inst = MOV_rm_i32;+				return SLJIT_SUCCESS;+			}+			return emit_load_imm64(compiler, dst, srcw);+		}+		compiler->mode32 = 1;+		inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm_i32;+		compiler->mode32 = 0;+		return SLJIT_SUCCESS;+	}++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if ((dst & SLJIT_MEM) && FAST_IS_REG(src))+		dst_r = src;+	else {+		if (sign) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);+			FAIL_IF(!inst);+			*inst++ = MOVSXD_r_rm;+		} else {+			compiler->mode32 = 1;+			FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));+			compiler->mode32 = 0;+		}+	}++	if (dst & SLJIT_MEM) {+		compiler->mode32 = 1;+		inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm_r;+		compiler->mode32 = 0;+	}++	return SLJIT_SUCCESS;+}++static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)+{+	sljit_s32 tmp, size;++	/* Don't adjust shadow stack if it isn't enabled.  */+	if (!cpu_has_shadow_stack ())+		return SLJIT_SUCCESS;++	size = compiler->local_size;+	tmp = compiler->scratches;+	if (tmp >= SLJIT_FIRST_SAVED_REG)+		size += (tmp - SLJIT_FIRST_SAVED_REG + 1) * sizeof(sljit_uw);+	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;+	if (SLJIT_S0 >= tmp)+		size += (SLJIT_S0 - tmp + 1) * sizeof(sljit_uw);++	return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size);+}
+ src/c/pcre2/src/sljit/sljitNativeX86_common.c view
@@ -0,0 +1,3142 @@+/*+ *    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.+ */++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+}++/*+   32b register indexes:+     0 - EAX+     1 - ECX+     2 - EDX+     3 - EBX+     4 - ESP+     5 - EBP+     6 - ESI+     7 - EDI+*/++/*+   64b register indexes:+     0 - RAX+     1 - RCX+     2 - RDX+     3 - RBX+     4 - RSP+     5 - RBP+     6 - RSI+     7 - RDI+     8 - R8   - From now on REX prefix is required+     9 - R9+    10 - R10+    11 - R11+    12 - R12+    13 - R13+    14 - R14+    15 - R15+*/++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)++/* Last register + 1. */+#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, 0, 0, 7, 6, 3, 4, 5+};++#define CHECK_EXTRA_REGS(p, w, do) \+	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; \+	}++#else /* SLJIT_CONFIG_X86_32 */++/* Last register + 1. */+#define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)+#define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)++/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present+   Note: avoid to use r12 and r13 for memory addessing+   therefore r12 is better to be a higher saved register. */+#ifndef _WIN64+/* 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 + 4] = {+	0, 0, 6, 7, 1, 0, 3,  2,  4,  5,  5,  6,  7, 3, 4, 2, 1+};+#else+/* 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 + 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+#define REX_B		0x41+#define REX		0x40++#ifndef _WIN64+#define HALFWORD_MAX 0x7fffffffl+#define HALFWORD_MIN -0x80000000l+#else+#define HALFWORD_MAX 0x7fffffffll+#define HALFWORD_MIN -0x80000000ll+#endif++#define IS_HALFWORD(x)		((x) <= HALFWORD_MAX && (x) >= HALFWORD_MIN)+#define NOT_HALFWORD(x)		((x) > HALFWORD_MAX || (x) < HALFWORD_MIN)++#define CHECK_EXTRA_REGS(p, w, do)++#endif /* SLJIT_CONFIG_X86_32 */++#define TMP_FREG	(0)++/* Size flags for emit_x86_instruction: */+#define EX86_BIN_INS		0x0010+#define EX86_SHIFT_INS		0x0020+#define EX86_REX		0x0040+#define EX86_NO_REXW		0x0080+#define EX86_BYTE_ARG		0x0100+#define EX86_HALF_ARG		0x0200+#define EX86_PREF_66		0x0400+#define EX86_PREF_F2		0x0800+#define EX86_PREF_F3		0x1000+#define EX86_SSE2_OP1		0x2000+#define EX86_SSE2_OP2		0x4000+#define EX86_SSE2		(EX86_SSE2_OP1 | EX86_SSE2_OP2)++/* --------------------------------------------------------------------- */+/*  Instrucion forms                                                     */+/* --------------------------------------------------------------------- */++#define ADD		(/* BINARY */ 0 << 3)+#define ADD_EAX_i32	0x05+#define ADD_r_rm	0x03+#define ADD_rm_r	0x01+#define ADDSD_x_xm	0x58+#define ADC		(/* BINARY */ 2 << 3)+#define ADC_EAX_i32	0x15+#define ADC_r_rm	0x13+#define ADC_rm_r	0x11+#define AND		(/* BINARY */ 4 << 3)+#define AND_EAX_i32	0x25+#define AND_r_rm	0x23+#define AND_rm_r	0x21+#define ANDPD_x_xm	0x54+#define BSR_r_rm	(/* GROUP_0F */ 0xbd)+#define CALL_i32	0xe8+#define CALL_rm		(/* GROUP_FF */ 2 << 3)+#define CDQ		0x99+#define CMOVE_r_rm	(/* GROUP_0F */ 0x44)+#define CMP		(/* BINARY */ 7 << 3)+#define CMP_EAX_i32	0x3d+#define CMP_r_rm	0x3b+#define CMP_rm_r	0x39+#define CVTPD2PS_x_xm	0x5a+#define CVTSI2SD_x_rm	0x2a+#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)+#define IMUL_r_rm	(/* GROUP_0F */ 0xaf)+#define IMUL_r_rm_i8	0x6b+#define IMUL_r_rm_i32	0x69+#define JE_i8		0x74+#define JNE_i8		0x75+#define JMP_i8		0xeb+#define JMP_i32		0xe9+#define JMP_rm		(/* GROUP_FF */ 4 << 3)+#define LEA_r_m		0x8d+#define MOV_r_rm	0x8b+#define MOV_r_i32	0xb8+#define MOV_rm_r	0x89+#define MOV_rm_i32	0xc7+#define MOV_rm8_i8	0xc6+#define MOV_rm8_r8	0x88+#define MOVSD_x_xm	0x10+#define MOVSD_xm_x	0x11+#define MOVSXD_r_rm	0x63+#define MOVSX_r_rm8	(/* GROUP_0F */ 0xbe)+#define MOVSX_r_rm16	(/* GROUP_0F */ 0xbf)+#define MOVZX_r_rm8	(/* GROUP_0F */ 0xb6)+#define MOVZX_r_rm16	(/* GROUP_0F */ 0xb7)+#define MUL		(/* GROUP_F7 */ 4 << 3)+#define MULSD_x_xm	0x59+#define NEG_rm		(/* GROUP_F7 */ 3 << 3)+#define NOP		0x90+#define NOT_rm		(/* GROUP_F7 */ 2 << 3)+#define OR		(/* BINARY */ 1 << 3)+#define OR_r_rm		0x0b+#define OR_EAX_i32	0x0d+#define OR_rm_r		0x09+#define OR_rm8_r8	0x08+#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)+#define PUSHF		0x9c+#define RET_near	0xc3+#define RET_i16		0xc2+#define SBB		(/* BINARY */ 3 << 3)+#define SBB_EAX_i32	0x1d+#define SBB_r_rm	0x1b+#define SBB_rm_r	0x19+#define SAR		(/* SHIFT */ 7 << 3)+#define SHL		(/* SHIFT */ 4 << 3)+#define SHR		(/* SHIFT */ 5 << 3)+#define SUB		(/* BINARY */ 5 << 3)+#define SUB_EAX_i32	0x2d+#define SUB_r_rm	0x2b+#define SUB_rm_r	0x29+#define SUBSD_x_xm	0x5c+#define TEST_EAX_i32	0xa9+#define TEST_rm_r	0x85+#define UCOMISD_x_xm	0x2e+#define UNPCKLPD_x_xm	0x14+#define XCHG_EAX_r	0x90+#define XCHG_r_rm	0x87+#define XOR		(/* BINARY */ 6 << 3)+#define XOR_EAX_i32	0x35+#define XOR_r_rm	0x33+#define XOR_rm_r	0x31+#define XORPD_x_xm	0x57++#define GROUP_0F	0x0f+#define GROUP_F7	0xf7+#define GROUP_FF	0xff+#define GROUP_BINARY_81	0x81+#define GROUP_BINARY_83	0x83+#define GROUP_SHIFT_1	0xd1+#define GROUP_SHIFT_N	0xc1+#define GROUP_SHIFT_CL	0xd3++#define MOD_REG		0xc0+#define MOD_DISP8	0x40++#define INC_SIZE(s)			(*inst++ = (s), compiler->size += (s))++#define PUSH_REG(r)			(*inst++ = (PUSH_r + (r)))+#define POP_REG(r)			(*inst++ = (POP_r + (r)))+#define RET()				(*inst++ = (RET_near))+#define RET_I16(n)			(*inst++ = (RET_i16), *inst++ = n, *inst++ = 0)+/* r32, r/m32 */+#define MOV_RM(mod, reg, rm)		(*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm))++/* Multithreading does not affect these static variables, since they store+   built-in CPU features. Therefore they can be overwritten by different threads+   if they detect the CPU features in the same time. */+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)+static sljit_s32 cpu_has_sse2 = -1;+#endif+static sljit_s32 cpu_has_cmov = -1;++#ifdef _WIN32_WCE+#include <cmnintrin.h>+#elif defined(_MSC_VER) && _MSC_VER >= 1400+#include <intrin.h>+#endif++/******************************************************/+/*    Unaligned-store functions                       */+/******************************************************/++static SLJIT_INLINE void sljit_unaligned_store_s16(void *addr, sljit_s16 value)+{+	SLJIT_MEMCPY(addr, &value, sizeof(value));+}++static SLJIT_INLINE void sljit_unaligned_store_s32(void *addr, sljit_s32 value)+{+	SLJIT_MEMCPY(addr, &value, sizeof(value));+}++static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value)+{+	SLJIT_MEMCPY(addr, &value, sizeof(value));+}++/******************************************************/+/*    Utility functions                               */+/******************************************************/++static void get_cpu_features(void)+{+	sljit_u32 features;++#if defined(_MSC_VER) && _MSC_VER >= 1400++	int CPUInfo[4];+	__cpuid(CPUInfo, 1);+	features = (sljit_u32)CPUInfo[3];++#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)++	/* AT&T syntax. */+	__asm__ (+		"movl $0x1, %%eax\n"+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		/* On x86-32, there is no red zone, so this+		   should work (no need for a local variable). */+		"push %%ebx\n"+#endif+		"cpuid\n"+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		"pop %%ebx\n"+#endif+		"movl %%edx, %0\n"+		: "=g" (features)+		:+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		: "%eax", "%ecx", "%edx"+#else+		: "%rax", "%rbx", "%rcx", "%rdx"+#endif+	);++#else /* _MSC_VER && _MSC_VER >= 1400 */++	/* Intel syntax. */+	__asm {+		mov eax, 1+		cpuid+		mov features, edx+	}++#endif /* _MSC_VER && _MSC_VER >= 1400 */++#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)+	cpu_has_sse2 = (features >> 26) & 0x1;+#endif+	cpu_has_cmov = (features >> 15) & 0x1;+}++static sljit_u8 get_jump_code(sljit_s32 type)+{+	switch (type) {+	case SLJIT_EQUAL:+	case SLJIT_EQUAL_F64:+		return 0x84 /* je */;++	case SLJIT_NOT_EQUAL:+	case SLJIT_NOT_EQUAL_F64:+		return 0x85 /* jne */;++	case SLJIT_LESS:+	case SLJIT_LESS_F64:+		return 0x82 /* jc */;++	case SLJIT_GREATER_EQUAL:+	case SLJIT_GREATER_EQUAL_F64:+		return 0x83 /* jae */;++	case SLJIT_GREATER:+	case SLJIT_GREATER_F64:+		return 0x87 /* jnbe */;++	case SLJIT_LESS_EQUAL:+	case SLJIT_LESS_EQUAL_F64:+		return 0x86 /* jbe */;++	case SLJIT_SIG_LESS:+		return 0x8c /* jl */;++	case SLJIT_SIG_GREATER_EQUAL:+		return 0x8d /* jnl */;++	case SLJIT_SIG_GREATER:+		return 0x8f /* jnle */;++	case SLJIT_SIG_LESS_EQUAL:+		return 0x8e /* jle */;++	case SLJIT_OVERFLOW:+	case SLJIT_MUL_OVERFLOW:+		return 0x80 /* jo */;++	case SLJIT_NOT_OVERFLOW:+	case SLJIT_MUL_NOT_OVERFLOW:+		return 0x81 /* jno */;++	case SLJIT_UNORDERED_F64:+		return 0x8a /* jp */;++	case SLJIT_ORDERED_F64:+		return 0x8b /* jpo */;+	}+	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_sw executable_offset);+#else+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr);+static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label);+#endif++static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)+{+	sljit_s32 type = jump->flags >> TYPE_SHIFT;+	sljit_s32 short_jump;+	sljit_uw label_addr;++	if (jump->flags & JUMP_LABEL)+		label_addr = (sljit_uw)(code + jump->u.label->size);+	else+		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)+	if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN)+		return generate_far_jump_code(jump, code_ptr);+#endif++	if (type == SLJIT_JUMP) {+		if (short_jump)+			*code_ptr++ = JMP_i8;+		else+			*code_ptr++ = JMP_i32;+		jump->addr++;+	}+	else if (type >= SLJIT_FAST_CALL) {+		short_jump = 0;+		*code_ptr++ = CALL_i32;+		jump->addr++;+	}+	else if (short_jump) {+		*code_ptr++ = get_jump_code(type) - 0x10;+		jump->addr++;+	}+	else {+		*code_ptr++ = GROUP_0F;+		*code_ptr++ = get_jump_code(type);+		jump->addr += 2;+	}++	if (short_jump) {+		jump->flags |= PATCH_MB;+		code_ptr += sizeof(sljit_s8);+	} else {+		jump->flags |= PATCH_MW;+		code_ptr += sizeof(sljit_s32);+	}++	return code_ptr;+}++SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)+{+	struct sljit_memory_fragment *buf;+	sljit_u8 *code;+	sljit_u8 *code_ptr;+	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;+	struct sljit_const *const_;+	struct sljit_put_label *put_label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_generate_code(compiler));+	reverse_buf(compiler);++	/* Second code generation pass. */+	code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data);+	PTR_FAIL_WITH_EXEC_IF(code);+	buf = compiler->buf;++	code_ptr = code;+	label = compiler->labels;+	jump = compiler->jumps;+	const_ = compiler->consts;+	put_label = compiler->put_labels;+	executable_offset = SLJIT_EXEC_OFFSET(code);++	do {+		buf_ptr = buf->memory;+		buf_end = buf_ptr + buf->used_size;+		do {+			len = *buf_ptr++;+			if (len > 0) {+				/* The code is already generated. */+				SLJIT_MEMCPY(code_ptr, buf_ptr, len);+				code_ptr += len;+				buf_ptr += len;+			}+			else {+				switch (*buf_ptr) {+				case 0:+					label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);+					label->size = code_ptr - code;+					label = label->next;+					break;+				case 1:+					jump->addr = (sljit_uw)code_ptr;+					if (!(jump->flags & SLJIT_REWRITABLE_JUMP))+						code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset);+					else {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+						code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset);+#else+						code_ptr = generate_far_jump_code(jump, code_ptr);+#endif+					}+					jump = jump->next;+					break;+				case 2:+					const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);+					const_ = const_->next;+					break;+				default:+					SLJIT_ASSERT(*buf_ptr == 3);+					SLJIT_ASSERT(put_label->label);+					put_label->addr = (sljit_uw)code_ptr;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+					code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size);+#endif+					put_label = put_label->next;+					break;+				}+				buf_ptr++;+			}+		} while (buf_ptr < buf_end);+		SLJIT_ASSERT(buf_ptr == buf_end);+		buf = buf->next;+	} while (buf);++	SLJIT_ASSERT(!label);+	SLJIT_ASSERT(!jump);+	SLJIT_ASSERT(!const_);+	SLJIT_ASSERT(!put_label);+	SLJIT_ASSERT(code_ptr <= code + compiler->size);++	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)));+		} 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))));+#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))));+#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))));+#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))));+#endif+			}+		}+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		else if (jump->flags & PATCH_MD)+			sljit_unaligned_store_sw((void*)jump->addr, jump->u.label->addr);+#endif++		jump = jump->next;+	}++	put_label = compiler->put_labels;+	while (put_label) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);+#else+		if (put_label->flags & PATCH_MD) {+			SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX);+			sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);+		}+		else {+			SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX);+			sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr);+		}+#endif++		put_label = put_label->next;+	}++	compiler->error = SLJIT_ERR_COMPILED;+	compiler->executable_offset = executable_offset;+	compiler->executable_size = code_ptr - code;++	code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);++	SLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1);+	return (void*)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;+#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_PREFETCH:+		return 1;++	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_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_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_mov(struct sljit_compiler *compiler,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw);++#define EMIT_MOV(compiler, dst, dstw, src, srcw) \+	FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));++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_sse2_load(struct sljit_compiler *compiler,+	sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);++static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w);++static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler)+{+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)+	/* Emit endbr32/endbr64 when CET is enabled.  */+	sljit_u8 *inst;+	inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);+	FAIL_IF(!inst);+	INC_SIZE(4);+	*inst++ = 0xf3;+	*inst++ = 0x0f;+	*inst++ = 0x1e;+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	*inst = 0xfb;+#else+	*inst = 0xfa;+#endif+#else /* !SLJIT_CONFIG_X86_CET */+	SLJIT_UNUSED_ARG(compiler);+#endif /* SLJIT_CONFIG_X86_CET */+	return SLJIT_SUCCESS;+}++#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)++static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg)+{+	sljit_u8 *inst;+	sljit_s32 size;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	size = 5;+#else+	size = 4;+#endif++	inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+	FAIL_IF(!inst);+	INC_SIZE(size);+	*inst++ = 0xf3;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);+#endif+	*inst++ = 0x0f;+	*inst++ = 0x1e;+	*inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg)+{+	sljit_u8 *inst;+	sljit_s32 size;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	size = 5;+#else+	size = 4;+#endif++	inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+	FAIL_IF(!inst);+	INC_SIZE(size);+	*inst++ = 0xf3;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);+#endif+	*inst++ = 0x0f;+	*inst++ = 0xae;+	*inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7);+	return SLJIT_SUCCESS;+}++#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */++static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)+{+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)+	return _get_ssp() != 0;+#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */+	return 0;+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */+}++static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,+	sljit_s32 src, sljit_sw srcw, sljit_s32 base, sljit_sw disp)+{+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)+	sljit_u8 *inst, *jz_after_cmp_inst;+	sljit_uw size_jz_after_cmp_inst;++	sljit_uw size_before_rdssp_inst = compiler->size;++	/* Generate "RDSSP TMP_REG1". */+	FAIL_IF(emit_rdssp(compiler, TMP_REG1));++	/* Load return address on shadow stack into TMP_REG1. */+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	SLJIT_ASSERT(reg_map[TMP_REG1] == 5);++	/* Hand code unsupported "mov 0x0(%ebp),%ebp". */+	inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);+	FAIL_IF(!inst);+	INC_SIZE(3);+	*inst++ = 0x8b;+	*inst++ = 0x6d;+	*inst = 0;+#else /* !SLJIT_CONFIG_X86_32 */+	EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0);+#endif /* SLJIT_CONFIG_X86_32 */++	if (src == SLJIT_UNUSED) {+		/* Return address is on stack.  */+		src = SLJIT_MEM1(base);+		srcw = disp;+	}++	/* Compare return address against TMP_REG1. */+	FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw));++	/* Generate JZ to skip shadow stack ajdustment when shadow+	   stack matches normal stack. */+	inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+	FAIL_IF(!inst);+	INC_SIZE(2);+	*inst++ = get_jump_code(SLJIT_EQUAL) - 0x10;+	size_jz_after_cmp_inst = compiler->size;+	jz_after_cmp_inst = inst;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	/* REX_W is not necessary. */+	compiler->mode32 = 1;+#endif+	/* Load 1 into TMP_REG1. */+	EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);++	/* Generate "INCSSP TMP_REG1". */+	FAIL_IF(emit_incssp(compiler, TMP_REG1));++	/* Jump back to "RDSSP TMP_REG1" to check shadow stack again. */+	inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+	FAIL_IF(!inst);+	INC_SIZE(2);+	*inst++ = JMP_i8;+	*inst = size_before_rdssp_inst - compiler->size;++	*jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst;+#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */+	SLJIT_UNUSED_ARG(compiler);+	SLJIT_UNUSED_ARG(src);+	SLJIT_UNUSED_ARG(srcw);+	SLJIT_UNUSED_ARG(base);+	SLJIT_UNUSED_ARG(disp);+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */+	return SLJIT_SUCCESS;+}++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+#include "sljitNativeX86_32.c"+#else+#include "sljitNativeX86_64.c"+#endif++static sljit_s32 emit_mov(struct sljit_compiler *compiler,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_u8* inst;++	SLJIT_ASSERT(dst != SLJIT_UNUSED);++	if (FAST_IS_REG(src)) {+		inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm_r;+		return SLJIT_SUCCESS;+	}+	if (src & SLJIT_IMM) {+		if (FAST_IS_REG(dst)) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+			return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);+#else+			if (!compiler->mode32) {+				if (NOT_HALFWORD(srcw))+					return emit_load_imm64(compiler, dst, srcw);+			}+			else+				return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, MOV_r_i32 + reg_lmap[dst], srcw);+#endif+		}+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if (!compiler->mode32 && NOT_HALFWORD(srcw)) {+			/* 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;+		}+#endif+		inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm_i32;+		return SLJIT_SUCCESS;+	}+	if (FAST_IS_REG(dst)) {+		inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);+		FAIL_IF(!inst);+		*inst = MOV_r_rm;+		return SLJIT_SUCCESS;+	}++	/* 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;+	inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);+	FAIL_IF(!inst);+	*inst = MOV_rm_r;+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)+{+	sljit_u8 *inst;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	sljit_s32 size;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op0(compiler, op));++	switch (GET_OPCODE(op)) {+	case SLJIT_BREAKPOINT:+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+		FAIL_IF(!inst);+		INC_SIZE(1);+		*inst = INT3;+		break;+	case SLJIT_NOP:+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+		FAIL_IF(!inst);+		INC_SIZE(1);+		*inst = NOP;+		break;+	case SLJIT_LMUL_UW:+	case SLJIT_LMUL_SW:+	case SLJIT_DIVMOD_UW:+	case SLJIT_DIVMOD_SW:+	case SLJIT_DIV_UW:+	case SLJIT_DIV_SW:+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+#ifdef _WIN64+		SLJIT_ASSERT(+			reg_map[SLJIT_R0] == 0+			&& reg_map[SLJIT_R1] == 2+			&& reg_map[TMP_REG1] > 7);+#else+		SLJIT_ASSERT(+			reg_map[SLJIT_R0] == 0+			&& reg_map[SLJIT_R1] < 7+			&& reg_map[TMP_REG1] == 2);+#endif+		compiler->mode32 = op & SLJIT_I32_OP;+#endif+		SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);++		op = GET_OPCODE(op);+		if ((op | 0x2) == SLJIT_DIV_UW) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)+			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);+			inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);+#else+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);+#endif+			FAIL_IF(!inst);+			*inst = XOR_r_rm;+		}++		if ((op | 0x2) == SLJIT_DIV_SW) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)+			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);+#endif++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+			FAIL_IF(!inst);+			INC_SIZE(1);+			*inst = CDQ;+#else+			if (compiler->mode32) {+				inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+				FAIL_IF(!inst);+				INC_SIZE(1);+				*inst = CDQ;+			} else {+				inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+				FAIL_IF(!inst);+				INC_SIZE(2);+				*inst++ = REX_W;+				*inst = CDQ;+			}+#endif+		}++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);+		FAIL_IF(!inst);+		INC_SIZE(2);+		*inst++ = GROUP_F7;+		*inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);+#else+#ifdef _WIN64+		size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2;+#else+		size = (!compiler->mode32) ? 3 : 2;+#endif+		inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+		FAIL_IF(!inst);+		INC_SIZE(size);+#ifdef _WIN64+		if (!compiler->mode32)+			*inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0);+		else if (op >= SLJIT_DIVMOD_UW)+			*inst++ = REX_B;+		*inst++ = GROUP_F7;+		*inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);+#else+		if (!compiler->mode32)+			*inst++ = REX_W;+		*inst++ = GROUP_F7;+		*inst = MOD_REG | reg_map[SLJIT_R1];+#endif+#endif+		switch (op) {+		case SLJIT_LMUL_UW:+			*inst |= MUL;+			break;+		case SLJIT_LMUL_SW:+			*inst |= IMUL;+			break;+		case SLJIT_DIVMOD_UW:+		case SLJIT_DIV_UW:+			*inst |= DIV;+			break;+		case SLJIT_DIVMOD_SW:+		case SLJIT_DIV_SW:+			*inst |= IDIV;+			break;+		}+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)+		if (op <= SLJIT_DIVMOD_SW)+			EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);+#else+		if (op >= SLJIT_DIV_UW)+			EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);+#endif+		break;+	case SLJIT_ENDBR:+		return emit_endbranch(compiler);+	case SLJIT_SKIP_FRAMES_BEFORE_RETURN:+		return skip_frames_before_return(compiler);+	}++	return SLJIT_SUCCESS;+}++#define ENCODE_PREFIX(prefix) \+	do { \+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \+		FAIL_IF(!inst); \+		INC_SIZE(1); \+		*inst = (prefix); \+	} while (0)++static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_u8* inst;+	sljit_s32 dst_r;+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	sljit_s32 work_r;+#endif++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 0;+#endif++	if (src & SLJIT_IMM) {+		if (FAST_IS_REG(dst)) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+			return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);+#else+			inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);+			FAIL_IF(!inst);+			*inst = MOV_rm_i32;+			return SLJIT_SUCCESS;+#endif+		}+		inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm8_i8;+		return SLJIT_SUCCESS;+	}++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		if (reg_map[src] >= 4) {+			SLJIT_ASSERT(dst_r == TMP_REG1);+			EMIT_MOV(compiler, TMP_REG1, 0, src, 0);+		} else+			dst_r = src;+#else+		dst_r = src;+#endif+	}+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	else if (FAST_IS_REG(src) && reg_map[src] >= 4) {+		/* src, dst are registers. */+		SLJIT_ASSERT(SLOW_IS_REG(dst));+		if (reg_map[dst] < 4) {+			if (dst != src)+				EMIT_MOV(compiler, dst, 0, src, 0);+			inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);+			FAIL_IF(!inst);+			*inst++ = GROUP_0F;+			*inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8;+		}+		else {+			if (dst != src)+				EMIT_MOV(compiler, dst, 0, src, 0);+			if (sign) {+				/* shl reg, 24 */+				inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);+				FAIL_IF(!inst);+				*inst |= SHL;+				/* sar reg, 24 */+				inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);+				FAIL_IF(!inst);+				*inst |= SAR;+			}+			else {+				inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0);+				FAIL_IF(!inst);+				*(inst + 1) |= AND;+			}+		}+		return SLJIT_SUCCESS;+	}+#endif+	else {+		/* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */+		inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);+		FAIL_IF(!inst);+		*inst++ = GROUP_0F;+		*inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8;+	}++	if (dst & SLJIT_MEM) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		if (dst_r == TMP_REG1) {+			/* Find a non-used register, whose reg_map[src] < 4. */+			if ((dst & REG_MASK) == SLJIT_R0) {+				if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1))+					work_r = SLJIT_R2;+				else+					work_r = SLJIT_R1;+			}+			else {+				if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))+					work_r = SLJIT_R0;+				else if ((dst & REG_MASK) == SLJIT_R1)+					work_r = SLJIT_R2;+				else+					work_r = SLJIT_R1;+			}++			if (work_r == SLJIT_R0) {+				ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);+			}+			else {+				inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);+				FAIL_IF(!inst);+				*inst = XCHG_r_rm;+			}++			inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);+			FAIL_IF(!inst);+			*inst = MOV_rm8_r8;++			if (work_r == SLJIT_R0) {+				ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);+			}+			else {+				inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);+				FAIL_IF(!inst);+				*inst = XCHG_r_rm;+			}+		}+		else {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);+			FAIL_IF(!inst);+			*inst = MOV_rm8_r8;+		}+#else+		inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm8_r8;+#endif+	}++	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_PREFETCH_L1)+		*inst |= (1 << 3);+	else if (op == SLJIT_PREFETCH_L2)+		*inst |= (2 << 3);+	else if (op == SLJIT_PREFETCH_L3)+		*inst |= (3 << 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)+{+	sljit_u8* inst;+	sljit_s32 dst_r;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 0;+#endif++	if (src & SLJIT_IMM) {+		if (FAST_IS_REG(dst)) {+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+			return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);+#else+			inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);+			FAIL_IF(!inst);+			*inst = MOV_rm_i32;+			return SLJIT_SUCCESS;+#endif+		}+		inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm_i32;+		return SLJIT_SUCCESS;+	}++	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if ((dst & SLJIT_MEM) && FAST_IS_REG(src))+		dst_r = src;+	else {+		inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);+		FAIL_IF(!inst);+		*inst++ = GROUP_0F;+		*inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16;+	}++	if (dst & SLJIT_MEM) {+		inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);+		FAIL_IF(!inst);+		*inst = MOV_rm_r;+	}++	return SLJIT_SUCCESS;+}++static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_u8* inst;++	if (dst == src && dstw == srcw) {+		/* Same input and output */+		inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);+		FAIL_IF(!inst);+		*inst++ = GROUP_F7;+		*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, 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);+	*inst++ = GROUP_F7;+	*inst |= opcode;+	EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_u8* inst;++	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, 0);+		FAIL_IF(!inst);+		*inst++ = GROUP_F7;+		*inst |= NOT_rm;+		inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);+		FAIL_IF(!inst);+		*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);+	*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;+	EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);+	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)+{+	sljit_u8* inst;+	sljit_s32 dst_r;++	SLJIT_UNUSED_ARG(op_flags);++	if (cpu_has_cmov == -1)+		get_cpu_features();++	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 (cpu_has_cmov) {+		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 = CMOVE_r_rm;+	}+	else+		FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, 32 + 31));++	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 (dst & SLJIT_MEM)+		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);+	return SLJIT_SUCCESS;+}++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)+{+	sljit_s32 op_flags = GET_ALL_FLAGS(op);+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	sljit_s32 dst_is_ereg = 0;+#endif++	CHECK_ERROR();+	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src, srcw);++	CHECK_EXTRA_REGS(dst, dstw, dst_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++	op = GET_OPCODE(op);++	if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		compiler->mode32 = 0;+#endif++		if (FAST_IS_REG(src) && src == dst) {+			if (!TYPE_CAST_NEEDED(op))+				return SLJIT_SUCCESS;+		}++		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) {+			switch (op) {+			case SLJIT_MOV_U8:+				srcw = (sljit_u8)srcw;+				break;+			case SLJIT_MOV_S8:+				srcw = (sljit_s8)srcw;+				break;+			case SLJIT_MOV_U16:+				srcw = (sljit_u16)srcw;+				break;+			case SLJIT_MOV_S16:+				srcw = (sljit_s16)srcw;+				break;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+			case SLJIT_MOV_U32:+				srcw = (sljit_u32)srcw;+				break;+			case SLJIT_MOV_S32:+				srcw = (sljit_s32)srcw;+				break;+#endif+			}+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+			if (SLJIT_UNLIKELY(dst_is_ereg))+				return emit_mov(compiler, dst, dstw, src, srcw);+#endif+		}++#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));+			dst = TMP_REG1;+		}+#endif++		switch (op) {+		case SLJIT_MOV:+		case SLJIT_MOV_P:+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		case SLJIT_MOV_U32:+		case SLJIT_MOV_S32:+#endif+			FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));+			break;+		case SLJIT_MOV_U8:+			FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw));+			break;+		case SLJIT_MOV_S8:+			FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw));+			break;+		case SLJIT_MOV_U16:+			FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw));+			break;+		case SLJIT_MOV_S16:+			FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw));+			break;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		case SLJIT_MOV_U32:+			FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw));+			break;+		case SLJIT_MOV_S32:+			FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw));+			break;+#endif+		}++#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)+			return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);+#endif+		return SLJIT_SUCCESS;+	}++	switch (op) {+	case SLJIT_NOT:+		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:+		return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw);++	case SLJIT_CLZ:+		return emit_clz(compiler, op_flags, dst, dstw, src, srcw);+	}++	return SLJIT_SUCCESS;+}++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)++#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \+	if (IS_HALFWORD(immw) || compiler->mode32) { \+		inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \+		FAIL_IF(!inst); \+		*(inst + 1) |= (op_imm); \+	} \+	else { \+		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); \+	}++#define BINARY_EAX_IMM(op_eax_imm, immw) \+	FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw))++#else++#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \+	inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \+	FAIL_IF(!inst); \+	*(inst + 1) |= (op_imm);++#define BINARY_EAX_IMM(op_eax_imm, immw) \+	FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw))++#endif++static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,+	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);+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		return SLJIT_SUCCESS;+	}++	if (dst == src1 && dstw == src1w) {+		if (src2 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+			if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {+#else+			if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {+#endif+				BINARY_EAX_IMM(op_eax_imm, src2w);+			}+			else {+				BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);+			}+		}+		else if (FAST_IS_REG(dst)) {+			inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		else if (FAST_IS_REG(src2)) {+			/* Special exception for sljit_emit_op_flags. */+			inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);+			FAIL_IF(!inst);+			*inst = op_mr;+		}+		else {+			EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);+			FAIL_IF(!inst);+			*inst = op_mr;+		}+		return SLJIT_SUCCESS;+	}++	/* Only for cumulative operations. */+	if (dst == src2 && dstw == src2w) {+		if (src1 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+			if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {+#else+			if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128)) {+#endif+				BINARY_EAX_IMM(op_eax_imm, src1w);+			}+			else {+				BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);+			}+		}+		else if (FAST_IS_REG(dst)) {+			inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		else if (FAST_IS_REG(src1)) {+			inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);+			FAIL_IF(!inst);+			*inst = op_mr;+		}+		else {+			EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);+			FAIL_IF(!inst);+			*inst = op_mr;+		}+		return SLJIT_SUCCESS;+	}++	/* General version. */+	if (FAST_IS_REG(dst)) {+		EMIT_MOV(compiler, dst, 0, src1, src1w);+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(op_imm, op_mr, src2w, dst, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+	}+	else {+		/* This version requires less memory writing. */+		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);+	}++	return SLJIT_SUCCESS;+}++static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,+	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);+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		return SLJIT_SUCCESS;+	}++	if (dst == src1 && dstw == src1w) {+		if (src2 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+			if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {+#else+			if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128)) {+#endif+				BINARY_EAX_IMM(op_eax_imm, src2w);+			}+			else {+				BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);+			}+		}+		else if (FAST_IS_REG(dst)) {+			inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		else if (FAST_IS_REG(src2)) {+			inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);+			FAIL_IF(!inst);+			*inst = op_mr;+		}+		else {+			EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);+			FAIL_IF(!inst);+			*inst = op_mr;+		}+		return SLJIT_SUCCESS;+	}++	/* General version. */+	if (FAST_IS_REG(dst) && dst != src2) {+		EMIT_MOV(compiler, dst, 0, src1, src1w);+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(op_imm, op_mr, src2w, dst, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+	}+	else {+		/* This version requires less memory writing. */+		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = op_rm;+		}+		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);+	}++	return SLJIT_SUCCESS;+}++static sljit_s32 emit_mul(struct sljit_compiler *compiler,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	sljit_u8* inst;+	sljit_s32 dst_r;++	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;++	/* Register destination. */+	if (dst_r == src1 && !(src2 & SLJIT_IMM)) {+		inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);+		FAIL_IF(!inst);+		*inst++ = GROUP_0F;+		*inst = IMUL_r_rm;+	}+	else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {+		inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);+		FAIL_IF(!inst);+		*inst++ = GROUP_0F;+		*inst = IMUL_r_rm;+	}+	else if (src1 & SLJIT_IMM) {+		if (src2 & SLJIT_IMM) {+			EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);+			src2 = dst_r;+			src2w = 0;+		}++		if (src1w <= 127 && src1w >= -128) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = IMUL_r_rm_i8;+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+			FAIL_IF(!inst);+			INC_SIZE(1);+			*inst = (sljit_s8)src1w;+		}+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		else {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = IMUL_r_rm_i32;+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);+			FAIL_IF(!inst);+			INC_SIZE(4);+			sljit_unaligned_store_sw(inst, src1w);+		}+#else+		else if (IS_HALFWORD(src1w)) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = IMUL_r_rm_i32;+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);+			FAIL_IF(!inst);+			INC_SIZE(4);+			sljit_unaligned_store_s32(inst, (sljit_s32)src1w);+		}+		else {+			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;+			*inst = IMUL_r_rm;+		}+#endif+	}+	else if (src2 & SLJIT_IMM) {+		/* Note: src1 is NOT immediate. */++		if (src2w <= 127 && src2w >= -128) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);+			FAIL_IF(!inst);+			*inst = IMUL_r_rm_i8;+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);+			FAIL_IF(!inst);+			INC_SIZE(1);+			*inst = (sljit_s8)src2w;+		}+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		else {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);+			FAIL_IF(!inst);+			*inst = IMUL_r_rm_i32;+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);+			FAIL_IF(!inst);+			INC_SIZE(4);+			sljit_unaligned_store_sw(inst, src2w);+		}+#else+		else if (IS_HALFWORD(src2w)) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);+			FAIL_IF(!inst);+			*inst = IMUL_r_rm_i32;+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);+			FAIL_IF(!inst);+			INC_SIZE(4);+			sljit_unaligned_store_s32(inst, (sljit_s32)src2w);+		}+		else {+			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;+			*inst = IMUL_r_rm;+		}+#endif+	}+	else {+		/* Neither argument is immediate. */+		if (ADDRESSING_DEPENDS_ON(src2, dst_r))+			dst_r = TMP_REG1;+		EMIT_MOV(compiler, dst_r, 0, src1, src1w);+		inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);+		FAIL_IF(!inst);+		*inst++ = GROUP_0F;+		*inst = IMUL_r_rm;+	}++	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 dst, sljit_sw dstw,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	sljit_u8* inst;+	sljit_s32 dst_r, done = 0;++	/* These cases better be left to handled by normal way. */+	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;++	if (FAST_IS_REG(src1)) {+		if (FAST_IS_REG(src2)) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);+			FAIL_IF(!inst);+			*inst = LEA_r_m;+			done = 1;+		}+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w);+#else+		if (src2 & SLJIT_IMM) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);+#endif+			FAIL_IF(!inst);+			*inst = LEA_r_m;+			done = 1;+		}+	}+	else if (FAST_IS_REG(src2)) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w);+#else+		if (src1 & SLJIT_IMM) {+			inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);+#endif+			FAIL_IF(!inst);+			*inst = LEA_r_m;+			done = 1;+		}+	}++	if (done) {+		if (dst_r == TMP_REG1)+			return emit_mov(compiler, dst, dstw, TMP_REG1, 0);+		return SLJIT_SUCCESS;+	}+	return SLJIT_ERR_UNSUPPORTED;+}++static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	sljit_u8* inst;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {+#else+	if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {+#endif+		BINARY_EAX_IMM(CMP_EAX_i32, src2w);+		return SLJIT_SUCCESS;+	}++	if (FAST_IS_REG(src1)) {+		if (src2 & SLJIT_IMM) {+			BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0);+		}+		else {+			inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = CMP_r_rm;+		}+		return SLJIT_SUCCESS;+	}++	if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) {+		inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);+		FAIL_IF(!inst);+		*inst = CMP_rm_r;+		return SLJIT_SUCCESS;+	}++	if (src2 & SLJIT_IMM) {+		if (src1 & SLJIT_IMM) {+			EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+			src1 = TMP_REG1;+			src1w = 0;+		}+		BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w);+	}+	else {+		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+		inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);+		FAIL_IF(!inst);+		*inst = CMP_r_rm;+	}+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_test_binary(struct sljit_compiler *compiler,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	sljit_u8* inst;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {+#else+	if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {+#endif+		BINARY_EAX_IMM(TEST_EAX_i32, src2w);+		return SLJIT_SUCCESS;+	}++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	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+		BINARY_EAX_IMM(TEST_EAX_i32, src1w);+		return SLJIT_SUCCESS;+	}++	if (!(src1 & SLJIT_IMM)) {+		if (src2 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+			if (IS_HALFWORD(src2w) || compiler->mode32) {+				inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);+				FAIL_IF(!inst);+				*inst = GROUP_F7;+			}+			else {+				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;+			}+#else+			inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);+			FAIL_IF(!inst);+			*inst = GROUP_F7;+#endif+			return SLJIT_SUCCESS;+		}+		else if (FAST_IS_REG(src1)) {+			inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);+			FAIL_IF(!inst);+			*inst = TEST_rm_r;+			return SLJIT_SUCCESS;+		}+	}++	if (!(src2 & SLJIT_IMM)) {+		if (src1 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+			if (IS_HALFWORD(src1w) || compiler->mode32) {+				inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w);+				FAIL_IF(!inst);+				*inst = GROUP_F7;+			}+			else {+				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;+			}+#else+			inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w);+			FAIL_IF(!inst);+			*inst = GROUP_F7;+#endif+			return SLJIT_SUCCESS;+		}+		else if (FAST_IS_REG(src2)) {+			inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);+			FAIL_IF(!inst);+			*inst = TEST_rm_r;+			return SLJIT_SUCCESS;+		}+	}++	EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+	if (src2 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if (IS_HALFWORD(src2w) || compiler->mode32) {+			inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);+			FAIL_IF(!inst);+			*inst = GROUP_F7;+		}+		else {+			FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));+			inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REG1, 0);+			FAIL_IF(!inst);+			*inst = TEST_rm_r;+		}+#else+		inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0);+		FAIL_IF(!inst);+		*inst = GROUP_F7;+#endif+	}+	else {+		inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);+		FAIL_IF(!inst);+		*inst = TEST_rm_r;+	}+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_shift(struct sljit_compiler *compiler,+	sljit_u8 mode,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	sljit_u8* inst;++	if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {+		if (dst == src1 && dstw == src1w) {+			inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);+			FAIL_IF(!inst);+			*inst |= mode;+			return SLJIT_SUCCESS;+		}+		if (dst == SLJIT_UNUSED) {+			EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+			inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);+			FAIL_IF(!inst);+			*inst |= mode;+			return SLJIT_SUCCESS;+		}+		if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {+			EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+			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_REG1, 0);+			return SLJIT_SUCCESS;+		}+		if (FAST_IS_REG(dst)) {+			EMIT_MOV(compiler, dst, 0, src1, src1w);+			inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);+			FAIL_IF(!inst);+			*inst |= mode;+			return SLJIT_SUCCESS;+		}++		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+		inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);+		FAIL_IF(!inst);+		*inst |= mode;+		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);+		return SLJIT_SUCCESS;+	}++	if (dst == SLJIT_PREF_SHIFT_REG) {+		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);+		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_REG1, 0);+	}+	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);+		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);+		inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);+		FAIL_IF(!inst);+		*inst |= mode;+		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);+	}+	else {+		/* 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_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;+		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0);+#else+		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+		if (dst != SLJIT_UNUSED)+			return emit_mov(compiler, dst, dstw, TMP_REG1, 0);+	}++	return SLJIT_SUCCESS;+}++static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,+	sljit_u8 mode, sljit_s32 set_flags,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	/* The CPU does not set flags if the shift count is 0. */+	if (src2 & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))+			return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);+#else+		if ((src2w & 0x1f) != 0)+			return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);+#endif+		if (!set_flags)+			return emit_mov(compiler, dst, dstw, src1, src1w);+		/* OR dst, src, 0 */+		return emit_cum_binary(compiler, BINARY_OPCODE(OR),+			dst, dstw, src1, src1w, SLJIT_IMM, 0);+	}++	if (!set_flags)+		return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);++	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));++	if (FAST_IS_REG(dst))+		return emit_cmp_binary(compiler, (dst == SLJIT_UNUSED) ? TMP_REG1 : dst, dstw, SLJIT_IMM, 0);+	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(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)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++	CHECK_EXTRA_REGS(dst, dstw, (void)0);+	CHECK_EXTRA_REGS(src1, src1w, (void)0);+	CHECK_EXTRA_REGS(src2, src2w, (void)0);+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = op & SLJIT_I32_OP;+#endif++	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))+		return SLJIT_SUCCESS;++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD:+		if (!HAS_FLAGS(op)) {+			if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)+				return compiler->error;+		}+		return emit_cum_binary(compiler, BINARY_OPCODE(ADD),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_ADDC:+		return emit_cum_binary(compiler, BINARY_OPCODE(ADC),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_SUB:+		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;+			if (SLOW_IS_REG(dst) && src2 == dst) {+				FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));+				return emit_unary(compiler, NEG_rm, dst, 0, dst, 0);+			}+		}++		if (dst == SLJIT_UNUSED)+			return emit_cmp_binary(compiler, src1, src1w, src2, src2w);+		return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_SUBC:+		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, BINARY_OPCODE(AND),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_OR:+		return emit_cum_binary(compiler, BINARY_OPCODE(OR),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_XOR:+		return emit_cum_binary(compiler, BINARY_OPCODE(XOR),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_SHL:+		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, HAS_FLAGS(op),+			dst, dstw, src1, src1w, src2, src2w);+	case SLJIT_ASHR:+		return emit_shift_with_flags(compiler, SAR, HAS_FLAGS(op),+			dst, dstw, src1, src1w, src2, src2w);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src, sljit_sw srcw)+{+	CHECK_ERROR();+	CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	CHECK_EXTRA_REGS(src, srcw, (void)0);++	switch (op) {+	case SLJIT_FAST_RETURN:+		return emit_fast_return(compiler, src, srcw);+	case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:+		/* Don't adjust shadow stack if it isn't enabled.  */+		if (!cpu_has_shadow_stack ())+			return SLJIT_SUCCESS;+		return adjust_shadow_stack(compiler, src, srcw, SLJIT_UNUSED, 0);+	case SLJIT_PREFETCH_L1:+	case SLJIT_PREFETCH_L2:+	case SLJIT_PREFETCH_L3:+	case SLJIT_PREFETCH_ONCE:+		return emit_prefetch(compiler, op, src, srcw);+	}++	return SLJIT_SUCCESS;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)+{+	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_R8)+		return -1;+#endif+	return reg_map[reg];+}++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,+	void *instruction, sljit_s32 size)+{+	sljit_u8 *inst;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op_custom(compiler, instruction, size));++	inst = (sljit_u8*)ensure_buf(compiler, 1 + size);+	FAIL_IF(!inst);+	INC_SIZE(size);+	SLJIT_MEMCPY(inst, instruction, size);+	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Floating point operators                                             */+/* --------------------------------------------------------------------- */++/* 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 (each constant is 16 byte long). */+	sse2_buffer[0] = 0x80000000;+	sse2_buffer[4] = 0x7fffffff;+	/* 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;+}++static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode,+	sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)+{+	sljit_u8 *inst;++	inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w);+	FAIL_IF(!inst);+	*inst++ = GROUP_0F;+	*inst = opcode;+	return SLJIT_SUCCESS;+}++static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode,+	sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)+{+	sljit_u8 *inst;++	inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w);+	FAIL_IF(!inst);+	*inst++ = GROUP_0F;+	*inst = opcode;+	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)+{+	return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw);+}++static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,+	sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src)+{+	return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw);+}++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 = FAST_IS_REG(dst) ? dst : TMP_REG1;+	sljit_u8 *inst;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)+		compiler->mode32 = 0;+#endif++	inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw);+	FAIL_IF(!inst);+	*inst++ = GROUP_0F;+	*inst = CVTTSD2SI_r_xm;++	if (dst & SLJIT_MEM)+		return emit_mov(compiler, dst, dstw, TMP_REG1, 0);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 dst, sljit_sw dstw,+	sljit_s32 src, sljit_sw srcw)+{+	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;+	sljit_u8 *inst;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)+		compiler->mode32 = 0;+#endif++	if (src & SLJIT_IMM) {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)+			srcw = (sljit_s32)srcw;+#endif+		EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);+		src = TMP_REG1;+		srcw = 0;+	}++	inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw);+	FAIL_IF(!inst);+	*inst++ = GROUP_0F;+	*inst = CVTSI2SD_x_rm;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 1;+#endif+	if (dst_r == TMP_FREG)+		return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);+	return SLJIT_SUCCESS;+}++static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,+	sljit_s32 src1, sljit_sw src1w,+	sljit_s32 src2, sljit_sw src2w)+{+	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);+}++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_s32 dst_r;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 1;+#endif++	CHECK_ERROR();+	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);++	if (GET_OPCODE(op) == SLJIT_MOV_F64) {+		if (FAST_IS_REG(dst))+			return emit_sse2_load(compiler, op & SLJIT_F32_OP, dst, src, srcw);+		if (FAST_IS_REG(src))+			return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, src);+		FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src, srcw));+		return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);+	}++	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) {+		dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG;+		if (FAST_IS_REG(src)) {+			/* We overwrite the high bits of source. From SLJIT point of view,+			   this is not an issue.+			   Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */+			FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_F32_OP, src, src, 0));+		}+		else {+			FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_F32_OP), TMP_FREG, src, srcw));+			src = TMP_FREG;+		}++		FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_F32_OP, dst_r, src, 0));+		if (dst_r == TMP_FREG)+			return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);+		return SLJIT_SUCCESS;+	}++	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));+	}+	else {+		dst_r = TMP_FREG;+		FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw));+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_NEG_F64:+		FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer : sse2_buffer + 8)));+		break;++	case SLJIT_ABS_F64:+		FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer + 4 : sse2_buffer + 12)));+		break;+	}++	if (dst_r == TMP_FREG)+		return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);+	return SLJIT_SUCCESS;+}++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_s32 dst_r;++	CHECK_ERROR();+	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));+	ADJUST_LOCAL_OFFSET(dst, dstw);+	ADJUST_LOCAL_OFFSET(src1, src1w);+	ADJUST_LOCAL_OFFSET(src2, src2w);++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 1;+#endif++	if (FAST_IS_REG(dst)) {+		dst_r = dst;+		if (dst == src1)+			; /* Do nothing here. */+		else if (dst == src2 && (op == SLJIT_ADD_F64 || op == SLJIT_MUL_F64)) {+			/* Swap arguments. */+			src2 = src1;+			src2w = src1w;+		}+		else if (dst != src2)+			FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src1, src1w));+		else {+			dst_r = TMP_FREG;+			FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));+		}+	}+	else {+		dst_r = TMP_FREG;+		FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));+	}++	switch (GET_OPCODE(op)) {+	case SLJIT_ADD_F64:+		FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));+		break;++	case SLJIT_SUB_F64:+		FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));+		break;++	case SLJIT_MUL_F64:+		FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));+		break;++	case SLJIT_DIV_F64:+		FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));+		break;+	}++	if (dst_r == TMP_FREG)+		return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);+	return SLJIT_SUCCESS;+}++/* --------------------------------------------------------------------- */+/*  Conditional instructions                                             */+/* --------------------------------------------------------------------- */++SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)+{+	sljit_u8 *inst;+	struct sljit_label *label;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_label(compiler));++	if (compiler->last_label && compiler->last_label->size == compiler->size)+		return compiler->last_label;++	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));+	PTR_FAIL_IF(!label);+	set_label(label, compiler);++	inst = (sljit_u8*)ensure_buf(compiler, 2);+	PTR_FAIL_IF(!inst);++	*inst++ = 0;+	*inst++ = 0;++	return label;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)+{+	sljit_u8 *inst;+	struct sljit_jump *jump;++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_jump(compiler, type));++	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) << TYPE_SHIFT));+	type &= 0xff;++	/* Worst case size. */+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;+#else+	compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);+#endif++	inst = (sljit_u8*)ensure_buf(compiler, 2);+	PTR_FAIL_IF_NULL(inst);++	*inst++ = 0;+	*inst++ = 1;+	return jump;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)+{+	sljit_u8 *inst;+	struct sljit_jump *jump;++	CHECK_ERROR();+	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));+	ADJUST_LOCAL_OFFSET(src, srcw);++	CHECK_EXTRA_REGS(src, srcw, (void)0);++	if (src == SLJIT_IMM) {+		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));+		FAIL_IF_NULL(jump);+		set_jump(jump, compiler, JUMP_ADDR | (type << TYPE_SHIFT));+		jump->u.target = srcw;++		/* Worst case size. */+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+		compiler->size += 5;+#else+		compiler->size += 10 + 3;+#endif++		inst = (sljit_u8*)ensure_buf(compiler, 2);+		FAIL_IF_NULL(inst);++		*inst++ = 0;+		*inst++ = 1;+	}+	else {+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+		/* REX_W is not necessary (src is not immediate). */+		compiler->mode32 = 1;+#endif+		inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);+		FAIL_IF(!inst);+		*inst++ = GROUP_FF;+		*inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm;+	}+	return SLJIT_SUCCESS;+}++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 type)+{+	sljit_u8 *inst;+	sljit_u8 cond_set = 0;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	sljit_s32 reg;+#endif+	/* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */+	sljit_s32 dst_save = dst;+	sljit_sw dstw_save = dstw;++	CHECK_ERROR();+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));++	ADJUST_LOCAL_OFFSET(dst, dstw);+	CHECK_EXTRA_REGS(dst, dstw, (void)0);++	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)) {+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3);+		FAIL_IF(!inst);+		INC_SIZE(4 + 3);+		/* Set low register to conditional flag. */+		*inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B;+		*inst++ = GROUP_0F;+		*inst++ = cond_set;+		*inst++ = MOD_REG | reg_lmap[TMP_REG1];+		*inst++ = REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B);+		*inst++ = OR_rm8_r8;+		*inst++ = MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst];+		return SLJIT_SUCCESS;+	}++	reg = (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG1;++	inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4);+	FAIL_IF(!inst);+	INC_SIZE(4 + 4);+	/* Set low register to conditional flag. */+	*inst++ = (reg_map[reg] <= 7) ? REX : REX_B;+	*inst++ = GROUP_0F;+	*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];++	if (reg != TMP_REG1)+		return SLJIT_SUCCESS;++	if (GET_OPCODE(op) < SLJIT_ADD) {+		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_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. */+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3);+			FAIL_IF(!inst);+			INC_SIZE(3 + 3);+			/* Set low byte to conditional flag. */+			*inst++ = GROUP_0F;+			*inst++ = cond_set;+			*inst++ = MOD_REG | reg_map[dst];++			*inst++ = GROUP_0F;+			*inst++ = MOVZX_r_rm8;+			*inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst];+			return SLJIT_SUCCESS;+		}++		/* Low byte is not accessible. */+		if (cpu_has_cmov == -1)+			get_cpu_features();++		if (cpu_has_cmov) {+			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);+			/* a xor reg, reg operation would overwrite the flags. */+			EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0);++			inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);+			FAIL_IF(!inst);+			INC_SIZE(3);++			*inst++ = GROUP_0F;+			/* cmovcc = setcc - 0x50. */+			*inst++ = cond_set - 0x50;+			*inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1];+			return SLJIT_SUCCESS;+		}++		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);+		FAIL_IF(!inst);+		INC_SIZE(1 + 3 + 3 + 1);+		*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];+		/* Set al to conditional flag. */+		*inst++ = GROUP_0F;+		*inst++ = cond_set;+		*inst++ = MOD_REG | 0 /* eax */;++		*inst++ = GROUP_0F;+		*inst++ = MOVZX_r_rm8;+		*inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */;+		*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];+		return SLJIT_SUCCESS;+	}++	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);+			INC_SIZE(1 + 3 + 2 + 1);+			/* Set low register to conditional flag. */+			*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];+			*inst++ = GROUP_0F;+			*inst++ = cond_set;+			*inst++ = MOD_REG | 0 /* eax */;+			*inst++ = OR_rm8_r8;+			*inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst];+			*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];+		}+		else {+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2);+			FAIL_IF(!inst);+			INC_SIZE(2 + 3 + 2 + 2);+			/* Set low register to conditional flag. */+			*inst++ = XCHG_r_rm;+			*inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1];+			*inst++ = GROUP_0F;+			*inst++ = cond_set;+			*inst++ = MOD_REG | 1 /* ecx */;+			*inst++ = OR_rm8_r8;+			*inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */;+			*inst++ = XCHG_r_rm;+			*inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1];+		}+		return SLJIT_SUCCESS;+	}++	/* Set TMP_REG1 to the bit. */+	inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);+	FAIL_IF(!inst);+	INC_SIZE(1 + 3 + 3 + 1);+	*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];+	/* Set al to conditional flag. */+	*inst++ = GROUP_0F;+	*inst++ = cond_set;+	*inst++ = MOD_REG | 0 /* eax */;++	*inst++ = GROUP_0F;+	*inst++ = MOVZX_r_rm8;+	*inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */;++	*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];++	if (GET_OPCODE(op) < SLJIT_ADD)+		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_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);+#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();+	CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	CHECK_EXTRA_REGS(dst, dstw, (void)0);++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 0;+#endif++	ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	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, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);+		return compiler->error;+#else+		return emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);+#endif+	}+#endif++	if (offset != 0)+		return emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);+	return emit_mov(compiler, dst, dstw, SLJIT_SP, 0);+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)+{+	sljit_u8 *inst;+	struct sljit_const *const_;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	sljit_s32 reg;+#endif++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	CHECK_EXTRA_REGS(dst, dstw, (void)0);++	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));+	PTR_FAIL_IF(!const_);+	set_const(const_, compiler);++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 0;+	reg = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if (emit_load_imm64(compiler, reg, init_value))+		return NULL;+#else+	if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))+		return NULL;+#endif++	inst = (sljit_u8*)ensure_buf(compiler, 2);+	PTR_FAIL_IF(!inst);++	*inst++ = 0;+	*inst++ = 2;++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	if (dst & SLJIT_MEM)+		if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))+			return NULL;+#endif++	return const_;+}++SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)+{+	struct sljit_put_label *put_label;+	sljit_u8 *inst;+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	sljit_s32 reg;+	sljit_uw start_size;+#endif++	CHECK_ERROR_PTR();+	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));+	ADJUST_LOCAL_OFFSET(dst, dstw);++	CHECK_EXTRA_REGS(dst, dstw, (void)0);++	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));+	PTR_FAIL_IF(!put_label);+	set_put_label(put_label, compiler, 0);++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	compiler->mode32 = 0;+	reg = FAST_IS_REG(dst) ? dst : TMP_REG1;++	if (emit_load_imm64(compiler, reg, 0))+		return NULL;+#else+	if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0))+		return NULL;+#endif++#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)+	if (dst & SLJIT_MEM) {+		start_size = compiler->size;+		if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))+			return NULL;+		put_label->flags = compiler->size - start_size;+	}+#endif++	inst = (sljit_u8*)ensure_buf(compiler, 2);+	PTR_FAIL_IF(!inst);++	*inst++ = 0;+	*inst++ = 3;++	return put_label;+}++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);++	SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)+	sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);+#else+	sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);+#endif+	SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);+}++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_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0);+	sljit_unaligned_store_sw((void*)addr, new_constant);+	SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1);+}
+ src/c/pcre2/src/sljit/sljitProtExecAllocator.c view
@@ -0,0 +1,474 @@+/*+ *    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;+};++/*+   alloc_chunk / free_chunk :+     * allocate executable system memory chunks+     * the size is always divisible by CHUNK_SIZE+   SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :+     * provided as part of sljitUtils+     * only the allocator requires this lock, sljit is fully thread safe+       as it only uses local variables+*/++#ifndef __NetBSD__+#include <sys/stat.h>+#include <fcntl.h>+#include <stdio.h>+#include <string.h>++#ifndef O_NOATIME+#define O_NOATIME 0+#endif++/* this is a linux extension available since kernel 3.11 */+#ifndef O_TMPFILE+#define O_TMPFILE 020200000+#endif++#ifndef _GNU_SOURCE+char *secure_getenv(const char *name);+int mkostemp(char *template, int flags);+#endif++static SLJIT_INLINE int create_tempfile(void)+{+	int fd;+	char tmp_name[256];+	size_t tmp_name_len = 0;+	char *dir;+	struct stat st;+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED+	mode_t mode;+#endif++#ifdef HAVE_MEMFD_CREATE+	/* this is a GNU extension, make sure to use -D_GNU_SOURCE */+	fd = memfd_create("sljit", MFD_CLOEXEC);+	if (fd != -1) {+		fchmod(fd, 0);+		return fd;+	}+#endif++	dir = secure_getenv("TMPDIR");++	if (dir) {+		tmp_name_len = strlen(dir);+		if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) {+			if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode))+				strcpy(tmp_name, dir);+		}+	}++#ifdef P_tmpdir+	if (!tmp_name_len) {+		tmp_name_len = strlen(P_tmpdir);+		if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))+			strcpy(tmp_name, P_tmpdir);+	}+#endif+	if (!tmp_name_len) {+		strcpy(tmp_name, "/tmp");+		tmp_name_len = 4;+	}++	SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));++	if (tmp_name[tmp_name_len - 1] == '/')+		tmp_name[--tmp_name_len] = '\0';++#ifdef __linux__+	/*+	 * the previous trimming might had left an empty string if TMPDIR="/"+	 * so work around the problem below+	 */+	fd = open(tmp_name_len ? tmp_name : "/",+		O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);+	if (fd != -1)+		return fd;+#endif++	if (tmp_name_len + 7 >= sizeof(tmp_name))+		return -1;++	strcpy(tmp_name + tmp_name_len, "/XXXXXX");+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED+	mode = umask(0777);+#endif+	fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED+	umask(mode);+#else+	fchmod(fd, 0);+#endif++	if (fd == -1)+		return -1;++	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((void *)retval, size);+		close(fd);+		return NULL;+	}++	close(fd);+	return retval;+}+#else+/*+ * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to+ * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed+ */+static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)+{+	struct chunk_header *retval;++	retval = (struct chunk_header *)mmap(NULL, size,+			PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),+			MAP_ANON | MAP_SHARED, -1, 0);++	if (retval == MAP_FAILED)+		return NULL;++	retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);+	if (retval->executable == MAP_FAILED) {+		munmap((void *)retval, size);+		return NULL;+	}++	if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {+		munmap(retval->executable, size);+		munmap((void *)retval, size);+		return NULL;+	}++	return retval;+}+#endif /* NetBSD */++static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)+{+	struct chunk_header *header = ((struct chunk_header *)chunk) - 1;++	munmap(header->executable, size);+	munmap((void *)header, size);+}++/* --------------------------------------------------------------------- */+/*  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;++	SLJIT_ALLOCATOR_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;+			SLJIT_ALLOCATOR_UNLOCK();+			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) {+		SLJIT_ALLOCATOR_UNLOCK();+		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;+	SLJIT_ALLOCATOR_UNLOCK();+	return MEM_START(header);+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)+{+	struct block_header *header;+	struct free_block* free_block;++	SLJIT_ALLOCATOR_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 chunk_header) ++				sizeof(struct block_header));+		}+	}++	SLJIT_ALLOCATOR_UNLOCK();+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)+{+	struct free_block* free_block;+	struct free_block* next_free_block;++	SLJIT_ALLOCATOR_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 chunk_header) ++				sizeof(struct block_header));+		}+		free_block = next_free_block;+	}++	SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));+	SLJIT_ALLOCATOR_UNLOCK();+}++SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)+{+	return ((struct block_header *)(ptr))[-1].executable_offset;+}
+ src/c/pcre2/src/sljit/sljitUtils.c view
@@ -0,0 +1,337 @@+/*+ *    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.+ */++/* ------------------------------------------------------------------------ */+/*  Locks                                                                   */+/* ------------------------------------------------------------------------ */++/* Executable Allocator */++#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \+	&& !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)+#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)+#define SLJIT_ALLOCATOR_LOCK()+#define SLJIT_ALLOCATOR_UNLOCK()+#elif !(defined _WIN32)+#include <pthread.h>++static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;++#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)+#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)+#else /* windows */+static HANDLE allocator_lock;++static SLJIT_INLINE void allocator_grab_lock(void)+{+	HANDLE lock;+	if (SLJIT_UNLIKELY(!allocator_lock)) {+		lock = CreateMutex(NULL, FALSE, NULL);+		if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))+			CloseHandle(lock);+	}+	WaitForSingleObject(allocator_lock, INFINITE);+}++#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()+#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)+#endif /* thread implementation */+#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */++/* ------------------------------------------------------------------------ */+/*  Stack                                                                   */+/* ------------------------------------------------------------------------ */++#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \+	&& !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \+	|| ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \+	&& !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \+	|| (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))++#ifndef _WIN32+/* Provides mmap function. */+#include <sys/types.h>+#include <sys/mman.h>++#ifndef MAP_ANON+#ifdef MAP_ANONYMOUS+#define MAP_ANON MAP_ANONYMOUS+#endif /* MAP_ANONYMOUS */+#endif /* !MAP_ANON */++#ifndef MAP_ANON++#include <fcntl.h>++#ifdef O_CLOEXEC+#define SLJIT_CLOEXEC	O_CLOEXEC+#else /* !O_CLOEXEC */+#define SLJIT_CLOEXEC	0+#endif /* O_CLOEXEC */++/* Some old systems do not have MAP_ANON. */+static int dev_zero = -1;++#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)++static SLJIT_INLINE int open_dev_zero(void)+{+	dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);++	return dev_zero < 0;+}++#else /* !SLJIT_SINGLE_THREADED */++#include <pthread.h>++static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;++static SLJIT_INLINE int open_dev_zero(void)+{+	pthread_mutex_lock(&dev_zero_mutex);+	if (SLJIT_UNLIKELY(dev_zero < 0))+		dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);++	pthread_mutex_unlock(&dev_zero_mutex);+	return dev_zero < 0;+}++#endif /* SLJIT_SINGLE_THREADED */+#undef SLJIT_CLOEXEC+#endif /* !MAP_ANON */+#endif /* !_WIN32 */+#endif /* open_dev_zero */++#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \+	|| (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)++#ifdef _WIN32++static SLJIT_INLINE sljit_sw get_page_alignment(void) {+	SYSTEM_INFO si;+	static sljit_sw sljit_page_align;+	if (!sljit_page_align) {+		GetSystemInfo(&si);+		sljit_page_align = si.dwPageSize - 1;+	}+	return sljit_page_align;+}++#else++#include <unistd.h>++static SLJIT_INLINE sljit_sw get_page_alignment(void) {+	static sljit_sw sljit_page_align;+	if (!sljit_page_align) {+		sljit_page_align = sysconf(_SC_PAGESIZE);+		/* Should never happen. */+		if (sljit_page_align < 0)+			sljit_page_align = 4096;+		sljit_page_align--;+	}+	return sljit_page_align;+}++#endif /* _WIN32 */++#endif /* get_page_alignment() */++#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)++#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)++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;+	void *ptr;++	SLJIT_UNUSED_ARG(allocator_data);++	if (start_size > max_size || start_size < 1)+		return NULL;++	stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);+	if (stack == NULL)+		return NULL;++	ptr = SLJIT_MALLOC(max_size, allocator_data);+	if (ptr == NULL) {+		SLJIT_FREE(stack, allocator_data);+		return NULL;+	}++	stack->min_start = (sljit_u8 *)ptr;+ 	stack->end = stack->min_start + max_size;+ 	stack->start = stack->end - start_size;+	stack->top = stack->end;+	return stack;+}++SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)+{+	SLJIT_UNUSED_ARG(allocator_data);+	SLJIT_FREE((void*)stack->min_start, allocator_data);+	SLJIT_FREE(stack, allocator_data);+}++SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)+{+	if ((new_start < stack->min_start) || (new_start >= stack->end))+		return NULL;+	stack->start = new_start;+	return new_start;+}++#else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */++#ifdef _WIN32++SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)+{+	SLJIT_UNUSED_ARG(allocator_data);+	VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);+	SLJIT_FREE(stack, allocator_data);+}++#else /* !_WIN32 */++SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)+{+	SLJIT_UNUSED_ARG(allocator_data);+	munmap((void*)stack->min_start, stack->end - stack->min_start);+	SLJIT_FREE(stack, allocator_data);+}++#endif /* _WIN32 */++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;+	void *ptr;+	sljit_sw page_align;++	SLJIT_UNUSED_ARG(allocator_data);++	if (start_size > max_size || start_size < 1)+		return NULL;++	stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);+	if (stack == NULL)+		return NULL;++	/* Align max_size. */+	page_align = get_page_alignment();+	max_size = (max_size + page_align) & ~page_align;++#ifdef _WIN32+	ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);+	if (!ptr) {+		SLJIT_FREE(stack, allocator_data);+		return NULL;+	}++	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 /* !_WIN32 */+#ifdef MAP_ANON+	ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);+#else /* !MAP_ANON */+	if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {+		SLJIT_FREE(stack, allocator_data);+		return NULL;+	}+	ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);+#endif /* MAP_ANON */+	if (ptr == MAP_FAILED) {+		SLJIT_FREE(stack, allocator_data);+		return NULL;+	}+	stack->min_start = (sljit_u8 *)ptr;+	stack->end = stack->min_start + max_size;+	stack->start = stack->end - start_size;+#endif /* _WIN32 */++	stack->top = stack->end;+	return stack;+}++SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)+{+#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)+	sljit_uw aligned_old_start;+	sljit_uw aligned_new_start;+	sljit_sw page_align;+#endif++	if ((new_start < stack->min_start) || (new_start >= stack->end))+		return NULL;++#ifdef _WIN32+	page_align = get_page_alignment();++	aligned_new_start = (sljit_uw)new_start & ~page_align;+	aligned_old_start = ((sljit_uw)stack->start) & ~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_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))+				return NULL;+		}+	}+#elif defined(POSIX_MADV_DONTNEED)+	if (stack->start < new_start) {+		page_align = get_page_alignment();++		aligned_new_start = (sljit_uw)new_start & ~page_align;+		aligned_old_start = ((sljit_uw)stack->start) & ~page_align;++		if (aligned_new_start > aligned_old_start) {+			posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);+#ifdef MADV_FREE+			madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);+#endif /* MADV_FREE */+		}+	}+#endif /* _WIN32 */++	stack->start = new_start;+	return new_start;+}++#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */++#endif /* SLJIT_UTIL_STACK */
+ src/c/pcre2/src/sljit/sljitWXExecAllocator.c view
@@ -0,0 +1,225 @@+/*+ *    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 W^X executable memory allocator for POSIX+   like systems and Windows++   In *NIX, MAP_ANON is required (that is considered a feature) so make+   sure to set the right availability macros for your system or the code+   will fail to build.++   If your system doesn't support mapping of anonymous pages (ex: IRIX) it+   is also likely that it doesn't need this allocator and should be using+   the standard one instead.++   It allocates a separate map for each code block and may waste a lot of+   memory, because whatever was requested, will be rounded up to the page+   size (minimum 4KB, but could be even bigger).++   It changes the page permissions (RW <-> RX) as needed and therefore, if you+   will be updating the code after it has been generated, need to make sure to+   block any concurrent execution, or could result in a SIGBUS, that could+   even manifest itself at a different address than the one that was being+   modified.++   Only use if you are unable to use the regular allocator because of security+   restrictions and adding exceptions to your application or the system are+   not possible.+*/++#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \+	sljit_update_wx_flags((from), (to), (enable_exec))++#ifndef _WIN32+#include <sys/types.h>+#include <sys/mman.h>++#ifdef __NetBSD__+#if defined(PROT_MPROTECT)+#define check_se_protected(ptr, size) (0)+#define SLJIT_PROT_WX PROT_MPROTECT(PROT_EXEC)+#else /* !PROT_MPROTECT */+#ifdef _NETBSD_SOURCE+#include <sys/param.h>+#else /* !_NETBSD_SOURCE */+typedef unsigned int	u_int;+#define devmajor_t sljit_s32+#endif /* _NETBSD_SOURCE */+#include <sys/sysctl.h>+#include <unistd.h>++#define check_se_protected(ptr, size) netbsd_se_protected()++static SLJIT_INLINE int netbsd_se_protected(void)+{+	int mib[3];+	int paxflags;+	size_t len = sizeof(paxflags);++	mib[0] = CTL_PROC;+	mib[1] = getpid();+	mib[2] = PROC_PID_PAXFLAGS;++	if (SLJIT_UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) < 0))+		return -1;++	return (paxflags & CTL_PROC_PAXFLAGS_MPROTECT) ? -1 : 0;+}+#endif /* PROT_MPROTECT */+#else /* POSIX */+#define check_se_protected(ptr, size) generic_se_protected(ptr, size)++static SLJIT_INLINE int generic_se_protected(void *ptr, sljit_uw size)+{+	if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))+		return mprotect(ptr, size, PROT_READ | PROT_WRITE);++	return -1;+}+#endif /* NetBSD */++#if defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED+#define SLJIT_SE_LOCK()+#define SLJIT_SE_UNLOCK()+#else /* !SLJIT_SINGLE_THREADED */+#include <pthread.h>+#define SLJIT_SE_LOCK()	pthread_mutex_lock(&se_lock)+#define SLJIT_SE_UNLOCK()	pthread_mutex_unlock(&se_lock)+#endif /* SLJIT_SINGLE_THREADED */++#ifndef SLJIT_PROT_WX+#define SLJIT_PROT_WX 0+#endif /* !SLJIT_PROT_WX */++SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)+{+#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)+	static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;+#endif+	static int se_protected = !SLJIT_PROT_WX;+	sljit_uw* ptr;++	if (SLJIT_UNLIKELY(se_protected < 0))+		return NULL;++	size += sizeof(sljit_uw);+	ptr = (sljit_uw*)mmap(NULL, size, PROT_READ | PROT_WRITE | SLJIT_PROT_WX,+				MAP_PRIVATE | MAP_ANON, -1, 0);++	if (ptr == MAP_FAILED)+		return NULL;++	if (SLJIT_UNLIKELY(se_protected > 0)) {+		SLJIT_SE_LOCK();+		se_protected = check_se_protected(ptr, size);+		SLJIT_SE_UNLOCK();+		if (SLJIT_UNLIKELY(se_protected < 0)) {+			munmap((void *)ptr, size);+			return NULL;+		}+	}++	*ptr++ = size;+	return ptr;+}++#undef SLJIT_PROT_WX+#undef SLJIT_SE_UNLOCK+#undef SLJIT_SE_LOCK++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)+{+	sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;+	munmap((void*)start_ptr, *start_ptr);+}++static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)+{+	sljit_uw page_mask = (sljit_uw)get_page_alignment();+	sljit_uw start = (sljit_uw)from;+	sljit_uw end = (sljit_uw)to;+	int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);++	SLJIT_ASSERT(start < end);++	start &= ~page_mask;+	end = (end + page_mask) & ~page_mask;++	mprotect((void*)start, end - start, prot);+}++#else /* windows */++SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)+{+	sljit_uw *ptr;++	size += sizeof(sljit_uw);+	ptr = (sljit_uw*)VirtualAlloc(NULL, size,+				MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);++	if (!ptr)+		return NULL;++	*ptr++ = size;++	return ptr;+}++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)+{+	sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);+#if defined(SLJIT_DEBUG) && SLJIT_DEBUG+	sljit_uw page_mask = (sljit_uw)get_page_alignment();++	SLJIT_ASSERT(!(start & page_mask));+#endif+	VirtualFree((void*)start, 0, MEM_RELEASE);+}++static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)+{+	DWORD oldprot;+	sljit_uw page_mask = (sljit_uw)get_page_alignment();+	sljit_uw start = (sljit_uw)from;+	sljit_uw end = (sljit_uw)to;+	DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;++	SLJIT_ASSERT(start < end);++	start &= ~page_mask;+	end = (end + page_mask) & ~page_mask;++	VirtualProtect((void*)start, end - start, prot, &oldprot);+}++#endif /* !windows */++SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)+{+	/* This allocator does not keep unused memory for future allocations. */+}
+ src/c/pcre2_chartables.c view
@@ -0,0 +1,204 @@+// Copied per the PCRE2 source's NON-AUTOTOOLS-BUILD instructions.++/*************************************************+*      Perl-Compatible Regular Expressions       *+*************************************************/++/* This file was automatically written by the pcre2_dftables auxiliary+program. It contains character tables that are used when no external+tables are passed to PCRE2 by the application that calls it. The tables+are used only for characters whose code values are less than 256. */++/* This set of tables was written in the C locale. */++/* The pcre2_ftables program (which is distributed with PCRE2) can be used+to build alternative versions of this file. This is necessary if you are+running in an EBCDIC environment, or if you want to default to a different+encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates+these tables in the "C" locale by default. This happens automatically if+PCRE2 is configured with --enable-rebuild-chartables. However, you can run+pcre2_dftables manually with the -L option to build tables using the LC_ALL+locale. */++/* The following #include is present because without it gcc 4.x may remove+the array definition from the final binary if PCRE2 is built into a static+library and dead code stripping is activated. This leads to link errors.+Pulling in the header ensures that the array gets flagged as "someone+outside this compilation unit might reference this" and so it will always+be supplied to the linker. */++#ifdef HAVE_CONFIG_H+#include "config.h"+#endif++#include "pcre2_internal.h"++const uint8_t PRIV(default_tables)[] = {++/* This table is a lower casing table. */++    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, 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, 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,++/* This table is a case flipping table. */++    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, 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, 91, 92, 93, 94, 95,+   96, 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,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,++/* This table contains bit maps for various character classes. Each map is 32+bytes long and the bits run from the least significant end of each byte. The+classes that have their own maps are: space, xdigit, digit, upper, lower, word,+graph, print, punct, and cntrl. Other classes are built from combinations. */++  0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,  /* space */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,  /* xdigit */+  0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,  /* digit */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* upper */+  0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* lower */+  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,  /* word */+  0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,  /* graph */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,  /* print */+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,  /* punct */+  0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++  0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,  /* cntrl */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,++/* This table identifies various classes of character by individual bits:+  0x01   white space character+  0x02   letter+  0x04   lower case letter+  0x08   decimal digit+  0x10   alphanumeric or '_'+*/++  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */+  0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */+  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*    - '  */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  ( - /  */+  0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /*  0 - 7  */+  0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /*  8 - ?  */+  0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  @ - G  */+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */+  0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x10, /*  X - _  */+  0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /*  ` - g  */+  0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /*  h - o  */+  0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /*  p - w  */+  0x16,0x16,0x16,0x00,0x00,0x00,0x00,0x00, /*  x -127 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */++/* End of pcre2_chartables.c */
+ src/hs/Text/Regex/Pcre2.hs view
@@ -0,0 +1,354 @@+module Text.Regex.Pcre2 (+    -- * Matching and substitution+    {-|+    /__Introduction__/++    Atop the low-level binding to the C API, we present a high-level interface+    to add regular expressions to Haskell programs.++    All input and output strings are strict `Text`, which maps directly to how+    PCRE2 operates on strings of 16-bit-wide code units.++    The C API requires pattern strings to be compiled and the compiled patterns+    to be executed on subject strings in discrete steps.  We hide this+    procedure, accepting pattern and subject as arguments in a single function,+    essentially:++    > pattern -> subject -> result++    The implementation guarantees that,+    when [partially applied](https://wiki.haskell.org/Partial_application) to+    pattern but not subject, the resulting function+    will [close](https://en.wikipedia.org/wiki/Closure_(computer_programming\))+    on the underlying compiled object and reuse it for every subject it is+    subsequently applied to.++    Likewise, we do not require the user to know whether a PCRE2 option is to be+    applied at pattern compile time or match time.  Instead we fold all possible+    options into a single datatype, `Option`.  Most functions have vanilla and+    configurable variants; the latter have \"@Opt@\" in the name and accept a+    value of this type.++    Similar to how @head :: [a] -> a@ sacrifices totality for type simplicity,+    we represent user errors as imprecise exceptions.  Unlike with @head@, these+    exceptions are typed (as `SomePcre2Exception`s); moreover, we offer Template+    Haskell facilities that can intercept some of these errors before the+    program is run.  (Failure to match is not considered a user error and is+    represented in the types.)++    [There's more than one way to do it](https://en.wikipedia.org/wiki/There's_more_than_one_way_to_do_it)+    with this library.  The choices between functions and traversals,+    poly-kinded `Captures` and plain lists, string literals and+    quasi-quotations, quasi-quoted expressions and quasi-quoted patterns...these+    are left to the user.  She will observe that advanced features\' extra+    safety, power, and convenience entail additional language extensions,+    cognitive overhead, and (for lenses) library dependencies, so it\'s really a+    matter of finding the best trade-offs for her case.++    /__Definitions__/++    [Pattern]:  The string defining a regular expression.  Refer to+    syntax [here](https://pcre.org/current/doc/html/pcre2pattern.html).++    [Subject]:  The string the compiled regular expression is executed on.++    [Regex]:  A function of the form @`Text` -> result@, where the argument is+    the subject.  It is \"compiled\" via partial application as discussed above.+    (Lens users:  A regex has the more abstract form+    @[Traversal\'](https://hackage.haskell.org/package/microlens/docs/Lens-Micro.html#t:Traversal-39-)+    `Text` result@, but the concept is the same.)++    [Capture (or capture group)]:  Any substrings of the subject matched by the+    pattern, meaning the whole pattern and any parenthesized groupings.  The+    PCRE2 docs do not refer to the former as a \"capture\"; however it is+    accessed the same way in the C API, just with index 0, so we will consider+    it the 0th capture for consistency.  Parenthesized captures are implicitly+    numbered from 1.++    [Unset capture]:  A capture considered unset as distinct from empty.  This+    can arise from matching the pattern @(a)?@ to an empty subject&#x2014;the+    0th capture will be set as empty, but the 1st will be unset altogether.  We+    represent both as empty `Text` for simplicity.  See below for discussions+    about how unset captures may be detected or substituted using this library.++    [Named capture]:  A parenthesized capture can be named like this:+    @(?\<foo\>...)@.  Whether they have names or not, captures are always+    numbered as described above.++    /__Performance__/++    Each API function is designed such that, when a regex is obtained, the+    underlying C data generated from the pattern and any options is reused for+    that regex\'s lifetime.  Care should be taken that the same regex is not+    recreated /ex nihilo/ and discarded for each new subject:++    > isEmptyOrHas2Digits :: Text -> Bool+    > isEmptyOrHas2Digits s = Text.null s || matches "\\d{2}" s -- bad, fully applied++    Instead, store it in a partially applied state:++    > isEmptyOrHas2Digits = (||) <$> Text.null <*> matches "\\d{2}" -- OK but abstruse++    When in doubt, always create regexes as top-level values:++    > has2Digits :: Text -> Bool+    > has2Digits = matches "\\d{2}"+    >+    > isEmptyOrHas2Digits s = Text.null s || has2Digits s -- good++    Note: Template Haskell regexes are immune from this problem and may be+    freely inlined; see below.++    /__Handling errors__/++    In a few places we use the `Alternative` typeclass to optionally return+    match results, expressing success via `pure` and failure via `empty`.+    Typically the user will choose the instance `Maybe`, but other useful ones+    exist, notably @[STM](https://hackage.haskell.org/package/stm/docs/Control-Monad-STM.html#t:STM)@,+    that of [optparse-applicative](https://hackage.haskell.org/package/optparse-applicative/docs/Options-Applicative.html#t:Parser),+    and those of parser combinator libraries such+    as [megaparsec](https://hackage.haskell.org/package/megaparsec/docs/Text-Megaparsec.html#t:ParsecT).++    By contrast, user errors are thrown purely.  If a user error is to be+    caught, it must be at the site where the match or substitution results are+    evaluated&#x2014;in other words, wherever the regex is applied to a subject.+    Even pattern compile errors are deferred to match sites, due to the way this+    library employs `System.IO.Unsafe.unsafePerformIO` to implement laziness.++    >>> broken = match "*"+    >>> broken "foo"+    *** Exception: pcre2_compile: quantifier does not follow a repeatable item+                        *+                        ^++    `Control.Exception.evaluate` comes in handy to force results into the `IO`+    monad in order to catch errors reliably:++    >>> evaluate (broken "foo") `catch` \(_ :: SomePcre2Exception) -> return Nothing+    Nothing++    Or simply select `IO` as the `Alternative` instance:++    >>> :t broken+    broken :: Alternative f => Text -> f Text+    >>> broken "foo" `catch` \(_ :: SomePcre2Exception) -> return "broken"+    "broken"+    -}++    -- ** Basic matching functions+    match,+    matchOpt,+    matches,+    matchesOpt,+    captures,+    capturesOpt,+    capturesA,+    capturesOptA,++    -- ** PCRE2-native substitution+    sub,+    gsub,+    subOpt,++    -- ** Lens-powered matching and substitution+    --+    -- | To use this portion of the library, there are two prerequisites:+    --+    -- 1.  A basic working understanding of optics.  Many tutorials exist+    -- online, such as+    -- [this](https://hackage.haskell.org/package/lens-tutorial-1.0.4/docs/Control-Lens-Tutorial.html),+    -- and videos such as [this](https://www.youtube.com/watch?v=7fbziKgQjnw).+    --+    -- 2.  A library providing combinators.  For lens newcomers, it is+    -- recommended to grab+    -- [microlens-platform](https://hackage.haskell.org/package/microlens-platform)&#x2014;most+    -- of the examples in this library work with it,+    -- @[packed](https://hackage.haskell.org/package/microlens-platform/docs/Lens-Micro-Platform.html#v:packed)@+    -- and+    -- @[unpacked](https://hackage.haskell.org/package/microlens-platform/docs/Lens-Micro-Platform.html#v:packed)@+    -- are included for working with `Text`, and it is upwards-compatible with+    -- the full [lens](https://hackage.haskell.org/package/lens) library.+    --+    -- We expose a set of traversals that focus on matched substrings within a+    -- subject.  Like the basic functional regexes, they should be \"compiled\"+    -- and memoized, rather than created inline.+    --+    -- > _nee :: Traversal' Text Text+    -- > _nee = _match "(?i)\\bnee\\b"+    --+    -- In addition to getting results, they support substitution through+    -- setting; more generally, they can accrete effects while performing+    -- replacements.+    --+    -- >>> promptNee = traverseOf (_nee . unpacked) $ \s -> print s >> getLine+    -- >>> promptNee "We are the knights who say...NEE!"+    -- "NEE"+    -- NOO+    -- "We are the knights who say...NOO!"+    -- >>>+    --+    -- The optic interface signals match failure by not targeting anything.+    --+    -- >>> promptNee "Shhhhh"+    -- "Shhhhh"+    -- >>>+    --+    -- In general these traversals are not law-abiding.+    _match,+    _matchOpt,+    _captures,+    _capturesOpt,++    -- * Compile-time validation+    --+    -- | Despite whatever virtues, the API thus far has some fragility arising+    -- from various scenarios:+    --+    -- * pattern malformation such as mismatched parentheses /(runtime error)/+    --+    -- * out-of-bounds indexing of a capture group list /(runtime error)/+    --+    -- * out-of-bounds @ix@ing of a @Traversal\'@ target+    -- /(spurious failure to match)/+    --+    -- * case expression containing a Haskell list pattern of the wrong length+    -- /(spurious failure to match)/+    --+    -- * regex created and discarded inline /(suboptimal performance)/+    --+    -- * precariously many backslashes in a pattern.  Matching a literal+    -- backslash requires the sequence @\"\\\\\\\\\"@!+    --+    -- Using a combination of language extensions and pattern introspection+    -- features, we provide a Template Haskell API to mitigate these scenarios.+    -- To make use of it these must be enabled:+    --+    -- +--------------------+---------------------------------------+------------------------------++    -- | Extension          | Required for                          | When                         |+    -- +====================+=======================================+==============================++    -- | @DataKinds@        | `GHC.TypeLits.Nat`s (numbers),        | Using `regex`\/`_regex` with |+    -- |                    | `GHC.TypeLits.Symbol`s (strings), and | a pattern containing         |+    -- |                    | other type-level data powering        | parenthesized captures       |+    -- |                    | compile-time capture lookups          |                              |+    -- +--------------------+---------------------------------------+------------------------------++    -- | @QuasiQuotes@      | @[@/f/@|@...@|]@ syntax               | Always                       |+    -- +--------------------+---------------------------------------+------------------------------++    -- | @TemplateHaskell@  | Running PCRE2 at compile time and     | Always                       |+    -- |                    | generating code                       |                              |+    -- +--------------------+---------------------------------------+------------------------------++    -- | @TypeApplications@ | @\@i@ syntax for supplying type index | Using `capture`\/`_capture`  |+    -- |                    | arguments to applicable functions     |                              |+    -- +--------------------+---------------------------------------+------------------------------++    -- | @ViewPatterns@     | Running code and binding variables in | Using `regex` as a Haskell   |+    -- |                    | pattern context proper (pattern       | pattern                      |+    -- |                    | guards are off-limits for this)       |                              |+    -- +--------------------+---------------------------------------+------------------------------++    --+    -- The inspiration for this portion of the library is Ruby, which supports+    -- regular expressions with [superior ergonomics](https://ruby-doc.org/core-2.7.2/Regexp.html#class-Regexp-label-Capturing).++    -- ** Quasi-quoters+    regex,+    _regex,++    -- ** Type-indexed capture groups+    Captures(),+    capture,+    _capture,++    -- * Options++    Option(+        AllowEmptyClass,+        AltBsux,+        AltBsuxLegacy,+        AltCircumflex,+        AltVerbNames,+        Anchored,+        AutoCallout,+        BadEscapeIsLiteral,+        Bsr,+        Caseless,+        DepthLimit,+        DollarEndOnly,+        DotAll,+        DupNames,+        EndAnchored,+        EscapedCrIsLf,+        Extended,+        ExtendedMore,+        FirstLine,+        HeapLimit,+        Literal,+        MatchLimit,+        MatchLine,+        MatchUnsetBackRef,+        MatchWord,+        MaxPatternLength,+        Multiline,+        NeverBackslashC,+        NeverUcp,+        Newline,+        NoAutoCapture,+        NoAutoPossess,+        NoDotStarAnchor,+        NoStartOptimize,+        NotBol,+        NotEmpty,+        NotEmptyAtStart,+        NotEol,+        OffsetLimit,+        ParensLimit,+        PartialHard,+        PartialSoft,+        SubGlobal,+        SubLiteral,+        SubReplacementOnly,+        SubUnknownUnset,+        SubUnsetEmpty,+        Ucp,+        Ungreedy,+        UnsafeCallout,+        UnsafeCompileRecGuard,+        UnsafeSubCallout,+        Utf),++    Bsr(..),+    Newline(..),++    -- ** Callout interface+    -- *** Capture callouts+    CalloutInfo(..),+    CalloutIndex(..),+    CalloutResult(..),+    -- *** Substitution callouts+    SubCalloutInfo(..),+    SubCalloutResult(..),++    -- * User errors+    SomePcre2Exception(),+    Pcre2Exception(),+    Pcre2CompileException(),++    -- * PCRE2 build configuration+    defaultBsr,+    compiledWidths,+    defaultDepthLimit,+    defaultHeapLimit,+    supportsJit,+    jitTarget,+    linkSize,+    defaultMatchLimit,+    defaultNewline,+    defaultIsNeverBackslashC,+    defaultParensLimit,+    defaultTablesLength,+    unicodeVersion,+    supportsUnicode,+    pcreVersion)+where++import Control.Applicative       (Alternative(..))+import Data.Text                 (Text)+import Text.Regex.Pcre2.Internal+import Text.Regex.Pcre2.TH
+ src/hs/Text/Regex/Pcre2/Foreign.hs view
@@ -0,0 +1,639 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE TemplateHaskell #-}++-- | A complete binding to the low-level C API.+--+-- Items here are named identically to their C counterparts.  Therefore,+-- documentation will be sparse;+-- [the official PCRE2 API docs](https://pcre.org/current/doc/html/pcre2api.html#SEC36)+-- should suffice.+module Text.Regex.Pcre2.Foreign where++import Foreign+import Foreign.C.Types+import Text.Regex.Pcre2.Foreign.TH (constant, getter)++-- * Types++-- | \"The @UCHAR@ types define unsigned code units of the appropriate widths.+-- For example, @PCRE2_UCHAR16@ is usually defined as @uint16_t@.\"+type PCRE2_UCHAR = CUShort++-- | \"The @SPTR@ types are constant pointers to the equivalent @UCHAR@ types,+-- that is, they are pointers to vectors of unsigned code units.\"+type PCRE2_SPTR = Ptr PCRE2_UCHAR++-- | \"...string lengths and offsets into strings of code units...are always of+-- type @PCRE2_SIZE@...currently always defined as @size_t@.\"+type PCRE2_SIZE = CSize++-- ** Opaque types+--+-- $OpaqueTypes+-- These correspond to structs that are only ever passed by reference.  They+-- simply exist for type safety and cannot be constructed in Haskell.+data Pcre2_general_context+data Pcre2_compile_context+data Pcre2_match_context+data Pcre2_callout_block+data Pcre2_substitute_callout_block+data Pcre2_code+data Pcre2_jit_stack+data Pcre2_match_data+data Pcre2_callout_enumerate_block++-- * The general context++foreign import capi safe "pcre2.h" pcre2_general_context_create+    :: FunPtr (PCRE2_SIZE -> Ptr a -> IO (Ptr b)) -- ^ custom malloc+    -> FunPtr (Ptr b -> Ptr a -> IO ())           -- ^ custom free+    -> Ptr a+    -> IO (Ptr Pcre2_general_context)++foreign import capi safe "pcre2.h" pcre2_general_context_copy+    :: Ptr Pcre2_general_context+    -> IO (Ptr Pcre2_general_context)++foreign import capi safe "pcre2.h" pcre2_general_context_free+    :: Ptr Pcre2_general_context+    -> IO ()++-- * The compile context++foreign import capi safe "pcre2.h" pcre2_compile_context_create+    :: Ptr Pcre2_general_context+    -> IO (Ptr Pcre2_compile_context)++foreign import capi safe "pcre2.h" pcre2_compile_context_copy+    :: Ptr Pcre2_compile_context+    -> IO (Ptr Pcre2_compile_context)++foreign import capi safe "pcre2.h" pcre2_compile_context_free+    :: Ptr Pcre2_compile_context+    -> IO ()++-- ** Compile context setters++-- TODO Maybe this goes next to wherever errors appear in the docs?+constant "ERROR_BADDATA" ''CInt++foreign import capi unsafe "pcre2.h" pcre2_set_bsr+    :: Ptr Pcre2_compile_context+    -> CUInt -- ^ See below for possible values.+    -> IO CInt++constant "BSR_ANYCRLF" ''CUInt+constant "BSR_UNICODE" ''CUInt++foreign import capi "pcre2.h" pcre2_set_character_tables+    :: Ptr Pcre2_compile_context+    -> Ptr CUChar+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_compile_extra_options+    :: Ptr Pcre2_compile_context+    -> CUInt -- ^ See \"Extra compile options\" below for possible bit flags.+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_max_pattern_length+    :: Ptr Pcre2_compile_context+    -> PCRE2_SIZE+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_newline+    :: Ptr Pcre2_compile_context+    -> CUInt -- ^ See below for possible values.+    -> IO CInt++constant "NEWLINE_CR" ''CUInt+constant "NEWLINE_LF" ''CUInt+constant "NEWLINE_CRLF" ''CUInt+constant "NEWLINE_ANY" ''CUInt+constant "NEWLINE_ANYCRLF" ''CUInt+constant "NEWLINE_NUL" ''CUInt++foreign import capi unsafe "pcre2.h" pcre2_set_parens_nest_limit+    :: Ptr Pcre2_compile_context+    -> CUInt+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_compile_recursion_guard+    :: Ptr Pcre2_compile_context+    -> FunPtr (CUInt -> Ptr a -> IO CInt)+    -> Ptr a+    -> IO CInt++-- * The match context++foreign import capi safe "pcre2.h" pcre2_match_context_create+    :: Ptr Pcre2_general_context+    -> IO (Ptr Pcre2_match_context)++foreign import capi safe "pcre2.h" pcre2_match_context_copy+    :: Ptr Pcre2_match_context+    -> IO (Ptr Pcre2_match_context)++foreign import capi safe "pcre2.h" pcre2_match_context_free+    :: Ptr Pcre2_match_context+    -> IO ()++-- ** Match context setters++foreign import capi unsafe "pcre2.h" pcre2_set_callout+    :: Ptr Pcre2_match_context+    -> FunPtr (Ptr Pcre2_callout_block -> Ptr a -> IO CInt)+    -> Ptr a+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_substitute_callout+    :: Ptr Pcre2_match_context+    -> FunPtr (Ptr Pcre2_substitute_callout_block -> Ptr a -> IO CInt)+    -> Ptr a+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_offset_limit+    :: Ptr Pcre2_match_context+    -> PCRE2_SIZE -- ^ Can be unset.  See below.+    -> IO CInt++constant "UNSET" ''PCRE2_SIZE++foreign import capi unsafe "pcre2.h" pcre2_set_heap_limit+    :: Ptr Pcre2_match_context+    -> CUInt+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_match_limit+    :: Ptr Pcre2_match_context+    -> CUInt+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_set_depth_limit+    :: Ptr Pcre2_match_context+    -> CUInt+    -> IO CInt++-- * Checking build-time options++foreign import capi unsafe "pcre2.h" pcre2_config+    :: CUInt   -- ^ See below for possible values.+    -> Ptr a   -- ^ See the C API docs for what gets returned here.+    -> IO CInt++constant "CONFIG_BSR" ''CUInt+constant "CONFIG_COMPILED_WIDTHS" ''CUInt+constant "CONFIG_DEPTHLIMIT" ''CUInt+constant "CONFIG_HEAPLIMIT" ''CUInt+constant "CONFIG_JIT" ''CUInt+constant "CONFIG_JITTARGET" ''CUInt+constant "CONFIG_LINKSIZE" ''CUInt+constant "CONFIG_MATCHLIMIT" ''CUInt+constant "CONFIG_NEWLINE" ''CUInt+constant "CONFIG_NEVER_BACKSLASH_C" ''CUInt+constant "CONFIG_PARENSLIMIT" ''CUInt+constant "CONFIG_STACKRECURSE" ''CUInt+constant "CONFIG_TABLES_LENGTH" ''CUInt+constant "CONFIG_UNICODE_VERSION" ''CUInt+constant "CONFIG_UNICODE" ''CUInt+constant "CONFIG_VERSION" ''CUInt++-- * Compiling a pattern++foreign import capi safe "pcre2.h" pcre2_compile+    :: PCRE2_SPTR+    -> PCRE2_SIZE -- ^ Can be zero-terminated.  See below.+    -> CUInt+    -- ^ See \"Main compile options\" below for possible bit flags.+    -> Ptr CInt+    -> Ptr PCRE2_SIZE+    -> Ptr Pcre2_compile_context+    -> IO (Ptr Pcre2_code)++constant "ZERO_TERMINATED" ''PCRE2_SIZE++foreign import capi safe "pcre2.h" pcre2_code_free+    :: Ptr Pcre2_code+    -> IO ()++foreign import capi safe "pcre2.h" pcre2_code_copy+    :: Ptr Pcre2_code+    -> IO (Ptr Pcre2_code)++foreign import capi "pcre2.h" pcre2_code_copy_with_tables+    :: Ptr Pcre2_code+    -> IO (Ptr Pcre2_code)++-- ** Main compile options+constant "ANCHORED" ''CUInt+constant "ALLOW_EMPTY_CLASS" ''CUInt+constant "ALT_BSUX" ''CUInt+constant "ALT_CIRCUMFLEX" ''CUInt+constant "ALT_VERBNAMES" ''CUInt+constant "AUTO_CALLOUT" ''CUInt+constant "CASELESS" ''CUInt+constant "DOLLAR_ENDONLY" ''CUInt+constant "DOTALL" ''CUInt+constant "DUPNAMES" ''CUInt+constant "ENDANCHORED" ''CUInt+constant "EXTENDED" ''CUInt+constant "EXTENDED_MORE" ''CUInt+constant "FIRSTLINE" ''CUInt+constant "LITERAL" ''CUInt+constant "MATCH_INVALID_UTF" ''CUInt+constant "MATCH_UNSET_BACKREF" ''CUInt+constant "MULTILINE" ''CUInt+constant "NEVER_BACKSLASH_C" ''CUInt+constant "NEVER_UCP" ''CUInt+constant "NEVER_UTF" ''CUInt+constant "NO_AUTO_CAPTURE" ''CUInt+constant "NO_AUTO_POSSESS" ''CUInt+constant "NO_DOTSTAR_ANCHOR" ''CUInt+constant "NO_START_OPTIMIZE" ''CUInt+constant "NO_UTF_CHECK" ''CUInt+constant "UCP" ''CUInt+constant "UNGREEDY" ''CUInt+constant "USE_OFFSET_LIMIT" ''CUInt+constant "UTF" ''CUInt++-- ** Extra compile options+constant "EXTRA_ALLOW_SURROGATE_ESCAPES" ''CUInt+constant "EXTRA_ALT_BSUX" ''CUInt+constant "EXTRA_BAD_ESCAPE_IS_LITERAL" ''CUInt+constant "EXTRA_ESCAPED_CR_IS_LF" ''CUInt+constant "EXTRA_MATCH_LINE" ''CUInt+constant "EXTRA_MATCH_WORD" ''CUInt++-- * JIT compilation++foreign import capi safe "pcre2.h" pcre2_jit_compile+    :: Ptr Pcre2_code+    -> CUInt -- ^ See below for possible bit flags.+    -> IO CInt++constant "JIT_COMPLETE" ''CUInt+constant "JIT_PARTIAL_HARD" ''CUInt+constant "JIT_PARTIAL_SOFT" ''CUInt++-- | May be returned by 'pcre2_jit_compile'.+constant "ERROR_JIT_BADOPTION" ''CInt++foreign import capi safe "pcre2.h" pcre2_jit_match+    :: Ptr Pcre2_code+    -> PCRE2_SPTR              -- ^ subject+    -> PCRE2_SIZE              -- ^ length+    -> PCRE2_SIZE              -- ^ startoffset+    -> CUInt                   -- ^ options+    -> Ptr Pcre2_match_data+    -> Ptr Pcre2_match_context+    -> IO CInt++foreign import capi safe "pcre2.h" pcre2_jit_free_unused_memory+    :: Ptr Pcre2_general_context+    -> IO ()++foreign import capi safe "pcre2.h" pcre2_jit_stack_create+    :: PCRE2_SIZE+    -> PCRE2_SIZE+    -> Ptr Pcre2_general_context+    -> IO (Ptr Pcre2_jit_stack)++foreign import capi unsafe "pcre2.h" pcre2_jit_stack_assign+    :: Ptr Pcre2_match_context+    -> FunPtr (Ptr a -> IO (Ptr Pcre2_jit_stack))+    -> Ptr a+    -> IO ()++foreign import capi safe "pcre2.h" pcre2_jit_stack_free+    :: Ptr Pcre2_jit_stack+    -> IO ()++-- * Locale support++foreign import capi safe "pcre2.h" pcre2_maketables+    :: Ptr Pcre2_general_context+    -> IO (Ptr CUChar)++foreign import capi safe "pcre2.h" pcre2_maketables_free+    :: Ptr Pcre2_general_context+    -> Ptr CUChar+    -> IO ()++-- * Information about a compiled pattern++foreign import capi unsafe "pcre2.h" pcre2_pattern_info+    :: Ptr Pcre2_code+    -> CUInt          -- ^ See below for possible values.+    -> Ptr a+    -> IO CInt        -- ^ See below for possible error values.++constant "INFO_ALLOPTIONS" ''CUInt+constant "INFO_ARGOPTIONS" ''CUInt+constant "INFO_EXTRAOPTIONS" ''CUInt+constant "INFO_BACKREFMAX" ''CUInt+constant "INFO_BSR" ''CUInt+constant "INFO_CAPTURECOUNT" ''CUInt+constant "INFO_DEPTHLIMIT" ''CUInt+constant "INFO_FIRSTBITMAP"   ''CUInt+constant "INFO_FIRSTCODETYPE" ''CUInt+constant "INFO_FIRSTCODEUNIT" ''CUInt+constant "INFO_FRAMESIZE" ''CUInt+constant "INFO_HASBACKSLASHC" ''CUInt+constant "INFO_HASCRORLF" ''CUInt+constant "INFO_HEAPLIMIT" ''CUInt+constant "INFO_JCHANGED" ''CUInt+constant "INFO_JITSIZE" ''CUInt+constant "INFO_LASTCODETYPE" ''CUInt+constant "INFO_LASTCODEUNIT" ''CUInt+constant "INFO_MATCHEMPTY" ''CUInt+constant "INFO_MATCHLIMIT" ''CUInt+constant "INFO_MAXLOOKBEHIND" ''CUInt+constant "INFO_MINLENGTH" ''CUInt+constant "INFO_NAMECOUNT" ''CUInt+constant "INFO_NAMEENTRYSIZE" ''CUInt+constant "INFO_NAMETABLE" ''CUInt+constant "INFO_NEWLINE" ''CUInt+constant "INFO_SIZE" ''CUInt++constant "ERROR_UNSET" ''CInt++-- ** Duplicate capture group names+foreign import capi unsafe "pcre2.h" pcre2_substring_nametable_scan+    :: Ptr Pcre2_code+    -> PCRE2_SPTR     -- ^ name+    -> Ptr PCRE2_SPTR -- ^ first+    -> Ptr PCRE2_SPTR -- ^ last+    -> IO CInt++-- * Callouts++foreign import capi safe "pcre2.h" pcre2_callout_enumerate+    :: Ptr Pcre2_code+    -> FunPtr (Ptr Pcre2_callout_enumerate_block -> Ptr a -> IO CInt)+    -> Ptr a+    -> IO CInt++-- ** Callout struct getters+--+-- $CalloutStructGetters+-- These functions are not part of the official API; we provide them here.  C+-- API consumers are supposed to access struct fields directly, but the FFI+-- cannot yet do that as of GHC 8.8.4.++-- *** @pcre2_callout_block@+getter "callout_block" "version" ''CUInt+getter "callout_block" "callout_number" ''CUInt+getter "callout_block" "capture_top" ''CUInt+getter "callout_block" "capture_last" ''CUInt+getter "callout_block" "callout_flags" ''CUInt+-- ^ See below for possible bit flags.+constant "CALLOUT_STARTMATCH" ''CUInt+constant "CALLOUT_BACKTRACK" ''CUInt+foreign import capi unsafe "getters.h" pcre2_callout_block_offset_vector+    :: Ptr Pcre2_callout_block+    -> IO (Ptr PCRE2_SIZE)+getter "callout_block" "mark" ''PCRE2_SPTR+getter "callout_block" "subject" ''PCRE2_SPTR+getter "callout_block" "subject_length" ''PCRE2_SIZE+getter "callout_block" "start_match" ''PCRE2_SIZE+getter "callout_block" "current_position" ''PCRE2_SIZE+getter "callout_block" "pattern_position" ''PCRE2_SIZE+getter "callout_block" "next_item_length" ''PCRE2_SIZE+getter "callout_block" "callout_string_offset" ''PCRE2_SIZE+getter "callout_block" "callout_string_length" ''PCRE2_SIZE+getter "callout_block" "callout_string" ''PCRE2_SPTR++-- *** @pcre2_callout_enumerate_block@+getter "callout_enumerate_block" "version" ''CUInt+getter "callout_enumerate_block" "pattern_position" ''PCRE2_SIZE+getter "callout_enumerate_block" "next_item_length" ''PCRE2_SIZE+getter "callout_enumerate_block" "callout_number" ''CUInt+getter "callout_enumerate_block" "callout_string_offset" ''PCRE2_SIZE+getter "callout_enumerate_block" "callout_string_length" ''PCRE2_SIZE+getter "callout_enumerate_block" "callout_string" ''PCRE2_SPTR++-- *** @pcre2_substitute_callout_block@+getter "substitute_callout_block" "version" ''CUInt+getter "substitute_callout_block" "subscount" ''CUInt+getter "substitute_callout_block" "input" ''PCRE2_SPTR+getter "substitute_callout_block" "output" ''PCRE2_SPTR+foreign import capi unsafe "getters.h" pcre2_substitute_callout_block_ovector+    :: Ptr Pcre2_substitute_callout_block+    -> IO (Ptr PCRE2_SIZE)+getter "substitute_callout_block" "oveccount" ''CUInt+foreign import capi unsafe "getters.h"+    pcre2_substitute_callout_block_output_offsets+        :: Ptr Pcre2_substitute_callout_block+        -> IO (Ptr PCRE2_SIZE) -- ^ Array of 2 (@PCRE2_SIZE[2]@)++-- * The match data block++foreign import capi safe "pcre2.h" pcre2_match_data_create+    :: CUInt                     -- ^ ovecsize+    -> Ptr Pcre2_general_context+    -> IO (Ptr Pcre2_match_data)++foreign import capi safe "pcre2.h" pcre2_match_data_create_from_pattern+    :: Ptr Pcre2_code+    -> Ptr Pcre2_general_context+    -> IO (Ptr Pcre2_match_data)++foreign import capi safe "pcre2.h" pcre2_match_data_free+    :: Ptr Pcre2_match_data+    -> IO ()++-- * Matching a pattern++foreign import capi safe "pcre2.h" pcre2_match+    :: Ptr Pcre2_code+    -> PCRE2_SPTR              -- ^ subject+    -> PCRE2_SIZE              -- ^ length+    -> PCRE2_SIZE              -- ^ startoffset+    -> CUInt                   -- ^ See below for possible bit flags.+    -> Ptr Pcre2_match_data+    -> Ptr Pcre2_match_context+    -> IO CInt++-- ** Match options+constant "COPY_MATCHED_SUBJECT" ''CUInt+constant "NOTBOL" ''CUInt+constant "NOTEOL" ''CUInt+constant "NOTEMPTY" ''CUInt+constant "NOTEMPTY_ATSTART" ''CUInt+constant "NO_JIT" ''CUInt+constant "PARTIAL_HARD" ''CUInt+constant "PARTIAL_SOFT" ''CUInt++-- ** Match errors+constant "ERROR_NOMATCH" ''CInt+constant "ERROR_PARTIAL" ''CInt+constant "ERROR_BADMAGIC" ''CInt+constant "ERROR_BADMODE" ''CInt+constant "ERROR_BADOFFSET" ''CInt+constant "ERROR_BADOPTION" ''CInt+constant "ERROR_BADUTFOFFSET" ''CInt+constant "ERROR_CALLOUT" ''CInt+constant "ERROR_DEPTHLIMIT" ''CInt+constant "ERROR_HEAPLIMIT" ''CInt+constant "ERROR_INTERNAL" ''CInt+constant "ERROR_JIT_STACKLIMIT" ''CInt+constant "ERROR_MATCHLIMIT" ''CInt+constant "ERROR_NOMEMORY" ''CInt+constant "ERROR_NULL" ''CInt+-- *** UTF-16-specific errors+--+-- | \"Missing low surrogate at end of string\"+constant "ERROR_UTF16_ERR1" ''CInt+-- | \"Invalid low surrogate follows high surrogate\"+constant "ERROR_UTF16_ERR2" ''CInt+-- | \"Isolated low surrogate\"+constant "ERROR_UTF16_ERR3" ''CInt++-- * DFA matching++foreign import capi safe "pcre2.h" pcre2_dfa_match+    :: Ptr Pcre2_code+    -> PCRE2_SPTR              -- ^ subject+    -> PCRE2_SIZE              -- ^ length+    -> PCRE2_SIZE              -- ^ startoffset+    -> CUInt                   -- ^ options+    -> Ptr Pcre2_match_data+    -> Ptr Pcre2_match_context+    -> Ptr CInt                -- ^ workspace+    -> PCRE2_SIZE              -- ^ wscount+    -> IO CInt++-- ** DFA matching options+constant "DFA_SHORTEST" ''CUInt+constant "DFA_RESTART" ''CUInt++-- ** DFA matching errors+constant "ERROR_DFA_UFUNC" ''CInt+constant "ERROR_DFA_UITEM" ''CInt+constant "ERROR_DFA_UCOND" ''CInt+constant "ERROR_DFA_UINVALID_UTF" ''CInt+constant "ERROR_DFA_WSSIZE" ''CInt+constant "ERROR_DFA_RECURSE" ''CInt+constant "ERROR_DFA_BADRESTART" ''CInt++-- * Returned string and captured substrings++foreign import capi unsafe "pcre2.h" pcre2_get_ovector_count+    :: Ptr Pcre2_match_data+    -> IO CUInt++foreign import capi unsafe "pcre2.h" pcre2_get_ovector_pointer+    :: Ptr Pcre2_match_data+    -> IO (Ptr PCRE2_SIZE)++foreign import capi unsafe "pcre2.h" pcre2_substring_length_bynumber+    :: Ptr Pcre2_match_data+    -> CUInt                -- ^ number+    -> Ptr PCRE2_SIZE       -- ^ length+    -> IO CInt++foreign import capi safe "pcre2.h" pcre2_substring_copy_bynumber+    :: Ptr Pcre2_match_data+    -> CUInt                -- ^ number+    -> Ptr PCRE2_UCHAR      -- ^ buffer+    -> Ptr PCRE2_SIZE       -- ^ bufflen+    -> IO CInt++foreign import capi safe "pcre2.h" pcre2_substring_get_bynumber+    :: Ptr Pcre2_match_data+    -> CUInt                 -- ^ name+    -> Ptr (Ptr PCRE2_UCHAR) -- ^ bufferptr+    -> Ptr PCRE2_SIZE        -- ^ bufflen+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_substring_list_get+    :: Ptr Pcre2_match_data+    -> Ptr (Ptr (Ptr PCRE2_UCHAR)) -- ^ listptr+    -> Ptr (Ptr PCRE2_SIZE)        -- ^ lengthsptr+    -> IO CInt++foreign import capi safe "pcre2.h" pcre2_substring_list_free+    :: Ptr PCRE2_SPTR+    -> IO ()++foreign import capi unsafe "pcre2.h" pcre2_substring_number_from_name+    :: Ptr Pcre2_code+    -> PCRE2_SPTR     -- ^ name+    -> IO CInt++foreign import capi unsafe "pcre2.h" pcre2_substring_length_byname+    :: Ptr Pcre2_match_data+    -> PCRE2_SPTR           -- ^ name+    -> Ptr PCRE2_SIZE       -- ^ length+    -> IO CInt++foreign import capi safe "pcre2.h" pcre2_substring_copy_byname+    :: Ptr Pcre2_match_data+    -> PCRE2_SPTR           -- ^ name+    -> Ptr PCRE2_UCHAR      -- ^ buffer+    -> Ptr PCRE2_SIZE       -- ^ bufflen+    -> IO CInt++foreign import capi safe "pcre2.h" pcre2_substring_get_byname+    :: Ptr Pcre2_match_data+    -> PCRE2_SPTR            -- ^ name+    -> Ptr (Ptr PCRE2_UCHAR) -- ^ bufferptr+    -> Ptr PCRE2_SIZE        -- ^ bufflen+    -> IO CInt++-- NOTE Maybe after all other substring functions?+foreign import capi safe "pcre2.h" pcre2_substring_free+    :: Ptr PCRE2_UCHAR+    -> IO ()++constant "ERROR_NOSUBSTRING" ''CInt+constant "ERROR_NOUNIQUESUBSTRING" ''CInt+constant "ERROR_UNAVAILABLE" ''CInt++-- * Creating a new string with substitutions++foreign import capi safe "pcre2.h" pcre2_substitute+    :: Ptr Pcre2_code+    -> PCRE2_SPTR              -- ^ subject+    -> PCRE2_SIZE              -- ^ length+    -> PCRE2_SIZE              -- ^ startoffset+    -> CUInt                   -- ^ options+    -> Ptr Pcre2_match_data+    -> Ptr Pcre2_match_context+    -> PCRE2_SPTR              -- ^ replacement+    -> PCRE2_SIZE              -- ^ rlength+    -> Ptr PCRE2_UCHAR         -- ^ outputbuffer+    -> Ptr PCRE2_SIZE          -- ^ outlengthptr+    -> IO CInt++-- ** Substitution options+constant "SUBSTITUTE_REPLACEMENT_ONLY" ''CUInt+constant "SUBSTITUTE_GLOBAL" ''CUInt+constant "SUBSTITUTE_MATCHED" ''CUInt+constant "SUBSTITUTE_OVERFLOW_LENGTH" ''CUInt+constant "SUBSTITUTE_LITERAL" ''CUInt+constant "SUBSTITUTE_UNKNOWN_UNSET" ''CUInt+constant "SUBSTITUTE_UNSET_EMPTY" ''CUInt+constant "SUBSTITUTE_EXTENDED" ''CUInt++-- ** Substitution errors+constant "ERROR_BADREPLACEMENT" ''CInt+constant "ERROR_BADREPESCAPE" ''CInt+constant "ERROR_BADSUBSTITUTION" ''CInt+constant "ERROR_BADSUBSPATTERN" ''CInt++-- * Other information about a match++foreign import capi unsafe "pcre2.h" pcre2_get_mark+    :: Ptr Pcre2_match_data+    -> IO PCRE2_SPTR++foreign import capi unsafe "pcre2.h" pcre2_get_startchar+    :: Ptr Pcre2_match_data+    -> IO PCRE2_SIZE++-- * Obtaining a textual error message+foreign import capi safe "pcre2.h" pcre2_get_error_message+    :: CInt+    -> Ptr PCRE2_UCHAR+    -> PCRE2_SIZE+    -> IO CInt
+ src/hs/Text/Regex/Pcre2/Foreign/TH.hs view
@@ -0,0 +1,37 @@+module Text.Regex.Pcre2.Foreign.TH where++import Language.Haskell.TH++{-+    For example,+constant "ERROR_NOMATCH" ''CInt+    will produce+foreign import capi unsafe "pcre2.h value PCRE2_ERROR_NOMATCH"+    pcre2_ERROR_NOMATCH :: CInt+-}+constant :: String -> Name -> DecsQ+constant suffix typeName = return [dec] where+    dec = ForeignD $ ImportF CApi Unsafe str name ty+    str = "pcre2.h value PCRE2_" ++ suffix+    name = mkName $ "pcre2_" ++ suffix+    ty = ConT typeName++{-+    For example,+getter "callout_block" "version" ''CUInt+    will produce+foreign import capi unsafe "getters.h" pcre2_callout_block_version+    :: Ptr Pcre2_callout_block+    -> IO CUInt+-}+getter :: String -> String -> Name -> DecsQ+getter blockSuffix field typeName = return [dec] where+    dec = ForeignD $ ImportF CApi Unsafe "getters.h" name ty+    name = mkName $ "pcre2_" ++ blockSuffix ++ "_" ++ field+    ty = AppT+        (AppT ArrowT $ AppT+            (ConT $ mkName "Ptr")+            (ConT $ mkName $ "Pcre2_" ++ blockSuffix))+        (AppT+            (ConT $ mkName "IO")+            (ConT typeName))
+ src/hs/Text/Regex/Pcre2/Internal.hs view
@@ -0,0 +1,1410 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Text.Regex.Pcre2.Internal where++import           Control.Applicative        (Alternative(..))+import           Control.Exception          hiding (TypeError)+import           Control.Monad.State.Strict+import           Data.Either                (partitionEithers)+import           Data.Function              ((&))+import           Data.Functor               ((<&>))+import           Data.Functor.Const         (Const(..))+import           Data.Functor.Identity      (Identity(..))+import           Data.IORef+import           Data.IntMap.Strict         (IntMap)+import qualified Data.IntMap.Strict         as IM+import           Data.List                  (foldl', intercalate)+import           Data.List.NonEmpty         (NonEmpty(..))+import qualified Data.List.NonEmpty         as NE+import           Data.Maybe                 (fromJust, fromMaybe)+import           Data.Monoid                (Alt(..), Any(..), First(..))+import           Data.Proxy                 (Proxy(..))+import           Data.Text                  (Text)+import qualified Data.Text                  as Text+import qualified Data.Text.Foreign          as Text+import           Data.Type.Bool             (type (||), If)+import           Data.Type.Equality         (type (==))+import           Data.Typeable              (cast)+import           Foreign+import           Foreign.C.Types+import qualified Foreign.Concurrent         as Conc+import           GHC.TypeLits               hiding (Text)+import qualified GHC.TypeLits               as TypeLits+import           System.IO.Unsafe           (unsafePerformIO)+import           Text.Regex.Pcre2.Foreign++-- * General utilities++-- | There is no @nullForeignPtr@ to pass to `withForeignPtr`, so we have to+-- fake it with a `Maybe`.+withForeignOrNullPtr :: Maybe (ForeignPtr a) -> (Ptr a -> IO b) -> IO b+withForeignOrNullPtr Nothing   = \action -> action nullPtr+withForeignOrNullPtr (Just fp) = withForeignPtr fp++-- | Helper so we never leak untracked 'Ptr's.+mkForeignPtr :: (Ptr a -> IO ()) -> IO (Ptr a) -> IO (ForeignPtr a)+mkForeignPtr finalize create = create >>= Conc.newForeignPtr <*> finalize++-- | Helper so we never leak untracked 'FunPtr's.+mkFunPtr :: ForeignPtr b -> IO (FunPtr a) -> IO (FunPtr a)+mkFunPtr anchor create = do+    fPtr <- create+    Conc.addForeignPtrFinalizer anchor $ freeHaskellFunPtr fPtr+    return fPtr++safeLast :: [a] -> Maybe a+safeLast [] = Nothing+safeLast xs = Just $ last xs++bitOr :: (Foldable t, Num a, Bits a) => t a -> a+bitOr = foldl' (.|.) 0++-- | Equivalent to @flip fix@.+--+-- Used to express a recursive function of one argument that is called only once+-- on an initial value:+--+-- > let go x = ... in go x0+--+-- as:+--+-- > fix1 x0 $ \go x -> ...+fix1 :: a -> ((a -> b) -> a -> b) -> b+fix1 x f = fix f x++-- | Like `fix1`, but for a function of two arguments.  Currently unused.+fix2 :: a -> b -> ((a -> b -> c) -> a -> b -> c) -> c+fix2 x y f = fix f x y++-- | Like `fix1`, but for a function of three arguments.  Currently unused.+fix3 :: a -> b -> c -> ((a -> b -> c -> d) -> a -> b -> c -> d) -> d+fix3 x y z f = fix f x y z++-- ** Fast @Text@ slicing++data SliceRange = SliceRange+    {-# UNPACK #-} !Text.I16+    {-# UNPACK #-} !Text.I16++-- | Zero-copy slice a 'Text'.  An unset capture is represented by a+-- `pcre2_UNSET` range and is interpreted in this library as `Text.empty`.+thinSlice :: Text -> SliceRange -> Text+thinSlice text (SliceRange off offEnd)+    | off == fromIntegral pcre2_UNSET = Text.empty+    | otherwise                       = text+        & Text.dropWord16 off+        & Text.takeWord16 (offEnd - off)++-- | Slice a 'Text', copying if it\'s less than half of the original.+slice :: Text -> SliceRange -> Text+slice text sliceRange =+    let substring = thinSlice text sliceRange+    in if Text.length substring > Text.length text `div` 2+        then substring+        else Text.copy substring++-- | Probably unnecessary, but unrestricted 'castPtr' feels dangerous.+class CastCUs a b | a -> b where+    castCUs :: Ptr a -> Ptr b+    castCUs = castPtr+    {-# INLINE castCUs #-}+instance CastCUs CUShort Word16+instance CastCUs Word16 CUShort++-- ** Lens types and utilities+--+-- $LensTypesAndUtilities+-- The combinators\' types are excessively polymorphic\/polykinded\/ugly because+-- they have no accompanying signatures (not worth the trouble).++type Lens'      s a = forall f. (Functor f)     => (a -> f a) -> s -> f s+type Traversal' s a = forall f. (Applicative f) => (a -> f a) -> s -> f s++preview l = getFirst . getConst . l (Const . First . Just)+view l = getConst . l Const+to k f = Const . getConst . f . k+has l = getAny . getConst . l (\_ -> Const $ Any True)++-- toAlternativeOf :: (Alternative f) => Getting (Alt f a) s a -> s -> f a+toAlternativeOf l = getAlt . view (l . to (Alt . pure))++_headNE :: Lens' (NonEmpty a) a+_headNE f (x :| xs) = f x <&> \x' -> x' :| xs++-- * Assembling inputs into @Matcher@s and @Subber@s++-- | A matching function where all inputs and auxilliary data structures have+-- been \"compiled\".  It takes a subject and produces a raw result code and+-- match data, to be passed to further validation and inspection.+type Matcher = Text -> IO (CInt, MatchData)++-- | A substitution function.  It takes a subject and produces the number of+-- substitutions performed (0 or 1, or more in the presence of `SubGlobal`)+-- along with the transformed subject.  Currently the number is unused.+type Subber = Text -> IO (CInt, Text)++-- ** Options++-- | A `Monoid` representing nearly every facility PCRE2 presents for tweaking+-- the behavior of regex compilation and execution.+--+-- All library functions that take options have the suffix @Opt@ in their names;+-- for each of them, there\'s also a non-@Opt@ convenience function that simply+-- has the (unexported) `mempty` option.  For many uses, options won\'t be+-- needed.+--+-- Some options can be enabled by special character sequences in the pattern as+-- an alternative to specifying them as an `Option`.  See `Caseless` for+-- example.+--+-- Documentation is scant here.  For more complete, accurate information,+-- including discussions of corner cases arising from specific combinations of+-- options and pattern items, please see the [C API+-- documentation](https://pcre.org/current/doc/html/pcre2api.html).+data Option+    = NoOptions -- ^ `mempty`+    | TwoOptions Option Option -- ^ `<>`++    | AllowEmptyClass -- ^ Make @[]@ not match anything, rather than counting+    -- the @]@ as the first character of the class.+    | AltBsux -- ^ Like `AltBsuxLegacy`, except with ECMAScript 6 hex literal+    -- feature for @\\u@.+    | AltBsuxLegacy -- ^ Behave like ECMAScript 5 for @\\U@, @\\u@, and @\\x@.+    -- See 'AltBsux'.+    | AltCircumflex -- ^ Match a @^@ after a newline at the end of the subject.+    -- Only relevant in multiline mode.+    | AltVerbNames -- ^ Enable backslash escapes in verb names.  E.g.,+    -- @(*MARK:L\\(O\\)L)@.+    | Anchored -- ^ Equivalent to beginning pattern with @^@.+    | AutoCallout -- ^ Run callout for every pattern item.  Only relevant if a+    -- callout is set.+    | BadEscapeIsLiteral -- ^ Do not throw an error for unrecognized or+    -- malformed escapes.  /\"This is a dangerous option.\"/+    | Bsr Bsr -- ^ Override what @\\R@ matches (default given by `defaultBsr`).+    | Caseless -- ^ Case-insensitive match.  Equivalent to @(?i)@.+    | DepthLimit Word32 -- ^ Override maximum depth of nested backtracking+    -- (default given by `defaultDepthLimit`).  Equivalent to+    -- @(*LIMIT_DEPTH=@/number/@)@.+    | DollarEndOnly -- ^ Don\'t match @$@ with a newline at the end of the+    -- subject.+    | DotAll -- ^ A dot also matches a (single-character) newline.  Equivalent+    -- to @(?s)@.+    | DupNames -- ^ Allow non-unique capture names.+    | EndAnchored -- ^ More or less like ending pattern with @$@.+    | EscapedCrIsLf -- ^ Interpret @\\r@ as @\\n@.+    | Extended -- ^ In the pattern, ignore whitespace, and enable comments+    -- starting with @#@.  Equivalent to @(?x)@.+    | ExtendedMore -- ^ Like `Extended` but also ignore spaces and tabs within+    -- @[]@.+    | FirstLine -- ^ The match must begin in the first line of the subject.+    | HeapLimit Word32 -- ^ Override maximum heap memory (in kibibytes) used to+    -- hold backtracking information (default given by `defaultHeapLimit`).+    -- Equivalent to @(*LIMIT_HEAP=@/number/@)@.+    | Literal -- ^ Treat the pattern as a literal string.+    | MatchLimit Word32 -- ^ Override maximum value of the main matching loop\'s+    -- internal counter (default given by `defaultMatchLimit`), as a simple CPU+    -- throttle.  Equivalent to @(*LIMIT_MATCH=@/number/@)@.+    | MatchLine -- ^ Only match complete lines.  Equivalent to bracketing the+    -- pattern with @^(?:@/pattern/@)$@.+    | MatchUnsetBackRef -- ^ A backreference to an unset capture group matches+    -- an empty string.+    | MatchWord -- ^ Only match subjects that have word boundaries at the+    -- beginning and end.  Equivalent to bracketing the pattern with+    -- @\\b(?:@/pattern/@)\\b@.+    | MaxPatternLength Word64 -- ^ Default is `maxBound`.+    | Multiline -- ^ @^@ and @$@ mean \"beginning\/end of a line\" rather than+    -- \"beginning\/end of the subject\".  Equivalent to @(?m)@.+    | NeverBackslashC -- ^ Do not allow the unsafe @\\C@ sequence.+    | NeverUcp -- ^ Don\'t count Unicode characters in some character classes+    -- such as @\\d@.  Overrides @(*UCP)@.+    | Newline Newline -- ^ Override what a newline is (default given by+    -- `defaultNewline`).  Equivalent to @(*CRLF)@ or similar.+    | NoAutoCapture -- ^ Disable numbered capturing parentheses.+    | NoAutoPossess -- ^ Turn off some optimizations, possibly resulting in some+    -- callouts not being called.+    | NoDotStarAnchor -- ^ Turn off an optimization involving @.*@, possibly+    -- resulting in some callouts not being called.+    | NoStartOptimize -- ^ Turn off some optimizations normally performed at the+    -- beginning of a pattern.+    | NotBol -- ^ First character of subject is not the __b__eginning __o__f+    -- __l__ine.  Only affects @^@.+    | NotEmpty -- ^ The 0th capture doesn\'t match if it would be empty.+    | NotEmptyAtStart -- ^ The 0th capture doesn\'t match if it would be empty+    -- and at the beginning of the subject.+    | NotEol -- ^ End of subject is not the __e__nd __o__f __l__ine.  Only+    -- affects @$@.+    | OffsetLimit Word64 -- ^ Limit how far an unanchored search can advance in+    -- the subject.+    | ParensLimit Word32 -- ^ Override max depth of nested parentheses (default+    -- given by `defaultParensLimit`).+    | PartialHard -- ^ If the subject ends without finding a complete match,+    -- stop trying alternatives and signal a partial match immediately.+    -- Currently we do this by throwing a `Pcre2Exception` but we should do+    -- better.+    | PartialSoft -- ^ If the subject ends and all alternatives have been tried,+    -- but no complete match is found, signal a partial match.  Currently we do+    -- this by throwing a `Pcre2Exception` but we should do better.+    | SubGlobal -- ^ /Affects `subOpt`./  Replace all, rather than just the+    -- first.+    | SubLiteral -- ^ /Affects `subOpt`./  Treat the replacement as a literal+    -- string.+    | SubReplacementOnly -- ^ /Affects `subOpt`./  Return just the rendered+    -- replacement instead of it within the subject.  With `SubGlobal`, all+    -- results are concatenated.+    | SubUnknownUnset -- ^ /Affects `subOpt`./  References in the replacement+    -- to non-existent captures don\'t error but are treated as unset.+    | SubUnsetEmpty -- ^ /Affects `subOpt`./  References in the replacement+    -- to unset captures don\'t error but are treated as empty.+    | Ucp -- ^ Count Unicode characters in some character classes such as @\\d@.+    -- Incompatible with `NeverUcp`.+    | Ungreedy -- ^ Invert the effect of @?@.  Without it, quantifiers are+    -- non-greedy; with it, they are greedy.  Equivalent to @(?U)@.+    | UnsafeCallout (CalloutInfo -> IO CalloutResult) -- ^ Run the given callout+    -- on every capture.  Multiples of this option before the rightmost are+    -- ignored.+    --+    -- /NOTE: The callout is run via `unsafePerformIO` within pure code!/+    | UnsafeCompileRecGuard (Int -> IO Bool) -- ^ Run the given guard on every+    -- new descent into a level of parentheses, passing the current depth as+    -- argument.  Returning @False@ aborts pattern compilation with an+    -- exception.  Multiples of this option before the rightmost are ignored.+    --+    -- /NOTE: Currently (PCRE2 version 10\.35) patterns seem to be parsed in/+    -- /two passes, both times triggering the recursion guard.  Also, it is/+    -- /triggered at the beginning of the pattern, passing 0.  None of this is/+    -- /documented; expect the unexpected in the presence of side effects!/+    --+    -- /NOTE: The guard is run via `unsafePerformIO` within pure code!/+    | UnsafeSubCallout (SubCalloutInfo -> IO SubCalloutResult) -- ^ Run the+    -- given callout on every substitution.  This is at most once unless+    -- `SubGlobal` is set.  Multiples of this option before the rightmost are+    -- ignored.+    --+    -- /NOTE: The callout is run via `unsafePerformIO` within pure code!/+    | Utf -- ^ Treat both the pattern and subject as UTF rather than fixed-width+    -- 16-bit code units.++instance Semigroup Option where+    (<>) = TwoOptions++instance Monoid Option where+    mempty = NoOptions++-- | What @\\R@, __b__ack__s__lash __R__, can mean.+data Bsr+    = BsrUnicode -- ^ any Unicode line ending sequence+    | BsrAnyCrlf -- ^ @\\r@, @\\n@, or @\\r\\n@+    deriving (Eq, Show)++-- | C to Haskell.+bsrFromC :: CUInt -> Bsr+bsrFromC x+    | x == pcre2_BSR_UNICODE = BsrUnicode+    | x == pcre2_BSR_ANYCRLF = BsrAnyCrlf+    | otherwise              = error $ "bsrFromC: bad value " ++ show x++-- | Haskell to C.+bsrToC :: Bsr -> CUInt+bsrToC BsrUnicode = pcre2_BSR_UNICODE+bsrToC BsrAnyCrlf = pcre2_BSR_ANYCRLF++-- | What\'s considered a newline.+data Newline+    = NewlineCr      -- ^ @\\r@ only+    | NewlineLf      -- ^ @\\n@ only+    | NewlineCrlf    -- ^ @\\r\\n@ only+    | NewlineAny     -- ^ any Unicode line ending sequence+    | NewlineAnyCrlf -- ^ any of the above+    | NewlineNul     -- ^ binary zero+    deriving (Eq, Show)++-- | C to Haskell.+newlineFromC :: CUInt -> Newline+newlineFromC x+    | x == pcre2_NEWLINE_CR      = NewlineCr+    | x == pcre2_NEWLINE_LF      = NewlineLf+    | x == pcre2_NEWLINE_CRLF    = NewlineCrlf+    | x == pcre2_NEWLINE_ANY     = NewlineAny+    | x == pcre2_NEWLINE_ANYCRLF = NewlineAnyCrlf+    | x == pcre2_NEWLINE_NUL     = NewlineNul+    | otherwise                  = error $ "newlineFromC: bad value " ++ show x++-- | Haskell to C.+newlineToC :: Newline -> CUInt+newlineToC NewlineCr      = pcre2_NEWLINE_CR+newlineToC NewlineLf      = pcre2_NEWLINE_LF+newlineToC NewlineCrlf    = pcre2_NEWLINE_CRLF+newlineToC NewlineAny     = pcre2_NEWLINE_ANY+newlineToC NewlineAnyCrlf = pcre2_NEWLINE_ANYCRLF+newlineToC NewlineNul     = pcre2_NEWLINE_NUL++-- | Input for user-defined callouts.+data CalloutInfo+    = CalloutInfo {+        -- | The index of which capture we\'re on.  Note that callouts are never+        -- run for the 0th capture.+        calloutIndex :: CalloutIndex,+        -- | The captures that have been set so far.+        calloutCaptures :: NonEmpty (Maybe Text),+        -- | The original subject.+        calloutSubject :: Text,+        -- | The name of the most recently passed @(*MARK)@, @(*PRUNE)@, or+        -- @(*THEN)@, if any.+        calloutMark :: Maybe Text,+        -- | Is this the first callout after the start of matching?+        calloutIsFirst :: Bool,+        -- | Has a backtrack occurred since the previous callout, or the+        -- beginning of matching if no previous callouts?+        calloutBacktracked :: Bool}+    deriving (Show, Eq)++-- | What caused the callout.+data CalloutIndex+    = CalloutNumber Int -- ^ Numbered capture.+    | CalloutName Text -- ^ Named capture.+    | CalloutAuto Int Int -- ^ The item located at this half-open range of+    -- offsets within the pattern.  See `AutoCallout`.+    deriving (Show, Eq)++-- | Callout functions return one of these values, which dictates what happens+-- next in the match.+data CalloutResult+    = CalloutProceed -- ^ Keep going.+    | CalloutNoMatchHere -- ^ Fail the current capture, but not the whole match.+    -- For example, backtracking may occur.+    | CalloutNoMatch -- ^ Fail the whole match.+    deriving (Show, Eq)++-- | Input for user-defined substitution callouts.+data SubCalloutInfo+    = SubCalloutInfo {+        -- | The 1-based index of which substitution we\'re on.  Only goes past+        -- 1 during global substitutions.+        subCalloutSubsCount :: Int,+        -- | The captures that have been set so far.+        subCalloutCaptures :: NonEmpty (Maybe Text),+        -- | The original subject.+        subCalloutSubject :: Text,+        -- | The replacement.+        subCalloutReplacement :: Text}+    deriving (Show, Eq)++-- | Substitution callout functions return one of these values, which dictates+-- what happens next in the substitution.+data SubCalloutResult+    = SubCalloutAccept -- ^ Succeed, and keep going if in global mode.+    | SubCalloutSkip -- ^ Do not perform this substitution, but keep going if in+    -- global mode.+    | SubCalloutAbort -- ^ Do not perform this or any subsequent substitutions.+    deriving (Show, Eq)++-- ** Lower-level representation of options and C data++type CompileContext = ForeignPtr Pcre2_compile_context+type Code           = ForeignPtr Pcre2_code+type MatchContext   = ForeignPtr Pcre2_match_context+type MatchData      = ForeignPtr Pcre2_match_data++-- | An `Option` can result in multiple \"plans\".+applyOption :: Option -> [AppliedOption]+applyOption = \case+    NoOptions            -> []+    TwoOptions opt0 opt1 -> applyOption opt0 ++ applyOption opt1++    -- CompileOption+    Anchored          -> [CompileOption pcre2_ANCHORED]+    AllowEmptyClass   -> [CompileOption pcre2_ALLOW_EMPTY_CLASS]+    AltBsuxLegacy     -> [CompileOption pcre2_ALT_BSUX]+    AltCircumflex     -> [CompileOption pcre2_ALT_CIRCUMFLEX]+    AltVerbNames      -> [CompileOption pcre2_ALT_VERBNAMES]+    AutoCallout       -> [CompileOption pcre2_AUTO_CALLOUT]+    Caseless          -> [CompileOption pcre2_CASELESS]+    DollarEndOnly     -> [CompileOption pcre2_DOLLAR_ENDONLY]+    DotAll            -> [CompileOption pcre2_DOTALL]+    DupNames          -> [CompileOption pcre2_DUPNAMES]+    EndAnchored       -> [CompileOption pcre2_ENDANCHORED]+    Extended          -> [CompileOption pcre2_EXTENDED]+    ExtendedMore      -> [CompileOption pcre2_EXTENDED_MORE]+    FirstLine         -> [CompileOption pcre2_FIRSTLINE]+    Literal           -> [CompileOption pcre2_LITERAL]+    MatchUnsetBackRef -> [CompileOption pcre2_MATCH_UNSET_BACKREF]+    Multiline         -> [CompileOption pcre2_MULTILINE]+    NeverBackslashC   -> [CompileOption pcre2_NEVER_BACKSLASH_C]+    NeverUcp          -> [CompileOption pcre2_NEVER_UCP]+    NoAutoCapture     -> [CompileOption pcre2_NO_AUTO_CAPTURE]+    NoAutoPossess     -> [CompileOption pcre2_NO_AUTO_POSSESS]+    NoDotStarAnchor   -> [CompileOption pcre2_NO_DOTSTAR_ANCHOR]+    NoStartOptimize   -> [CompileOption pcre2_NO_START_OPTIMIZE]+    Ucp               -> [CompileOption pcre2_UCP]+    Ungreedy          -> [CompileOption pcre2_UNGREEDY]+    Utf               -> [CompileOption pcre2_UTF]++    -- ExtraCompileOption+    AltBsux            -> [CompileExtraOption pcre2_EXTRA_ALT_BSUX]+    BadEscapeIsLiteral -> [CompileExtraOption pcre2_EXTRA_BAD_ESCAPE_IS_LITERAL]+    EscapedCrIsLf      -> [CompileExtraOption pcre2_EXTRA_ESCAPED_CR_IS_LF]+    MatchLine          -> [CompileExtraOption pcre2_EXTRA_MATCH_LINE]+    MatchWord          -> [CompileExtraOption pcre2_EXTRA_MATCH_WORD]++    -- CompileContextOption+    Bsr bsr -> unary+        CompileContextOption pcre2_set_bsr (bsrToC bsr)+    MaxPatternLength len -> unary+        CompileContextOption pcre2_set_max_pattern_length (fromIntegral len)+    Newline newline -> unary+        CompileContextOption pcre2_set_newline (newlineToC newline)+    ParensLimit limit -> unary+        CompileContextOption pcre2_set_parens_nest_limit (fromIntegral limit)++    -- CompileRecGuardOption+    UnsafeCompileRecGuard f -> [CompileRecGuardOption f]++    -- MatchOption+    NotBol             -> [MatchOption pcre2_NOTBOL]+    NotEol             -> [MatchOption pcre2_NOTEOL]+    NotEmpty           -> [MatchOption pcre2_NOTEMPTY]+    NotEmptyAtStart    -> [MatchOption pcre2_NOTEMPTY_ATSTART]+    PartialHard        -> [MatchOption pcre2_PARTIAL_HARD]+    PartialSoft        -> [MatchOption pcre2_PARTIAL_SOFT]+    SubReplacementOnly -> [MatchOption pcre2_SUBSTITUTE_REPLACEMENT_ONLY]+    SubGlobal          -> [MatchOption pcre2_SUBSTITUTE_GLOBAL]+    SubLiteral         -> [MatchOption pcre2_SUBSTITUTE_LITERAL]+    SubUnknownUnset    -> [MatchOption pcre2_SUBSTITUTE_UNKNOWN_UNSET]+    SubUnsetEmpty      -> [MatchOption pcre2_SUBSTITUTE_UNSET_EMPTY]++    -- CalloutOption+    UnsafeCallout f -> [CalloutOption f]++    -- SubCalloutOption+    UnsafeSubCallout f -> [SubCalloutOption f]++    -- MatchContextOption+    OffsetLimit limit -> CompileOption pcre2_USE_OFFSET_LIMIT : unary+        MatchContextOption pcre2_set_offset_limit (fromIntegral limit)+    HeapLimit limit -> unary+        MatchContextOption pcre2_set_heap_limit (fromIntegral limit)+    MatchLimit limit -> unary+        MatchContextOption pcre2_set_match_limit (fromIntegral limit)+    DepthLimit limit -> unary+        MatchContextOption pcre2_set_depth_limit (fromIntegral limit)++    where+    unary ctor f x = (: []) $ ctor $ \ctx -> withForeignPtr ctx $ \ctxPtr ->+        f ctxPtr x >>= check (== 0)++-- | Intermediate representation of options expressing what effect they\'ll have+-- on which stage of regex compilation\/execution.  Also provide fake @Prism'@s.+data AppliedOption+    = CompileOption CUInt+    | CompileExtraOption CUInt+    | CompileContextOption (CompileContext -> IO ())+    | CompileRecGuardOption (Int -> IO Bool)+    | MatchOption CUInt+    | CalloutOption (CalloutInfo -> IO CalloutResult)+    | SubCalloutOption (SubCalloutInfo -> IO SubCalloutResult)+    | MatchContextOption (MatchContext -> IO ())++_CompileOption f =+    \case CompileOption x -> CompileOption <$> f x; o -> pure o+_CompileExtraOption f =+    \case CompileExtraOption x -> CompileExtraOption <$> f x; o -> pure o+_CompileContextOption f =+    \case CompileContextOption x -> CompileContextOption <$> f x; o -> pure o+_CompileRecGuardOption f =+    \case CompileRecGuardOption x -> CompileRecGuardOption <$> f x; o -> pure o+_MatchOption f =+    \case MatchOption x -> MatchOption <$> f x; o -> pure o+_CalloutOption f =+    \case CalloutOption x -> CalloutOption <$> f x; o -> pure o+_SubCalloutOption f =+    \case SubCalloutOption x -> SubCalloutOption <$> f x; o -> pure o+_MatchContextOption f =+    \case MatchContextOption x -> MatchContextOption <$> f x; o -> pure o++-- ** Extracting options at the right times+--+-- $ExtractingOptionsAtTheRightTimes+-- We interleave the extraction of options with the manipulation of foreign data+-- en route to the target `Matcher` or `Subber`.++-- | A `Monad` modeling both option extraction and foreign effects.+type ExtractOpts = StateT [AppliedOption] IO++-- | Use a fake @Prism'@ to extract a category of options.+extractOptsOf :: Traversal' AppliedOption a -> ExtractOpts [a]+extractOptsOf traversal = state $ partitionEithers . map discrim where+    discrim opt = maybe (Right opt) Left $ preview traversal opt++-- | Prepare to compile a `Code`.+extractCompileEnv :: ExtractOpts CompileEnv+extractCompileEnv = do+    ctxUpds <- extractOptsOf _CompileContextOption+    xtraOpts <- bitOr <$> extractOptsOf _CompileExtraOption+    recGuard <- safeLast <$> extractOptsOf _CompileRecGuardOption++    compileEnvCtx <- sequence $ do+        guard $ not $ null ctxUpds && xtraOpts == 0 && null recGuard+        Just $ liftIO $ do+            ctx <- mkForeignPtr pcre2_compile_context_free $+                pcre2_compile_context_create nullPtr++            forM_ ctxUpds $ \update -> update ctx+            when (xtraOpts /= 0) $ withForeignPtr ctx $ \ctxPtr ->+                pcre2_set_compile_extra_options ctxPtr xtraOpts >>= check (== 0)++            return ctx++    compileEnvERef <- sequence $ do+        ctx <- compileEnvCtx+        f <- recGuard+        Just $ liftIO $ do+            eRef <- newIORef Nothing+            fPtr <- mkFunPtr ctx $ mkRecursionGuard $ \depth _ -> do+                resultOrE <- try $ do+                    f <- evaluate f+                    result <- f $ fromIntegral depth+                    evaluate result+                case resultOrE of+                    Right success -> return $ if success then 0 else 1+                    Left e        -> writeIORef eRef (Just e) >> return 1++            withForeignPtr ctx $ \ctxPtr -> do+                result <- pcre2_set_compile_recursion_guard ctxPtr fPtr nullPtr+                check (== 0) result++            return eRef++    return $ CompileEnv {..}++-- | Inputs to `Code` compilation besides the pattern.+data CompileEnv = CompileEnv {+    compileEnvCtx :: Maybe CompileContext,+    -- | A register for catching exceptions thrown in recursion guards, if+    -- needed.+    compileEnvERef :: Maybe (IORef (Maybe SomeException))}++-- | Compile a `Code`.+extractCode :: Text -> CompileEnv -> ExtractOpts Code+extractCode patt (CompileEnv {..}) = do+    opts <- bitOr <$> extractOptsOf _CompileOption++    liftIO $ mkForeignPtr pcre2_code_free $+        Text.useAsPtr patt $ \pattPtr pattCUs ->+        alloca $ \errorCodePtr ->+        alloca $ \errorOffPtr ->+        withForeignOrNullPtr compileEnvCtx $ \ctxPtr -> do+            codePtr <- pcre2_compile+                (castCUs pattPtr)+                (fromIntegral pattCUs)+                opts+                errorCodePtr+                errorOffPtr+                ctxPtr+            when (codePtr == nullPtr) $ do+                -- Re-throw exception (if any) from recursion guard (if any)+                forM_ compileEnvERef $ readIORef >=> mapM_ throwIO+                -- Otherwise throw PCRE2 error+                errorCode <- peek errorCodePtr+                offCUs <- peek errorOffPtr+                throwIO $ Pcre2CompileException errorCode patt offCUs++            return codePtr++-- | `Code` and auxiliary compiled data used in preparation for a match or+-- substitution.  This remains constant for the lifetime of a `Matcher` or+-- `Subber`.+data MatchEnv = MatchEnv {+    matchEnvCode       :: Code,+    matchEnvOpts       :: CUInt,+    matchEnvCtx        :: Maybe MatchContext,+    matchEnvCallout    :: Maybe (CalloutInfo -> IO CalloutResult),+    matchEnvSubCallout :: Maybe (SubCalloutInfo -> IO SubCalloutResult)}++-- | Prepare a matching function.+extractMatchEnv :: Code -> ExtractOpts MatchEnv+extractMatchEnv matchEnvCode = do+    matchEnvOpts <- bitOr <$> extractOptsOf _MatchOption++    matchEnvCtx <- extractOptsOf _MatchContextOption >>= \case+        []      -> return Nothing+        ctxUpds -> liftIO $ Just <$> do+            ctx <- mkForeignPtr pcre2_match_context_free $+                pcre2_match_context_create nullPtr++            forM_ ctxUpds $ \update -> update ctx++            return ctx++    matchEnvCallout <- safeLast <$> extractOptsOf _CalloutOption+    matchEnvSubCallout <- safeLast <$> extractOptsOf _SubCalloutOption++    return $ MatchEnv {..}++-- | Helper for @assemble*@ functions.  Basically, extract all options and help+-- produce a function that takes a `Text` subject and does something.+assembleSubjFun+    :: (MatchEnv -> Text -> IO a)+    -> Option+    -> Text+    -> IO (Text -> IO a)+assembleSubjFun mkSubjFun option patt =+    runStateT extractAll (applyOption option) <&> \case+        (subjFun, []) -> subjFun+        _             -> error "BUG! Options not fully extracted"++    where+    extractAll = do+        compileEnv <- extractCompileEnv+        code <- extractCode patt compileEnv+        matchEnv <- extractMatchEnv code++        return $ mkSubjFun matchEnv++-- | Produce a `Matcher`.+assembleMatcher+    :: Option+    -> Text       -- ^ pattern+    -> IO Matcher+assembleMatcher = assembleSubjFun $ \matchEnv@(MatchEnv {..}) ->+    let matchTempEnvWithSubj = mkMatchTempEnv matchEnv+    in \subject -> withForeignPtr matchEnvCode $ \codePtr -> do+        matchData <- mkForeignPtr pcre2_match_data_free $+            pcre2_match_data_create_from_pattern codePtr nullPtr++        MatchTempEnv {..} <- matchTempEnvWithSubj subject+        result <-+            Text.useAsPtr subject $ \subjPtr subjCUs ->+            withForeignOrNullPtr matchTempEnvCtx $ \ctxPtr ->+            withForeignPtr matchData $ \matchDataPtr -> pcre2_match+                codePtr+                (castCUs subjPtr)+                (fromIntegral subjCUs)+                0+                matchEnvOpts+                matchDataPtr+                ctxPtr+        maybeRethrow matchTempEnvRef++        return (result, matchData)++-- | A `Subber` works by first writing results to a reasonably-sized buffer.  If+-- we run out of room, PCRE2 allows us to simulate the rest of the substitution+-- without writing anything, in order to calculate how big the buffer actually+-- has to be.  In this event, we rerun the substitution with a new,+-- exactly-sized buffer.+--+-- One potential issue arising from two attempts is running effectful callouts+-- twice.  We mitigate this by skipping callouts the second time:+--+-- * all capture callouts, since they had run during the simulation, and+--+-- * those substitution callouts that had run the first time.+--+-- Therefore, the first time, log the substitution callout indexes that had run+-- along with their results, and replay the log the second time, returning those+-- same results without re-incurring effects.+assembleSubber+    :: Text      -- ^ replacement+    -> Option+    -> Text      -- ^ pattern+    -> IO Subber+assembleSubber replacement =+    assembleSubjFun $ \firstMatchEnv@(MatchEnv {..}) ->+    -- Subber+    \subject ->+    withForeignPtr matchEnvCode $ \codePtr ->+    Text.useAsPtr subject $ \subjPtr subjCUs ->+    Text.useAsPtr replacement $ \replPtr replCUs ->+    alloca $ \outLenPtr -> do+        let checkAndGetOutput :: CInt -> PCRE2_SPTR -> IO (CInt, Text)+            checkAndGetOutput 0      _         = return (0, subject)+            checkAndGetOutput result outBufPtr = do+                check (> 0) result+                outLen <- peek outLenPtr+                out <- Text.fromPtr (castCUs outBufPtr) (fromIntegral outLen)+                return (result, out)++            run :: CUInt -> Ptr Pcre2_match_context -> PCRE2_SPTR -> IO CInt+            run curOpts ctxPtr outBufPtr = pcre2_substitute+                codePtr+                (castCUs subjPtr)+                (fromIntegral subjCUs)+                0+                (matchEnvOpts .|. curOpts)+                nullPtr+                ctxPtr+                (castCUs replPtr)+                (fromIntegral replCUs)+                outBufPtr+                outLenPtr++            -- Guess the size of the output to be <= 2x that of the subject.+            initOutLen = Text.length subject * 2++        poke outLenPtr $ fromIntegral initOutLen+        MatchTempEnv {..} <- mkMatchTempEnv firstMatchEnv subject+        firstAttempt <- withForeignOrNullPtr matchTempEnvCtx $ \ctxPtr ->+            allocaArray initOutLen $ \outBufPtr -> do+                result <- run pcre2_SUBSTITUTE_OVERFLOW_LENGTH ctxPtr outBufPtr+                maybeRethrow matchTempEnvRef+                if result == pcre2_ERROR_NOMEMORY+                    then Left <$> case matchTempEnvRef of+                        Nothing  -> return IM.empty+                        Just ref -> calloutStateSubsLog <$> readIORef ref+                    else Right <$> checkAndGetOutput result outBufPtr++        case firstAttempt of+            Right resultAndOutput -> return resultAndOutput+            Left subsLog          -> do+                -- The output was bigger than we guessed.  Try again.+                computedOutLen <- fromIntegral <$> peek outLenPtr+                let finalMatchEnv = firstMatchEnv {+                        -- Do not run capture callouts again.+                        matchEnvCallout = Nothing,+                        -- Do not run any substitution callouts run previously.+                        matchEnvSubCallout = fastFwd <$> matchEnvSubCallout}+                    fastFwd f = \info ->+                        case subsLog IM.!? subCalloutSubsCount info of+                            Just result -> return result+                            Nothing     -> f info+                MatchTempEnv {..} <- mkMatchTempEnv finalMatchEnv subject+                withForeignOrNullPtr matchTempEnvCtx $ \ctxPtr ->+                    allocaArray computedOutLen $ \outBufPtr -> do+                        result <- run 0 ctxPtr outBufPtr+                        maybeRethrow matchTempEnvRef+                        checkAndGetOutput result outBufPtr++-- | Generate per-call data for @pcre2_match()@ etc., to accommodate callouts.+--+-- We need to save and inspect state that occurs in potentially concurrent+-- matches.  This means a new state ref for each match, which means a new+-- `FunPtr` to close on it, which means a new match context to set it to.+mkMatchTempEnv+    :: MatchEnv+    -> Text -- ^ Callout info requires access to the original subject.+    -> IO MatchTempEnv+mkMatchTempEnv (MatchEnv {..})+    | null matchEnvCallout && null matchEnvSubCallout = \_ -> return noCallouts+    | otherwise                                       = \subject -> do+        calloutStateRef <- newIORef $ CalloutState {+            calloutStateException = Nothing,+            calloutStateSubsLog   = IM.empty}+        ctx <- mkForeignPtr pcre2_match_context_free ctxPtrForCallouts++        -- Install C function pointers in the @pcre2_match_context@.  When+        -- dereferenced and called, they will force the user-supplied Haskell+        -- callout functions and their results, catching any exceptions and+        -- saving them.++        -- Install callout, if any+        forM_ matchEnvCallout $ \f -> do+            fPtr <- mkFunPtr ctx $ mkCallout $ \blockPtr _ -> do+                info <- getCalloutInfo subject blockPtr+                resultOrE <- try $ do+                    f <- evaluate f+                    result <- f info+                    evaluate result+                case resultOrE of+                    Right result -> return $ case result of+                        CalloutProceed     -> 0+                        CalloutNoMatchHere -> 1+                        CalloutNoMatch     -> pcre2_ERROR_NOMATCH+                    Left e -> do+                        modifyIORef' calloutStateRef $ \cst -> cst {+                            calloutStateException = Just e}+                        return pcre2_ERROR_CALLOUT+            withForeignPtr ctx $ \ctxPtr ->+                pcre2_set_callout ctxPtr fPtr nullPtr >>= check (== 0)++        -- Install substitution callout, if any+        forM_ matchEnvSubCallout $ \f -> do+            fPtr <- mkFunPtr ctx $ mkCallout $ \blockPtr _ -> do+                info <- getSubCalloutInfo subject blockPtr+                resultOrE <- try $ do+                    f <- evaluate f+                    result <- f info+                    evaluate result+                case resultOrE of+                    Right result -> do+                        modifyIORef' calloutStateRef $ \cst -> cst {+                            calloutStateSubsLog = IM.insert+                                (subCalloutSubsCount info)+                                result+                                (calloutStateSubsLog cst)}+                        return $ case result of+                            SubCalloutAccept ->  0+                            SubCalloutSkip   ->  1+                            SubCalloutAbort  -> -1+                    Left e -> do+                        modifyIORef' calloutStateRef $ \cst -> cst {+                            calloutStateException = Just e}+                        return (-1)+            withForeignPtr ctx $ \ctxPtr -> do+                result <- pcre2_set_substitute_callout ctxPtr fPtr nullPtr+                check (== 0) result++        return $ MatchTempEnv {+            matchTempEnvCtx = Just ctx,+            matchTempEnvRef = Just calloutStateRef}++    where+    noCallouts = MatchTempEnv {+        matchTempEnvCtx = matchEnvCtx,+        matchTempEnvRef = Nothing}+    ctxPtrForCallouts = case matchEnvCtx of+        -- No pre-existing match context, so create one afresh.+        Nothing -> pcre2_match_context_create nullPtr+        -- Pre-existing match context, so copy it.+        Just ctx -> withForeignPtr ctx pcre2_match_context_copy++-- | Per-call data for @pcre2_match()@ etc.+data MatchTempEnv = MatchTempEnv {+    matchTempEnvCtx :: Maybe MatchContext,+    matchTempEnvRef :: Maybe (IORef CalloutState)}++-- | Data computed during callouts that will be stashed in an IORef and+-- inspected after @pcre2_match()@ or similar completes.+data CalloutState = CalloutState {+    calloutStateException :: Maybe SomeException,+    calloutStateSubsLog   :: IntMap SubCalloutResult}++-- | FFI wrapper.+foreign import ccall "wrapper" mkRecursionGuard+    :: (CUInt -> Ptr a -> IO CInt)+    -> IO (FunPtr (CUInt -> Ptr a -> IO CInt))++-- | FFI wrapper.+foreign import ccall "wrapper" mkCallout+    :: (Ptr block -> Ptr a -> IO CInt)+    -> IO (FunPtr (Ptr block -> Ptr a -> IO CInt))++-- | Within a callout, marshal the original subject and @pcre2_callout_block@+-- data to Haskell and present to the user function.  Ensure no pointers are+-- leaked!+getCalloutInfo :: Text -> Ptr Pcre2_callout_block -> IO CalloutInfo+getCalloutInfo subject blockPtr = do+    calloutIndex <- do+        str <- pcre2_callout_block_callout_string blockPtr+        if str == nullPtr+            then pcre2_callout_block_callout_number blockPtr >>= \case+                -- Auto callout+                255 -> liftM2 CalloutAuto pattPos itemLen where+                    pattPos = intVia pcre2_callout_block_pattern_position+                    itemLen = intVia pcre2_callout_block_next_item_length+                    intVia getter = fromIntegral <$> getter blockPtr+                -- Numerical callout+                number -> return $ CalloutNumber $ fromIntegral number+            else do+                -- String callout+                len <- pcre2_callout_block_callout_string_length blockPtr+                CalloutName <$> Text.fromPtr (castCUs str) (fromIntegral len)++    let calloutSubject = subject++    calloutCaptures <- do+        ovecPtr <- pcre2_callout_block_offset_vector blockPtr+        top <- pcre2_callout_block_capture_top blockPtr+        forM (0 :| [1 .. fromIntegral top - 1]) $ \n -> do+            start <- peekElemOff ovecPtr $ n * 2+            if start == pcre2_UNSET+                then return Nothing+                else Just <$> do+                    end <- peekElemOff ovecPtr $ n * 2 + 1+                    return $ slice calloutSubject $ SliceRange+                        (fromIntegral start)+                        (fromIntegral end)++    calloutMark <- do+        ptr <- pcre2_callout_block_mark blockPtr+        if ptr == nullPtr+            then return Nothing+            else Just <$> do+                -- TODO Replace this with a more obviously best way to slurp a+                -- zero-terminated region of memory into a `Text`, given+                -- whatever the pcre2callout spec means by "zero-terminated".+                len <- fix1 0 $ \go off -> peekElemOff ptr off >>= \case+                    0 -> return off+                    _ -> go $ off + 1+                Text.fromPtr (castCUs ptr) (fromIntegral len)++    flags <- pcre2_callout_block_callout_flags blockPtr+    let calloutIsFirst = flags .&. pcre2_CALLOUT_STARTMATCH /= 0+        calloutBacktracked = flags .&. pcre2_CALLOUT_BACKTRACK /= 0++    return $ CalloutInfo {..}++-- | Within a substitution callout, marshal the original subject and+-- @pcre2_substitute_callout_block@ data to Haskell and present to the user+-- function.  Ensure no pointers are leaked!+getSubCalloutInfo+    :: Text -> Ptr Pcre2_substitute_callout_block -> IO SubCalloutInfo+getSubCalloutInfo subCalloutSubject blockPtr = do+    subCalloutSubsCount <-+        fromIntegral <$> pcre2_substitute_callout_block_subscount blockPtr++    subCalloutCaptures <- do+        ovecPtr <- pcre2_substitute_callout_block_ovector blockPtr+        ovecCount <- pcre2_substitute_callout_block_oveccount blockPtr+        forM (0 :| [1 .. fromIntegral ovecCount - 1]) $ \n -> do+            start <- peekElemOff ovecPtr $ n * 2+            if start == pcre2_UNSET+                then return Nothing+                else Just <$> do+                    end <- peekElemOff ovecPtr $ n * 2 + 1+                    return $ slice subCalloutSubject $ SliceRange+                        (fromIntegral start)+                        (fromIntegral end)++    subCalloutReplacement <- do+        outPtr <- pcre2_substitute_callout_block_output blockPtr+        offsetsPtr <- pcre2_substitute_callout_block_output_offsets blockPtr+        [start, end] <- forM [0, 1] $ peekElemOff offsetsPtr+        Text.fromPtr+            (castCUs $ advancePtr outPtr $ fromIntegral start)+            (fromIntegral $ end - start)++    return $ SubCalloutInfo {..}++-- | If there was a callout and it threw an exception, rethrow it.+maybeRethrow :: Maybe (IORef CalloutState) -> IO ()+maybeRethrow = mapM_ $ readIORef >=> mapM_ throwIO . calloutStateException++-- * Packaging @Matcher@s and @Subber@s as public API functions++-- | The most general form of a matching function, which can also be used as a+-- @Setter'@ to perform substitutions at the Haskell level.+--+-- When any capture is forced, all captures are forced in order to GC C data+-- more promptly.  When we need /some/ captures but not /all/ captures, we can+-- pass in a whitelist of the numbers of captures we want, thereby avoiding+-- unnecessary allocations.+--+-- Internal only!  Users should not (have to) know about `Matcher`.+_capturesInternal :: Matcher -> [Int] -> Traversal' Text (NonEmpty Text)+_capturesInternal matcher whitelist f subject+    | result == pcre2_ERROR_NOMATCH = pure subject+    | result <= 0                   = throw $ Pcre2Exception result+    | otherwise                     = f cs <&> \cs' ->+        -- Swag foldl-as-foldr to create only as many segments as we need to+        -- stitch back together and no more.+        let triples = ovecEntries `NE.zip` cs `NE.zip` cs'+        in Text.concat $ foldr mkSegments termSegments triples 0++    where++    (result, matchData) = unsafePerformIO $ matcher subject+    cs = unsafePerformIO $ forM ovecEntries $ evaluate . slice subject+    ovecEntries = unsafePerformIO $ getOvecEntriesAt whitelist matchData++    mkSegments ((SliceRange off offEnd, c), c') r prevOffEnd+        | off == fromIntegral pcre2_UNSET || c == c' =+            -- This substring is unset or unchanged.  Keep going without making+            -- cuts.+            r prevOffEnd+        | otherwise =+            -- Emit the subject up until here, and the new substring, and keep+            -- going, remembering where we are now.+            thinSlice subject (SliceRange prevOffEnd off) : c' : r offEnd+    termSegments off =+        let offEnd = fromIntegral $ Text.length subject+        -- If the terminal segment is empty, omit it altogether.  That way,+        -- `Text.concat` can just return the subject without copying anything in+        -- cases where no substring is changed.+        in [thinSlice subject (SliceRange off offEnd) | off /= offEnd]++-- | Strictly read specifically indexed captures' offsets from match results.+-- Truncate indexes when they go out of bounds, to support infinite lists.+getOvecEntriesAt :: [Int] -> MatchData -> IO (NonEmpty SliceRange)+getOvecEntriesAt ns matchData = withForeignPtr matchData $ \matchDataPtr -> do+    count <- fromIntegral <$> pcre2_get_ovector_count matchDataPtr++    case NE.nonEmpty $ takeWhile (< count) ns of+        Nothing -> error "BUG! Tried to get empty list of captures"+        Just ns -> do+            ovecPtr <- pcre2_get_ovector_pointer matchDataPtr++            let peekOvec :: Int -> IO Text.I16+                peekOvec = fmap fromIntegral . peekElemOff ovecPtr++            forM ns $ \n -> liftM2 SliceRange+                (peekOvec $ n * 2)+                (peekOvec $ n * 2 + 1)++-- | Helper to create non-Template Haskell API functions.  They all take options+-- and a pattern, and then do something via a 'Matcher'.+withMatcher :: (Matcher -> a) -> Option -> Text -> a+withMatcher f option patt = f $ unsafePerformIO $ assembleMatcher option patt++-- | Match a pattern to a subject and return a list of captures, or @[]@ if no+-- match.+captures :: Text -> Text -> [Text]+captures = capturesOpt mempty++-- | @capturesOpt mempty = captures@+capturesOpt :: Option -> Text -> Text -> [Text]+capturesOpt option patt = view $ _capturesOpt option patt . to NE.toList++-- | Match a pattern to a subject and return a non-empty list of captures in an+-- `Alternative`, or `empty` if no match.  The non-empty list constructor `:|`+-- serves as a cue to differentiate the 0th capture from the others:+--+-- > let parseDate = capturesA "(\\d{4})-(\\d{2})-(\\d{2})"+-- > in case parseDate "submitted 2020-10-20" of+-- >     Just (date :| [y, m, d]) -> ...+-- >     Nothing                  -> putStrLn "didn't match"+capturesA :: (Alternative f) => Text -> Text -> f (NonEmpty Text)+capturesA = capturesOptA mempty++-- | @capturesOptA mempty = capturesA@+capturesOptA :: (Alternative f) => Option -> Text -> Text -> f (NonEmpty Text)+capturesOptA option patt = toAlternativeOf $ _capturesOpt option patt++-- | Does the pattern match the subject?+matches :: Text -> Text -> Bool+matches = matchesOpt mempty++-- | @matchesOpt mempty = matches@+matchesOpt :: Option -> Text -> Text -> Bool+matchesOpt = withMatcher $ \matcher -> has $ _capturesInternal matcher []++-- | Match a pattern to a subject and return the portion that matched in an+-- @Alternative@, or `empty` if no match.+match :: (Alternative f) => Text -> Text -> f Text+match = matchOpt mempty++-- | @matchOpt mempty = match@+matchOpt :: (Alternative f) => Option -> Text -> Text -> f Text+matchOpt option patt = toAlternativeOf $ _matchOpt option patt++-- | Perform at most one substitution.  See+-- [the docs](https://pcre.org/current/doc/html/pcre2api.html#SEC36) for the+-- special syntax of /replacement/.+--+-- >>> sub "(\\w+) calling the (\\w+)" "$2 calling the $1" "the pot calling the kettle black"+-- "the kettle calling the pot black"+sub+    :: Text -- ^ pattern+    -> Text -- ^ replacement+    -> Text -- ^ subject+    -> Text -- ^ result+sub = subOpt mempty++-- | Perform substitutions globally.+--+-- >>> gsub "a" "o" "apples and bananas"+-- "opples ond bononos"+gsub :: Text -> Text -> Text -> Text+gsub = subOpt SubGlobal++-- | @+-- subOpt mempty = sub+-- subOpt SubGlobal = gsub+-- @+subOpt :: Option -> Text -> Text -> Text -> Text+subOpt option patt replacement = snd . unsafePerformIO . subber where+    subber = unsafePerformIO $ assembleSubber replacement option patt++-- | Given a pattern, produce an affine traversal (0 or 1 targets) that focuses+-- from a subject to a potential non-empty list of captures.+--+-- Substitution works in the following way:  If a capture is set such that the+-- new `Text` is not equal to the old one, a substitution occurs, otherwise it+-- doesn\'t.  This matters in cases where a capture encloses another+-- capture&#x2014;notably, /all/ parenthesized captures are enclosed by the 0th.+--+-- >>> threeAndMiddle = _captures ". (.) ."+-- >>> "A A A" & threeAndMiddle .~ "A A A" :| ["B"]+-- "A B A"+-- >>> "A A A" & threeAndMiddle .~ "A B A" :| ["A"]+-- "A B A"+--+-- Changing multiple overlapping captures won\'t do what you want and is+-- unsupported.+--+-- Changing an unset capture is unsupported because the PCRE2 match API does not+-- give location info about it.  Currently we ignore all such attempts.  (Native+-- substitution functions like `sub` do not have this limitation.  See also+-- `SubUnknownUnset` and `SubUnsetEmpty`.)+--+-- If the list becomes longer for some reason, the extra elements are ignored.+-- If it\'s shortened, the absent elements are considered to be unchanged.+--+-- It's recommended that the list be modified capture-wise,+-- using [@ix@](https://hackage.haskell.org/package/microlens/docs/Lens-Micro.html#v:ix).+--+-- > let madlibs = _captures "(\\w+) my (\\w+)"+-- >+-- > print $ "Well bust my buttons!" &~ do+-- >     zoom madlibs $ do+-- >         ix 1 . _head .= 'd'+-- >         ix 2 %= Text.reverse+-- >     _last .= '?'+-- >+-- > -- "Well dust my snottub?"+_captures :: Text -> Traversal' Text (NonEmpty Text)+_captures = _capturesOpt mempty++-- | @_capturesOpt mempty = _captures@+_capturesOpt :: Option -> Text -> Traversal' Text (NonEmpty Text)+_capturesOpt = withMatcher $ \matcher -> _capturesInternal matcher [0 ..]++-- | Given a pattern, produce an affine traversal (0 or 1 targets) that focuses+-- from a subject to the portion of it that matches.+--+-- Equivalent to @\\patt -> `_captures` patt . ix 0@, but more efficient.+_match :: Text -> Traversal' Text Text+_match = _matchOpt mempty++-- | @_matchOpt mempty = _match@+_matchOpt :: Option -> Text -> Traversal' Text Text+_matchOpt = withMatcher $ \matcher -> _capturesInternal matcher [0] . _headNE++-- * Support for Template Haskell compile-time regex analysis++-- | From options and pattern, determine parenthesized patterns\' names in+-- order.+predictCaptureNames :: Option -> Text -> IO [Maybe Text]+predictCaptureNames option patt = do+    code <- evalStateT+        (extractCompileEnv >>= extractCode patt)+        (applyOption option)++    withForeignPtr code getCaptureNames++-- | NOTE: The 0th capture is always named @Nothing@.+getCaptureNames :: Ptr Pcre2_code -> IO [Maybe Text]+getCaptureNames codePtr = do+    nameCount <- getCodeInfo @CUInt codePtr pcre2_INFO_NAMECOUNT+    nameEntrySize <- getCodeInfo @CUInt codePtr pcre2_INFO_NAMEENTRYSIZE+    nameTable <- getCodeInfo @PCRE2_SPTR codePtr pcre2_INFO_NAMETABLE++    -- Can't do [0 .. nameCount - 1] because it underflows when nameCount == 0+    let indexes = takeWhile (< nameCount) [0 ..]+    names <- fmap IM.fromList $ forM indexes $ \i -> do+        let entryPtr = nameTable `advancePtr` fromIntegral (i * nameEntrySize)+            groupNamePtr = entryPtr `advancePtr` 1+        groupNumber <- peek entryPtr+        groupNameLen <- lengthArray0 0 groupNamePtr+        groupName <- Text.fromPtr+            (castCUs groupNamePtr)+            (fromIntegral groupNameLen)+        return (fromIntegral groupNumber, groupName)++    hiCaptNum <- getCodeInfo @CUInt codePtr pcre2_INFO_CAPTURECOUNT++    return $ map (names IM.!?) [0 .. fromIntegral hiCaptNum]++-- | Low-level access to compiled pattern info, per the docs.+getCodeInfo :: (Storable a) => Ptr Pcre2_code -> CUInt -> IO a+getCodeInfo codePtr what = alloca $ \wherePtr -> do+    pcre2_pattern_info codePtr what wherePtr >>= check (== 0)+    peek wherePtr++-- | A wrapper around a list of captures that carries additional type-level+-- information about the number and names of those captures.+--+-- This type is only intended to be created by+-- `Text.Regex.Pcre2.regex`\/`Text.Regex.Pcre2._regex` and consumed by+-- `Text.Regex.Pcre2.capture`\/`Text.Regex.Pcre2._capture`, relying on type+-- inference.  Specifying the @info@ explicitly in a type signature is not+-- supported&#x2014;the definition of `CapturesInfo` is not part of the public+-- API and may change without warning.+--+-- After obtaining `Captures` it\'s recommended to immediately consume them and+-- transform them into application-level data, to avoid leaking the types to top+-- level and having to write signatures.  In times of need, \"@Captures _@\" may+-- be written with the help of @{-\# LANGUAGE PartialTypeSignatures \#-}@.+newtype Captures (info :: CapturesInfo) = Captures (NonEmpty Text)++-- | The kind of `Captures`\'s @info@.+type CapturesInfo = (Nat, [(Symbol, Nat)])++-- | Look up the number of a capture at compile time, either by number or by+-- name.  Throw a helpful 'TypeError' if the index doesn\'t exist.+type family CaptNum (i :: k) (info :: CapturesInfo) :: Nat where+    CaptNum (num :: Nat) '(hi, _) =+        If (CmpNat num 0 == 'LT || CmpNat num hi == 'GT)+            -- then+            (TypeError (TypeLits.Text "No capture numbered " :<>: ShowType num))+            -- else+            num++    CaptNum (name :: Symbol) '(_, '(name, num) ': _) = num+    CaptNum (name :: Symbol) '(hi, _ ': kvs) = 1 + CaptNum name '(hi, kvs)+    CaptNum (name :: Symbol) _ = TypeError+        (TypeLits.Text "No capture named " :<>: ShowType name)++    CaptNum _ _ = TypeError+        (TypeLits.Text "Capture index must be a number (Nat) or name (Symbol)")++-- | Safely lookup a capture in a `Captures` result obtained from a Template+-- Haskell-generated matching function.+--+-- The ugly type signature may be interpreted like this:  /Given some capture/+-- /group index @i@ and some @info@ about a regex, ensure that index exists and/+-- /is resolved to the number @num@ at compile time.  Then, at runtime, get a/+-- /capture group from a list of captures./+--+-- In practice the variable @i@ is specified by type application and the other+-- variables are inferred.+--+-- > capture @3+-- > capture @"bar"+--+-- Specifying a nonexistant number or name will result in a type error.+capture :: forall i info num. (CaptNum i info ~ num, KnownNat num) =>+    Captures info -> Text+capture = view $ _capture @i++-- | Like `capture` but focus from a `Captures` to a capture.+_capture :: forall i info num. (CaptNum i info ~ num, KnownNat num) =>+    Lens' (Captures info) Text+_capture f (Captures cs) =+    let (ls, c : rs) = NE.splitAt (fromInteger $ natVal @num Proxy) cs+    in f c <&> \c' -> Captures $ NE.fromList $ ls ++ c' : rs++-- * Exceptions++-- | The root of the PCRE2 exception hierarchy.+data SomePcre2Exception = forall e. (Exception e) => SomePcre2Exception e+instance Show SomePcre2Exception where+    show (SomePcre2Exception e) = show e+instance Exception SomePcre2Exception++-- | Vanilla PCRE2 exceptions with messages generated by the underlying C+-- library.+newtype Pcre2Exception = Pcre2Exception CInt+instance Show Pcre2Exception where+    show (Pcre2Exception x) = "pcre2: " ++ Text.unpack (getErrorMessage x)+instance Exception Pcre2Exception where+    toException = toException . SomePcre2Exception+    fromException = fromException >=> \(SomePcre2Exception e) -> cast e++-- | PCRE2 compile exceptions.  Along with a message stating the cause, we show+-- the pattern with a cursor pointing at where the error is (if not after the+-- last character).+data Pcre2CompileException = Pcre2CompileException !CInt !Text !PCRE2_SIZE+instance Show Pcre2CompileException where+    show (Pcre2CompileException x patt offset) = intercalate "\n" $ [+        "pcre2_compile: " ++ Text.unpack (getErrorMessage x),+        replicate tab ' ' ++ Text.unpack patt] +++        [replicate (tab + offset') ' ' ++ "^" | offset' < Text.length patt]+        where+        tab = 20+        offset' = fromIntegral offset+instance Exception Pcre2CompileException where+    toException = toException . SomePcre2Exception+    fromException = fromException >=> \(SomePcre2Exception e) -> cast e++-- | Built-in message corresponding to the integer error code.+getErrorMessage :: CInt -> Text+getErrorMessage errorCode = unsafePerformIO $ do+    let bufCUs = 120+    allocaBytes (bufCUs * 2) $ \bufPtr -> do+        cus <- pcre2_get_error_message errorCode bufPtr (fromIntegral bufCUs)+        Text.fromPtr (castCUs bufPtr) (fromIntegral cus)++-- | Most PCRE2 C functions return an @int@ indicating a possible error.  Test+-- it against a predicate, and throw an exception upon failure.+check :: (CInt -> Bool) -> CInt -> IO ()+check p x = unless (p x) $ throwIO $ Pcre2Exception x++-- * PCRE2 compile-time config++-- | Helper for getting PCRE2 compile-time config integers.+getConfigNumeric :: CUInt -> CUInt+getConfigNumeric what = unsafePerformIO $ alloca $ \ptr -> do+    pcre2_config what ptr+    peek ptr++-- | Helper for getting PCRE2 compile-time config strings.+getConfigString :: CUInt -> Maybe Text+getConfigString what = unsafePerformIO $ do+    len <- pcre2_config what nullPtr+    if len == pcre2_ERROR_BADOPTION+        then return Nothing+        -- FIXME Do we really need "+ 1" here?+        else allocaBytes (fromIntegral (len + 1) * 2) $ \ptr -> do+            pcre2_config what ptr+            Just <$> Text.fromPtr ptr (fromIntegral len - 1)++-- | See `Bsr`.+defaultBsr :: Bsr+defaultBsr = bsrFromC $ getConfigNumeric pcre2_CONFIG_BSR++-- | Which code widths PCRE2 is compiled to operate on.  Can be any combination+-- of 8, 16, and 32.  Should be @[16]@ but provided here for completeness.+compiledWidths :: [Int]+compiledWidths =+    let bitmap = getConfigNumeric pcre2_CONFIG_COMPILED_WIDTHS+    in [w | (b, w) <- [(1, 8), (2, 16), (4, 32)], b .&. bitmap /= 0]++-- | See `DepthLimit`.+defaultDepthLimit :: Int+defaultDepthLimit = fromIntegral $ getConfigNumeric pcre2_CONFIG_DEPTHLIMIT++-- | See `HeapLimit`.+defaultHeapLimit :: Int+defaultHeapLimit = fromIntegral $ getConfigNumeric pcre2_CONFIG_HEAPLIMIT++-- | Was PCRE2 built with JIT support?+supportsJit :: Bool+supportsJit = getConfigNumeric pcre2_CONFIG_JIT == 1++-- | A nice description of the CPU architecture JIT support is compiled for, if+-- any.+jitTarget :: Maybe Text+jitTarget = getConfigString pcre2_CONFIG_JITTARGET++-- | Number of bytes used for internal linkage in compiled regexes.+linkSize :: Int+linkSize = fromIntegral $ getConfigNumeric pcre2_CONFIG_LINKSIZE++-- | See `MatchLimit`.+defaultMatchLimit :: Int+defaultMatchLimit = fromIntegral $ getConfigNumeric pcre2_CONFIG_MATCHLIMIT++-- | See `Newline`.+defaultNewline :: Newline+defaultNewline = newlineFromC $ getConfigNumeric pcre2_CONFIG_NEWLINE++-- | See `NeverBackslashC`.+defaultIsNeverBackslashC :: Bool+defaultIsNeverBackslashC = getConfigNumeric pcre2_CONFIG_NEVER_BACKSLASH_C == 1++-- | See `ParensLimit`.+defaultParensLimit :: Int+defaultParensLimit = fromIntegral $ getConfigNumeric pcre2_CONFIG_PARENSLIMIT++-- | Size in bytes of PCRE2\'s built-in character processing tables.+defaultTablesLength :: Int+defaultTablesLength = fromIntegral $ getConfigNumeric pcre2_CONFIG_TABLES_LENGTH++-- | Unicode version string such as @8.0.0@, if Unicode is supported at all.+unicodeVersion :: Maybe Text+unicodeVersion = case getConfigString pcre2_CONFIG_UNICODE_VERSION of+    Just v | Text.unpack v == "Unicode not supported" -> Nothing+    maybeV                                            -> maybeV++-- | Was PCRE2 built with Unicode support?+supportsUnicode :: Bool+supportsUnicode = getConfigNumeric pcre2_CONFIG_UNICODE == 1++-- | Version of the built-in C library.  The versioning scheme is that PCRE+-- legacy is 8.x and PCRE2 is 10.x, so this should be @10.@/something/.+pcreVersion :: Text+pcreVersion = case getConfigString pcre2_CONFIG_VERSION of+    Just v  -> v+    Nothing -> error "pcreVersion: unable to get string"
+ src/hs/Text/Regex/Pcre2/TH.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module Text.Regex.Pcre2.TH where++import           Control.Applicative        (Alternative(..))+import           Data.IORef+import           Data.Functor               ((<&>))+import           Data.List.NonEmpty         (NonEmpty)+import qualified Data.List.NonEmpty         as NE+import           Data.Map.Lazy              (Map)+import qualified Data.Map.Lazy              as Map+import           Data.Text                  (Text)+import qualified Data.Text                  as Text+import           Language.Haskell.TH+import           Language.Haskell.TH.Quote+import           Language.Haskell.TH.Syntax+import           System.IO.Unsafe           (unsafePerformIO)+import           Text.Regex.Pcre2.Internal++globalMatcherCache :: IORef (Map Text Matcher)+globalMatcherCache = unsafePerformIO $ newIORef Map.empty++memoMatcher :: Text -> Matcher+memoMatcher patt = unsafePerformIO $ do+    cache <- readIORef globalMatcherCache+    case Map.lookup patt cache of+        Just matcher -> return matcher+        Nothing      -> do+            let matcher = unsafePerformIO $ assembleMatcher mempty patt+            atomicModifyIORef' globalMatcherCache $ \cache ->+                (Map.insert patt matcher cache, ())+            return matcher++matcherQ :: String -> ExpQ+matcherQ s = [e| memoMatcher $ Text.pack $(stringE s) |]++predictCaptureNamesQ :: String -> Q [Maybe Text]+predictCaptureNamesQ = runIO . predictCaptureNames mempty . Text.pack++toKVs :: [Maybe Text] -> [(Int, Text)]+toKVs names = [(number, name) | (number, Just name) <- zip [0 ..] names]++capturesInfoQ :: String -> Q (Maybe Type)+capturesInfoQ s = predictCaptureNamesQ s >>= \case+    -- No named captures, so need for Captures, so no info.+    [Nothing] -> return Nothing++    -- Named captures.  Present+    --     [Nothing, Just "foo", Just "bar", Nothing]+    -- as+    --     '(3, '[ '("foo", 1), '("bar", 2)]).+    captureNames -> Just <$> promotedTupleT 2 `appT` hi `appT` kvs where+        -- 3+        hi = litT $ numTyLit $ fromIntegral $ length captureNames - 1+        -- '[ '("foo", 1), '("bar", 2)]+        kvs = foldr f promotedNilT $ toKVs captureNames where+            -- '("foo", 1) ': ...+            f (number, name) = appT $ appT promotedConsT $       -- ':+                promotedTupleT 2                                 -- '(,)+                    `appT` litT (strTyLit $ Text.unpack name)    -- "foo"+                    `appT` litT (numTyLit $ fromIntegral number) -- 1++-- | /__As an expression__/+--+-- > regex :: (Alternative f) => String -> Text -> f (Captures info)+--+-- in the presence of parenthesized captures, or+--+-- > regex :: (Alternative f) => String -> Text -> f Text+--+-- if there are none.  In other words, if there is more than the 0th capture,+-- this behaves like `capturesA` (except returning an opaque `Captures` instead+-- of a list), otherwise it behaves like `match`.+--+-- To retrieve an individual capture from a `Captures`, use `capture`.+--+-- > case [regex|(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})|] "submitted 2020-10-20" of+-- >     Just cs ->+-- >         let date = capture @0 cs+-- >             year = read @Int $ Text.unpack $ capture @"y" cs+-- >             ...+--+-- > forM_ ([regex|^\s+$|] line :: Maybe Text) $ \spaces ->+-- >     error $ "line has spaces only: " ++ show spaces+--+-- /__As a pattern__/+--+-- This matches when the regex matches, whereupon any named captures are bound+-- to variables of the same names.+--+-- > case "submitted 2020-10-20" of+-- >     [regex|(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})|] ->+-- >         let year = read @Int $ Text.unpack y+-- >             ...+--+-- Note that it is not possible to access the 0th capture this way.  As a+-- workaround, explicitly capture the whole pattern and name it.+--+-- If there are no named captures, this simply acts as a guard.+regex :: QuasiQuoter+regex = QuasiQuoter {+    quoteExp = \s -> capturesInfoQ s >>= \case+        Nothing -> [e|+            let _cs = _capturesInternal $(matcherQ s) [0]+            in toAlternativeOf $ _cs . _headNE |]+        Just info -> [e|+            let wrap cs = Captures cs :: Captures $(return info)+                _cs = _capturesInternal $(matcherQ s) [0 ..]+            in toAlternativeOf $ _cs . to wrap |],++    quotePat = \s -> do+        captureNames <- predictCaptureNamesQ s++        case toKVs captureNames of+            -- No named captures.  Test whether the string matches without+            -- creating any new Text values.+            [] -> viewP+                [e| has $ _capturesInternal $(matcherQ s) [] |]+                [p| True |]++            -- One or more named captures.  Attempt to bind only those to local+            -- variables of the same names.+            numberedNames -> viewP e p where+                (nums, names) = unzip numberedNames+                e = [e|+                    let _cs = _capturesInternal $(matcherQ s) $(liftData nums)+                    in view $ _cs . to NE.toList |]+                p = listP $ map (varP . mkName . Text.unpack) names,++    quoteType = const $ fail "regex: cannot produce a type",++    quoteDec = const $ fail "regex: cannot produce declarations"}++-- | A lens variant of `regex`.  Can only be used as an expression.+--+-- > _regex :: String -> Traversal' Text (Captures info)+-- > _regex :: String -> Traversal' Text Text+--+-- > import Control.Lens+-- > import Data.Text.Lens+-- >+-- > embeddedNumber :: Traversal' String Int+-- > embeddedNumber = packed . [_regex|\d+|] . unpacked . _Show+-- >+-- > main :: IO ()+-- > main = putStrLn $ "There are 14 competing standards" & embeddedNumber %~ (+ 1)+-- >+-- > -- There are 15 competing standards+--+_regex :: QuasiQuoter+_regex = QuasiQuoter {+    quoteExp = \s -> capturesInfoQ s >>= \case+        Nothing   -> [e| _capturesInternal $(matcherQ s) [0] . _headNE |]+        Just info -> [e|+            let wrapped :: Lens' (NonEmpty Text) (Captures $(return info))+                wrapped f cs = f (Captures cs) <&> \(Captures cs') -> cs'+            in _capturesInternal $(matcherQ s) [0 ..] . wrapped |],++    quotePat = const $ fail "_regex: cannot produce a pattern",++    quoteType = const $ fail "_regex: cannot produce a type",++    quoteDec = const $ fail "_regex: cannot produce declarations"}
+ test/Spec.hs view
@@ -0,0 +1,220 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-}++module Main where++import           Control.Applicative    (Alternative)+import           Control.Exception      (catch, evaluate, handle)+import           Control.Monad.RWS.Lazy (ask, evalRWS, forM_, tell, void)+import           Data.IORef+import           Data.List.NonEmpty     (NonEmpty(..))+import           Data.Text              (Text)+import qualified Data.Text              as Text+import           Lens.Micro.Platform+import           Test.Hspec+import           Text.Regex.Pcre2++main :: IO ()+main = hspec $ do+    let submitted = "submitted 2020-10-20"++    describe "partial application" $ do+        it "only causes one compilation" $ do+            onlyCausesOneCompilation $ \option ->+                matchesOpt option "foo"++        it "only causes one compilation (point-free expression)" $ do+            onlyCausesOneCompilation $ \option ->+                (||) <$> Text.null <*> matchesOpt option "foo"++    describe "basic matching" $ do+        -- verifies that NotEmpty makes a difference, see below+        it "matches an empty pattern to an empty subject" $ do+            match "" "" `shouldBe` Just ""++        it "works using matches" $ do+            matches "(?i)foo" "FOO" `shouldBe` True++        it "works using capturesA" $ do+            case capturesA "(\\d{4})-(\\d{2})-(\\d{2})" submitted of+                Just ne -> ne `shouldBe` "2020-10-20" :| ["2020", "10", "20"]+                Nothing -> expectationFailure "didn't match"++    describe "lens-powered matching" $ do+        let _nee :: Traversal' Text Text+            _nee = _match "(?i)\\bnee\\b"+            promptNee = traverseOf (_nee . unpacked) $ \s -> tell [s] >> ask++        it "can accrete effects while performing replacements" $ do+            let result = evalRWS+                    (promptNee "We are the knights who say...NEE!")+                    "NOO"+                    undefined+            result `shouldBe` ("We are the knights who say...NOO!", ["NEE"])++        it "signals match failure by not targeting anything" $ do+            let result = evalRWS+                    (promptNee "Shhhhh")+                    undefined+                    undefined+            result `shouldBe` ("Shhhhh", [])++        it "does not substitute when setting equal Text" $ do+            let threeAndMiddle = _captures ". (.) ."+            ("A A A" & threeAndMiddle .~ "A A A" :| ["B"]) `shouldBe` "A B A"+            ("A A A" & threeAndMiddle .~ "A B A" :| ["A"]) `shouldBe` "A B A"++    describe "option handling" $ do+        it "includes compile options" $ do+            matchOpt Ungreedy "a+" "aaa" `shouldBe` Just "a"++        it "includes extra compile options" $ do+            matchOpt BadEscapeIsLiteral "\\j" "\\j" `shouldBe` Just "j"++        it "includes compile context options" $ do+            let otherBsr+                    | defaultBsr == BsrUnicode = BsrAnyCrlf+                    | otherwise                = BsrUnicode+                lineSep = "\x2028"+            matches "\\R" lineSep+                `shouldNotBe` matchesOpt (Bsr otherBsr) "\\R" lineSep++        -- We already know it includes compile recursion guards++        it "includes match options" $ do+            matchOpt NotEmpty "" "" `shouldBe` Nothing++        it "includes callouts" $ do+            calloutRanRef <- newIORef 0+            let callout = UnsafeCallout $ \_ -> do+                    modifyIORef calloutRanRef (+ 1)+                    return CalloutProceed+            matchOpt callout "(?C'foo')a(?C42)a" "aa" `shouldBe` Just "aa"+            readIORef calloutRanRef `shouldReturn` 2++        it "includes substitution callouts" $ do+            subCalloutRanRef <- newIORef 0+            let subCallout = UnsafeSubCallout $ \_ -> do+                    modifyIORef subCalloutRanRef (+ 1)+                    return SubCalloutAccept+            subOpt (subCallout <> SubGlobal) "a" "b" "aa" `shouldBe` "bb"+            readIORef subCalloutRanRef `shouldReturn` 2++        it "includes match context options" $ do+            matchOpt (OffsetLimit 10) "b" "aaaaaaaaaaab" `shouldBe` Nothing++    describe "user errors" $ do+        it "are thrown at match time" $ do+            (broken @Maybe "foo" `seq` return ())+                `shouldThrow` anyPcre2Exception++        it "are catchable using Control.Exception.evaluate" $ do+            let example = evaluate (broken "foo") `catch`+                    \(_ :: SomePcre2Exception) -> return Nothing+            example `shouldReturn` Nothing++        it "are catchable using instance Alternative IO" $ do+            let example = broken "foo" `catch`+                    \(_ :: SomePcre2Exception) -> return "broken"+            example `shouldReturn` "broken"++    describe "native substitution" $ do+        it "works using sub" $ do+            let result = sub+                    "(\\w+) calling the (\\w+)"+                    "$2 calling the $1"+                    "the pot calling the kettle black"+            result `shouldBe` "the kettle calling the pot black"++        it "works using gsub" $ do+            gsub "a" "o" "apples and bananas" `shouldBe` "opples ond bononos"++    describe "regex :: QuasiQuoter" $ do+        context "as an expression" $ do+            it "works with parenthesized captures" $ do+                case [regex|(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})|] submitted of+                    Nothing -> expectationFailure "regex didn't match"+                    Just cs -> do+                        let date = capture @0 cs+                            year = read @Int $ Text.unpack $ capture @"y" cs+                        (date, year) `shouldBe` ("2020-10-20", 2020)++            it "works without parenthesized captures" $ do+                let example = forM_ @Maybe ([regex|^\s+$|] "  ") $ \spaces ->+                        error $ "line has spaces only: " ++ show spaces+                example `shouldThrow` anyErrorCall++        context "as a pattern" $ do+            it "works with named captures" $ do+                case submitted of+                    [regex|(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})|] -> do+                        let year = read @Int $ Text.unpack y+                        year `shouldBe` 2020+                    _ -> expectationFailure "regex didn't match"++            it "works without named captures" $ do+                case "abc" of+                    [regex|a(b)c|] -> return ()+                    _              -> expectationFailure "regex didn't match"++    describe "_regex" $ do+        it "works with parenthesized captures" $ do+            -- Adapt the _captures example for use here+            let result = "Well bust my buttons!" &~ do+                    zoom [_regex|(\w+) my (\w+)|] $ do+                        _capture @1 . _head .= 'd'+                        _capture @2 %= Text.reverse+                    _last .= '?'+            result `shouldBe` "Well dust my snottub?"++        it "works without parenthesized captures" $ do+            let embeddedNumber :: Traversal' String Int+                embeddedNumber = packed . [_regex|\d+|] . unpacked . _Show+                result = "There are 14 competing standards"+                    & embeddedNumber %~ (+ 1)+            result `shouldBe` "There are 15 competing standards"++    describe "an unset capture" $ do+        it "is treated as empty" $ do+            captures "(a)?" "" `shouldBe` ["", ""]++        it "is unchanged via Traversal'" $ do+            ("" & [_regex|(a)?|] . _capture @1 .~ "foo") `shouldBe` ""++        it "permits other captures to be changed via Traversal'" $ do+            ("" & [_regex|(a)?|] . _capture @0 .~ "foo") `shouldBe` "foo"++onlyCausesOneCompilation :: (Option -> Text -> a) -> Expectation+onlyCausesOneCompilation regexWithOpt = do+    counter <- newIORef (0 :: Int)+    let option = UnsafeCompileRecGuard $ \_ -> do+            modifyIORef counter (+ 1)+            return True+        run = void . evaluate . regexWithOpt option+        getCount = readIORef counter++    run "foo"+    countAfterOnce <- getCount+    countAfterOnce `shouldSatisfy` (> 0) -- probably 2!++    run "bar"+    run "baz"+    countAfterTwiceMore <- getCount+    countAfterTwiceMore `shouldBe` countAfterOnce++anyPcre2Exception :: Selector SomePcre2Exception+anyPcre2Exception _ = True++broken :: (Alternative f) => Text -> f Text+broken = match "*"++-- microlens doesn't have this yet as of 12/5/2020+_Show :: (Read a, Show a) => Traversal' String a+_Show f s = case reads s of+    [(x, "")] -> show <$> f x+    _         -> pure s