diff --git a/seamonkey-2.53.10-mozilla-1449641.patch b/seamonkey-2.53.10-mozilla-1449641.patch deleted file mode 100644 index 2df8b6a..0000000 --- a/seamonkey-2.53.10-mozilla-1449641.patch +++ /dev/null @@ -1,38 +0,0 @@ - -# HG changeset patch -# User Markus Stange -# Date 1522257104 14400 -# Node ID cfc4cc67701f0cb1e371cfa5bea33e9f9c24a288 -# Parent 0ea578dacf239fbb31c3d6e3f6b616d6f61da263 -Bug 1449641 - Use the correct parameter when computing the clear rect. r=sotaro - -This was incorrectly using the invalid rect, so it was clearing more than -necessary and not taking advantage of the opaque region that the caller computes. -The idea is that we don't need to clear parts of the invalid region that will be -covered by something opaque. - -MozReview-Commit-ID: LhEkVUMnjC9 - -diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp ---- a/gfx/layers/basic/BasicCompositor.cpp -+++ b/gfx/layers/basic/BasicCompositor.cpp -@@ -308,17 +308,17 @@ BasicCompositor::CreateRenderTargetForWi - } else { - IntRect windowRect = rect; - // Adjust bounds rect to account for new origin at (0, 0). - if (windowRect.Size() != mDrawTarget->GetSize()) { - windowRect.ExpandToEnclose(IntPoint(0, 0)); - } - rt = new BasicCompositingRenderTarget(mDrawTarget, windowRect); - if (!aClearRect.IsEmpty()) { -- IntRect clearRect = aRect.ToUnknownRect(); -+ IntRect clearRect = aClearRect.ToUnknownRect(); - mDrawTarget->ClearRect(Rect(clearRect - rt->GetOrigin())); - } - } - - return rt.forget(); - } - - already_AddRefed - diff --git a/seamonkey-2.53.11-mozilla-1513677.patch b/seamonkey-2.53.11-mozilla-1513677.patch deleted file mode 100644 index 9b57766..0000000 --- a/seamonkey-2.53.11-mozilla-1513677.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- mozilla/netwerk/protocol/http/nsHttpHandler.cpp.orig 2022-02-15 16:26:14.697023318 +0300 -+++ mozilla/netwerk/protocol/http/nsHttpHandler.cpp 2022-02-15 16:26:21.180976404 +0300 -@@ -370,11 +370,18 @@ nsHttpHandler::EnsureUAOverridesInit() - MOZ_ASSERT(XRE_IsParentProcess()); - MOZ_ASSERT(NS_IsMainThread()); - -+ static bool initDone = false; -+ -+ if (initDone) -+ return; -+ - nsresult rv; - nsCOMPtr bootstrapper - = do_GetService("@mozilla.org/network/ua-overrides-bootstrapper;1", &rv); - MOZ_ASSERT(bootstrapper); - MOZ_ASSERT(NS_SUCCEEDED(rv)); -+ -+ initDone = true; - } - - nsHttpHandler::~nsHttpHandler() diff --git a/seamonkey-2.53.13-ffmpeg59-headers.patch b/seamonkey-2.53.13-ffmpeg59-headers.patch deleted file mode 100644 index 0357a84..0000000 --- a/seamonkey-2.53.13-ffmpeg59-headers.patch +++ /dev/null @@ -1,13751 +0,0 @@ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/COPYING.LGPLv2.1 mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/COPYING.LGPLv2.1 ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/COPYING.LGPLv2.1 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/COPYING.LGPLv2.1 2022-07-05 00:21:22.438315868 +0300 -@@ -0,0 +1,504 @@ -+ GNU LESSER GENERAL PUBLIC LICENSE -+ Version 2.1, February 1999 -+ -+ Copyright (C) 1991, 1999 Free Software Foundation, Inc. -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+[This is the first released version of the Lesser GPL. It also counts -+ as the successor of the GNU Library Public License, version 2, hence -+ the version number 2.1.] -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+Licenses are intended to guarantee your freedom to share and change -+free software--to make sure the software is free for all its users. -+ -+ This license, the Lesser General Public License, applies to some -+specially designated software packages--typically libraries--of the -+Free Software Foundation and other authors who decide to use it. You -+can use it too, but we suggest you first think carefully about whether -+this license or the ordinary General Public License is the better -+strategy to use in any particular case, based on the explanations below. -+ -+ When we speak of free software, we are referring to freedom of use, -+not price. Our General Public Licenses are designed to make sure that -+you have the freedom to distribute copies of free software (and charge -+for this service if you wish); that you receive source code or can get -+it if you want it; that you can change the software and use pieces of -+it in new free programs; and that you are informed that you can do -+these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+distributors to deny you these rights or to ask you to surrender these -+rights. These restrictions translate to certain responsibilities for -+you if you distribute copies of the library or if you modify it. -+ -+ For example, if you distribute copies of the library, whether gratis -+or for a fee, you must give the recipients all the rights that we gave -+you. You must make sure that they, too, receive or can get the source -+code. If you link other code with the library, you must provide -+complete object files to the recipients, so that they can relink them -+with the library after making changes to the library and recompiling -+it. And you must show them these terms so they know their rights. -+ -+ We protect your rights with a two-step method: (1) we copyright the -+library, and (2) we offer you this license, which gives you legal -+permission to copy, distribute and/or modify the library. -+ -+ To protect each distributor, we want to make it very clear that -+there is no warranty for the free library. Also, if the library is -+modified by someone else and passed on, the recipients should know -+that what they have is not the original version, so that the original -+author's reputation will not be affected by problems that might be -+introduced by others. -+ -+ Finally, software patents pose a constant threat to the existence of -+any free program. We wish to make sure that a company cannot -+effectively restrict the users of a free program by obtaining a -+restrictive license from a patent holder. Therefore, we insist that -+any patent license obtained for a version of the library must be -+consistent with the full freedom of use specified in this license. -+ -+ Most GNU software, including some libraries, is covered by the -+ordinary GNU General Public License. This license, the GNU Lesser -+General Public License, applies to certain designated libraries, and -+is quite different from the ordinary General Public License. We use -+this license for certain libraries in order to permit linking those -+libraries into non-free programs. -+ -+ When a program is linked with a library, whether statically or using -+a shared library, the combination of the two is legally speaking a -+combined work, a derivative of the original library. The ordinary -+General Public License therefore permits such linking only if the -+entire combination fits its criteria of freedom. The Lesser General -+Public License permits more lax criteria for linking other code with -+the library. -+ -+ We call this license the "Lesser" General Public License because it -+does Less to protect the user's freedom than the ordinary General -+Public License. It also provides other free software developers Less -+of an advantage over competing non-free programs. These disadvantages -+are the reason we use the ordinary General Public License for many -+libraries. However, the Lesser license provides advantages in certain -+special circumstances. -+ -+ For example, on rare occasions, there may be a special need to -+encourage the widest possible use of a certain library, so that it becomes -+a de-facto standard. To achieve this, non-free programs must be -+allowed to use the library. A more frequent case is that a free -+library does the same job as widely used non-free libraries. In this -+case, there is little to gain by limiting the free library to free -+software only, so we use the Lesser General Public License. -+ -+ In other cases, permission to use a particular library in non-free -+programs enables a greater number of people to use a large body of -+free software. For example, permission to use the GNU C Library in -+non-free programs enables many more people to use the whole GNU -+operating system, as well as its variant, the GNU/Linux operating -+system. -+ -+ Although the Lesser General Public License is Less protective of the -+users' freedom, it does ensure that the user of a program that is -+linked with the Library has the freedom and the wherewithal to run -+that program using a modified version of the Library. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. Pay close attention to the difference between a -+"work based on the library" and a "work that uses the library". The -+former contains code derived from the library, whereas the latter must -+be combined with the library in order to run. -+ -+ GNU LESSER GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License Agreement applies to any software library or other -+program which contains a notice placed by the copyright holder or -+other authorized party saying it may be distributed under the terms of -+this Lesser General Public License (also called "this License"). -+Each licensee is addressed as "you". -+ -+ A "library" means a collection of software functions and/or data -+prepared so as to be conveniently linked with application programs -+(which use some of those functions and data) to form executables. -+ -+ The "Library", below, refers to any such software library or work -+which has been distributed under these terms. A "work based on the -+Library" means either the Library or any derivative work under -+copyright law: that is to say, a work containing the Library or a -+portion of it, either verbatim or with modifications and/or translated -+straightforwardly into another language. (Hereinafter, translation is -+included without limitation in the term "modification".) -+ -+ "Source code" for a work means the preferred form of the work for -+making modifications to it. For a library, complete source code means -+all the source code for all modules it contains, plus any associated -+interface definition files, plus the scripts used to control compilation -+and installation of the library. -+ -+ Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running a program using the Library is not restricted, and output from -+such a program is covered only if its contents constitute a work based -+on the Library (independent of the use of the Library in a tool for -+writing it). Whether that is true depends on what the Library does -+and what the program that uses the Library does. -+ -+ 1. You may copy and distribute verbatim copies of the Library's -+complete source code as you receive it, in any medium, provided that -+you conspicuously and appropriately publish on each copy an -+appropriate copyright notice and disclaimer of warranty; keep intact -+all the notices that refer to this License and to the absence of any -+warranty; and distribute a copy of this License along with the -+Library. -+ -+ You may charge a fee for the physical act of transferring a copy, -+and you may at your option offer warranty protection in exchange for a -+fee. -+ -+ 2. You may modify your copy or copies of the Library or any portion -+of it, thus forming a work based on the Library, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) The modified work must itself be a software library. -+ -+ b) You must cause the files modified to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ c) You must cause the whole of the work to be licensed at no -+ charge to all third parties under the terms of this License. -+ -+ d) If a facility in the modified Library refers to a function or a -+ table of data to be supplied by an application program that uses -+ the facility, other than as an argument passed when the facility -+ is invoked, then you must make a good faith effort to ensure that, -+ in the event an application does not supply such function or -+ table, the facility still operates, and performs whatever part of -+ its purpose remains meaningful. -+ -+ (For example, a function in a library to compute square roots has -+ a purpose that is entirely well-defined independent of the -+ application. Therefore, Subsection 2d requires that any -+ application-supplied function or table used by this function must -+ be optional: if the application does not supply it, the square -+ root function must still compute square roots.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Library, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Library, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote -+it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Library. -+ -+In addition, mere aggregation of another work not based on the Library -+with the Library (or with a work based on the Library) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may opt to apply the terms of the ordinary GNU General Public -+License instead of this License to a given copy of the Library. To do -+this, you must alter all the notices that refer to this License, so -+that they refer to the ordinary GNU General Public License, version 2, -+instead of to this License. (If a newer version than version 2 of the -+ordinary GNU General Public License has appeared, then you can specify -+that version instead if you wish.) Do not make any other change in -+these notices. -+ -+ Once this change is made in a given copy, it is irreversible for -+that copy, so the ordinary GNU General Public License applies to all -+subsequent copies and derivative works made from that copy. -+ -+ This option is useful when you wish to copy part of the code of -+the Library into a program that is not a library. -+ -+ 4. You may copy and distribute the Library (or a portion or -+derivative of it, under Section 2) in object code or executable form -+under the terms of Sections 1 and 2 above provided that you accompany -+it with the complete corresponding machine-readable source code, which -+must be distributed under the terms of Sections 1 and 2 above on a -+medium customarily used for software interchange. -+ -+ If distribution of object code is made by offering access to copy -+from a designated place, then offering equivalent access to copy the -+source code from the same place satisfies the requirement to -+distribute the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 5. A program that contains no derivative of any portion of the -+Library, but is designed to work with the Library by being compiled or -+linked with it, is called a "work that uses the Library". Such a -+work, in isolation, is not a derivative work of the Library, and -+therefore falls outside the scope of this License. -+ -+ However, linking a "work that uses the Library" with the Library -+creates an executable that is a derivative of the Library (because it -+contains portions of the Library), rather than a "work that uses the -+library". The executable is therefore covered by this License. -+Section 6 states terms for distribution of such executables. -+ -+ When a "work that uses the Library" uses material from a header file -+that is part of the Library, the object code for the work may be a -+derivative work of the Library even though the source code is not. -+Whether this is true is especially significant if the work can be -+linked without the Library, or if the work is itself a library. The -+threshold for this to be true is not precisely defined by law. -+ -+ If such an object file uses only numerical parameters, data -+structure layouts and accessors, and small macros and small inline -+functions (ten lines or less in length), then the use of the object -+file is unrestricted, regardless of whether it is legally a derivative -+work. (Executables containing this object code plus portions of the -+Library will still fall under Section 6.) -+ -+ Otherwise, if the work is a derivative of the Library, you may -+distribute the object code for the work under the terms of Section 6. -+Any executables containing that work also fall under Section 6, -+whether or not they are linked directly with the Library itself. -+ -+ 6. As an exception to the Sections above, you may also combine or -+link a "work that uses the Library" with the Library to produce a -+work containing portions of the Library, and distribute that work -+under terms of your choice, provided that the terms permit -+modification of the work for the customer's own use and reverse -+engineering for debugging such modifications. -+ -+ You must give prominent notice with each copy of the work that the -+Library is used in it and that the Library and its use are covered by -+this License. You must supply a copy of this License. If the work -+during execution displays copyright notices, you must include the -+copyright notice for the Library among them, as well as a reference -+directing the user to the copy of this License. Also, you must do one -+of these things: -+ -+ a) Accompany the work with the complete corresponding -+ machine-readable source code for the Library including whatever -+ changes were used in the work (which must be distributed under -+ Sections 1 and 2 above); and, if the work is an executable linked -+ with the Library, with the complete machine-readable "work that -+ uses the Library", as object code and/or source code, so that the -+ user can modify the Library and then relink to produce a modified -+ executable containing the modified Library. (It is understood -+ that the user who changes the contents of definitions files in the -+ Library will not necessarily be able to recompile the application -+ to use the modified definitions.) -+ -+ b) Use a suitable shared library mechanism for linking with the -+ Library. A suitable mechanism is one that (1) uses at run time a -+ copy of the library already present on the user's computer system, -+ rather than copying library functions into the executable, and (2) -+ will operate properly with a modified version of the library, if -+ the user installs one, as long as the modified version is -+ interface-compatible with the version that the work was made with. -+ -+ c) Accompany the work with a written offer, valid for at -+ least three years, to give the same user the materials -+ specified in Subsection 6a, above, for a charge no more -+ than the cost of performing this distribution. -+ -+ d) If distribution of the work is made by offering access to copy -+ from a designated place, offer equivalent access to copy the above -+ specified materials from the same place. -+ -+ e) Verify that the user has already received a copy of these -+ materials or that you have already sent this user a copy. -+ -+ For an executable, the required form of the "work that uses the -+Library" must include any data and utility programs needed for -+reproducing the executable from it. However, as a special exception, -+the materials to be distributed need not include anything that is -+normally distributed (in either source or binary form) with the major -+components (compiler, kernel, and so on) of the operating system on -+which the executable runs, unless that component itself accompanies -+the executable. -+ -+ It may happen that this requirement contradicts the license -+restrictions of other proprietary libraries that do not normally -+accompany the operating system. Such a contradiction means you cannot -+use both them and the Library together in an executable that you -+distribute. -+ -+ 7. You may place library facilities that are a work based on the -+Library side-by-side in a single library together with other library -+facilities not covered by this License, and distribute such a combined -+library, provided that the separate distribution of the work based on -+the Library and of the other library facilities is otherwise -+permitted, and provided that you do these two things: -+ -+ a) Accompany the combined library with a copy of the same work -+ based on the Library, uncombined with any other library -+ facilities. This must be distributed under the terms of the -+ Sections above. -+ -+ b) Give prominent notice with the combined library of the fact -+ that part of it is a work based on the Library, and explaining -+ where to find the accompanying uncombined form of the same work. -+ -+ 8. You may not copy, modify, sublicense, link with, or distribute -+the Library except as expressly provided under this License. Any -+attempt otherwise to copy, modify, sublicense, link with, or -+distribute the Library is void, and will automatically terminate your -+rights under this License. However, parties who have received copies, -+or rights, from you under this License will not have their licenses -+terminated so long as such parties remain in full compliance. -+ -+ 9. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Library or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Library (or any work based on the -+Library), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Library or works based on it. -+ -+ 10. Each time you redistribute the Library (or any work based on the -+Library), the recipient automatically receives a license from the -+original licensor to copy, distribute, link with or modify the Library -+subject to these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties with -+this License. -+ -+ 11. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Library at all. For example, if a patent -+license would not permit royalty-free redistribution of the Library by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Library. -+ -+If any portion of this section is held invalid or unenforceable under any -+particular circumstance, the balance of the section is intended to apply, -+and the section as a whole is intended to apply in other circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 12. If the distribution and/or use of the Library is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Library under this License may add -+an explicit geographical distribution limitation excluding those countries, -+so that distribution is permitted only in or among countries not thus -+excluded. In such case, this License incorporates the limitation as if -+written in the body of this License. -+ -+ 13. The Free Software Foundation may publish revised and/or new -+versions of the Lesser General Public License from time to time. -+Such new versions will be similar in spirit to the present version, -+but may differ in detail to address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Library -+specifies a version number of this License which applies to it and -+"any later version", you have the option of following the terms and -+conditions either of that version or of any later version published by -+the Free Software Foundation. If the Library does not specify a -+license version number, you may choose any version ever published by -+the Free Software Foundation. -+ -+ 14. If you wish to incorporate parts of the Library into other free -+programs whose distribution conditions are incompatible with these, -+write to the author to ask for permission. For software which is -+copyrighted by the Free Software Foundation, write to the Free -+Software Foundation; we sometimes make exceptions for this. Our -+decision will be guided by the two goals of preserving the free status -+of all derivatives of our free software and of promoting the sharing -+and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. -+ -+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -+DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Libraries -+ -+ If you develop a new library, and you want it to be of the greatest -+possible use to the public, we recommend making it free software that -+everyone can redistribute and change. You can do so by permitting -+redistribution under these terms (or, alternatively, under the terms of the -+ordinary General Public License). -+ -+ To apply these terms, attach the following notices to the library. It is -+safest to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least the -+"copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ This library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with this library; if not, write to the Free Software -+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the library, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the -+ library `Frob' (a library for tweaking knobs) written by James Random Hacker. -+ -+ , 1 April 1990 -+ Ty Coon, President of Vice -+ -+That's all there is to it! -+ -+ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avcodec.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avcodec.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avcodec.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avcodec.h 2022-07-05 00:21:22.440315856 +0300 -@@ -0,0 +1,3204 @@ -+/* -+ * copyright (c) 2001 Fabrice Bellard -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_AVCODEC_H -+#define AVCODEC_AVCODEC_H -+ -+/** -+ * @file -+ * @ingroup libavc -+ * Libavcodec external API header -+ */ -+ -+#include "libavutil/samplefmt.h" -+#include "libavutil/attributes.h" -+#include "libavutil/avutil.h" -+#include "libavutil/buffer.h" -+#include "libavutil/dict.h" -+#include "libavutil/frame.h" -+#include "libavutil/log.h" -+#include "libavutil/pixfmt.h" -+#include "libavutil/rational.h" -+ -+#include "codec.h" -+#include "codec_desc.h" -+#include "codec_par.h" -+#include "codec_id.h" -+#include "defs.h" -+#include "packet.h" -+#include "version.h" -+ -+/** -+ * @defgroup libavc libavcodec -+ * Encoding/Decoding Library -+ * -+ * @{ -+ * -+ * @defgroup lavc_decoding Decoding -+ * @{ -+ * @} -+ * -+ * @defgroup lavc_encoding Encoding -+ * @{ -+ * @} -+ * -+ * @defgroup lavc_codec Codecs -+ * @{ -+ * @defgroup lavc_codec_native Native Codecs -+ * @{ -+ * @} -+ * @defgroup lavc_codec_wrappers External library wrappers -+ * @{ -+ * @} -+ * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge -+ * @{ -+ * @} -+ * @} -+ * @defgroup lavc_internal Internal -+ * @{ -+ * @} -+ * @} -+ */ -+ -+/** -+ * @ingroup libavc -+ * @defgroup lavc_encdec send/receive encoding and decoding API overview -+ * @{ -+ * -+ * The avcodec_send_packet()/avcodec_receive_frame()/avcodec_send_frame()/ -+ * avcodec_receive_packet() functions provide an encode/decode API, which -+ * decouples input and output. -+ * -+ * The API is very similar for encoding/decoding and audio/video, and works as -+ * follows: -+ * - Set up and open the AVCodecContext as usual. -+ * - Send valid input: -+ * - For decoding, call avcodec_send_packet() to give the decoder raw -+ * compressed data in an AVPacket. -+ * - For encoding, call avcodec_send_frame() to give the encoder an AVFrame -+ * containing uncompressed audio or video. -+ * -+ * In both cases, it is recommended that AVPackets and AVFrames are -+ * refcounted, or libavcodec might have to copy the input data. (libavformat -+ * always returns refcounted AVPackets, and av_frame_get_buffer() allocates -+ * refcounted AVFrames.) -+ * - Receive output in a loop. Periodically call one of the avcodec_receive_*() -+ * functions and process their output: -+ * - For decoding, call avcodec_receive_frame(). On success, it will return -+ * an AVFrame containing uncompressed audio or video data. -+ * - For encoding, call avcodec_receive_packet(). On success, it will return -+ * an AVPacket with a compressed frame. -+ * -+ * Repeat this call until it returns AVERROR(EAGAIN) or an error. The -+ * AVERROR(EAGAIN) return value means that new input data is required to -+ * return new output. In this case, continue with sending input. For each -+ * input frame/packet, the codec will typically return 1 output frame/packet, -+ * but it can also be 0 or more than 1. -+ * -+ * At the beginning of decoding or encoding, the codec might accept multiple -+ * input frames/packets without returning a frame, until its internal buffers -+ * are filled. This situation is handled transparently if you follow the steps -+ * outlined above. -+ * -+ * In theory, sending input can result in EAGAIN - this should happen only if -+ * not all output was received. You can use this to structure alternative decode -+ * or encode loops other than the one suggested above. For example, you could -+ * try sending new input on each iteration, and try to receive output if that -+ * returns EAGAIN. -+ * -+ * End of stream situations. These require "flushing" (aka draining) the codec, -+ * as the codec might buffer multiple frames or packets internally for -+ * performance or out of necessity (consider B-frames). -+ * This is handled as follows: -+ * - Instead of valid input, send NULL to the avcodec_send_packet() (decoding) -+ * or avcodec_send_frame() (encoding) functions. This will enter draining -+ * mode. -+ * - Call avcodec_receive_frame() (decoding) or avcodec_receive_packet() -+ * (encoding) in a loop until AVERROR_EOF is returned. The functions will -+ * not return AVERROR(EAGAIN), unless you forgot to enter draining mode. -+ * - Before decoding can be resumed again, the codec has to be reset with -+ * avcodec_flush_buffers(). -+ * -+ * Using the API as outlined above is highly recommended. But it is also -+ * possible to call functions outside of this rigid schema. For example, you can -+ * call avcodec_send_packet() repeatedly without calling -+ * avcodec_receive_frame(). In this case, avcodec_send_packet() will succeed -+ * until the codec's internal buffer has been filled up (which is typically of -+ * size 1 per output frame, after initial input), and then reject input with -+ * AVERROR(EAGAIN). Once it starts rejecting input, you have no choice but to -+ * read at least some output. -+ * -+ * Not all codecs will follow a rigid and predictable dataflow; the only -+ * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on -+ * one end implies that a receive/send call on the other end will succeed, or -+ * at least will not fail with AVERROR(EAGAIN). In general, no codec will -+ * permit unlimited buffering of input or output. -+ * -+ * A codec is not allowed to return AVERROR(EAGAIN) for both sending and -+ * receiving. This would be an invalid state, which could put the codec user -+ * into an endless loop. The API has no concept of time either: it cannot happen -+ * that trying to do avcodec_send_packet() results in AVERROR(EAGAIN), but a -+ * repeated call 1 second later accepts the packet (with no other receive/flush -+ * API calls involved). The API is a strict state machine, and the passage of -+ * time is not supposed to influence it. Some timing-dependent behavior might -+ * still be deemed acceptable in certain cases. But it must never result in both -+ * send/receive returning EAGAIN at the same time at any point. It must also -+ * absolutely be avoided that the current state is "unstable" and can -+ * "flip-flop" between the send/receive APIs allowing progress. For example, -+ * it's not allowed that the codec randomly decides that it actually wants to -+ * consume a packet now instead of returning a frame, after it just returned -+ * AVERROR(EAGAIN) on an avcodec_send_packet() call. -+ * @} -+ */ -+ -+/** -+ * @defgroup lavc_core Core functions/structures. -+ * @ingroup libavc -+ * -+ * Basic definitions, functions for querying libavcodec capabilities, -+ * allocating core structures, etc. -+ * @{ -+ */ -+ -+/** -+ * @ingroup lavc_encoding -+ * minimum encoding buffer size -+ * Used to avoid some checks during header writing. -+ */ -+#define AV_INPUT_BUFFER_MIN_SIZE 16384 -+ -+/** -+ * @ingroup lavc_encoding -+ */ -+typedef struct RcOverride { -+ int start_frame; -+ int end_frame; -+ int qscale; // If this is 0 then quality_factor will be used instead. -+ float quality_factor; -+} RcOverride; -+ -+/* encoding support -+ These flags can be passed in AVCodecContext.flags before initialization. -+ Note: Not everything is supported yet. -+*/ -+ -+/** -+ * Allow decoders to produce frames with data planes that are not aligned -+ * to CPU requirements (e.g. due to cropping). -+ */ -+#define AV_CODEC_FLAG_UNALIGNED (1 << 0) -+/** -+ * Use fixed qscale. -+ */ -+#define AV_CODEC_FLAG_QSCALE (1 << 1) -+/** -+ * 4 MV per MB allowed / advanced prediction for H.263. -+ */ -+#define AV_CODEC_FLAG_4MV (1 << 2) -+/** -+ * Output even those frames that might be corrupted. -+ */ -+#define AV_CODEC_FLAG_OUTPUT_CORRUPT (1 << 3) -+/** -+ * Use qpel MC. -+ */ -+#define AV_CODEC_FLAG_QPEL (1 << 4) -+/** -+ * Don't output frames whose parameters differ from first -+ * decoded frame in stream. -+ */ -+#define AV_CODEC_FLAG_DROPCHANGED (1 << 5) -+/** -+ * Use internal 2pass ratecontrol in first pass mode. -+ */ -+#define AV_CODEC_FLAG_PASS1 (1 << 9) -+/** -+ * Use internal 2pass ratecontrol in second pass mode. -+ */ -+#define AV_CODEC_FLAG_PASS2 (1 << 10) -+/** -+ * loop filter. -+ */ -+#define AV_CODEC_FLAG_LOOP_FILTER (1 << 11) -+/** -+ * Only decode/encode grayscale. -+ */ -+#define AV_CODEC_FLAG_GRAY (1 << 13) -+/** -+ * error[?] variables will be set during encoding. -+ */ -+#define AV_CODEC_FLAG_PSNR (1 << 15) -+#if FF_API_FLAG_TRUNCATED -+/** -+ * Input bitstream might be truncated at a random location -+ * instead of only at frame boundaries. -+ * -+ * @deprecated use codec parsers for packetizing input -+ */ -+# define AV_CODEC_FLAG_TRUNCATED (1 << 16) -+#endif -+/** -+ * Use interlaced DCT. -+ */ -+#define AV_CODEC_FLAG_INTERLACED_DCT (1 << 18) -+/** -+ * Force low delay. -+ */ -+#define AV_CODEC_FLAG_LOW_DELAY (1 << 19) -+/** -+ * Place global headers in extradata instead of every keyframe. -+ */ -+#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) -+/** -+ * Use only bitexact stuff (except (I)DCT). -+ */ -+#define AV_CODEC_FLAG_BITEXACT (1 << 23) -+/* Fx : Flag for H.263+ extra options */ -+/** -+ * H.263 advanced intra coding / MPEG-4 AC prediction -+ */ -+#define AV_CODEC_FLAG_AC_PRED (1 << 24) -+/** -+ * interlaced motion estimation -+ */ -+#define AV_CODEC_FLAG_INTERLACED_ME (1 << 29) -+#define AV_CODEC_FLAG_CLOSED_GOP (1U << 31) -+ -+/** -+ * Allow non spec compliant speedup tricks. -+ */ -+#define AV_CODEC_FLAG2_FAST (1 << 0) -+/** -+ * Skip bitstream encoding. -+ */ -+#define AV_CODEC_FLAG2_NO_OUTPUT (1 << 2) -+/** -+ * Place global headers at every keyframe instead of in extradata. -+ */ -+#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3) -+ -+/** -+ * timecode is in drop frame format. DEPRECATED!!!! -+ */ -+#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13) -+ -+/** -+ * Input bitstream might be truncated at a packet boundaries -+ * instead of only at frame boundaries. -+ */ -+#define AV_CODEC_FLAG2_CHUNKS (1 << 15) -+/** -+ * Discard cropping information from SPS. -+ */ -+#define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16) -+ -+/** -+ * Show all frames before the first keyframe -+ */ -+#define AV_CODEC_FLAG2_SHOW_ALL (1 << 22) -+/** -+ * Export motion vectors through frame side data -+ */ -+#define AV_CODEC_FLAG2_EXPORT_MVS (1 << 28) -+/** -+ * Do not skip samples and export skip information as frame side data -+ */ -+#define AV_CODEC_FLAG2_SKIP_MANUAL (1 << 29) -+/** -+ * Do not reset ASS ReadOrder field on flush (subtitles decoding) -+ */ -+#define AV_CODEC_FLAG2_RO_FLUSH_NOOP (1 << 30) -+ -+/* Unsupported options : -+ * Syntax Arithmetic coding (SAC) -+ * Reference Picture Selection -+ * Independent Segment Decoding */ -+/* /Fx */ -+/* codec capabilities */ -+ -+/* Exported side data. -+ These flags can be passed in AVCodecContext.export_side_data before -+ initialization. -+*/ -+/** -+ * Export motion vectors through frame side data -+ */ -+#define AV_CODEC_EXPORT_DATA_MVS (1 << 0) -+/** -+ * Export encoder Producer Reference Time through packet side data -+ */ -+#define AV_CODEC_EXPORT_DATA_PRFT (1 << 1) -+/** -+ * Decoding only. -+ * Export the AVVideoEncParams structure through frame side data. -+ */ -+#define AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS (1 << 2) -+/** -+ * Decoding only. -+ * Do not apply film grain, export it instead. -+ */ -+#define AV_CODEC_EXPORT_DATA_FILM_GRAIN (1 << 3) -+ -+/** -+ * The decoder will keep a reference to the frame and may reuse it later. -+ */ -+#define AV_GET_BUFFER_FLAG_REF (1 << 0) -+ -+/** -+ * The encoder will keep a reference to the packet and may reuse it later. -+ */ -+#define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0) -+ -+struct AVCodecInternal; -+ -+/** -+ * main external API structure. -+ * New fields can be added to the end with minor version bumps. -+ * Removal, reordering and changes to existing fields require a major -+ * version bump. -+ * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from -+ * user applications. The name string for AVOptions options matches the -+ * associated command line parameter name and can be found in -+ * libavcodec/options_table.h The AVOption/command line parameter names differ -+ * in some cases from the C structure field names for historic reasons or -+ * brevity. sizeof(AVCodecContext) must not be used outside libav*. -+ */ -+typedef struct AVCodecContext { -+ /** -+ * information on struct for av_log -+ * - set by avcodec_alloc_context3 -+ */ -+ const AVClass* av_class; -+ int log_level_offset; -+ -+ enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ -+ const struct AVCodec* codec; -+ enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ -+ -+ /** -+ * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). -+ * This is used to work around some encoder bugs. -+ * A demuxer should set this to what is stored in the field used to identify -+ * the codec. If there are multiple such fields in a container then the -+ * demuxer should choose the one which maximizes the information about the -+ * used codec. If the codec tag field in a container is larger than 32 bits -+ * then the demuxer should remap the longer ID to 32 bits with a table or -+ * other structure. Alternatively a new extra_codec_tag + size could be added -+ * but for this a clear advantage must be demonstrated first. -+ * - encoding: Set by user, if not then the default based on codec_id will be -+ * used. -+ * - decoding: Set by user, will be converted to uppercase by libavcodec -+ * during init. -+ */ -+ unsigned int codec_tag; -+ -+ void* priv_data; -+ -+ /** -+ * Private context used for internal data. -+ * -+ * Unlike priv_data, this is not codec-specific. It is used in general -+ * libavcodec functions. -+ */ -+ struct AVCodecInternal* internal; -+ -+ /** -+ * Private data of the user, can be used to carry app specific stuff. -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ void* opaque; -+ -+ /** -+ * the average bitrate -+ * - encoding: Set by user; unused for constant quantizer encoding. -+ * - decoding: Set by user, may be overwritten by libavcodec -+ * if this info is available in the stream -+ */ -+ int64_t bit_rate; -+ -+ /** -+ * number of bits the bitstream is allowed to diverge from the reference. -+ * the reference can be CBR (for CBR pass1) or VBR (for pass2) -+ * - encoding: Set by user; unused for constant quantizer encoding. -+ * - decoding: unused -+ */ -+ int bit_rate_tolerance; -+ -+ /** -+ * Global quality for codecs which cannot change it per frame. -+ * This should be proportional to MPEG-1/2/4 qscale. -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int global_quality; -+ -+ /** -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int compression_level; -+#define FF_COMPRESSION_DEFAULT -1 -+ -+ /** -+ * AV_CODEC_FLAG_*. -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ int flags; -+ -+ /** -+ * AV_CODEC_FLAG2_* -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ int flags2; -+ -+ /** -+ * some codecs need / can use extradata like Huffman tables. -+ * MJPEG: Huffman tables -+ * rv10: additional flags -+ * MPEG-4: global headers (they can be in the bitstream or here) -+ * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger -+ * than extradata_size to avoid problems if it is read with the bitstream -+ * reader. The bytewise contents of extradata must not depend on the -+ * architecture or CPU endianness. Must be allocated with the av_malloc() -+ * family of functions. -+ * - encoding: Set/allocated/freed by libavcodec. -+ * - decoding: Set/allocated/freed by user. -+ */ -+ uint8_t* extradata; -+ int extradata_size; -+ -+ /** -+ * This is the fundamental unit of time (in seconds) in terms -+ * of which frame timestamps are represented. For fixed-fps content, -+ * timebase should be 1/framerate and timestamp increments should be -+ * identically 1. -+ * This often, but not always is the inverse of the frame rate or field rate -+ * for video. 1/time_base is not the average frame rate if the frame rate is -+ * not constant. -+ * -+ * Like containers, elementary streams also can store timestamps, 1/time_base -+ * is the unit in which these timestamps are specified. -+ * As example of such codec time base see ISO/IEC 14496-2:2001(E) -+ * vop_time_increment_resolution and fixed_vop_rate -+ * (fixed_vop_rate == 0 implies that it is different from the framerate) -+ * -+ * - encoding: MUST be set by user. -+ * - decoding: the use of this field for decoding is deprecated. -+ * Use framerate instead. -+ */ -+ AVRational time_base; -+ -+ /** -+ * For some codecs, the time base is closer to the field rate than the frame -+ * rate. Most notably, H.264 and MPEG-2 specify time_base as half of frame -+ * duration if no telecine is used ... -+ * -+ * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it -+ * to 2. -+ */ -+ int ticks_per_frame; -+ -+ /** -+ * Codec delay. -+ * -+ * Encoding: Number of frames delay there will be from the encoder input to -+ * the decoder output. (we assume the decoder matches the spec) -+ * Decoding: Number of frames delay in addition to what a standard decoder -+ * as specified in the spec would produce. -+ * -+ * Video: -+ * Number of frames the decoded output will be delayed relative to the -+ * encoded input. -+ * -+ * Audio: -+ * For encoding, this field is unused (see initial_padding). -+ * -+ * For decoding, this is the number of samples the decoder needs to -+ * output before the decoder's output is valid. When seeking, you should -+ * start decoding this many samples prior to your desired seek point. -+ * -+ * - encoding: Set by libavcodec. -+ * - decoding: Set by libavcodec. -+ */ -+ int delay; -+ -+ /* video only */ -+ /** -+ * picture width / height. -+ * -+ * @note Those fields may not match the values of the last -+ * AVFrame output by avcodec_receive_frame() due frame -+ * reordering. -+ * -+ * - encoding: MUST be set by user. -+ * - decoding: May be set by the user before opening the decoder if known e.g. -+ * from the container. Some decoders will require the dimensions -+ * to be set by the caller. During decoding, the decoder may -+ * overwrite those values as required while parsing the data. -+ */ -+ int width, height; -+ -+ /** -+ * Bitstream width / height, may be different from width/height e.g. when -+ * the decoded frame is cropped before being output or lowres is enabled. -+ * -+ * @note Those field may not match the value of the last -+ * AVFrame output by avcodec_receive_frame() due frame -+ * reordering. -+ * -+ * - encoding: unused -+ * - decoding: May be set by the user before opening the decoder if known -+ * e.g. from the container. During decoding, the decoder may -+ * overwrite those values as required while parsing the data. -+ */ -+ int coded_width, coded_height; -+ -+ /** -+ * the number of pictures in a group of pictures, or 0 for intra_only -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int gop_size; -+ -+ /** -+ * Pixel format, see AV_PIX_FMT_xxx. -+ * May be set by the demuxer if known from headers. -+ * May be overridden by the decoder if it knows better. -+ * -+ * @note This field may not match the value of the last -+ * AVFrame output by avcodec_receive_frame() due frame -+ * reordering. -+ * -+ * - encoding: Set by user. -+ * - decoding: Set by user if known, overridden by libavcodec while -+ * parsing the data. -+ */ -+ enum AVPixelFormat pix_fmt; -+ -+ /** -+ * If non NULL, 'draw_horiz_band' is called by the libavcodec -+ * decoder to draw a horizontal band. It improves cache usage. Not -+ * all codecs can do that. You must check the codec capabilities -+ * beforehand. -+ * When multithreading is used, it may be called from multiple threads -+ * at the same time; threads might draw different parts of the same AVFrame, -+ * or multiple AVFrames, and there is no guarantee that slices will be drawn -+ * in order. -+ * The function is also used by hardware acceleration APIs. -+ * It is called at least once during frame decoding to pass -+ * the data needed for hardware render. -+ * In that mode instead of pixel data, AVFrame points to -+ * a structure specific to the acceleration API. The application -+ * reads the structure and can change some fields to indicate progress -+ * or mark state. -+ * - encoding: unused -+ * - decoding: Set by user. -+ * @param height the height of the slice -+ * @param y the y position of the slice -+ * @param type 1->top field, 2->bottom field, 3->frame -+ * @param offset offset into the AVFrame.data from which the slice should be -+ * read -+ */ -+ void (*draw_horiz_band)(struct AVCodecContext* s, const AVFrame* src, -+ int offset[AV_NUM_DATA_POINTERS], int y, int type, -+ int height); -+ -+ /** -+ * Callback to negotiate the pixel format. Decoding only, may be set by the -+ * caller before avcodec_open2(). -+ * -+ * Called by some decoders to select the pixel format that will be used for -+ * the output frames. This is mainly used to set up hardware acceleration, -+ * then the provided format list contains the corresponding hwaccel pixel -+ * formats alongside the "software" one. The software pixel format may also -+ * be retrieved from \ref sw_pix_fmt. -+ * -+ * This callback will be called when the coded frame properties (such as -+ * resolution, pixel format, etc.) change and more than one output format is -+ * supported for those new properties. If a hardware pixel format is chosen -+ * and initialization for it fails, the callback may be called again -+ * immediately. -+ * -+ * This callback may be called from different threads if the decoder is -+ * multi-threaded, but not from more than one thread simultaneously. -+ * -+ * @param fmt list of formats which may be used in the current -+ * configuration, terminated by AV_PIX_FMT_NONE. -+ * @warning Behavior is undefined if the callback returns a value other -+ * than one of the formats in fmt or AV_PIX_FMT_NONE. -+ * @return the chosen format or AV_PIX_FMT_NONE -+ */ -+ enum AVPixelFormat (*get_format)(struct AVCodecContext* s, -+ const enum AVPixelFormat* fmt); -+ -+ /** -+ * maximum number of B-frames between non-B-frames -+ * Note: The output will be delayed by max_b_frames+1 relative to the input. -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int max_b_frames; -+ -+ /** -+ * qscale factor between IP and B-frames -+ * If > 0 then the last P-frame quantizer will be used (q= -+ * lastp_q*factor+offset). If < 0 then normal ratecontrol will be done (q= -+ * -normal_q*factor+offset). -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float b_quant_factor; -+ -+ /** -+ * qscale offset between IP and B-frames -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float b_quant_offset; -+ -+ /** -+ * Size of the frame reordering buffer in the decoder. -+ * For MPEG-2 it is 1 IPB or 0 low delay IP. -+ * - encoding: Set by libavcodec. -+ * - decoding: Set by libavcodec. -+ */ -+ int has_b_frames; -+ -+ /** -+ * qscale factor between P- and I-frames -+ * If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + -+ * offset). If < 0 then normal ratecontrol will be done (q= -+ * -normal_q*factor+offset). -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float i_quant_factor; -+ -+ /** -+ * qscale offset between P and I-frames -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float i_quant_offset; -+ -+ /** -+ * luminance masking (0-> disabled) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float lumi_masking; -+ -+ /** -+ * temporary complexity masking (0-> disabled) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float temporal_cplx_masking; -+ -+ /** -+ * spatial complexity masking (0-> disabled) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float spatial_cplx_masking; -+ -+ /** -+ * p block masking (0-> disabled) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float p_masking; -+ -+ /** -+ * darkness masking (0-> disabled) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ float dark_masking; -+ -+ /** -+ * slice count -+ * - encoding: Set by libavcodec. -+ * - decoding: Set by user (or 0). -+ */ -+ int slice_count; -+ -+ /** -+ * slice offsets in the frame in bytes -+ * - encoding: Set/allocated by libavcodec. -+ * - decoding: Set/allocated by user (or NULL). -+ */ -+ int* slice_offset; -+ -+ /** -+ * sample aspect ratio (0 if unknown) -+ * That is the width of a pixel divided by the height of the pixel. -+ * Numerator and denominator must be relatively prime and smaller than 256 for -+ * some video standards. -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ AVRational sample_aspect_ratio; -+ -+ /** -+ * motion estimation comparison function -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int me_cmp; -+ /** -+ * subpixel motion estimation comparison function -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int me_sub_cmp; -+ /** -+ * macroblock comparison function (not supported yet) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int mb_cmp; -+ /** -+ * interlaced DCT comparison function -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int ildct_cmp; -+#define FF_CMP_SAD 0 -+#define FF_CMP_SSE 1 -+#define FF_CMP_SATD 2 -+#define FF_CMP_DCT 3 -+#define FF_CMP_PSNR 4 -+#define FF_CMP_BIT 5 -+#define FF_CMP_RD 6 -+#define FF_CMP_ZERO 7 -+#define FF_CMP_VSAD 8 -+#define FF_CMP_VSSE 9 -+#define FF_CMP_NSSE 10 -+#define FF_CMP_W53 11 -+#define FF_CMP_W97 12 -+#define FF_CMP_DCTMAX 13 -+#define FF_CMP_DCT264 14 -+#define FF_CMP_MEDIAN_SAD 15 -+#define FF_CMP_CHROMA 256 -+ -+ /** -+ * ME diamond size & shape -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int dia_size; -+ -+ /** -+ * amount of previous MV predictors (2a+1 x 2a+1 square) -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int last_predictor_count; -+ -+ /** -+ * motion estimation prepass comparison function -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int me_pre_cmp; -+ -+ /** -+ * ME prepass diamond size & shape -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int pre_dia_size; -+ -+ /** -+ * subpel ME quality -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int me_subpel_quality; -+ -+ /** -+ * maximum motion estimation search range in subpel units -+ * If 0 then no limit. -+ * -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int me_range; -+ -+ /** -+ * slice flags -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ int slice_flags; -+#define SLICE_FLAG_CODED_ORDER \ -+ 0x0001 ///< draw_horiz_band() is called in coded order instead of display -+#define SLICE_FLAG_ALLOW_FIELD \ -+ 0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics) -+#define SLICE_FLAG_ALLOW_PLANE \ -+ 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) -+ -+ /** -+ * macroblock decision mode -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int mb_decision; -+#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp -+#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits -+#define FF_MB_DECISION_RD 2 ///< rate distortion -+ -+ /** -+ * custom intra quantization matrix -+ * Must be allocated with the av_malloc() family of functions, and will be -+ * freed in avcodec_free_context(). -+ * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. -+ * - decoding: Set/allocated/freed by libavcodec. -+ */ -+ uint16_t* intra_matrix; -+ -+ /** -+ * custom inter quantization matrix -+ * Must be allocated with the av_malloc() family of functions, and will be -+ * freed in avcodec_free_context(). -+ * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. -+ * - decoding: Set/allocated/freed by libavcodec. -+ */ -+ uint16_t* inter_matrix; -+ -+ /** -+ * precision of the intra DC coefficient - 8 -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec -+ */ -+ int intra_dc_precision; -+ -+ /** -+ * Number of macroblock rows at the top which are skipped. -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ int skip_top; -+ -+ /** -+ * Number of macroblock rows at the bottom which are skipped. -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ int skip_bottom; -+ -+ /** -+ * minimum MB Lagrange multiplier -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int mb_lmin; -+ -+ /** -+ * maximum MB Lagrange multiplier -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int mb_lmax; -+ -+ /** -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int bidir_refine; -+ -+ /** -+ * minimum GOP size -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int keyint_min; -+ -+ /** -+ * number of reference frames -+ * - encoding: Set by user. -+ * - decoding: Set by lavc. -+ */ -+ int refs; -+ -+ /** -+ * Note: Value depends upon the compare function used for fullpel ME. -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int mv0_threshold; -+ -+ /** -+ * Chromaticity coordinates of the source primaries. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVColorPrimaries color_primaries; -+ -+ /** -+ * Color Transfer Characteristic. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVColorTransferCharacteristic color_trc; -+ -+ /** -+ * YUV colorspace type. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVColorSpace colorspace; -+ -+ /** -+ * MPEG vs JPEG YUV range. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVColorRange color_range; -+ -+ /** -+ * This defines the location of chroma samples. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVChromaLocation chroma_sample_location; -+ -+ /** -+ * Number of slices. -+ * Indicates number of picture subdivisions. Used for parallelized -+ * decoding. -+ * - encoding: Set by user -+ * - decoding: unused -+ */ -+ int slices; -+ -+ /** Field order -+ * - encoding: set by libavcodec -+ * - decoding: Set by user. -+ */ -+ enum AVFieldOrder field_order; -+ -+ /* audio only */ -+ int sample_rate; ///< samples per second -+ int channels; ///< number of audio channels -+ -+ /** -+ * audio sample format -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ enum AVSampleFormat sample_fmt; ///< sample format -+ -+ /* The following data should not be initialized. */ -+ /** -+ * Number of samples per channel in an audio frame. -+ * -+ * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame -+ * except the last must contain exactly frame_size samples per channel. -+ * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then -+ * the frame size is not restricted. -+ * - decoding: may be set by some decoders to indicate constant frame size -+ */ -+ int frame_size; -+ -+ /** -+ * Frame counter, set by libavcodec. -+ * -+ * - decoding: total number of frames returned from the decoder so far. -+ * - encoding: total number of frames passed to the encoder so far. -+ * -+ * @note the counter is not incremented if encoding/decoding resulted in -+ * an error. -+ */ -+ int frame_number; -+ -+ /** -+ * number of bytes per packet if constant and known or 0 -+ * Used by some WAV based audio codecs. -+ */ -+ int block_align; -+ -+ /** -+ * Audio cutoff bandwidth (0 means "automatic") -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int cutoff; -+ -+ /** -+ * Audio channel layout. -+ * - encoding: set by user. -+ * - decoding: set by user, may be overwritten by libavcodec. -+ */ -+ uint64_t channel_layout; -+ -+ /** -+ * Request decoder to use this channel layout if it can (0 for default) -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ uint64_t request_channel_layout; -+ -+ /** -+ * Type of service that the audio stream conveys. -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ enum AVAudioServiceType audio_service_type; -+ -+ /** -+ * desired sample format -+ * - encoding: Not used. -+ * - decoding: Set by user. -+ * Decoder will decode to this format if it can. -+ */ -+ enum AVSampleFormat request_sample_fmt; -+ -+ /** -+ * This callback is called at the beginning of each frame to get data -+ * buffer(s) for it. There may be one contiguous buffer for all the data or -+ * there may be a buffer per each data plane or anything in between. What -+ * this means is, you may set however many entries in buf[] you feel -+ * necessary. Each buffer must be reference-counted using the AVBuffer API -+ * (see description of buf[] below). -+ * -+ * The following fields will be set in the frame before this callback is -+ * called: -+ * - format -+ * - width, height (video only) -+ * - sample_rate, channel_layout, nb_samples (audio only) -+ * Their values may differ from the corresponding values in -+ * AVCodecContext. This callback must use the frame values, not the codec -+ * context values, to calculate the required buffer size. -+ * -+ * This callback must fill the following fields in the frame: -+ * - data[] -+ * - linesize[] -+ * - extended_data: -+ * * if the data is planar audio with more than 8 channels, then this -+ * callback must allocate and fill extended_data to contain all pointers -+ * to all data planes. data[] must hold as many pointers as it can. -+ * extended_data must be allocated with av_malloc() and will be freed in -+ * av_frame_unref(). -+ * * otherwise extended_data must point to data -+ * - buf[] must contain one or more pointers to AVBufferRef structures. Each -+ * of the frame's data and extended_data pointers must be contained in these. -+ * That is, one AVBufferRef for each allocated chunk of memory, not -+ * necessarily one AVBufferRef per data[] entry. See: av_buffer_create(), -+ * av_buffer_alloc(), and av_buffer_ref(). -+ * - extended_buf and nb_extended_buf must be allocated with av_malloc() by -+ * this callback and filled with the extra buffers if there are more -+ * buffers than buf[] can hold. extended_buf will be freed in -+ * av_frame_unref(). -+ * -+ * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call -+ * avcodec_default_get_buffer2() instead of providing buffers allocated by -+ * some other means. -+ * -+ * Each data plane must be aligned to the maximum required by the target -+ * CPU. -+ * -+ * @see avcodec_default_get_buffer2() -+ * -+ * Video: -+ * -+ * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused -+ * (read and/or written to if it is writable) later by libavcodec. -+ * -+ * avcodec_align_dimensions2() should be used to find the required width and -+ * height, as they normally need to be rounded up to the next multiple of 16. -+ * -+ * Some decoders do not support linesizes changing between frames. -+ * -+ * If frame multithreading is used, this callback may be called from a -+ * different thread, but not from more than one at once. Does not need to be -+ * reentrant. -+ * -+ * @see avcodec_align_dimensions2() -+ * -+ * Audio: -+ * -+ * Decoders request a buffer of a particular size by setting -+ * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may, -+ * however, utilize only part of the buffer by setting AVFrame.nb_samples -+ * to a smaller value in the output frame. -+ * -+ * As a convenience, av_samples_get_buffer_size() and -+ * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2() -+ * functions to find the required data size and to fill data pointers and -+ * linesize. In AVFrame.linesize, only linesize[0] may be set for audio -+ * since all planes must be the same size. -+ * -+ * @see av_samples_get_buffer_size(), av_samples_fill_arrays() -+ * -+ * - encoding: unused -+ * - decoding: Set by libavcodec, user can override. -+ */ -+ int (*get_buffer2)(struct AVCodecContext* s, AVFrame* frame, int flags); -+ -+ /* - encoding parameters */ -+ float qcompress; ///< amount of qscale change between easy & hard scenes -+ ///< (0.0-1.0) -+ float qblur; ///< amount of qscale smoothing over time (0.0-1.0) -+ -+ /** -+ * minimum quantizer -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int qmin; -+ -+ /** -+ * maximum quantizer -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int qmax; -+ -+ /** -+ * maximum quantizer difference between frames -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int max_qdiff; -+ -+ /** -+ * decoder bitstream buffer size -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int rc_buffer_size; -+ -+ /** -+ * ratecontrol override, see RcOverride -+ * - encoding: Allocated/set/freed by user. -+ * - decoding: unused -+ */ -+ int rc_override_count; -+ RcOverride* rc_override; -+ -+ /** -+ * maximum bitrate -+ * - encoding: Set by user. -+ * - decoding: Set by user, may be overwritten by libavcodec. -+ */ -+ int64_t rc_max_rate; -+ -+ /** -+ * minimum bitrate -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int64_t rc_min_rate; -+ -+ /** -+ * Ratecontrol attempt to use, at maximum, of what can be used without -+ * an underflow. -+ * - encoding: Set by user. -+ * - decoding: unused. -+ */ -+ float rc_max_available_vbv_use; -+ -+ /** -+ * Ratecontrol attempt to use, at least, times the amount needed to -+ * prevent a vbv overflow. -+ * - encoding: Set by user. -+ * - decoding: unused. -+ */ -+ float rc_min_vbv_overflow_use; -+ -+ /** -+ * Number of bits which should be loaded into the rc buffer before decoding -+ * starts. -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int rc_initial_buffer_occupancy; -+ -+ /** -+ * trellis RD quantization -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int trellis; -+ -+ /** -+ * pass1 encoding statistics output buffer -+ * - encoding: Set by libavcodec. -+ * - decoding: unused -+ */ -+ char* stats_out; -+ -+ /** -+ * pass2 encoding statistics input buffer -+ * Concatenated stuff from stats_out of pass1 should be placed here. -+ * - encoding: Allocated/set/freed by user. -+ * - decoding: unused -+ */ -+ char* stats_in; -+ -+ /** -+ * Work around bugs in encoders which sometimes cannot be detected -+ * automatically. -+ * - encoding: Set by user -+ * - decoding: Set by user -+ */ -+ int workaround_bugs; -+#define FF_BUG_AUTODETECT 1 ///< autodetection -+#define FF_BUG_XVID_ILACE 4 -+#define FF_BUG_UMP4 8 -+#define FF_BUG_NO_PADDING 16 -+#define FF_BUG_AMV 32 -+#define FF_BUG_QPEL_CHROMA 64 -+#define FF_BUG_STD_QPEL 128 -+#define FF_BUG_QPEL_CHROMA2 256 -+#define FF_BUG_DIRECT_BLOCKSIZE 512 -+#define FF_BUG_EDGE 1024 -+#define FF_BUG_HPEL_CHROMA 2048 -+#define FF_BUG_DC_CLIP 4096 -+#define FF_BUG_MS \ -+ 8192 ///< Work around various bugs in Microsoft's broken decoders. -+#define FF_BUG_TRUNCATED 16384 -+#define FF_BUG_IEDGE 32768 -+ -+ /** -+ * strictly follow the standard (MPEG-4, ...). -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ * Setting this to STRICT or higher means the encoder and decoder will -+ * generally do stupid things, whereas setting it to unofficial or lower -+ * will mean the encoder might produce output that is not supported by all -+ * spec-compliant decoders. Decoders don't differentiate between normal, -+ * unofficial and experimental (that is, they always try to decode things -+ * when they can) unless they are explicitly asked to behave stupidly -+ * (=strictly conform to the specs) -+ */ -+ int strict_std_compliance; -+#define FF_COMPLIANCE_VERY_STRICT \ -+ 2 ///< Strictly conform to an older more strict version of the spec or -+ ///< reference software. -+#define FF_COMPLIANCE_STRICT \ -+ 1 ///< Strictly conform to all the things in the spec no matter what -+ ///< consequences. -+#define FF_COMPLIANCE_NORMAL 0 -+#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions -+#define FF_COMPLIANCE_EXPERIMENTAL \ -+ -2 ///< Allow nonstandardized experimental things. -+ -+ /** -+ * error concealment flags -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ int error_concealment; -+#define FF_EC_GUESS_MVS 1 -+#define FF_EC_DEBLOCK 2 -+#define FF_EC_FAVOR_INTER 256 -+ -+ /** -+ * debug -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ int debug; -+#define FF_DEBUG_PICT_INFO 1 -+#define FF_DEBUG_RC 2 -+#define FF_DEBUG_BITSTREAM 4 -+#define FF_DEBUG_MB_TYPE 8 -+#define FF_DEBUG_QP 16 -+#define FF_DEBUG_DCT_COEFF 0x00000040 -+#define FF_DEBUG_SKIP 0x00000080 -+#define FF_DEBUG_STARTCODE 0x00000100 -+#define FF_DEBUG_ER 0x00000400 -+#define FF_DEBUG_MMCO 0x00000800 -+#define FF_DEBUG_BUGS 0x00001000 -+#define FF_DEBUG_BUFFERS 0x00008000 -+#define FF_DEBUG_THREADS 0x00010000 -+#define FF_DEBUG_GREEN_MD 0x00800000 -+#define FF_DEBUG_NOMC 0x01000000 -+ -+ /** -+ * Error recognition; may misdetect some more or less valid parts as errors. -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ int err_recognition; -+ -+/** -+ * Verify checksums embedded in the bitstream (could be of either encoded or -+ * decoded data, depending on the codec) and print an error message on mismatch. -+ * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the -+ * decoder returning an error. -+ */ -+#define AV_EF_CRCCHECK (1 << 0) -+#define AV_EF_BITSTREAM (1 << 1) ///< detect bitstream specification deviations -+#define AV_EF_BUFFER (1 << 2) ///< detect improper bitstream length -+#define AV_EF_EXPLODE (1 << 3) ///< abort decoding on minor error detection -+ -+#define AV_EF_IGNORE_ERR (1 << 15) ///< ignore errors and continue -+#define AV_EF_CAREFUL \ -+ (1 << 16) ///< consider things that violate the spec, are fast to calculate -+ ///< and have not been seen in the wild as errors -+#define AV_EF_COMPLIANT \ -+ (1 << 17) ///< consider all spec non compliances as errors -+#define AV_EF_AGGRESSIVE \ -+ (1 << 18) ///< consider things that a sane encoder should not do as an error -+ -+ /** -+ * opaque 64-bit number (generally a PTS) that will be reordered and -+ * output in AVFrame.reordered_opaque -+ * - encoding: Set by libavcodec to the reordered_opaque of the input -+ * frame corresponding to the last returned packet. Only -+ * supported by encoders with the -+ * AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability. -+ * - decoding: Set by user. -+ */ -+ int64_t reordered_opaque; -+ -+ /** -+ * Hardware accelerator in use -+ * - encoding: unused. -+ * - decoding: Set by libavcodec -+ */ -+ const struct AVHWAccel* hwaccel; -+ -+ /** -+ * Hardware accelerator context. -+ * For some hardware accelerators, a global context needs to be -+ * provided by the user. In that case, this holds display-dependent -+ * data FFmpeg cannot instantiate itself. Please refer to the -+ * FFmpeg HW accelerator documentation to know how to fill this. -+ * - encoding: unused -+ * - decoding: Set by user -+ */ -+ void* hwaccel_context; -+ -+ /** -+ * error -+ * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR. -+ * - decoding: unused -+ */ -+ uint64_t error[AV_NUM_DATA_POINTERS]; -+ -+ /** -+ * DCT algorithm, see FF_DCT_* below -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int dct_algo; -+#define FF_DCT_AUTO 0 -+#define FF_DCT_FASTINT 1 -+#define FF_DCT_INT 2 -+#define FF_DCT_MMX 3 -+#define FF_DCT_ALTIVEC 5 -+#define FF_DCT_FAAN 6 -+ -+ /** -+ * IDCT algorithm, see FF_IDCT_* below. -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ int idct_algo; -+#define FF_IDCT_AUTO 0 -+#define FF_IDCT_INT 1 -+#define FF_IDCT_SIMPLE 2 -+#define FF_IDCT_SIMPLEMMX 3 -+#define FF_IDCT_ARM 7 -+#define FF_IDCT_ALTIVEC 8 -+#define FF_IDCT_SIMPLEARM 10 -+#define FF_IDCT_XVID 14 -+#define FF_IDCT_SIMPLEARMV5TE 16 -+#define FF_IDCT_SIMPLEARMV6 17 -+#define FF_IDCT_FAAN 20 -+#define FF_IDCT_SIMPLENEON 22 -+#define FF_IDCT_NONE \ -+ 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ -+#define FF_IDCT_SIMPLEAUTO 128 -+ -+ /** -+ * bits per sample/pixel from the demuxer (needed for huffyuv). -+ * - encoding: Set by libavcodec. -+ * - decoding: Set by user. -+ */ -+ int bits_per_coded_sample; -+ -+ /** -+ * Bits per sample/pixel of internal libavcodec pixel/sample format. -+ * - encoding: set by user. -+ * - decoding: set by libavcodec. -+ */ -+ int bits_per_raw_sample; -+ -+ /** -+ * low resolution decoding, 1-> 1/2 size, 2->1/4 size -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ int lowres; -+ -+ /** -+ * thread count -+ * is used to decide how many independent tasks should be passed to execute() -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ int thread_count; -+ -+ /** -+ * Which multithreading methods to use. -+ * Use of FF_THREAD_FRAME will increase decoding delay by one frame per -+ * thread, so clients which cannot provide future frames should not use it. -+ * -+ * - encoding: Set by user, otherwise the default is used. -+ * - decoding: Set by user, otherwise the default is used. -+ */ -+ int thread_type; -+#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once -+#define FF_THREAD_SLICE \ -+ 2 ///< Decode more than one part of a single frame at once -+ -+ /** -+ * Which multithreading methods are in use by the codec. -+ * - encoding: Set by libavcodec. -+ * - decoding: Set by libavcodec. -+ */ -+ int active_thread_type; -+ -+#if FF_API_THREAD_SAFE_CALLBACKS -+ /** -+ * Set by the client if its custom get_buffer() callback can be called -+ * synchronously from another thread, which allows faster multithreaded -+ * decoding. draw_horiz_band() will be called from other threads regardless of -+ * this setting. Ignored if the default get_buffer() is used. -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ * -+ * @deprecated the custom get_buffer2() callback should always be -+ * thread-safe. Thread-unsafe get_buffer2() implementations will be -+ * invalid starting with LIBAVCODEC_VERSION_MAJOR=60; in other words, -+ * libavcodec will behave as if this field was always set to 1. -+ * Callers that want to be forward compatible with future libavcodec -+ * versions should wrap access to this field in -+ * #if LIBAVCODEC_VERSION_MAJOR < 60 -+ */ -+ attribute_deprecated int thread_safe_callbacks; -+#endif -+ -+ /** -+ * The codec may call this to execute several independent things. -+ * It will return only after finishing all tasks. -+ * The user may replace this with some multithreaded implementation, -+ * the default implementation will execute the parts serially. -+ * @param count the number of things to execute -+ * - encoding: Set by libavcodec, user can override. -+ * - decoding: Set by libavcodec, user can override. -+ */ -+ int (*execute)(struct AVCodecContext* c, -+ int (*func)(struct AVCodecContext* c2, void* arg), void* arg2, -+ int* ret, int count, int size); -+ -+ /** -+ * The codec may call this to execute several independent things. -+ * It will return only after finishing all tasks. -+ * The user may replace this with some multithreaded implementation, -+ * the default implementation will execute the parts serially. -+ * Also see avcodec_thread_init and e.g. the --enable-pthread configure -+ * option. -+ * @param c context passed also to func -+ * @param count the number of things to execute -+ * @param arg2 argument passed unchanged to func -+ * @param ret return values of executed functions, must have space for "count" -+ * values. May be NULL. -+ * @param func function that will be called count times, with jobnr from 0 to -+ * count-1. threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS -+ * and so that no two instances of func executing at the same time will have -+ * the same threadnr. -+ * @return always 0 currently, but code should handle a future improvement -+ * where when any call to func returns < 0 no further calls to func may be -+ * done and < 0 is returned. -+ * - encoding: Set by libavcodec, user can override. -+ * - decoding: Set by libavcodec, user can override. -+ */ -+ int (*execute2)(struct AVCodecContext* c, -+ int (*func)(struct AVCodecContext* c2, void* arg, int jobnr, -+ int threadnr), -+ void* arg2, int* ret, int count); -+ -+ /** -+ * noise vs. sse weight for the nsse comparison function -+ * - encoding: Set by user. -+ * - decoding: unused -+ */ -+ int nsse_weight; -+ -+ /** -+ * profile -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ int profile; -+#define FF_PROFILE_UNKNOWN -99 -+#define FF_PROFILE_RESERVED -100 -+ -+#define FF_PROFILE_AAC_MAIN 0 -+#define FF_PROFILE_AAC_LOW 1 -+#define FF_PROFILE_AAC_SSR 2 -+#define FF_PROFILE_AAC_LTP 3 -+#define FF_PROFILE_AAC_HE 4 -+#define FF_PROFILE_AAC_HE_V2 28 -+#define FF_PROFILE_AAC_LD 22 -+#define FF_PROFILE_AAC_ELD 38 -+#define FF_PROFILE_MPEG2_AAC_LOW 128 -+#define FF_PROFILE_MPEG2_AAC_HE 131 -+ -+#define FF_PROFILE_DNXHD 0 -+#define FF_PROFILE_DNXHR_LB 1 -+#define FF_PROFILE_DNXHR_SQ 2 -+#define FF_PROFILE_DNXHR_HQ 3 -+#define FF_PROFILE_DNXHR_HQX 4 -+#define FF_PROFILE_DNXHR_444 5 -+ -+#define FF_PROFILE_DTS 20 -+#define FF_PROFILE_DTS_ES 30 -+#define FF_PROFILE_DTS_96_24 40 -+#define FF_PROFILE_DTS_HD_HRA 50 -+#define FF_PROFILE_DTS_HD_MA 60 -+#define FF_PROFILE_DTS_EXPRESS 70 -+ -+#define FF_PROFILE_MPEG2_422 0 -+#define FF_PROFILE_MPEG2_HIGH 1 -+#define FF_PROFILE_MPEG2_SS 2 -+#define FF_PROFILE_MPEG2_SNR_SCALABLE 3 -+#define FF_PROFILE_MPEG2_MAIN 4 -+#define FF_PROFILE_MPEG2_SIMPLE 5 -+ -+#define FF_PROFILE_H264_CONSTRAINED (1 << 9) // 8+1; constraint_set1_flag -+#define FF_PROFILE_H264_INTRA (1 << 11) // 8+3; constraint_set3_flag -+ -+#define FF_PROFILE_H264_BASELINE 66 -+#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66 | FF_PROFILE_H264_CONSTRAINED) -+#define FF_PROFILE_H264_MAIN 77 -+#define FF_PROFILE_H264_EXTENDED 88 -+#define FF_PROFILE_H264_HIGH 100 -+#define FF_PROFILE_H264_HIGH_10 110 -+#define FF_PROFILE_H264_HIGH_10_INTRA (110 | FF_PROFILE_H264_INTRA) -+#define FF_PROFILE_H264_MULTIVIEW_HIGH 118 -+#define FF_PROFILE_H264_HIGH_422 122 -+#define FF_PROFILE_H264_HIGH_422_INTRA (122 | FF_PROFILE_H264_INTRA) -+#define FF_PROFILE_H264_STEREO_HIGH 128 -+#define FF_PROFILE_H264_HIGH_444 144 -+#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244 -+#define FF_PROFILE_H264_HIGH_444_INTRA (244 | FF_PROFILE_H264_INTRA) -+#define FF_PROFILE_H264_CAVLC_444 44 -+ -+#define FF_PROFILE_VC1_SIMPLE 0 -+#define FF_PROFILE_VC1_MAIN 1 -+#define FF_PROFILE_VC1_COMPLEX 2 -+#define FF_PROFILE_VC1_ADVANCED 3 -+ -+#define FF_PROFILE_MPEG4_SIMPLE 0 -+#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1 -+#define FF_PROFILE_MPEG4_CORE 2 -+#define FF_PROFILE_MPEG4_MAIN 3 -+#define FF_PROFILE_MPEG4_N_BIT 4 -+#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5 -+#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6 -+#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7 -+#define FF_PROFILE_MPEG4_HYBRID 8 -+#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9 -+#define FF_PROFILE_MPEG4_CORE_SCALABLE 10 -+#define FF_PROFILE_MPEG4_ADVANCED_CODING 11 -+#define FF_PROFILE_MPEG4_ADVANCED_CORE 12 -+#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 -+#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 -+#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 -+ -+#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1 -+#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2 -+#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768 -+#define FF_PROFILE_JPEG2000_DCINEMA_2K 3 -+#define FF_PROFILE_JPEG2000_DCINEMA_4K 4 -+ -+#define FF_PROFILE_VP9_0 0 -+#define FF_PROFILE_VP9_1 1 -+#define FF_PROFILE_VP9_2 2 -+#define FF_PROFILE_VP9_3 3 -+ -+#define FF_PROFILE_HEVC_MAIN 1 -+#define FF_PROFILE_HEVC_MAIN_10 2 -+#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 -+#define FF_PROFILE_HEVC_REXT 4 -+ -+#define FF_PROFILE_VVC_MAIN_10 1 -+#define FF_PROFILE_VVC_MAIN_10_444 33 -+ -+#define FF_PROFILE_AV1_MAIN 0 -+#define FF_PROFILE_AV1_HIGH 1 -+#define FF_PROFILE_AV1_PROFESSIONAL 2 -+ -+#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT 0xc0 -+#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1 -+#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT 0xc2 -+#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS 0xc3 -+#define FF_PROFILE_MJPEG_JPEG_LS 0xf7 -+ -+#define FF_PROFILE_SBC_MSBC 1 -+ -+#define FF_PROFILE_PRORES_PROXY 0 -+#define FF_PROFILE_PRORES_LT 1 -+#define FF_PROFILE_PRORES_STANDARD 2 -+#define FF_PROFILE_PRORES_HQ 3 -+#define FF_PROFILE_PRORES_4444 4 -+#define FF_PROFILE_PRORES_XQ 5 -+ -+#define FF_PROFILE_ARIB_PROFILE_A 0 -+#define FF_PROFILE_ARIB_PROFILE_C 1 -+ -+#define FF_PROFILE_KLVA_SYNC 0 -+#define FF_PROFILE_KLVA_ASYNC 1 -+ -+ /** -+ * level -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ int level; -+#define FF_LEVEL_UNKNOWN -99 -+ -+ /** -+ * Skip loop filtering for selected frames. -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ enum AVDiscard skip_loop_filter; -+ -+ /** -+ * Skip IDCT/dequantization for selected frames. -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ enum AVDiscard skip_idct; -+ -+ /** -+ * Skip decoding for selected frames. -+ * - encoding: unused -+ * - decoding: Set by user. -+ */ -+ enum AVDiscard skip_frame; -+ -+ /** -+ * Header containing style information for text subtitles. -+ * For SUBTITLE_ASS subtitle type, it should contain the whole ASS -+ * [Script Info] and [V4+ Styles] section, plus the [Events] line and -+ * the Format line following. It shouldn't include any Dialogue line. -+ * - encoding: Set/allocated/freed by user (before avcodec_open2()) -+ * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) -+ */ -+ uint8_t* subtitle_header; -+ int subtitle_header_size; -+ -+ /** -+ * Audio only. The number of "priming" samples (padding) inserted by the -+ * encoder at the beginning of the audio. I.e. this number of leading -+ * decoded samples must be discarded by the caller to get the original audio -+ * without leading padding. -+ * -+ * - decoding: unused -+ * - encoding: Set by libavcodec. The timestamps on the output packets are -+ * adjusted by the encoder so that they always refer to the -+ * first sample of the data actually contained in the packet, -+ * including any added padding. E.g. if the timebase is -+ * 1/samplerate and the timestamp of the first input sample is -+ * 0, the timestamp of the first output packet will be -+ * -initial_padding. -+ */ -+ int initial_padding; -+ -+ /** -+ * - decoding: For codecs that store a framerate value in the compressed -+ * bitstream, the decoder may export it here. { 0, 1} when -+ * unknown. -+ * - encoding: May be used to signal the framerate of CFR content to an -+ * encoder. -+ */ -+ AVRational framerate; -+ -+ /** -+ * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx. -+ * - encoding: unused. -+ * - decoding: Set by libavcodec before calling get_format() -+ */ -+ enum AVPixelFormat sw_pix_fmt; -+ -+ /** -+ * Timebase in which pkt_dts/pts and AVPacket.dts/pts are. -+ * - encoding unused. -+ * - decoding set by user. -+ */ -+ AVRational pkt_timebase; -+ -+ /** -+ * AVCodecDescriptor -+ * - encoding: unused. -+ * - decoding: set by libavcodec. -+ */ -+ const AVCodecDescriptor* codec_descriptor; -+ -+ /** -+ * Current statistics for PTS correction. -+ * - decoding: maintained and used by libavcodec, not intended to be used by -+ * user apps -+ * - encoding: unused -+ */ -+ int64_t -+ pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far -+ int64_t -+ pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far -+ int64_t pts_correction_last_pts; /// PTS of the last frame -+ int64_t pts_correction_last_dts; /// DTS of the last frame -+ -+ /** -+ * Character encoding of the input subtitles file. -+ * - decoding: set by user -+ * - encoding: unused -+ */ -+ char* sub_charenc; -+ -+ /** -+ * Subtitles character encoding mode. Formats or codecs might be adjusting -+ * this setting (if they are doing the conversion themselves for instance). -+ * - decoding: set by libavcodec -+ * - encoding: unused -+ */ -+ int sub_charenc_mode; -+#define FF_SUB_CHARENC_MODE_DO_NOTHING \ -+ -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, -+ ///< or the codec is bitmap for instance) -+#define FF_SUB_CHARENC_MODE_AUTOMATIC \ -+ 0 ///< libavcodec will select the mode itself -+#define FF_SUB_CHARENC_MODE_PRE_DECODER \ -+ 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the -+ ///< decoder, requires iconv -+#define FF_SUB_CHARENC_MODE_IGNORE \ -+ 2 ///< neither convert the subtitles, nor check them for valid UTF-8 -+ -+ /** -+ * Skip processing alpha if supported by codec. -+ * Note that if the format uses pre-multiplied alpha (common with VP6, -+ * and recommended due to better video quality/compression) -+ * the image will look as if alpha-blended onto a black background. -+ * However for formats that do not use pre-multiplied alpha -+ * there might be serious artefacts (though e.g. libswscale currently -+ * assumes pre-multiplied alpha anyway). -+ * -+ * - decoding: set by user -+ * - encoding: unused -+ */ -+ int skip_alpha; -+ -+ /** -+ * Number of samples to skip after a discontinuity -+ * - decoding: unused -+ * - encoding: set by libavcodec -+ */ -+ int seek_preroll; -+ -+#if FF_API_DEBUG_MV -+ /** -+ * @deprecated unused -+ */ -+ attribute_deprecated int debug_mv; -+# define FF_DEBUG_VIS_MV_P_FOR \ -+ 0x00000001 // visualize forward predicted MVs of P frames -+# define FF_DEBUG_VIS_MV_B_FOR \ -+ 0x00000002 // visualize forward predicted MVs of B frames -+# define FF_DEBUG_VIS_MV_B_BACK \ -+ 0x00000004 // visualize backward predicted MVs of B frames -+#endif -+ -+ /** -+ * custom intra quantization matrix -+ * - encoding: Set by user, can be NULL. -+ * - decoding: unused. -+ */ -+ uint16_t* chroma_intra_matrix; -+ -+ /** -+ * dump format separator. -+ * can be ", " or "\n " or anything else -+ * - encoding: Set by user. -+ * - decoding: Set by user. -+ */ -+ uint8_t* dump_separator; -+ -+ /** -+ * ',' separated list of allowed decoders. -+ * If NULL then all are allowed -+ * - encoding: unused -+ * - decoding: set by user -+ */ -+ char* codec_whitelist; -+ -+ /** -+ * Properties of the stream that gets decoded -+ * - encoding: unused -+ * - decoding: set by libavcodec -+ */ -+ unsigned properties; -+#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001 -+#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002 -+#define FF_CODEC_PROPERTY_FILM_GRAIN 0x00000004 -+ -+ /** -+ * Additional data associated with the entire coded stream. -+ * -+ * - decoding: unused -+ * - encoding: may be set by libavcodec after avcodec_open2(). -+ */ -+ AVPacketSideData* coded_side_data; -+ int nb_coded_side_data; -+ -+ /** -+ * A reference to the AVHWFramesContext describing the input (for encoding) -+ * or output (decoding) frames. The reference is set by the caller and -+ * afterwards owned (and freed) by libavcodec - it should never be read by -+ * the caller after being set. -+ * -+ * - decoding: This field should be set by the caller from the get_format() -+ * callback. The previous reference (if any) will always be -+ * unreffed by libavcodec before the get_format() call. -+ * -+ * If the default get_buffer2() is used with a hwaccel pixel -+ * format, then this AVHWFramesContext will be used for -+ * allocating the frame buffers. -+ * -+ * - encoding: For hardware encoders configured to use a hwaccel pixel -+ * format, this field should be set by the caller to a reference -+ * to the AVHWFramesContext describing input frames. -+ * AVHWFramesContext.format must be equal to -+ * AVCodecContext.pix_fmt. -+ * -+ * This field should be set before avcodec_open2() is called. -+ */ -+ AVBufferRef* hw_frames_ctx; -+ -+#if FF_API_SUB_TEXT_FORMAT -+ /** -+ * @deprecated unused -+ */ -+ attribute_deprecated int sub_text_format; -+# define FF_SUB_TEXT_FMT_ASS 0 -+#endif -+ -+ /** -+ * Audio only. The amount of padding (in samples) appended by the encoder to -+ * the end of the audio. I.e. this number of decoded samples must be -+ * discarded by the caller from the end of the stream to get the original -+ * audio without any trailing padding. -+ * -+ * - decoding: unused -+ * - encoding: unused -+ */ -+ int trailing_padding; -+ -+ /** -+ * The number of pixels per image to maximally accept. -+ * -+ * - decoding: set by user -+ * - encoding: set by user -+ */ -+ int64_t max_pixels; -+ -+ /** -+ * A reference to the AVHWDeviceContext describing the device which will -+ * be used by a hardware encoder/decoder. The reference is set by the -+ * caller and afterwards owned (and freed) by libavcodec. -+ * -+ * This should be used if either the codec device does not require -+ * hardware frames or any that are used are to be allocated internally by -+ * libavcodec. If the user wishes to supply any of the frames used as -+ * encoder input or decoder output then hw_frames_ctx should be used -+ * instead. When hw_frames_ctx is set in get_format() for a decoder, this -+ * field will be ignored while decoding the associated stream segment, but -+ * may again be used on a following one after another get_format() call. -+ * -+ * For both encoders and decoders this field should be set before -+ * avcodec_open2() is called and must not be written to thereafter. -+ * -+ * Note that some decoders may require this field to be set initially in -+ * order to support hw_frames_ctx at all - in that case, all frames -+ * contexts used must be created on the same device. -+ */ -+ AVBufferRef* hw_device_ctx; -+ -+ /** -+ * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated -+ * decoding (if active). -+ * - encoding: unused -+ * - decoding: Set by user (either before avcodec_open2(), or in the -+ * AVCodecContext.get_format callback) -+ */ -+ int hwaccel_flags; -+ -+ /** -+ * Video decoding only. Certain video codecs support cropping, meaning that -+ * only a sub-rectangle of the decoded frame is intended for display. This -+ * option controls how cropping is handled by libavcodec. -+ * -+ * When set to 1 (the default), libavcodec will apply cropping internally. -+ * I.e. it will modify the output frame width/height fields and offset the -+ * data pointers (only by as much as possible while preserving alignment, or -+ * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that -+ * the frames output by the decoder refer only to the cropped area. The -+ * crop_* fields of the output frames will be zero. -+ * -+ * When set to 0, the width/height fields of the output frames will be set -+ * to the coded dimensions and the crop_* fields will describe the cropping -+ * rectangle. Applying the cropping is left to the caller. -+ * -+ * @warning When hardware acceleration with opaque output frames is used, -+ * libavcodec is unable to apply cropping from the top/left border. -+ * -+ * @note when this option is set to zero, the width/height fields of the -+ * AVCodecContext and output AVFrames have different meanings. The codec -+ * context fields store display dimensions (with the coded dimensions in -+ * coded_width/height), while the frame fields store the coded dimensions -+ * (with the display dimensions being determined by the crop_* fields). -+ */ -+ int apply_cropping; -+ -+ /* -+ * Video decoding only. Sets the number of extra hardware frames which -+ * the decoder will allocate for use by the caller. This must be set -+ * before avcodec_open2() is called. -+ * -+ * Some hardware decoders require all frames that they will use for -+ * output to be defined in advance before decoding starts. For such -+ * decoders, the hardware frame pool must therefore be of a fixed size. -+ * The extra frames set here are on top of any number that the decoder -+ * needs internally in order to operate normally (for example, frames -+ * used as reference pictures). -+ */ -+ int extra_hw_frames; -+ -+ /** -+ * The percentage of damaged samples to discard a frame. -+ * -+ * - decoding: set by user -+ * - encoding: unused -+ */ -+ int discard_damaged_percentage; -+ -+ /** -+ * The number of samples per frame to maximally accept. -+ * -+ * - decoding: set by user -+ * - encoding: set by user -+ */ -+ int64_t max_samples; -+ -+ /** -+ * Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of -+ * metadata exported in frame, packet, or coded stream side data by -+ * decoders and encoders. -+ * -+ * - decoding: set by user -+ * - encoding: set by user -+ */ -+ int export_side_data; -+ -+ /** -+ * This callback is called at the beginning of each packet to get a data -+ * buffer for it. -+ * -+ * The following field will be set in the packet before this callback is -+ * called: -+ * - size -+ * This callback must use the above value to calculate the required buffer -+ * size, which must padded by at least AV_INPUT_BUFFER_PADDING_SIZE bytes. -+ * -+ * In some specific cases, the encoder may not use the entire buffer allocated -+ * by this callback. This will be reflected in the size value in the packet -+ * once returned by avcodec_receive_packet(). -+ * -+ * This callback must fill the following fields in the packet: -+ * - data: alignment requirements for AVPacket apply, if any. Some -+ * architectures and encoders may benefit from having aligned data. -+ * - buf: must contain a pointer to an AVBufferRef structure. The packet's -+ * data pointer must be contained in it. See: av_buffer_create(), -+ * av_buffer_alloc(), and av_buffer_ref(). -+ * -+ * If AV_CODEC_CAP_DR1 is not set then get_encode_buffer() must call -+ * avcodec_default_get_encode_buffer() instead of providing a buffer allocated -+ * by some other means. -+ * -+ * The flags field may contain a combination of AV_GET_ENCODE_BUFFER_FLAG_ -+ * flags. They may be used for example to hint what use the buffer may get -+ * after being created. Implementations of this callback may ignore flags they -+ * don't understand. If AV_GET_ENCODE_BUFFER_FLAG_REF is set in flags then the -+ * packet may be reused (read and/or written to if it is writable) later by -+ * libavcodec. -+ * -+ * This callback must be thread-safe, as when frame threading is used, it may -+ * be called from multiple threads simultaneously. -+ * -+ * @see avcodec_default_get_encode_buffer() -+ * -+ * - encoding: Set by libavcodec, user can override. -+ * - decoding: unused -+ */ -+ int (*get_encode_buffer)(struct AVCodecContext* s, AVPacket* pkt, int flags); -+} AVCodecContext; -+ -+struct MpegEncContext; -+ -+/** -+ * @defgroup lavc_hwaccel AVHWAccel -+ * -+ * @note Nothing in this structure should be accessed by the user. At some -+ * point in future it will not be externally visible at all. -+ * -+ * @{ -+ */ -+typedef struct AVHWAccel { -+ /** -+ * Name of the hardware accelerated codec. -+ * The name is globally unique among encoders and among decoders (but an -+ * encoder and a decoder can share the same name). -+ */ -+ const char* name; -+ -+ /** -+ * Type of codec implemented by the hardware accelerator. -+ * -+ * See AVMEDIA_TYPE_xxx -+ */ -+ enum AVMediaType type; -+ -+ /** -+ * Codec implemented by the hardware accelerator. -+ * -+ * See AV_CODEC_ID_xxx -+ */ -+ enum AVCodecID id; -+ -+ /** -+ * Supported pixel format. -+ * -+ * Only hardware accelerated formats are supported here. -+ */ -+ enum AVPixelFormat pix_fmt; -+ -+ /** -+ * Hardware accelerated codec capabilities. -+ * see AV_HWACCEL_CODEC_CAP_* -+ */ -+ int capabilities; -+ -+ /***************************************************************** -+ * No fields below this line are part of the public API. They -+ * may not be used outside of libavcodec and can be changed and -+ * removed at will. -+ * New public fields should be added right above. -+ ***************************************************************** -+ */ -+ -+ /** -+ * Allocate a custom buffer -+ */ -+ int (*alloc_frame)(AVCodecContext* avctx, AVFrame* frame); -+ -+ /** -+ * Called at the beginning of each frame or field picture. -+ * -+ * Meaningful frame information (codec specific) is guaranteed to -+ * be parsed at this point. This function is mandatory. -+ * -+ * Note that buf can be NULL along with buf_size set to 0. -+ * Otherwise, this means the whole frame is available at this point. -+ * -+ * @param avctx the codec context -+ * @param buf the frame data buffer base -+ * @param buf_size the size of the frame in bytes -+ * @return zero if successful, a negative value otherwise -+ */ -+ int (*start_frame)(AVCodecContext* avctx, const uint8_t* buf, -+ uint32_t buf_size); -+ -+ /** -+ * Callback for parameter data (SPS/PPS/VPS etc). -+ * -+ * Useful for hardware decoders which keep persistent state about the -+ * video parameters, and need to receive any changes to update that state. -+ * -+ * @param avctx the codec context -+ * @param type the nal unit type -+ * @param buf the nal unit data buffer -+ * @param buf_size the size of the nal unit in bytes -+ * @return zero if successful, a negative value otherwise -+ */ -+ int (*decode_params)(AVCodecContext* avctx, int type, const uint8_t* buf, -+ uint32_t buf_size); -+ -+ /** -+ * Callback for each slice. -+ * -+ * Meaningful slice information (codec specific) is guaranteed to -+ * be parsed at this point. This function is mandatory. -+ * The only exception is XvMC, that works on MB level. -+ * -+ * @param avctx the codec context -+ * @param buf the slice data buffer base -+ * @param buf_size the size of the slice in bytes -+ * @return zero if successful, a negative value otherwise -+ */ -+ int (*decode_slice)(AVCodecContext* avctx, const uint8_t* buf, -+ uint32_t buf_size); -+ -+ /** -+ * Called at the end of each frame or field picture. -+ * -+ * The whole picture is parsed at this point and can now be sent -+ * to the hardware accelerator. This function is mandatory. -+ * -+ * @param avctx the codec context -+ * @return zero if successful, a negative value otherwise -+ */ -+ int (*end_frame)(AVCodecContext* avctx); -+ -+ /** -+ * Size of per-frame hardware accelerator private data. -+ * -+ * Private data is allocated with av_mallocz() before -+ * AVCodecContext.get_buffer() and deallocated after -+ * AVCodecContext.release_buffer(). -+ */ -+ int frame_priv_data_size; -+ -+ /** -+ * Called for every Macroblock in a slice. -+ * -+ * XvMC uses it to replace the ff_mpv_reconstruct_mb(). -+ * Instead of decoding to raw picture, MB parameters are -+ * stored in an array provided by the video driver. -+ * -+ * @param s the mpeg context -+ */ -+ void (*decode_mb)(struct MpegEncContext* s); -+ -+ /** -+ * Initialize the hwaccel private data. -+ * -+ * This will be called from ff_get_format(), after hwaccel and -+ * hwaccel_context are set and the hwaccel private data in AVCodecInternal -+ * is allocated. -+ */ -+ int (*init)(AVCodecContext* avctx); -+ -+ /** -+ * Uninitialize the hwaccel private data. -+ * -+ * This will be called from get_format() or avcodec_close(), after hwaccel -+ * and hwaccel_context are already uninitialized. -+ */ -+ int (*uninit)(AVCodecContext* avctx); -+ -+ /** -+ * Size of the private data to allocate in -+ * AVCodecInternal.hwaccel_priv_data. -+ */ -+ int priv_data_size; -+ -+ /** -+ * Internal hwaccel capabilities. -+ */ -+ int caps_internal; -+ -+ /** -+ * Fill the given hw_frames context with current codec parameters. Called -+ * from get_format. Refer to avcodec_get_hw_frames_parameters() for -+ * details. -+ * -+ * This CAN be called before AVHWAccel.init is called, and you must assume -+ * that avctx->hwaccel_priv_data is invalid. -+ */ -+ int (*frame_params)(AVCodecContext* avctx, AVBufferRef* hw_frames_ctx); -+} AVHWAccel; -+ -+/** -+ * HWAccel is experimental and is thus avoided in favor of non experimental -+ * codecs -+ */ -+#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 -+ -+/** -+ * Hardware acceleration should be used for decoding even if the codec level -+ * used is unknown or higher than the maximum supported level reported by the -+ * hardware driver. -+ * -+ * It's generally a good idea to pass this flag unless you have a specific -+ * reason not to, as hardware tends to under-report supported levels. -+ */ -+#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0) -+ -+/** -+ * Hardware acceleration can output YUV pixel formats with a different chroma -+ * sampling than 4:2:0 and/or other than 8 bits per component. -+ */ -+#define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1) -+ -+/** -+ * Hardware acceleration should still be attempted for decoding when the -+ * codec profile does not match the reported capabilities of the hardware. -+ * -+ * For example, this can be used to try to decode baseline profile H.264 -+ * streams in hardware - it will often succeed, because many streams marked -+ * as baseline profile actually conform to constrained baseline profile. -+ * -+ * @warning If the stream is actually not supported then the behaviour is -+ * undefined, and may include returning entirely incorrect output -+ * while indicating success. -+ */ -+#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) -+ -+/** -+ * @} -+ */ -+ -+enum AVSubtitleType { -+ SUBTITLE_NONE, -+ -+ SUBTITLE_BITMAP, ///< A bitmap, pict will be set -+ -+ /** -+ * Plain text, the text field must be set by the decoder and is -+ * authoritative. ass and pict fields may contain approximations. -+ */ -+ SUBTITLE_TEXT, -+ -+ /** -+ * Formatted text, the ass field must be set by the decoder and is -+ * authoritative. pict and text fields may contain approximations. -+ */ -+ SUBTITLE_ASS, -+}; -+ -+#define AV_SUBTITLE_FLAG_FORCED 0x00000001 -+ -+typedef struct AVSubtitleRect { -+ int x; ///< top left corner of pict, undefined when pict is not set -+ int y; ///< top left corner of pict, undefined when pict is not set -+ int w; ///< width of pict, undefined when pict is not set -+ int h; ///< height of pict, undefined when pict is not set -+ int nb_colors; ///< number of colors in pict, undefined when pict is not set -+ -+ /** -+ * data+linesize for the bitmap of this subtitle. -+ * Can be set for text/ass as well once they are rendered. -+ */ -+ uint8_t* data[4]; -+ int linesize[4]; -+ -+ enum AVSubtitleType type; -+ -+ char* text; ///< 0 terminated plain UTF-8 text -+ -+ /** -+ * 0 terminated ASS/SSA compatible event line. -+ * The presentation of this is unaffected by the other values in this -+ * struct. -+ */ -+ char* ass; -+ -+ int flags; -+} AVSubtitleRect; -+ -+typedef struct AVSubtitle { -+ uint16_t format; /* 0 = graphics */ -+ uint32_t start_display_time; /* relative to packet pts, in ms */ -+ uint32_t end_display_time; /* relative to packet pts, in ms */ -+ unsigned num_rects; -+ AVSubtitleRect** rects; -+ int64_t pts; ///< Same as packet pts, in AV_TIME_BASE -+} AVSubtitle; -+ -+/** -+ * Return the LIBAVCODEC_VERSION_INT constant. -+ */ -+unsigned avcodec_version(void); -+ -+/** -+ * Return the libavcodec build-time configuration. -+ */ -+const char* avcodec_configuration(void); -+ -+/** -+ * Return the libavcodec license. -+ */ -+const char* avcodec_license(void); -+ -+/** -+ * Allocate an AVCodecContext and set its fields to default values. The -+ * resulting struct should be freed with avcodec_free_context(). -+ * -+ * @param codec if non-NULL, allocate private data and initialize defaults -+ * for the given codec. It is illegal to then call avcodec_open2() -+ * with a different codec. -+ * If NULL, then the codec-specific defaults won't be initialized, -+ * which may result in suboptimal default settings (this is -+ * important mainly for encoders, e.g. libx264). -+ * -+ * @return An AVCodecContext filled with default values or NULL on failure. -+ */ -+AVCodecContext* avcodec_alloc_context3(const AVCodec* codec); -+ -+/** -+ * Free the codec context and everything associated with it and write NULL to -+ * the provided pointer. -+ */ -+void avcodec_free_context(AVCodecContext** avctx); -+ -+/** -+ * Get the AVClass for AVCodecContext. It can be used in combination with -+ * AV_OPT_SEARCH_FAKE_OBJ for examining options. -+ * -+ * @see av_opt_find(). -+ */ -+const AVClass* avcodec_get_class(void); -+ -+#if FF_API_GET_FRAME_CLASS -+/** -+ * @deprecated This function should not be used. -+ */ -+attribute_deprecated const AVClass* avcodec_get_frame_class(void); -+#endif -+ -+/** -+ * Get the AVClass for AVSubtitleRect. It can be used in combination with -+ * AV_OPT_SEARCH_FAKE_OBJ for examining options. -+ * -+ * @see av_opt_find(). -+ */ -+const AVClass* avcodec_get_subtitle_rect_class(void); -+ -+/** -+ * Fill the parameters struct based on the values from the supplied codec -+ * context. Any allocated fields in par are freed and replaced with duplicates -+ * of the corresponding fields in codec. -+ * -+ * @return >= 0 on success, a negative AVERROR code on failure -+ */ -+int avcodec_parameters_from_context(AVCodecParameters* par, -+ const AVCodecContext* codec); -+ -+/** -+ * Fill the codec context based on the values from the supplied codec -+ * parameters. Any allocated fields in codec that have a corresponding field in -+ * par are freed and replaced with duplicates of the corresponding field in par. -+ * Fields in codec that do not have a counterpart in par are not touched. -+ * -+ * @return >= 0 on success, a negative AVERROR code on failure. -+ */ -+int avcodec_parameters_to_context(AVCodecContext* codec, -+ const AVCodecParameters* par); -+ -+/** -+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this -+ * function the context has to be allocated with avcodec_alloc_context3(). -+ * -+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), -+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for -+ * retrieving a codec. -+ * -+ * @warning This function is not thread safe! -+ * -+ * @note Always call this function before using decoding routines (such as -+ * @ref avcodec_receive_frame()). -+ * -+ * @code -+ * av_dict_set(&opts, "b", "2.5M", 0); -+ * codec = avcodec_find_decoder(AV_CODEC_ID_H264); -+ * if (!codec) -+ * exit(1); -+ * -+ * context = avcodec_alloc_context3(codec); -+ * -+ * if (avcodec_open2(context, codec, opts) < 0) -+ * exit(1); -+ * @endcode -+ * -+ * @param avctx The context to initialize. -+ * @param codec The codec to open this context for. If a non-NULL codec has been -+ * previously passed to avcodec_alloc_context3() or -+ * for this context, then this parameter MUST be either NULL or -+ * equal to the previously passed codec. -+ * @param options A dictionary filled with AVCodecContext and codec-private -+ * options. On return this object will be filled with options that were not -+ * found. -+ * -+ * @return zero on success, a negative value on error -+ * @see avcodec_alloc_context3(), avcodec_find_decoder(), -+ * avcodec_find_encoder(), av_dict_set(), av_opt_find(). -+ */ -+int avcodec_open2(AVCodecContext* avctx, const AVCodec* codec, -+ AVDictionary** options); -+ -+/** -+ * Close a given AVCodecContext and free all the data associated with it -+ * (but not the AVCodecContext itself). -+ * -+ * Calling this function on an AVCodecContext that hasn't been opened will free -+ * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL -+ * codec. Subsequent calls will do nothing. -+ * -+ * @note Do not use this function. Use avcodec_free_context() to destroy a -+ * codec context (either open or closed). Opening and closing a codec context -+ * multiple times is not supported anymore -- use multiple codec contexts -+ * instead. -+ */ -+int avcodec_close(AVCodecContext* avctx); -+ -+/** -+ * Free all allocated data in the given subtitle struct. -+ * -+ * @param sub AVSubtitle to free. -+ */ -+void avsubtitle_free(AVSubtitle* sub); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @addtogroup lavc_decoding -+ * @{ -+ */ -+ -+/** -+ * The default callback for AVCodecContext.get_buffer2(). It is made public so -+ * it can be called by custom get_buffer2() implementations for decoders without -+ * AV_CODEC_CAP_DR1 set. -+ */ -+int avcodec_default_get_buffer2(AVCodecContext* s, AVFrame* frame, int flags); -+ -+/** -+ * The default callback for AVCodecContext.get_encode_buffer(). It is made -+ * public so it can be called by custom get_encode_buffer() implementations for -+ * encoders without AV_CODEC_CAP_DR1 set. -+ */ -+int avcodec_default_get_encode_buffer(AVCodecContext* s, AVPacket* pkt, -+ int flags); -+ -+/** -+ * Modify width and height values so that they will result in a memory -+ * buffer that is acceptable for the codec if you do not use any horizontal -+ * padding. -+ * -+ * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. -+ */ -+void avcodec_align_dimensions(AVCodecContext* s, int* width, int* height); -+ -+/** -+ * Modify width and height values so that they will result in a memory -+ * buffer that is acceptable for the codec if you also ensure that all -+ * line sizes are a multiple of the respective linesize_align[i]. -+ * -+ * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. -+ */ -+void avcodec_align_dimensions2(AVCodecContext* s, int* width, int* height, -+ int linesize_align[AV_NUM_DATA_POINTERS]); -+ -+/** -+ * Converts AVChromaLocation to swscale x/y chroma position. -+ * -+ * The positions represent the chroma (0,0) position in a coordinates system -+ * with luma (0,0) representing the origin and luma(1,1) representing 256,256 -+ * -+ * @param xpos horizontal chroma sample position -+ * @param ypos vertical chroma sample position -+ */ -+int avcodec_enum_to_chroma_pos(int* xpos, int* ypos, enum AVChromaLocation pos); -+ -+/** -+ * Converts swscale x/y chroma position to AVChromaLocation. -+ * -+ * The positions represent the chroma (0,0) position in a coordinates system -+ * with luma (0,0) representing the origin and luma(1,1) representing 256,256 -+ * -+ * @param xpos horizontal chroma sample position -+ * @param ypos vertical chroma sample position -+ */ -+enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); -+ -+/** -+ * Decode a subtitle message. -+ * Return a negative value on error, otherwise return the number of bytes used. -+ * If no subtitle could be decompressed, got_sub_ptr is zero. -+ * Otherwise, the subtitle is stored in *sub. -+ * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for -+ * simplicity, because the performance difference is expected to be negligible -+ * and reusing a get_buffer written for video codecs would probably perform -+ * badly due to a potentially very different allocation pattern. -+ * -+ * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between -+ * input and output. This means that for some packets they will not immediately -+ * produce decoded output and need to be flushed at the end of decoding to get -+ * all the decoded data. Flushing is done by calling this function with packets -+ * with avpkt->data set to NULL and avpkt->size set to 0 until it stops -+ * returning subtitles. It is safe to flush even those decoders that are not -+ * marked with AV_CODEC_CAP_DELAY, then no subtitles will be returned. -+ * -+ * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() -+ * before packets may be fed to the decoder. -+ * -+ * @param avctx the codec context -+ * @param[out] sub The preallocated AVSubtitle in which the decoded subtitle -+ * will be stored, must be freed with avsubtitle_free if *got_sub_ptr is set. -+ * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, -+ * otherwise, it is nonzero. -+ * @param[in] avpkt The input AVPacket containing the input buffer. -+ */ -+int avcodec_decode_subtitle2(AVCodecContext* avctx, AVSubtitle* sub, -+ int* got_sub_ptr, AVPacket* avpkt); -+ -+/** -+ * Supply raw packet data as input to a decoder. -+ * -+ * Internally, this call will copy relevant AVCodecContext fields, which can -+ * influence decoding per-packet, and apply them when the packet is actually -+ * decoded. (For example AVCodecContext.skip_frame, which might direct the -+ * decoder to drop the frame contained by the packet sent with this function.) -+ * -+ * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE -+ * larger than the actual read bytes because some optimized bitstream -+ * readers read 32 or 64 bits at once and could read over the end. -+ * -+ * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() -+ * before packets may be fed to the decoder. -+ * -+ * @param avctx codec context -+ * @param[in] avpkt The input AVPacket. Usually, this will be a single video -+ * frame, or several complete audio frames. -+ * Ownership of the packet remains with the caller, and the -+ * decoder will not write to the packet. The decoder may create -+ * a reference to the packet data (or copy it if the packet is -+ * not reference-counted). -+ * Unlike with older APIs, the packet is always fully consumed, -+ * and if it contains multiple frames (e.g. some audio codecs), -+ * will require you to call avcodec_receive_frame() multiple -+ * times afterwards before you can send a new packet. -+ * It can be NULL (or an AVPacket with data set to NULL and -+ * size set to 0); in this case, it is considered a flush -+ * packet, which signals the end of the stream. Sending the -+ * first flush packet will return success. Subsequent ones are -+ * unnecessary and will return AVERROR_EOF. If the decoder -+ * still has frames buffered, it will return them after sending -+ * a flush packet. -+ * -+ * @return 0 on success, otherwise negative error code: -+ * AVERROR(EAGAIN): input is not accepted in the current state - user -+ * must read output with avcodec_receive_frame() (once -+ * all output is read, the packet should be resent, and -+ * the call will not fail with EAGAIN). -+ * AVERROR_EOF: the decoder has been flushed, and no new packets can -+ * be sent to it (also returned if more than 1 flush -+ * packet is sent) -+ * AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush -+ * AVERROR(ENOMEM): failed to add packet to internal queue, or similar -+ * other errors: legitimate decoding errors -+ */ -+int avcodec_send_packet(AVCodecContext* avctx, const AVPacket* avpkt); -+ -+/** -+ * Return decoded output data from a decoder. -+ * -+ * @param avctx codec context -+ * @param frame This will be set to a reference-counted video or audio -+ * frame (depending on the decoder type) allocated by the -+ * decoder. Note that the function will always call -+ * av_frame_unref(frame) before doing anything else. -+ * -+ * @return -+ * 0: success, a frame was returned -+ * AVERROR(EAGAIN): output is not available in this state - user must try -+ * to send new input -+ * AVERROR_EOF: the decoder has been fully flushed, and there will be -+ * no more output frames -+ * AVERROR(EINVAL): codec not opened, or it is an encoder -+ * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters -+ * with respect to first decoded frame. Applicable -+ * when flag AV_CODEC_FLAG_DROPCHANGED is set. -+ * other negative values: legitimate decoding errors -+ */ -+int avcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame); -+ -+/** -+ * Supply a raw video or audio frame to the encoder. Use -+ * avcodec_receive_packet() to retrieve buffered output packets. -+ * -+ * @param avctx codec context -+ * @param[in] frame AVFrame containing the raw audio or video frame to be -+ * encoded. Ownership of the frame remains with the caller, and the encoder will -+ * not write to the frame. The encoder may create a reference to the frame data -+ * (or copy it if the frame is not reference-counted). It can be NULL, in which -+ * case it is considered a flush packet. This signals the end of the stream. If -+ * the encoder still has packets buffered, it will return them after this call. -+ * Once flushing mode has been entered, additional flush packets are ignored, -+ * and sending frames will return AVERROR_EOF. -+ * -+ * For audio: -+ * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame -+ * can have any number of samples. -+ * If it is not set, frame->nb_samples must be equal to -+ * avctx->frame_size for all frames except the last. -+ * The final frame may be smaller than avctx->frame_size. -+ * @return 0 on success, otherwise negative error code: -+ * AVERROR(EAGAIN): input is not accepted in the current state - user -+ * must read output with avcodec_receive_packet() (once -+ * all output is read, the packet should be resent, and -+ * the call will not fail with EAGAIN). -+ * AVERROR_EOF: the encoder has been flushed, and no new frames can -+ * be sent to it -+ * AVERROR(EINVAL): codec not opened, it is a decoder, or requires flush -+ * AVERROR(ENOMEM): failed to add packet to internal queue, or similar -+ * other errors: legitimate encoding errors -+ */ -+int avcodec_send_frame(AVCodecContext* avctx, const AVFrame* frame); -+ -+/** -+ * Read encoded data from the encoder. -+ * -+ * @param avctx codec context -+ * @param avpkt This will be set to a reference-counted packet allocated by the -+ * encoder. Note that the function will always call -+ * av_packet_unref(avpkt) before doing anything else. -+ * @return 0 on success, otherwise negative error code: -+ * AVERROR(EAGAIN): output is not available in the current state - user -+ * must try to send input -+ * AVERROR_EOF: the encoder has been fully flushed, and there will be -+ * no more output packets -+ * AVERROR(EINVAL): codec not opened, or it is a decoder -+ * other errors: legitimate encoding errors -+ */ -+int avcodec_receive_packet(AVCodecContext* avctx, AVPacket* avpkt); -+ -+/** -+ * Create and return a AVHWFramesContext with values adequate for hardware -+ * decoding. This is meant to get called from the get_format callback, and is -+ * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx. -+ * This API is for decoding with certain hardware acceleration modes/APIs only. -+ * -+ * The returned AVHWFramesContext is not initialized. The caller must do this -+ * with av_hwframe_ctx_init(). -+ * -+ * Calling this function is not a requirement, but makes it simpler to avoid -+ * codec or hardware API specific details when manually allocating frames. -+ * -+ * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx, -+ * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes -+ * it unnecessary to call this function or having to care about -+ * AVHWFramesContext initialization at all. -+ * -+ * There are a number of requirements for calling this function: -+ * -+ * - It must be called from get_format with the same avctx parameter that was -+ * passed to get_format. Calling it outside of get_format is not allowed, and -+ * can trigger undefined behavior. -+ * - The function is not always supported (see description of return values). -+ * Even if this function returns successfully, hwaccel initialization could -+ * fail later. (The degree to which implementations check whether the stream -+ * is actually supported varies. Some do this check only after the user's -+ * get_format callback returns.) -+ * - The hw_pix_fmt must be one of the choices suggested by get_format. If the -+ * user decides to use a AVHWFramesContext prepared with this API function, -+ * the user must return the same hw_pix_fmt from get_format. -+ * - The device_ref passed to this function must support the given hw_pix_fmt. -+ * - After calling this API function, it is the user's responsibility to -+ * initialize the AVHWFramesContext (returned by the out_frames_ref -+ * parameter), and to set AVCodecContext.hw_frames_ctx to it. If done, this must -+ * be done before returning from get_format (this is implied by the normal -+ * AVCodecContext.hw_frames_ctx API rules). -+ * - The AVHWFramesContext parameters may change every time time get_format is -+ * called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So -+ * you are inherently required to go through this process again on every -+ * get_format call. -+ * - It is perfectly possible to call this function without actually using -+ * the resulting AVHWFramesContext. One use-case might be trying to reuse a -+ * previously initialized AVHWFramesContext, and calling this API function -+ * only to test whether the required frame parameters have changed. -+ * - Fields that use dynamically allocated values of any kind must not be set -+ * by the user unless setting them is explicitly allowed by the documentation. -+ * If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque, -+ * the new free callback must call the potentially set previous free callback. -+ * This API call may set any dynamically allocated fields, including the free -+ * callback. -+ * -+ * The function will set at least the following fields on AVHWFramesContext -+ * (potentially more, depending on hwaccel API): -+ * -+ * - All fields set by av_hwframe_ctx_alloc(). -+ * - Set the format field to hw_pix_fmt. -+ * - Set the sw_format field to the most suited and most versatile format. (An -+ * implication is that this will prefer generic formats over opaque formats -+ * with arbitrary restrictions, if possible.) -+ * - Set the width/height fields to the coded frame size, rounded up to the -+ * API-specific minimum alignment. -+ * - Only _if_ the hwaccel requires a pre-allocated pool: set the -+ * initial_pool_size field to the number of maximum reference surfaces possible -+ * with the codec, plus 1 surface for the user to work (meaning the user can -+ * safely reference at most 1 decoded surface at a time), plus additional -+ * buffering introduced by frame threading. If the hwaccel does not require -+ * pre-allocation, the field is left to 0, and the decoder will allocate new -+ * surfaces on demand during decoding. -+ * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying -+ * hardware API. -+ * -+ * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but -+ * with basic frame parameters set. -+ * -+ * The function is stateless, and does not change the AVCodecContext or the -+ * device_ref AVHWDeviceContext. -+ * -+ * @param avctx The context which is currently calling get_format, and which -+ * implicitly contains all state needed for filling the returned -+ * AVHWFramesContext properly. -+ * @param device_ref A reference to the AVHWDeviceContext describing the device -+ * which will be used by the hardware decoder. -+ * @param hw_pix_fmt The hwaccel format you are going to return from get_format. -+ * @param out_frames_ref On success, set to a reference to an _uninitialized_ -+ * AVHWFramesContext, created from the given device_ref. -+ * Fields will be set to values required for decoding. -+ * Not changed if an error is returned. -+ * @return zero on success, a negative value on error. The following error codes -+ * have special semantics: -+ * AVERROR(ENOENT): the decoder does not support this functionality. Setup -+ * is always manual, or it is a decoder which does not -+ * support setting AVCodecContext.hw_frames_ctx at all, -+ * or it is a software format. -+ * AVERROR(EINVAL): it is known that hardware decoding is not supported for -+ * this configuration, or the device_ref is not supported -+ * for the hwaccel referenced by hw_pix_fmt. -+ */ -+int avcodec_get_hw_frames_parameters(AVCodecContext* avctx, -+ AVBufferRef* device_ref, -+ enum AVPixelFormat hw_pix_fmt, -+ AVBufferRef** out_frames_ref); -+ -+/** -+ * @defgroup lavc_parsing Frame parsing -+ * @{ -+ */ -+ -+enum AVPictureStructure { -+ AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown -+ AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field -+ AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field -+ AV_PICTURE_STRUCTURE_FRAME, //< coded as frame -+}; -+ -+typedef struct AVCodecParserContext { -+ void* priv_data; -+ const struct AVCodecParser* parser; -+ int64_t frame_offset; /* offset of the current frame */ -+ int64_t cur_offset; /* current offset -+ (incremented by each av_parser_parse()) */ -+ int64_t next_frame_offset; /* offset of the next frame */ -+ /* video info */ -+ int pict_type; /* XXX: Put it back in AVCodecContext. */ -+ /** -+ * This field is used for proper frame duration computation in lavf. -+ * It signals, how much longer the frame duration of the current frame -+ * is compared to normal frame duration. -+ * -+ * frame_duration = (1 + repeat_pict) * time_base -+ * -+ * It is used by codecs like H.264 to display telecined material. -+ */ -+ int repeat_pict; /* XXX: Put it back in AVCodecContext. */ -+ int64_t pts; /* pts of the current frame */ -+ int64_t dts; /* dts of the current frame */ -+ -+ /* private data */ -+ int64_t last_pts; -+ int64_t last_dts; -+ int fetch_timestamp; -+ -+#define AV_PARSER_PTS_NB 4 -+ int cur_frame_start_index; -+ int64_t cur_frame_offset[AV_PARSER_PTS_NB]; -+ int64_t cur_frame_pts[AV_PARSER_PTS_NB]; -+ int64_t cur_frame_dts[AV_PARSER_PTS_NB]; -+ -+ int flags; -+#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 -+#define PARSER_FLAG_ONCE 0x0002 -+/// Set if the parser has a valid file offset -+#define PARSER_FLAG_FETCHED_OFFSET 0x0004 -+#define PARSER_FLAG_USE_CODEC_TS 0x1000 -+ -+ int64_t offset; ///< byte offset from starting packet start -+ int64_t cur_frame_end[AV_PARSER_PTS_NB]; -+ -+ /** -+ * Set by parser to 1 for key frames and 0 for non-key frames. -+ * It is initialized to -1, so if the parser doesn't set this flag, -+ * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames -+ * will be used. -+ */ -+ int key_frame; -+ -+ // Timestamp generation support: -+ /** -+ * Synchronization point for start of timestamp generation. -+ * -+ * Set to >0 for sync point, 0 for no sync point and <0 for undefined -+ * (default). -+ * -+ * For example, this corresponds to presence of H.264 buffering period -+ * SEI message. -+ */ -+ int dts_sync_point; -+ -+ /** -+ * Offset of the current timestamp against last timestamp sync point in -+ * units of AVCodecContext.time_base. -+ * -+ * Set to INT_MIN when dts_sync_point unused. Otherwise, it must -+ * contain a valid timestamp offset. -+ * -+ * Note that the timestamp of sync point has usually a nonzero -+ * dts_ref_dts_delta, which refers to the previous sync point. Offset of -+ * the next frame after timestamp sync point will be usually 1. -+ * -+ * For example, this corresponds to H.264 cpb_removal_delay. -+ */ -+ int dts_ref_dts_delta; -+ -+ /** -+ * Presentation delay of current frame in units of AVCodecContext.time_base. -+ * -+ * Set to INT_MIN when dts_sync_point unused. Otherwise, it must -+ * contain valid non-negative timestamp delta (presentation time of a frame -+ * must not lie in the past). -+ * -+ * This delay represents the difference between decoding and presentation -+ * time of the frame. -+ * -+ * For example, this corresponds to H.264 dpb_output_delay. -+ */ -+ int pts_dts_delta; -+ -+ /** -+ * Position of the packet in file. -+ * -+ * Analogous to cur_frame_pts/dts -+ */ -+ int64_t cur_frame_pos[AV_PARSER_PTS_NB]; -+ -+ /** -+ * Byte position of currently parsed frame in stream. -+ */ -+ int64_t pos; -+ -+ /** -+ * Previous frame byte position. -+ */ -+ int64_t last_pos; -+ -+ /** -+ * Duration of the current frame. -+ * For audio, this is in units of 1 / AVCodecContext.sample_rate. -+ * For all other types, this is in units of AVCodecContext.time_base. -+ */ -+ int duration; -+ -+ enum AVFieldOrder field_order; -+ -+ /** -+ * Indicate whether a picture is coded as a frame, top field or bottom field. -+ * -+ * For example, H.264 field_pic_flag equal to 0 corresponds to -+ * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag -+ * equal to 1 and bottom_field_flag equal to 0 corresponds to -+ * AV_PICTURE_STRUCTURE_TOP_FIELD. -+ */ -+ enum AVPictureStructure picture_structure; -+ -+ /** -+ * Picture number incremented in presentation or output order. -+ * This field may be reinitialized at the first picture of a new sequence. -+ * -+ * For example, this corresponds to H.264 PicOrderCnt. -+ */ -+ int output_picture_number; -+ -+ /** -+ * Dimensions of the decoded video intended for presentation. -+ */ -+ int width; -+ int height; -+ -+ /** -+ * Dimensions of the coded video. -+ */ -+ int coded_width; -+ int coded_height; -+ -+ /** -+ * The format of the coded data, corresponds to enum AVPixelFormat for video -+ * and for enum AVSampleFormat for audio. -+ * -+ * Note that a decoder can have considerable freedom in how exactly it -+ * decodes the data, so the format reported here might be different from the -+ * one returned by a decoder. -+ */ -+ int format; -+} AVCodecParserContext; -+ -+typedef struct AVCodecParser { -+ int codec_ids[7]; /* several codec IDs are permitted */ -+ int priv_data_size; -+ int (*parser_init)(AVCodecParserContext* s); -+ /* This callback never returns an error, a negative value means that -+ * the frame start was in a previous packet. */ -+ int (*parser_parse)(AVCodecParserContext* s, AVCodecContext* avctx, -+ const uint8_t** poutbuf, int* poutbuf_size, -+ const uint8_t* buf, int buf_size); -+ void (*parser_close)(AVCodecParserContext* s); -+ int (*split)(AVCodecContext* avctx, const uint8_t* buf, int buf_size); -+} AVCodecParser; -+ -+/** -+ * Iterate over all registered codec parsers. -+ * -+ * @param opaque a pointer where libavcodec will store the iteration state. Must -+ * point to NULL to start the iteration. -+ * -+ * @return the next registered codec parser or NULL when the iteration is -+ * finished -+ */ -+const AVCodecParser* av_parser_iterate(void** opaque); -+ -+AVCodecParserContext* av_parser_init(int codec_id); -+ -+/** -+ * Parse a packet. -+ * -+ * @param s parser context. -+ * @param avctx codec context. -+ * @param poutbuf set to pointer to parsed buffer or NULL if not yet -+ finished. -+ * @param poutbuf_size set to size of parsed buffer or zero if not yet -+ finished. -+ * @param buf input buffer. -+ * @param buf_size buffer size in bytes without the padding. I.e. the full -+ buffer size is assumed to be buf_size + AV_INPUT_BUFFER_PADDING_SIZE. To signal -+ EOF, this should be 0 (so that the last frame can be output). -+ * @param pts input presentation timestamp. -+ * @param dts input decoding timestamp. -+ * @param pos input byte position in stream. -+ * @return the number of bytes of the input bitstream used. -+ * -+ * Example: -+ * @code -+ * while(in_len){ -+ * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, -+ * in_data, in_len, -+ * pts, dts, pos); -+ * in_data += len; -+ * in_len -= len; -+ * -+ * if(size) -+ * decode_frame(data, size); -+ * } -+ * @endcode -+ */ -+int av_parser_parse2(AVCodecParserContext* s, AVCodecContext* avctx, -+ uint8_t** poutbuf, int* poutbuf_size, const uint8_t* buf, -+ int buf_size, int64_t pts, int64_t dts, int64_t pos); -+ -+void av_parser_close(AVCodecParserContext* s); -+ -+/** -+ * @} -+ * @} -+ */ -+ -+/** -+ * @addtogroup lavc_encoding -+ * @{ -+ */ -+ -+int avcodec_encode_subtitle(AVCodecContext* avctx, uint8_t* buf, int buf_size, -+ const AVSubtitle* sub); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @defgroup lavc_misc Utility functions -+ * @ingroup libavc -+ * -+ * Miscellaneous utility functions related to both encoding and decoding -+ * (or neither). -+ * @{ -+ */ -+ -+/** -+ * @defgroup lavc_misc_pixfmt Pixel formats -+ * -+ * Functions for working with pixel formats. -+ * @{ -+ */ -+ -+/** -+ * Return a value representing the fourCC code associated to the -+ * pixel format pix_fmt, or 0 if no associated fourCC code can be -+ * found. -+ */ -+unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt); -+ -+/** -+ * Find the best pixel format to convert to given a certain source pixel -+ * format. When converting from one pixel format to another, information loss -+ * may occur. For example, when converting from RGB24 to GRAY, the color -+ * information will be lost. Similarly, other losses occur when converting from -+ * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches -+ * which of the given pixel formats should be used to suffer the least amount of -+ * loss. The pixel formats from which it chooses one, are determined by the -+ * pix_fmt_list parameter. -+ * -+ * -+ * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to -+ * choose from -+ * @param[in] src_pix_fmt source pixel format -+ * @param[in] has_alpha Whether the source pixel format alpha channel is used. -+ * @param[out] loss_ptr Combination of flags informing you what kind of losses -+ * will occur. -+ * @return The best pixel format to convert to or -1 if none was found. -+ */ -+enum AVPixelFormat avcodec_find_best_pix_fmt_of_list( -+ const enum AVPixelFormat* pix_fmt_list, enum AVPixelFormat src_pix_fmt, -+ int has_alpha, int* loss_ptr); -+ -+enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext* s, -+ const enum AVPixelFormat* fmt); -+ -+/** -+ * @} -+ */ -+ -+void avcodec_string(char* buf, int buf_size, AVCodecContext* enc, int encode); -+ -+int avcodec_default_execute(AVCodecContext* c, -+ int (*func)(AVCodecContext* c2, void* arg2), -+ void* arg, int* ret, int count, int size); -+int avcodec_default_execute2(AVCodecContext* c, -+ int (*func)(AVCodecContext* c2, void* arg2, int, -+ int), -+ void* arg, int* ret, int count); -+// FIXME func typedef -+ -+/** -+ * Fill AVFrame audio data and linesize pointers. -+ * -+ * The buffer buf must be a preallocated buffer with a size big enough -+ * to contain the specified samples amount. The filled AVFrame data -+ * pointers will point to this buffer. -+ * -+ * AVFrame extended_data channel pointers are allocated if necessary for -+ * planar audio. -+ * -+ * @param frame the AVFrame -+ * frame->nb_samples must be set prior to calling the -+ * function. This function fills in frame->data, -+ * frame->extended_data, frame->linesize[0]. -+ * @param nb_channels channel count -+ * @param sample_fmt sample format -+ * @param buf buffer to use for frame data -+ * @param buf_size size of buffer -+ * @param align plane size sample alignment (0 = default) -+ * @return >=0 on success, negative error code on failure -+ * @todo return the size in bytes required to store the samples in -+ * case of success, at the next libavutil bump -+ */ -+int avcodec_fill_audio_frame(AVFrame* frame, int nb_channels, -+ enum AVSampleFormat sample_fmt, const uint8_t* buf, -+ int buf_size, int align); -+ -+/** -+ * Reset the internal codec state / flush internal buffers. Should be called -+ * e.g. when seeking or when switching to a different stream. -+ * -+ * @note for decoders, this function just releases any references the decoder -+ * might keep internally, but the caller's references remain valid. -+ * -+ * @note for encoders, this function will only do something if the encoder -+ * declares support for AV_CODEC_CAP_ENCODER_FLUSH. When called, the encoder -+ * will drain any remaining packets, and can then be re-used for a different -+ * stream (as opposed to sending a null frame which will leave the encoder -+ * in a permanent EOF state after draining). This can be desirable if the -+ * cost of tearing down and replacing the encoder instance is high. -+ */ -+void avcodec_flush_buffers(AVCodecContext* avctx); -+ -+/** -+ * Return audio frame duration. -+ * -+ * @param avctx codec context -+ * @param frame_bytes size of the frame, or 0 if unknown -+ * @return frame duration, in samples, if known. 0 if not able to -+ * determine. -+ */ -+int av_get_audio_frame_duration(AVCodecContext* avctx, int frame_bytes); -+ -+/* memory */ -+ -+/** -+ * Same behaviour av_fast_malloc but the buffer has additional -+ * AV_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. -+ * -+ * In addition the whole buffer will initially and after resizes -+ * be 0-initialized so that no uninitialized data will ever appear. -+ */ -+void av_fast_padded_malloc(void* ptr, unsigned int* size, size_t min_size); -+ -+/** -+ * Same behaviour av_fast_padded_malloc except that buffer will always -+ * be 0-initialized after call. -+ */ -+void av_fast_padded_mallocz(void* ptr, unsigned int* size, size_t min_size); -+ -+/** -+ * @return a positive value if s is open (i.e. avcodec_open2() was called on it -+ * with no corresponding avcodec_close()), 0 otherwise. -+ */ -+int avcodec_is_open(AVCodecContext* s); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVCODEC_AVCODEC_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avfft.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avfft.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avfft.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/avfft.h 2022-07-05 00:21:22.441315850 +0300 -@@ -0,0 +1,119 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_AVFFT_H -+#define AVCODEC_AVFFT_H -+ -+/** -+ * @file -+ * @ingroup lavc_fft -+ * FFT functions -+ */ -+ -+/** -+ * @defgroup lavc_fft FFT functions -+ * @ingroup lavc_misc -+ * -+ * @{ -+ */ -+ -+typedef float FFTSample; -+ -+typedef struct FFTComplex { -+ FFTSample re, im; -+} FFTComplex; -+ -+typedef struct FFTContext FFTContext; -+ -+/** -+ * Set up a complex FFT. -+ * @param nbits log2 of the length of the input array -+ * @param inverse if 0 perform the forward transform, if 1 perform the -+ * inverse -+ */ -+FFTContext* av_fft_init(int nbits, int inverse); -+ -+/** -+ * Do the permutation needed BEFORE calling ff_fft_calc(). -+ */ -+void av_fft_permute(FFTContext* s, FFTComplex* z); -+ -+/** -+ * Do a complex FFT with the parameters defined in av_fft_init(). The -+ * input data must be permuted before. No 1.0/sqrt(n) normalization is done. -+ */ -+void av_fft_calc(FFTContext* s, FFTComplex* z); -+ -+void av_fft_end(FFTContext* s); -+ -+FFTContext* av_mdct_init(int nbits, int inverse, double scale); -+void av_imdct_calc(FFTContext* s, FFTSample* output, const FFTSample* input); -+void av_imdct_half(FFTContext* s, FFTSample* output, const FFTSample* input); -+void av_mdct_calc(FFTContext* s, FFTSample* output, const FFTSample* input); -+void av_mdct_end(FFTContext* s); -+ -+/* Real Discrete Fourier Transform */ -+ -+enum RDFTransformType { -+ DFT_R2C, -+ IDFT_C2R, -+ IDFT_R2C, -+ DFT_C2R, -+}; -+ -+typedef struct RDFTContext RDFTContext; -+ -+/** -+ * Set up a real FFT. -+ * @param nbits log2 of the length of the input array -+ * @param trans the type of transform -+ */ -+RDFTContext* av_rdft_init(int nbits, enum RDFTransformType trans); -+void av_rdft_calc(RDFTContext* s, FFTSample* data); -+void av_rdft_end(RDFTContext* s); -+ -+/* Discrete Cosine Transform */ -+ -+typedef struct DCTContext DCTContext; -+ -+enum DCTTransformType { -+ DCT_II = 0, -+ DCT_III, -+ DCT_I, -+ DST_I, -+}; -+ -+/** -+ * Set up DCT. -+ * -+ * @param nbits size of the input array: -+ * (1 << nbits) for DCT-II, DCT-III and DST-I -+ * (1 << nbits) + 1 for DCT-I -+ * @param type the type of transform -+ * -+ * @note the first element of the input of DST-I is ignored -+ */ -+DCTContext* av_dct_init(int nbits, enum DCTTransformType type); -+void av_dct_calc(DCTContext* s, FFTSample* data); -+void av_dct_end(DCTContext* s); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVCODEC_AVFFT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/bsf.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/bsf.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/bsf.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/bsf.h 2022-07-05 00:21:22.441315850 +0300 -@@ -0,0 +1,320 @@ -+/* -+ * Bitstream filters public API -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_BSF_H -+#define AVCODEC_BSF_H -+ -+#include "libavutil/dict.h" -+#include "libavutil/log.h" -+#include "libavutil/rational.h" -+ -+#include "codec_id.h" -+#include "codec_par.h" -+#include "packet.h" -+ -+/** -+ * @addtogroup lavc_core -+ * @{ -+ */ -+ -+/** -+ * The bitstream filter state. -+ * -+ * This struct must be allocated with av_bsf_alloc() and freed with -+ * av_bsf_free(). -+ * -+ * The fields in the struct will only be changed (by the caller or by the -+ * filter) as described in their documentation, and are to be considered -+ * immutable otherwise. -+ */ -+typedef struct AVBSFContext { -+ /** -+ * A class for logging and AVOptions -+ */ -+ const AVClass* av_class; -+ -+ /** -+ * The bitstream filter this context is an instance of. -+ */ -+ const struct AVBitStreamFilter* filter; -+ -+ /** -+ * Opaque filter-specific private data. If filter->priv_class is non-NULL, -+ * this is an AVOptions-enabled struct. -+ */ -+ void* priv_data; -+ -+ /** -+ * Parameters of the input stream. This field is allocated in -+ * av_bsf_alloc(), it needs to be filled by the caller before -+ * av_bsf_init(). -+ */ -+ AVCodecParameters* par_in; -+ -+ /** -+ * Parameters of the output stream. This field is allocated in -+ * av_bsf_alloc(), it is set by the filter in av_bsf_init(). -+ */ -+ AVCodecParameters* par_out; -+ -+ /** -+ * The timebase used for the timestamps of the input packets. Set by the -+ * caller before av_bsf_init(). -+ */ -+ AVRational time_base_in; -+ -+ /** -+ * The timebase used for the timestamps of the output packets. Set by the -+ * filter in av_bsf_init(). -+ */ -+ AVRational time_base_out; -+} AVBSFContext; -+ -+typedef struct AVBitStreamFilter { -+ const char* name; -+ -+ /** -+ * A list of codec ids supported by the filter, terminated by -+ * AV_CODEC_ID_NONE. -+ * May be NULL, in that case the bitstream filter works with any codec id. -+ */ -+ const enum AVCodecID* codec_ids; -+ -+ /** -+ * A class for the private data, used to declare bitstream filter private -+ * AVOptions. This field is NULL for bitstream filters that do not declare -+ * any options. -+ * -+ * If this field is non-NULL, the first member of the filter private data -+ * must be a pointer to AVClass, which will be set by libavcodec generic -+ * code to this class. -+ */ -+ const AVClass* priv_class; -+ -+ /***************************************************************** -+ * No fields below this line are part of the public API. They -+ * may not be used outside of libavcodec and can be changed and -+ * removed at will. -+ * New public fields should be added right above. -+ ***************************************************************** -+ */ -+ -+ int priv_data_size; -+ int (*init)(AVBSFContext* ctx); -+ int (*filter)(AVBSFContext* ctx, AVPacket* pkt); -+ void (*close)(AVBSFContext* ctx); -+ void (*flush)(AVBSFContext* ctx); -+} AVBitStreamFilter; -+ -+/** -+ * @return a bitstream filter with the specified name or NULL if no such -+ * bitstream filter exists. -+ */ -+const AVBitStreamFilter* av_bsf_get_by_name(const char* name); -+ -+/** -+ * Iterate over all registered bitstream filters. -+ * -+ * @param opaque a pointer where libavcodec will store the iteration state. Must -+ * point to NULL to start the iteration. -+ * -+ * @return the next registered bitstream filter or NULL when the iteration is -+ * finished -+ */ -+const AVBitStreamFilter* av_bsf_iterate(void** opaque); -+ -+/** -+ * Allocate a context for a given bitstream filter. The caller must fill in the -+ * context parameters as described in the documentation and then call -+ * av_bsf_init() before sending any data to the filter. -+ * -+ * @param filter the filter for which to allocate an instance. -+ * @param ctx a pointer into which the pointer to the newly-allocated context -+ * will be written. It must be freed with av_bsf_free() after the -+ * filtering is done. -+ * -+ * @return 0 on success, a negative AVERROR code on failure -+ */ -+int av_bsf_alloc(const AVBitStreamFilter* filter, AVBSFContext** ctx); -+ -+/** -+ * Prepare the filter for use, after all the parameters and options have been -+ * set. -+ */ -+int av_bsf_init(AVBSFContext* ctx); -+ -+/** -+ * Submit a packet for filtering. -+ * -+ * After sending each packet, the filter must be completely drained by calling -+ * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or -+ * AVERROR_EOF. -+ * -+ * @param pkt the packet to filter. The bitstream filter will take ownership of -+ * the packet and reset the contents of pkt. pkt is not touched if an error -+ * occurs. If pkt is empty (i.e. NULL, or pkt->data is NULL and -+ * pkt->side_data_elems zero), it signals the end of the stream (i.e. no more -+ * non-empty packets will be sent; sending more empty packets does nothing) and -+ * will cause the filter to output any packets it may have buffered internally. -+ * -+ * @return 0 on success. AVERROR(EAGAIN) if packets need to be retrieved from -+ * the filter (using av_bsf_receive_packet()) before new input can be consumed. -+ * Another negative AVERROR value if an error occurs. -+ */ -+int av_bsf_send_packet(AVBSFContext* ctx, AVPacket* pkt); -+ -+/** -+ * Retrieve a filtered packet. -+ * -+ * @param[out] pkt this struct will be filled with the contents of the filtered -+ * packet. It is owned by the caller and must be freed using -+ * av_packet_unref() when it is no longer needed. -+ * This parameter should be "clean" (i.e. freshly allocated -+ * with av_packet_alloc() or unreffed with av_packet_unref()) -+ * when this function is called. If this function returns -+ * successfully, the contents of pkt will be completely -+ * overwritten by the returned data. On failure, pkt is not -+ * touched. -+ * -+ * @return 0 on success. AVERROR(EAGAIN) if more packets need to be sent to the -+ * filter (using av_bsf_send_packet()) to get more output. AVERROR_EOF if there -+ * will be no further output from the filter. Another negative AVERROR value if -+ * an error occurs. -+ * -+ * @note one input packet may result in several output packets, so after sending -+ * a packet with av_bsf_send_packet(), this function needs to be called -+ * repeatedly until it stops returning 0. It is also possible for a filter to -+ * output fewer packets than were sent to it, so this function may return -+ * AVERROR(EAGAIN) immediately after a successful av_bsf_send_packet() call. -+ */ -+int av_bsf_receive_packet(AVBSFContext* ctx, AVPacket* pkt); -+ -+/** -+ * Reset the internal bitstream filter state. Should be called e.g. when -+ * seeking. -+ */ -+void av_bsf_flush(AVBSFContext* ctx); -+ -+/** -+ * Free a bitstream filter context and everything associated with it; write NULL -+ * into the supplied pointer. -+ */ -+void av_bsf_free(AVBSFContext** ctx); -+ -+/** -+ * Get the AVClass for AVBSFContext. It can be used in combination with -+ * AV_OPT_SEARCH_FAKE_OBJ for examining options. -+ * -+ * @see av_opt_find(). -+ */ -+const AVClass* av_bsf_get_class(void); -+ -+/** -+ * Structure for chain/list of bitstream filters. -+ * Empty list can be allocated by av_bsf_list_alloc(). -+ */ -+typedef struct AVBSFList AVBSFList; -+ -+/** -+ * Allocate empty list of bitstream filters. -+ * The list must be later freed by av_bsf_list_free() -+ * or finalized by av_bsf_list_finalize(). -+ * -+ * @return Pointer to @ref AVBSFList on success, NULL in case of failure -+ */ -+AVBSFList* av_bsf_list_alloc(void); -+ -+/** -+ * Free list of bitstream filters. -+ * -+ * @param lst Pointer to pointer returned by av_bsf_list_alloc() -+ */ -+void av_bsf_list_free(AVBSFList** lst); -+ -+/** -+ * Append bitstream filter to the list of bitstream filters. -+ * -+ * @param lst List to append to -+ * @param bsf Filter context to be appended -+ * -+ * @return >=0 on success, negative AVERROR in case of failure -+ */ -+int av_bsf_list_append(AVBSFList* lst, AVBSFContext* bsf); -+ -+/** -+ * Construct new bitstream filter context given it's name and options -+ * and append it to the list of bitstream filters. -+ * -+ * @param lst List to append to -+ * @param bsf_name Name of the bitstream filter -+ * @param options Options for the bitstream filter, can be set to NULL -+ * -+ * @return >=0 on success, negative AVERROR in case of failure -+ */ -+int av_bsf_list_append2(AVBSFList* lst, const char* bsf_name, -+ AVDictionary** options); -+/** -+ * Finalize list of bitstream filters. -+ * -+ * This function will transform @ref AVBSFList to single @ref AVBSFContext, -+ * so the whole chain of bitstream filters can be treated as single filter -+ * freshly allocated by av_bsf_alloc(). -+ * If the call is successful, @ref AVBSFList structure is freed and lst -+ * will be set to NULL. In case of failure, caller is responsible for -+ * freeing the structure by av_bsf_list_free() -+ * -+ * @param lst Filter list structure to be transformed -+ * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext -+ * structure representing the chain of bitstream filters -+ * -+ * @return >=0 on success, negative AVERROR in case of failure -+ */ -+int av_bsf_list_finalize(AVBSFList** lst, AVBSFContext** bsf); -+ -+/** -+ * Parse string describing list of bitstream filters and create single -+ * @ref AVBSFContext describing the whole chain of bitstream filters. -+ * Resulting @ref AVBSFContext can be treated as any other @ref AVBSFContext -+ * freshly allocated by av_bsf_alloc(). -+ * -+ * @param str String describing chain of bitstream filters in format -+ * `bsf1[=opt1=val1:opt2=val2][,bsf2]` -+ * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext -+ * structure representing the chain of bitstream filters -+ * -+ * @return >=0 on success, negative AVERROR in case of failure -+ */ -+int av_bsf_list_parse_str(const char* str, AVBSFContext** bsf); -+ -+/** -+ * Get null/pass-through bitstream filter. -+ * -+ * @param[out] bsf Pointer to be set to new instance of pass-through bitstream -+ * filter -+ * -+ * @return -+ */ -+int av_bsf_get_null_filter(AVBSFContext** bsf); -+ -+/** -+ * @} -+ */ -+ -+#endif // AVCODEC_BSF_H -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec.h 2022-07-05 00:21:22.442315843 +0300 -@@ -0,0 +1,513 @@ -+/* -+ * AVCodec public API -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_CODEC_H -+#define AVCODEC_CODEC_H -+ -+#include -+ -+#include "libavutil/avutil.h" -+#include "libavutil/hwcontext.h" -+#include "libavutil/log.h" -+#include "libavutil/pixfmt.h" -+#include "libavutil/rational.h" -+#include "libavutil/samplefmt.h" -+ -+#include "libavcodec/codec_id.h" -+#include "libavcodec/version.h" -+ -+/** -+ * @addtogroup lavc_core -+ * @{ -+ */ -+ -+/** -+ * Decoder can use draw_horiz_band callback. -+ */ -+#define AV_CODEC_CAP_DRAW_HORIZ_BAND (1 << 0) -+/** -+ * Codec uses get_buffer() or get_encode_buffer() for allocating buffers and -+ * supports custom allocators. -+ * If not set, it might not use get_buffer() or get_encode_buffer() at all, or -+ * use operations that assume the buffer was allocated by -+ * avcodec_default_get_buffer2 or avcodec_default_get_encode_buffer. -+ */ -+#define AV_CODEC_CAP_DR1 (1 << 1) -+#if FF_API_FLAG_TRUNCATED -+/** -+ * @deprecated Use parsers to always send proper frames. -+ */ -+# define AV_CODEC_CAP_TRUNCATED (1 << 3) -+#endif -+/** -+ * Encoder or decoder requires flushing with NULL input at the end in order to -+ * give the complete and correct output. -+ * -+ * NOTE: If this flag is not set, the codec is guaranteed to never be fed with -+ * with NULL data. The user can still send NULL data to the public encode -+ * or decode function, but libavcodec will not pass it along to the codec -+ * unless this flag is set. -+ * -+ * Decoders: -+ * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL, -+ * avpkt->size=0 at the end to get the delayed data until the decoder no longer -+ * returns frames. -+ * -+ * Encoders: -+ * The encoder needs to be fed with NULL data at the end of encoding until the -+ * encoder no longer returns data. -+ * -+ * NOTE: For encoders implementing the AVCodec.encode2() function, setting this -+ * flag also means that the encoder must set the pts and duration for -+ * each output packet. If this flag is not set, the pts and duration will -+ * be determined by libavcodec from the input frame. -+ */ -+#define AV_CODEC_CAP_DELAY (1 << 5) -+/** -+ * Codec can be fed a final frame with a smaller size. -+ * This can be used to prevent truncation of the last audio samples. -+ */ -+#define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6) -+ -+/** -+ * Codec can output multiple frames per AVPacket -+ * Normally demuxers return one frame at a time, demuxers which do not do -+ * are connected to a parser to split what they return into proper frames. -+ * This flag is reserved to the very rare category of codecs which have a -+ * bitstream that cannot be split into frames without timeconsuming -+ * operations like full decoding. Demuxers carrying such bitstreams thus -+ * may return multiple frames in a packet. This has many disadvantages like -+ * prohibiting stream copy in many cases thus it should only be considered -+ * as a last resort. -+ */ -+#define AV_CODEC_CAP_SUBFRAMES (1 << 8) -+/** -+ * Codec is experimental and is thus avoided in favor of non experimental -+ * encoders -+ */ -+#define AV_CODEC_CAP_EXPERIMENTAL (1 << 9) -+/** -+ * Codec should fill in channel configuration and samplerate instead of -+ * container -+ */ -+#define AV_CODEC_CAP_CHANNEL_CONF (1 << 10) -+/** -+ * Codec supports frame-level multithreading. -+ */ -+#define AV_CODEC_CAP_FRAME_THREADS (1 << 12) -+/** -+ * Codec supports slice-based (or partition-based) multithreading. -+ */ -+#define AV_CODEC_CAP_SLICE_THREADS (1 << 13) -+/** -+ * Codec supports changed parameters at any point. -+ */ -+#define AV_CODEC_CAP_PARAM_CHANGE (1 << 14) -+/** -+ * Codec supports multithreading through a method other than slice- or -+ * frame-level multithreading. Typically this marks wrappers around -+ * multithreading-capable external libraries. -+ */ -+#define AV_CODEC_CAP_OTHER_THREADS (1 << 15) -+#if FF_API_AUTO_THREADS -+# define AV_CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_OTHER_THREADS -+#endif -+/** -+ * Audio encoder supports receiving a different number of samples in each call. -+ */ -+#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE (1 << 16) -+/** -+ * Decoder is not a preferred choice for probing. -+ * This indicates that the decoder is not a good choice for probing. -+ * It could for example be an expensive to spin up hardware decoder, -+ * or it could simply not provide a lot of useful information about -+ * the stream. -+ * A decoder marked with this flag should only be used as last resort -+ * choice for probing. -+ */ -+#define AV_CODEC_CAP_AVOID_PROBING (1 << 17) -+ -+#if FF_API_UNUSED_CODEC_CAPS -+/** -+ * Deprecated and unused. Use AVCodecDescriptor.props instead -+ */ -+# define AV_CODEC_CAP_INTRA_ONLY 0x40000000 -+/** -+ * Deprecated and unused. Use AVCodecDescriptor.props instead -+ */ -+# define AV_CODEC_CAP_LOSSLESS 0x80000000 -+#endif -+ -+/** -+ * Codec is backed by a hardware implementation. Typically used to -+ * identify a non-hwaccel hardware decoder. For information about hwaccels, use -+ * avcodec_get_hw_config() instead. -+ */ -+#define AV_CODEC_CAP_HARDWARE (1 << 18) -+ -+/** -+ * Codec is potentially backed by a hardware implementation, but not -+ * necessarily. This is used instead of AV_CODEC_CAP_HARDWARE, if the -+ * implementation provides some sort of internal fallback. -+ */ -+#define AV_CODEC_CAP_HYBRID (1 << 19) -+ -+/** -+ * This codec takes the reordered_opaque field from input AVFrames -+ * and returns it in the corresponding field in AVCodecContext after -+ * encoding. -+ */ -+#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20) -+ -+/** -+ * This encoder can be flushed using avcodec_flush_buffers(). If this flag is -+ * not set, the encoder must be closed and reopened to ensure that no frames -+ * remain pending. -+ */ -+#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21) -+ -+/** -+ * AVProfile. -+ */ -+typedef struct AVProfile { -+ int profile; -+ const char* name; ///< short name for the profile -+} AVProfile; -+ -+typedef struct AVCodecDefault AVCodecDefault; -+ -+struct AVCodecContext; -+struct AVSubtitle; -+struct AVPacket; -+ -+/** -+ * AVCodec. -+ */ -+typedef struct AVCodec { -+ /** -+ * Name of the codec implementation. -+ * The name is globally unique among encoders and among decoders (but an -+ * encoder and a decoder can share the same name). -+ * This is the primary way to find a codec from the user perspective. -+ */ -+ const char* name; -+ /** -+ * Descriptive name for the codec, meant to be more human readable than name. -+ * You should use the NULL_IF_CONFIG_SMALL() macro to define it. -+ */ -+ const char* long_name; -+ enum AVMediaType type; -+ enum AVCodecID id; -+ /** -+ * Codec capabilities. -+ * see AV_CODEC_CAP_* -+ */ -+ int capabilities; -+ uint8_t max_lowres; ///< maximum value for lowres supported by the decoder -+ const AVRational* -+ supported_framerates; ///< array of supported framerates, or NULL if any, -+ ///< array is terminated by {0,0} -+ const enum AVPixelFormat* -+ pix_fmts; ///< array of supported pixel formats, or NULL if unknown, -+ ///< array is terminated by -1 -+ const int* -+ supported_samplerates; ///< array of supported audio samplerates, or NULL -+ ///< if unknown, array is terminated by 0 -+ const enum AVSampleFormat* -+ sample_fmts; ///< array of supported sample formats, or NULL if unknown, -+ ///< array is terminated by -1 -+ const uint64_t* -+ channel_layouts; ///< array of support channel layouts, or NULL if -+ ///< unknown. array is terminated by 0 -+ const AVClass* priv_class; ///< AVClass for the private context -+ const AVProfile* -+ profiles; ///< array of recognized profiles, or NULL if unknown, array is -+ ///< terminated by {FF_PROFILE_UNKNOWN} -+ -+ /** -+ * Group name of the codec implementation. -+ * This is a short symbolic name of the wrapper backing this codec. A -+ * wrapper uses some kind of external implementation for the codec, such -+ * as an external library, or a codec implementation provided by the OS or -+ * the hardware. -+ * If this field is NULL, this is a builtin, libavcodec native codec. -+ * If non-NULL, this will be the suffix in AVCodec.name in most cases -+ * (usually AVCodec.name will be of the form "_"). -+ */ -+ const char* wrapper_name; -+ -+ /***************************************************************** -+ * No fields below this line are part of the public API. They -+ * may not be used outside of libavcodec and can be changed and -+ * removed at will. -+ * New public fields should be added right above. -+ ***************************************************************** -+ */ -+ /** -+ * Internal codec capabilities. -+ * See FF_CODEC_CAP_* in internal.h -+ */ -+ int caps_internal; -+ -+ int priv_data_size; -+ /** -+ * @name Frame-level threading support functions -+ * @{ -+ */ -+ /** -+ * Copy necessary context variables from a previous thread context to the -+ * current one. If not defined, the next thread will start automatically; -+ * otherwise, the codec must call ff_thread_finish_setup(). -+ * -+ * dst and src will (rarely) point to the same context, in which case memcpy -+ * should be skipped. -+ */ -+ int (*update_thread_context)(struct AVCodecContext* dst, -+ const struct AVCodecContext* src); -+ -+ /** -+ * Copy variables back to the user-facing context -+ */ -+ int (*update_thread_context_for_user)(struct AVCodecContext* dst, -+ const struct AVCodecContext* src); -+ /** @} */ -+ -+ /** -+ * Private codec-specific defaults. -+ */ -+ const AVCodecDefault* defaults; -+ -+ /** -+ * Initialize codec static data, called from av_codec_iterate(). -+ * -+ * This is not intended for time consuming operations as it is -+ * run for every codec regardless of that codec being used. -+ */ -+ void (*init_static_data)(struct AVCodec* codec); -+ -+ int (*init)(struct AVCodecContext*); -+ int (*encode_sub)(struct AVCodecContext*, uint8_t* buf, int buf_size, -+ const struct AVSubtitle* sub); -+ /** -+ * Encode data to an AVPacket. -+ * -+ * @param avctx codec context -+ * @param avpkt output AVPacket -+ * @param[in] frame AVFrame containing the raw data to be encoded -+ * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a -+ * non-empty packet was returned in avpkt. -+ * @return 0 on success, negative error code on failure -+ */ -+ int (*encode2)(struct AVCodecContext* avctx, struct AVPacket* avpkt, -+ const struct AVFrame* frame, int* got_packet_ptr); -+ /** -+ * Decode picture or subtitle data. -+ * -+ * @param avctx codec context -+ * @param outdata codec type dependent output struct -+ * @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that a -+ * non-empty frame or subtitle was returned in -+ * outdata. -+ * @param[in] avpkt AVPacket containing the data to be decoded -+ * @return amount of bytes read from the packet on success, negative error -+ * code on failure -+ */ -+ int (*decode)(struct AVCodecContext* avctx, void* outdata, int* got_frame_ptr, -+ struct AVPacket* avpkt); -+ int (*close)(struct AVCodecContext*); -+ /** -+ * Encode API with decoupled frame/packet dataflow. This function is called -+ * to get one output packet. It should call ff_encode_get_frame() to obtain -+ * input data. -+ */ -+ int (*receive_packet)(struct AVCodecContext* avctx, struct AVPacket* avpkt); -+ -+ /** -+ * Decode API with decoupled packet/frame dataflow. This function is called -+ * to get one output frame. It should call ff_decode_get_packet() to obtain -+ * input data. -+ */ -+ int (*receive_frame)(struct AVCodecContext* avctx, struct AVFrame* frame); -+ /** -+ * Flush buffers. -+ * Will be called when seeking -+ */ -+ void (*flush)(struct AVCodecContext*); -+ -+ /** -+ * Decoding only, a comma-separated list of bitstream filters to apply to -+ * packets before decoding. -+ */ -+ const char* bsfs; -+ -+ /** -+ * Array of pointers to hardware configurations supported by the codec, -+ * or NULL if no hardware supported. The array is terminated by a NULL -+ * pointer. -+ * -+ * The user can only access this field via avcodec_get_hw_config(). -+ */ -+ const struct AVCodecHWConfigInternal* const* hw_configs; -+ -+ /** -+ * List of supported codec_tags, terminated by FF_CODEC_TAGS_END. -+ */ -+ const uint32_t* codec_tags; -+} AVCodec; -+ -+/** -+ * Iterate over all registered codecs. -+ * -+ * @param opaque a pointer where libavcodec will store the iteration state. Must -+ * point to NULL to start the iteration. -+ * -+ * @return the next registered codec or NULL when the iteration is -+ * finished -+ */ -+const AVCodec* av_codec_iterate(void** opaque); -+ -+/** -+ * Find a registered decoder with a matching codec ID. -+ * -+ * @param id AVCodecID of the requested decoder -+ * @return A decoder if one was found, NULL otherwise. -+ */ -+const AVCodec* avcodec_find_decoder(enum AVCodecID id); -+ -+/** -+ * Find a registered decoder with the specified name. -+ * -+ * @param name name of the requested decoder -+ * @return A decoder if one was found, NULL otherwise. -+ */ -+const AVCodec* avcodec_find_decoder_by_name(const char* name); -+ -+/** -+ * Find a registered encoder with a matching codec ID. -+ * -+ * @param id AVCodecID of the requested encoder -+ * @return An encoder if one was found, NULL otherwise. -+ */ -+const AVCodec* avcodec_find_encoder(enum AVCodecID id); -+ -+/** -+ * Find a registered encoder with the specified name. -+ * -+ * @param name name of the requested encoder -+ * @return An encoder if one was found, NULL otherwise. -+ */ -+const AVCodec* avcodec_find_encoder_by_name(const char* name); -+/** -+ * @return a non-zero number if codec is an encoder, zero otherwise -+ */ -+int av_codec_is_encoder(const AVCodec* codec); -+ -+/** -+ * @return a non-zero number if codec is a decoder, zero otherwise -+ */ -+int av_codec_is_decoder(const AVCodec* codec); -+ -+/** -+ * Return a name for the specified profile, if available. -+ * -+ * @param codec the codec that is searched for the given profile -+ * @param profile the profile value for which a name is requested -+ * @return A name for the profile if found, NULL otherwise. -+ */ -+const char* av_get_profile_name(const AVCodec* codec, int profile); -+ -+enum { -+ /** -+ * The codec supports this format via the hw_device_ctx interface. -+ * -+ * When selecting this format, AVCodecContext.hw_device_ctx should -+ * have been set to a device of the specified type before calling -+ * avcodec_open2(). -+ */ -+ AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01, -+ /** -+ * The codec supports this format via the hw_frames_ctx interface. -+ * -+ * When selecting this format for a decoder, -+ * AVCodecContext.hw_frames_ctx should be set to a suitable frames -+ * context inside the get_format() callback. The frames context -+ * must have been created on a device of the specified type. -+ * -+ * When selecting this format for an encoder, -+ * AVCodecContext.hw_frames_ctx should be set to the context which -+ * will be used for the input frames before calling avcodec_open2(). -+ */ -+ AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02, -+ /** -+ * The codec supports this format by some internal method. -+ * -+ * This format can be selected without any additional configuration - -+ * no device or frames context is required. -+ */ -+ AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 0x04, -+ /** -+ * The codec supports this format by some ad-hoc method. -+ * -+ * Additional settings and/or function calls are required. See the -+ * codec-specific documentation for details. (Methods requiring -+ * this sort of configuration are deprecated and others should be -+ * used in preference.) -+ */ -+ AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 0x08, -+}; -+ -+typedef struct AVCodecHWConfig { -+ /** -+ * For decoders, a hardware pixel format which that decoder may be -+ * able to decode to if suitable hardware is available. -+ * -+ * For encoders, a pixel format which the encoder may be able to -+ * accept. If set to AV_PIX_FMT_NONE, this applies to all pixel -+ * formats supported by the codec. -+ */ -+ enum AVPixelFormat pix_fmt; -+ /** -+ * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible -+ * setup methods which can be used with this configuration. -+ */ -+ int methods; -+ /** -+ * The device type associated with the configuration. -+ * -+ * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and -+ * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused. -+ */ -+ enum AVHWDeviceType device_type; -+} AVCodecHWConfig; -+ -+/** -+ * Retrieve supported hardware configurations for a codec. -+ * -+ * Values of index from zero to some maximum return the indexed configuration -+ * descriptor; all other values return NULL. If the codec does not support -+ * any hardware configurations then it will always return NULL. -+ */ -+const AVCodecHWConfig* avcodec_get_hw_config(const AVCodec* codec, int index); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVCODEC_CODEC_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_desc.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_desc.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_desc.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_desc.h 2022-07-05 00:21:22.442315843 +0300 -@@ -0,0 +1,128 @@ -+/* -+ * Codec descriptors public API -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_CODEC_DESC_H -+#define AVCODEC_CODEC_DESC_H -+ -+#include "libavutil/avutil.h" -+ -+#include "codec_id.h" -+ -+/** -+ * @addtogroup lavc_core -+ * @{ -+ */ -+ -+/** -+ * This struct describes the properties of a single codec described by an -+ * AVCodecID. -+ * @see avcodec_descriptor_get() -+ */ -+typedef struct AVCodecDescriptor { -+ enum AVCodecID id; -+ enum AVMediaType type; -+ /** -+ * Name of the codec described by this descriptor. It is non-empty and -+ * unique for each codec descriptor. It should contain alphanumeric -+ * characters and '_' only. -+ */ -+ const char* name; -+ /** -+ * A more descriptive name for this codec. May be NULL. -+ */ -+ const char* long_name; -+ /** -+ * Codec properties, a combination of AV_CODEC_PROP_* flags. -+ */ -+ int props; -+ /** -+ * MIME type(s) associated with the codec. -+ * May be NULL; if not, a NULL-terminated array of MIME types. -+ * The first item is always non-NULL and is the preferred MIME type. -+ */ -+ const char* const* mime_types; -+ /** -+ * If non-NULL, an array of profiles recognized for this codec. -+ * Terminated with FF_PROFILE_UNKNOWN. -+ */ -+ const struct AVProfile* profiles; -+} AVCodecDescriptor; -+ -+/** -+ * Codec uses only intra compression. -+ * Video and audio codecs only. -+ */ -+#define AV_CODEC_PROP_INTRA_ONLY (1 << 0) -+/** -+ * Codec supports lossy compression. Audio and video codecs only. -+ * @note a codec may support both lossy and lossless -+ * compression modes -+ */ -+#define AV_CODEC_PROP_LOSSY (1 << 1) -+/** -+ * Codec supports lossless compression. Audio and video codecs only. -+ */ -+#define AV_CODEC_PROP_LOSSLESS (1 << 2) -+/** -+ * Codec supports frame reordering. That is, the coded order (the order in which -+ * the encoded packets are output by the encoders / stored / input to the -+ * decoders) may be different from the presentation order of the corresponding -+ * frames. -+ * -+ * For codecs that do not have this property set, PTS and DTS should always be -+ * equal. -+ */ -+#define AV_CODEC_PROP_REORDER (1 << 3) -+/** -+ * Subtitle codec is bitmap based -+ * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field. -+ */ -+#define AV_CODEC_PROP_BITMAP_SUB (1 << 16) -+/** -+ * Subtitle codec is text based. -+ * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field. -+ */ -+#define AV_CODEC_PROP_TEXT_SUB (1 << 17) -+ -+/** -+ * @return descriptor for given codec ID or NULL if no descriptor exists. -+ */ -+const AVCodecDescriptor* avcodec_descriptor_get(enum AVCodecID id); -+ -+/** -+ * Iterate over all codec descriptors known to libavcodec. -+ * -+ * @param prev previous descriptor. NULL to get the first descriptor. -+ * -+ * @return next descriptor or NULL after the last descriptor -+ */ -+const AVCodecDescriptor* avcodec_descriptor_next(const AVCodecDescriptor* prev); -+ -+/** -+ * @return codec descriptor with the given name or NULL if no such descriptor -+ * exists. -+ */ -+const AVCodecDescriptor* avcodec_descriptor_get_by_name(const char* name); -+ -+/** -+ * @} -+ */ -+ -+#endif // AVCODEC_CODEC_DESC_H -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_id.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_id.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_id.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_id.h 2022-07-05 00:21:22.442315843 +0300 -@@ -0,0 +1,637 @@ -+/* -+ * Codec IDs -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_CODEC_ID_H -+#define AVCODEC_CODEC_ID_H -+ -+#include "libavutil/avutil.h" -+#include "libavutil/samplefmt.h" -+ -+/** -+ * @addtogroup lavc_core -+ * @{ -+ */ -+ -+/** -+ * Identify the syntax and semantics of the bitstream. -+ * The principle is roughly: -+ * Two decoders with the same ID can decode the same streams. -+ * Two encoders with the same ID can encode compatible streams. -+ * There may be slight deviations from the principle due to implementation -+ * details. -+ * -+ * If you add a codec ID to this list, add it so that -+ * 1. no value of an existing codec ID changes (that would break ABI), -+ * 2. it is as close as possible to similar codecs -+ * -+ * After adding new codec IDs, do not forget to add an entry to the codec -+ * descriptor list and bump libavcodec minor version. -+ */ -+enum AVCodecID { -+ AV_CODEC_ID_NONE, -+ -+ /* video codecs */ -+ AV_CODEC_ID_MPEG1VIDEO, -+ AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding -+ AV_CODEC_ID_H261, -+ AV_CODEC_ID_H263, -+ AV_CODEC_ID_RV10, -+ AV_CODEC_ID_RV20, -+ AV_CODEC_ID_MJPEG, -+ AV_CODEC_ID_MJPEGB, -+ AV_CODEC_ID_LJPEG, -+ AV_CODEC_ID_SP5X, -+ AV_CODEC_ID_JPEGLS, -+ AV_CODEC_ID_MPEG4, -+ AV_CODEC_ID_RAWVIDEO, -+ AV_CODEC_ID_MSMPEG4V1, -+ AV_CODEC_ID_MSMPEG4V2, -+ AV_CODEC_ID_MSMPEG4V3, -+ AV_CODEC_ID_WMV1, -+ AV_CODEC_ID_WMV2, -+ AV_CODEC_ID_H263P, -+ AV_CODEC_ID_H263I, -+ AV_CODEC_ID_FLV1, -+ AV_CODEC_ID_SVQ1, -+ AV_CODEC_ID_SVQ3, -+ AV_CODEC_ID_DVVIDEO, -+ AV_CODEC_ID_HUFFYUV, -+ AV_CODEC_ID_CYUV, -+ AV_CODEC_ID_H264, -+ AV_CODEC_ID_INDEO3, -+ AV_CODEC_ID_VP3, -+ AV_CODEC_ID_THEORA, -+ AV_CODEC_ID_ASV1, -+ AV_CODEC_ID_ASV2, -+ AV_CODEC_ID_FFV1, -+ AV_CODEC_ID_4XM, -+ AV_CODEC_ID_VCR1, -+ AV_CODEC_ID_CLJR, -+ AV_CODEC_ID_MDEC, -+ AV_CODEC_ID_ROQ, -+ AV_CODEC_ID_INTERPLAY_VIDEO, -+ AV_CODEC_ID_XAN_WC3, -+ AV_CODEC_ID_XAN_WC4, -+ AV_CODEC_ID_RPZA, -+ AV_CODEC_ID_CINEPAK, -+ AV_CODEC_ID_WS_VQA, -+ AV_CODEC_ID_MSRLE, -+ AV_CODEC_ID_MSVIDEO1, -+ AV_CODEC_ID_IDCIN, -+ AV_CODEC_ID_8BPS, -+ AV_CODEC_ID_SMC, -+ AV_CODEC_ID_FLIC, -+ AV_CODEC_ID_TRUEMOTION1, -+ AV_CODEC_ID_VMDVIDEO, -+ AV_CODEC_ID_MSZH, -+ AV_CODEC_ID_ZLIB, -+ AV_CODEC_ID_QTRLE, -+ AV_CODEC_ID_TSCC, -+ AV_CODEC_ID_ULTI, -+ AV_CODEC_ID_QDRAW, -+ AV_CODEC_ID_VIXL, -+ AV_CODEC_ID_QPEG, -+ AV_CODEC_ID_PNG, -+ AV_CODEC_ID_PPM, -+ AV_CODEC_ID_PBM, -+ AV_CODEC_ID_PGM, -+ AV_CODEC_ID_PGMYUV, -+ AV_CODEC_ID_PAM, -+ AV_CODEC_ID_FFVHUFF, -+ AV_CODEC_ID_RV30, -+ AV_CODEC_ID_RV40, -+ AV_CODEC_ID_VC1, -+ AV_CODEC_ID_WMV3, -+ AV_CODEC_ID_LOCO, -+ AV_CODEC_ID_WNV1, -+ AV_CODEC_ID_AASC, -+ AV_CODEC_ID_INDEO2, -+ AV_CODEC_ID_FRAPS, -+ AV_CODEC_ID_TRUEMOTION2, -+ AV_CODEC_ID_BMP, -+ AV_CODEC_ID_CSCD, -+ AV_CODEC_ID_MMVIDEO, -+ AV_CODEC_ID_ZMBV, -+ AV_CODEC_ID_AVS, -+ AV_CODEC_ID_SMACKVIDEO, -+ AV_CODEC_ID_NUV, -+ AV_CODEC_ID_KMVC, -+ AV_CODEC_ID_FLASHSV, -+ AV_CODEC_ID_CAVS, -+ AV_CODEC_ID_JPEG2000, -+ AV_CODEC_ID_VMNC, -+ AV_CODEC_ID_VP5, -+ AV_CODEC_ID_VP6, -+ AV_CODEC_ID_VP6F, -+ AV_CODEC_ID_TARGA, -+ AV_CODEC_ID_DSICINVIDEO, -+ AV_CODEC_ID_TIERTEXSEQVIDEO, -+ AV_CODEC_ID_TIFF, -+ AV_CODEC_ID_GIF, -+ AV_CODEC_ID_DXA, -+ AV_CODEC_ID_DNXHD, -+ AV_CODEC_ID_THP, -+ AV_CODEC_ID_SGI, -+ AV_CODEC_ID_C93, -+ AV_CODEC_ID_BETHSOFTVID, -+ AV_CODEC_ID_PTX, -+ AV_CODEC_ID_TXD, -+ AV_CODEC_ID_VP6A, -+ AV_CODEC_ID_AMV, -+ AV_CODEC_ID_VB, -+ AV_CODEC_ID_PCX, -+ AV_CODEC_ID_SUNRAST, -+ AV_CODEC_ID_INDEO4, -+ AV_CODEC_ID_INDEO5, -+ AV_CODEC_ID_MIMIC, -+ AV_CODEC_ID_RL2, -+ AV_CODEC_ID_ESCAPE124, -+ AV_CODEC_ID_DIRAC, -+ AV_CODEC_ID_BFI, -+ AV_CODEC_ID_CMV, -+ AV_CODEC_ID_MOTIONPIXELS, -+ AV_CODEC_ID_TGV, -+ AV_CODEC_ID_TGQ, -+ AV_CODEC_ID_TQI, -+ AV_CODEC_ID_AURA, -+ AV_CODEC_ID_AURA2, -+ AV_CODEC_ID_V210X, -+ AV_CODEC_ID_TMV, -+ AV_CODEC_ID_V210, -+ AV_CODEC_ID_DPX, -+ AV_CODEC_ID_MAD, -+ AV_CODEC_ID_FRWU, -+ AV_CODEC_ID_FLASHSV2, -+ AV_CODEC_ID_CDGRAPHICS, -+ AV_CODEC_ID_R210, -+ AV_CODEC_ID_ANM, -+ AV_CODEC_ID_BINKVIDEO, -+ AV_CODEC_ID_IFF_ILBM, -+#define AV_CODEC_ID_IFF_BYTERUN1 AV_CODEC_ID_IFF_ILBM -+ AV_CODEC_ID_KGV1, -+ AV_CODEC_ID_YOP, -+ AV_CODEC_ID_VP8, -+ AV_CODEC_ID_PICTOR, -+ AV_CODEC_ID_ANSI, -+ AV_CODEC_ID_A64_MULTI, -+ AV_CODEC_ID_A64_MULTI5, -+ AV_CODEC_ID_R10K, -+ AV_CODEC_ID_MXPEG, -+ AV_CODEC_ID_LAGARITH, -+ AV_CODEC_ID_PRORES, -+ AV_CODEC_ID_JV, -+ AV_CODEC_ID_DFA, -+ AV_CODEC_ID_WMV3IMAGE, -+ AV_CODEC_ID_VC1IMAGE, -+ AV_CODEC_ID_UTVIDEO, -+ AV_CODEC_ID_BMV_VIDEO, -+ AV_CODEC_ID_VBLE, -+ AV_CODEC_ID_DXTORY, -+ AV_CODEC_ID_V410, -+ AV_CODEC_ID_XWD, -+ AV_CODEC_ID_CDXL, -+ AV_CODEC_ID_XBM, -+ AV_CODEC_ID_ZEROCODEC, -+ AV_CODEC_ID_MSS1, -+ AV_CODEC_ID_MSA1, -+ AV_CODEC_ID_TSCC2, -+ AV_CODEC_ID_MTS2, -+ AV_CODEC_ID_CLLC, -+ AV_CODEC_ID_MSS2, -+ AV_CODEC_ID_VP9, -+ AV_CODEC_ID_AIC, -+ AV_CODEC_ID_ESCAPE130, -+ AV_CODEC_ID_G2M, -+ AV_CODEC_ID_WEBP, -+ AV_CODEC_ID_HNM4_VIDEO, -+ AV_CODEC_ID_HEVC, -+#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC -+ AV_CODEC_ID_FIC, -+ AV_CODEC_ID_ALIAS_PIX, -+ AV_CODEC_ID_BRENDER_PIX, -+ AV_CODEC_ID_PAF_VIDEO, -+ AV_CODEC_ID_EXR, -+ AV_CODEC_ID_VP7, -+ AV_CODEC_ID_SANM, -+ AV_CODEC_ID_SGIRLE, -+ AV_CODEC_ID_MVC1, -+ AV_CODEC_ID_MVC2, -+ AV_CODEC_ID_HQX, -+ AV_CODEC_ID_TDSC, -+ AV_CODEC_ID_HQ_HQA, -+ AV_CODEC_ID_HAP, -+ AV_CODEC_ID_DDS, -+ AV_CODEC_ID_DXV, -+ AV_CODEC_ID_SCREENPRESSO, -+ AV_CODEC_ID_RSCC, -+ AV_CODEC_ID_AVS2, -+ AV_CODEC_ID_PGX, -+ AV_CODEC_ID_AVS3, -+ AV_CODEC_ID_MSP2, -+ AV_CODEC_ID_VVC, -+#define AV_CODEC_ID_H266 AV_CODEC_ID_VVC -+ AV_CODEC_ID_Y41P, -+ AV_CODEC_ID_AVRP, -+ AV_CODEC_ID_012V, -+ AV_CODEC_ID_AVUI, -+ AV_CODEC_ID_AYUV, -+ AV_CODEC_ID_TARGA_Y216, -+ AV_CODEC_ID_V308, -+ AV_CODEC_ID_V408, -+ AV_CODEC_ID_YUV4, -+ AV_CODEC_ID_AVRN, -+ AV_CODEC_ID_CPIA, -+ AV_CODEC_ID_XFACE, -+ AV_CODEC_ID_SNOW, -+ AV_CODEC_ID_SMVJPEG, -+ AV_CODEC_ID_APNG, -+ AV_CODEC_ID_DAALA, -+ AV_CODEC_ID_CFHD, -+ AV_CODEC_ID_TRUEMOTION2RT, -+ AV_CODEC_ID_M101, -+ AV_CODEC_ID_MAGICYUV, -+ AV_CODEC_ID_SHEERVIDEO, -+ AV_CODEC_ID_YLC, -+ AV_CODEC_ID_PSD, -+ AV_CODEC_ID_PIXLET, -+ AV_CODEC_ID_SPEEDHQ, -+ AV_CODEC_ID_FMVC, -+ AV_CODEC_ID_SCPR, -+ AV_CODEC_ID_CLEARVIDEO, -+ AV_CODEC_ID_XPM, -+ AV_CODEC_ID_AV1, -+ AV_CODEC_ID_BITPACKED, -+ AV_CODEC_ID_MSCC, -+ AV_CODEC_ID_SRGC, -+ AV_CODEC_ID_SVG, -+ AV_CODEC_ID_GDV, -+ AV_CODEC_ID_FITS, -+ AV_CODEC_ID_IMM4, -+ AV_CODEC_ID_PROSUMER, -+ AV_CODEC_ID_MWSC, -+ AV_CODEC_ID_WCMV, -+ AV_CODEC_ID_RASC, -+ AV_CODEC_ID_HYMT, -+ AV_CODEC_ID_ARBC, -+ AV_CODEC_ID_AGM, -+ AV_CODEC_ID_LSCR, -+ AV_CODEC_ID_VP4, -+ AV_CODEC_ID_IMM5, -+ AV_CODEC_ID_MVDV, -+ AV_CODEC_ID_MVHA, -+ AV_CODEC_ID_CDTOONS, -+ AV_CODEC_ID_MV30, -+ AV_CODEC_ID_NOTCHLC, -+ AV_CODEC_ID_PFM, -+ AV_CODEC_ID_MOBICLIP, -+ AV_CODEC_ID_PHOTOCD, -+ AV_CODEC_ID_IPU, -+ AV_CODEC_ID_ARGO, -+ AV_CODEC_ID_CRI, -+ AV_CODEC_ID_SIMBIOSIS_IMX, -+ AV_CODEC_ID_SGA_VIDEO, -+ AV_CODEC_ID_GEM, -+ -+ /* various PCM "codecs" */ -+ AV_CODEC_ID_FIRST_AUDIO = -+ 0x10000, ///< A dummy id pointing at the start of audio codecs -+ AV_CODEC_ID_PCM_S16LE = 0x10000, -+ AV_CODEC_ID_PCM_S16BE, -+ AV_CODEC_ID_PCM_U16LE, -+ AV_CODEC_ID_PCM_U16BE, -+ AV_CODEC_ID_PCM_S8, -+ AV_CODEC_ID_PCM_U8, -+ AV_CODEC_ID_PCM_MULAW, -+ AV_CODEC_ID_PCM_ALAW, -+ AV_CODEC_ID_PCM_S32LE, -+ AV_CODEC_ID_PCM_S32BE, -+ AV_CODEC_ID_PCM_U32LE, -+ AV_CODEC_ID_PCM_U32BE, -+ AV_CODEC_ID_PCM_S24LE, -+ AV_CODEC_ID_PCM_S24BE, -+ AV_CODEC_ID_PCM_U24LE, -+ AV_CODEC_ID_PCM_U24BE, -+ AV_CODEC_ID_PCM_S24DAUD, -+ AV_CODEC_ID_PCM_ZORK, -+ AV_CODEC_ID_PCM_S16LE_PLANAR, -+ AV_CODEC_ID_PCM_DVD, -+ AV_CODEC_ID_PCM_F32BE, -+ AV_CODEC_ID_PCM_F32LE, -+ AV_CODEC_ID_PCM_F64BE, -+ AV_CODEC_ID_PCM_F64LE, -+ AV_CODEC_ID_PCM_BLURAY, -+ AV_CODEC_ID_PCM_LXF, -+ AV_CODEC_ID_S302M, -+ AV_CODEC_ID_PCM_S8_PLANAR, -+ AV_CODEC_ID_PCM_S24LE_PLANAR, -+ AV_CODEC_ID_PCM_S32LE_PLANAR, -+ AV_CODEC_ID_PCM_S16BE_PLANAR, -+ AV_CODEC_ID_PCM_S64LE, -+ AV_CODEC_ID_PCM_S64BE, -+ AV_CODEC_ID_PCM_F16LE, -+ AV_CODEC_ID_PCM_F24LE, -+ AV_CODEC_ID_PCM_VIDC, -+ AV_CODEC_ID_PCM_SGA, -+ -+ /* various ADPCM codecs */ -+ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, -+ AV_CODEC_ID_ADPCM_IMA_WAV, -+ AV_CODEC_ID_ADPCM_IMA_DK3, -+ AV_CODEC_ID_ADPCM_IMA_DK4, -+ AV_CODEC_ID_ADPCM_IMA_WS, -+ AV_CODEC_ID_ADPCM_IMA_SMJPEG, -+ AV_CODEC_ID_ADPCM_MS, -+ AV_CODEC_ID_ADPCM_4XM, -+ AV_CODEC_ID_ADPCM_XA, -+ AV_CODEC_ID_ADPCM_ADX, -+ AV_CODEC_ID_ADPCM_EA, -+ AV_CODEC_ID_ADPCM_G726, -+ AV_CODEC_ID_ADPCM_CT, -+ AV_CODEC_ID_ADPCM_SWF, -+ AV_CODEC_ID_ADPCM_YAMAHA, -+ AV_CODEC_ID_ADPCM_SBPRO_4, -+ AV_CODEC_ID_ADPCM_SBPRO_3, -+ AV_CODEC_ID_ADPCM_SBPRO_2, -+ AV_CODEC_ID_ADPCM_THP, -+ AV_CODEC_ID_ADPCM_IMA_AMV, -+ AV_CODEC_ID_ADPCM_EA_R1, -+ AV_CODEC_ID_ADPCM_EA_R3, -+ AV_CODEC_ID_ADPCM_EA_R2, -+ AV_CODEC_ID_ADPCM_IMA_EA_SEAD, -+ AV_CODEC_ID_ADPCM_IMA_EA_EACS, -+ AV_CODEC_ID_ADPCM_EA_XAS, -+ AV_CODEC_ID_ADPCM_EA_MAXIS_XA, -+ AV_CODEC_ID_ADPCM_IMA_ISS, -+ AV_CODEC_ID_ADPCM_G722, -+ AV_CODEC_ID_ADPCM_IMA_APC, -+ AV_CODEC_ID_ADPCM_VIMA, -+ AV_CODEC_ID_ADPCM_AFC, -+ AV_CODEC_ID_ADPCM_IMA_OKI, -+ AV_CODEC_ID_ADPCM_DTK, -+ AV_CODEC_ID_ADPCM_IMA_RAD, -+ AV_CODEC_ID_ADPCM_G726LE, -+ AV_CODEC_ID_ADPCM_THP_LE, -+ AV_CODEC_ID_ADPCM_PSX, -+ AV_CODEC_ID_ADPCM_AICA, -+ AV_CODEC_ID_ADPCM_IMA_DAT4, -+ AV_CODEC_ID_ADPCM_MTAF, -+ AV_CODEC_ID_ADPCM_AGM, -+ AV_CODEC_ID_ADPCM_ARGO, -+ AV_CODEC_ID_ADPCM_IMA_SSI, -+ AV_CODEC_ID_ADPCM_ZORK, -+ AV_CODEC_ID_ADPCM_IMA_APM, -+ AV_CODEC_ID_ADPCM_IMA_ALP, -+ AV_CODEC_ID_ADPCM_IMA_MTF, -+ AV_CODEC_ID_ADPCM_IMA_CUNNING, -+ AV_CODEC_ID_ADPCM_IMA_MOFLEX, -+ AV_CODEC_ID_ADPCM_IMA_ACORN, -+ -+ /* AMR */ -+ AV_CODEC_ID_AMR_NB = 0x12000, -+ AV_CODEC_ID_AMR_WB, -+ -+ /* RealAudio codecs*/ -+ AV_CODEC_ID_RA_144 = 0x13000, -+ AV_CODEC_ID_RA_288, -+ -+ /* various DPCM codecs */ -+ AV_CODEC_ID_ROQ_DPCM = 0x14000, -+ AV_CODEC_ID_INTERPLAY_DPCM, -+ AV_CODEC_ID_XAN_DPCM, -+ AV_CODEC_ID_SOL_DPCM, -+ AV_CODEC_ID_SDX2_DPCM, -+ AV_CODEC_ID_GREMLIN_DPCM, -+ AV_CODEC_ID_DERF_DPCM, -+ -+ /* audio codecs */ -+ AV_CODEC_ID_MP2 = 0x15000, -+ AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 -+ AV_CODEC_ID_AAC, -+ AV_CODEC_ID_AC3, -+ AV_CODEC_ID_DTS, -+ AV_CODEC_ID_VORBIS, -+ AV_CODEC_ID_DVAUDIO, -+ AV_CODEC_ID_WMAV1, -+ AV_CODEC_ID_WMAV2, -+ AV_CODEC_ID_MACE3, -+ AV_CODEC_ID_MACE6, -+ AV_CODEC_ID_VMDAUDIO, -+ AV_CODEC_ID_FLAC, -+ AV_CODEC_ID_MP3ADU, -+ AV_CODEC_ID_MP3ON4, -+ AV_CODEC_ID_SHORTEN, -+ AV_CODEC_ID_ALAC, -+ AV_CODEC_ID_WESTWOOD_SND1, -+ AV_CODEC_ID_GSM, ///< as in Berlin toast format -+ AV_CODEC_ID_QDM2, -+ AV_CODEC_ID_COOK, -+ AV_CODEC_ID_TRUESPEECH, -+ AV_CODEC_ID_TTA, -+ AV_CODEC_ID_SMACKAUDIO, -+ AV_CODEC_ID_QCELP, -+ AV_CODEC_ID_WAVPACK, -+ AV_CODEC_ID_DSICINAUDIO, -+ AV_CODEC_ID_IMC, -+ AV_CODEC_ID_MUSEPACK7, -+ AV_CODEC_ID_MLP, -+ AV_CODEC_ID_GSM_MS, /* as found in WAV */ -+ AV_CODEC_ID_ATRAC3, -+ AV_CODEC_ID_APE, -+ AV_CODEC_ID_NELLYMOSER, -+ AV_CODEC_ID_MUSEPACK8, -+ AV_CODEC_ID_SPEEX, -+ AV_CODEC_ID_WMAVOICE, -+ AV_CODEC_ID_WMAPRO, -+ AV_CODEC_ID_WMALOSSLESS, -+ AV_CODEC_ID_ATRAC3P, -+ AV_CODEC_ID_EAC3, -+ AV_CODEC_ID_SIPR, -+ AV_CODEC_ID_MP1, -+ AV_CODEC_ID_TWINVQ, -+ AV_CODEC_ID_TRUEHD, -+ AV_CODEC_ID_MP4ALS, -+ AV_CODEC_ID_ATRAC1, -+ AV_CODEC_ID_BINKAUDIO_RDFT, -+ AV_CODEC_ID_BINKAUDIO_DCT, -+ AV_CODEC_ID_AAC_LATM, -+ AV_CODEC_ID_QDMC, -+ AV_CODEC_ID_CELT, -+ AV_CODEC_ID_G723_1, -+ AV_CODEC_ID_G729, -+ AV_CODEC_ID_8SVX_EXP, -+ AV_CODEC_ID_8SVX_FIB, -+ AV_CODEC_ID_BMV_AUDIO, -+ AV_CODEC_ID_RALF, -+ AV_CODEC_ID_IAC, -+ AV_CODEC_ID_ILBC, -+ AV_CODEC_ID_OPUS, -+ AV_CODEC_ID_COMFORT_NOISE, -+ AV_CODEC_ID_TAK, -+ AV_CODEC_ID_METASOUND, -+ AV_CODEC_ID_PAF_AUDIO, -+ AV_CODEC_ID_ON2AVC, -+ AV_CODEC_ID_DSS_SP, -+ AV_CODEC_ID_CODEC2, -+ AV_CODEC_ID_FFWAVESYNTH, -+ AV_CODEC_ID_SONIC, -+ AV_CODEC_ID_SONIC_LS, -+ AV_CODEC_ID_EVRC, -+ AV_CODEC_ID_SMV, -+ AV_CODEC_ID_DSD_LSBF, -+ AV_CODEC_ID_DSD_MSBF, -+ AV_CODEC_ID_DSD_LSBF_PLANAR, -+ AV_CODEC_ID_DSD_MSBF_PLANAR, -+ AV_CODEC_ID_4GV, -+ AV_CODEC_ID_INTERPLAY_ACM, -+ AV_CODEC_ID_XMA1, -+ AV_CODEC_ID_XMA2, -+ AV_CODEC_ID_DST, -+ AV_CODEC_ID_ATRAC3AL, -+ AV_CODEC_ID_ATRAC3PAL, -+ AV_CODEC_ID_DOLBY_E, -+ AV_CODEC_ID_APTX, -+ AV_CODEC_ID_APTX_HD, -+ AV_CODEC_ID_SBC, -+ AV_CODEC_ID_ATRAC9, -+ AV_CODEC_ID_HCOM, -+ AV_CODEC_ID_ACELP_KELVIN, -+ AV_CODEC_ID_MPEGH_3D_AUDIO, -+ AV_CODEC_ID_SIREN, -+ AV_CODEC_ID_HCA, -+ AV_CODEC_ID_FASTAUDIO, -+ AV_CODEC_ID_MSNSIREN, -+ -+ /* subtitle codecs */ -+ AV_CODEC_ID_FIRST_SUBTITLE = -+ 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. -+ AV_CODEC_ID_DVD_SUBTITLE = 0x17000, -+ AV_CODEC_ID_DVB_SUBTITLE, -+ AV_CODEC_ID_TEXT, ///< raw UTF-8 text -+ AV_CODEC_ID_XSUB, -+ AV_CODEC_ID_SSA, -+ AV_CODEC_ID_MOV_TEXT, -+ AV_CODEC_ID_HDMV_PGS_SUBTITLE, -+ AV_CODEC_ID_DVB_TELETEXT, -+ AV_CODEC_ID_SRT, -+ AV_CODEC_ID_MICRODVD, -+ AV_CODEC_ID_EIA_608, -+ AV_CODEC_ID_JACOSUB, -+ AV_CODEC_ID_SAMI, -+ AV_CODEC_ID_REALTEXT, -+ AV_CODEC_ID_STL, -+ AV_CODEC_ID_SUBVIEWER1, -+ AV_CODEC_ID_SUBVIEWER, -+ AV_CODEC_ID_SUBRIP, -+ AV_CODEC_ID_WEBVTT, -+ AV_CODEC_ID_MPL2, -+ AV_CODEC_ID_VPLAYER, -+ AV_CODEC_ID_PJS, -+ AV_CODEC_ID_ASS, -+ AV_CODEC_ID_HDMV_TEXT_SUBTITLE, -+ AV_CODEC_ID_TTML, -+ AV_CODEC_ID_ARIB_CAPTION, -+ -+ /* other specific kind of codecs (generally used for attachments) */ -+ AV_CODEC_ID_FIRST_UNKNOWN = -+ 0x18000, ///< A dummy ID pointing at the start of various fake codecs. -+ AV_CODEC_ID_TTF = 0x18000, -+ -+ AV_CODEC_ID_SCTE_35, ///< Contain timestamp estimated through PCR of program -+ ///< stream. -+ AV_CODEC_ID_EPG, -+ AV_CODEC_ID_BINTEXT, -+ AV_CODEC_ID_XBIN, -+ AV_CODEC_ID_IDF, -+ AV_CODEC_ID_OTF, -+ AV_CODEC_ID_SMPTE_KLV, -+ AV_CODEC_ID_DVD_NAV, -+ AV_CODEC_ID_TIMED_ID3, -+ AV_CODEC_ID_BIN_DATA, -+ -+ AV_CODEC_ID_PROBE = -+ 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf -+ ///< should attempt to identify it -+ -+ AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS -+ * stream (only used by libavformat) */ -+ AV_CODEC_ID_MPEG4SYSTEMS = -+ 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems -+ * stream (only used by libavformat) */ -+ AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing -+ ///< only metadata information. -+ AV_CODEC_ID_WRAPPED_AVFRAME = -+ 0x21001, ///< Passthrough codec, AVFrames wrapped in AVPacket -+}; -+ -+/** -+ * Get the type of the given codec. -+ */ -+enum AVMediaType avcodec_get_type(enum AVCodecID codec_id); -+ -+/** -+ * Get the name of a codec. -+ * @return a static string identifying the codec; never NULL -+ */ -+const char* avcodec_get_name(enum AVCodecID id); -+ -+/** -+ * Return codec bits per sample. -+ * -+ * @param[in] codec_id the codec -+ * @return Number of bits per sample or zero if unknown for the given codec. -+ */ -+int av_get_bits_per_sample(enum AVCodecID codec_id); -+ -+/** -+ * Return codec bits per sample. -+ * Only return non-zero if the bits per sample is exactly correct, not an -+ * approximation. -+ * -+ * @param[in] codec_id the codec -+ * @return Number of bits per sample or zero if unknown for the given codec. -+ */ -+int av_get_exact_bits_per_sample(enum AVCodecID codec_id); -+ -+/** -+ * Return a name for the specified profile, if available. -+ * -+ * @param codec_id the ID of the codec to which the requested profile belongs -+ * @param profile the profile value for which a name is requested -+ * @return A name for the profile if found, NULL otherwise. -+ * -+ * @note unlike av_get_profile_name(), which searches a list of profiles -+ * supported by a specific decoder or encoder implementation, this -+ * function searches the list of profiles from the AVCodecDescriptor -+ */ -+const char* avcodec_profile_name(enum AVCodecID codec_id, int profile); -+ -+/** -+ * Return the PCM codec associated with a sample format. -+ * @param be endianness, 0 for little, 1 for big, -+ * -1 (or anything else) for native -+ * @return AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE -+ */ -+enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be); -+ -+/** -+ * @} -+ */ -+ -+#endif // AVCODEC_CODEC_ID_H -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_par.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_par.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_par.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/codec_par.h 2022-07-05 00:21:22.443315837 +0300 -@@ -0,0 +1,236 @@ -+/* -+ * Codec parameters public API -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_CODEC_PAR_H -+#define AVCODEC_CODEC_PAR_H -+ -+#include -+ -+#include "libavutil/avutil.h" -+#include "libavutil/rational.h" -+#include "libavutil/pixfmt.h" -+ -+#include "codec_id.h" -+ -+/** -+ * @addtogroup lavc_core -+ */ -+ -+enum AVFieldOrder { -+ AV_FIELD_UNKNOWN, -+ AV_FIELD_PROGRESSIVE, -+ AV_FIELD_TT, //< Top coded_first, top displayed first -+ AV_FIELD_BB, //< Bottom coded first, bottom displayed first -+ AV_FIELD_TB, //< Top coded first, bottom displayed first -+ AV_FIELD_BT, //< Bottom coded first, top displayed first -+}; -+ -+/** -+ * This struct describes the properties of an encoded stream. -+ * -+ * sizeof(AVCodecParameters) is not a part of the public ABI, this struct must -+ * be allocated with avcodec_parameters_alloc() and freed with -+ * avcodec_parameters_free(). -+ */ -+typedef struct AVCodecParameters { -+ /** -+ * General type of the encoded data. -+ */ -+ enum AVMediaType codec_type; -+ /** -+ * Specific type of the encoded data (the codec used). -+ */ -+ enum AVCodecID codec_id; -+ /** -+ * Additional information about the codec (corresponds to the AVI FOURCC). -+ */ -+ uint32_t codec_tag; -+ -+ /** -+ * Extra binary data needed for initializing the decoder, codec-dependent. -+ * -+ * Must be allocated with av_malloc() and will be freed by -+ * avcodec_parameters_free(). The allocated size of extradata must be at -+ * least extradata_size + AV_INPUT_BUFFER_PADDING_SIZE, with the padding -+ * bytes zeroed. -+ */ -+ uint8_t* extradata; -+ /** -+ * Size of the extradata content in bytes. -+ */ -+ int extradata_size; -+ -+ /** -+ * - video: the pixel format, the value corresponds to enum AVPixelFormat. -+ * - audio: the sample format, the value corresponds to enum AVSampleFormat. -+ */ -+ int format; -+ -+ /** -+ * The average bitrate of the encoded data (in bits per second). -+ */ -+ int64_t bit_rate; -+ -+ /** -+ * The number of bits per sample in the codedwords. -+ * -+ * This is basically the bitrate per sample. It is mandatory for a bunch of -+ * formats to actually decode them. It's the number of bits for one sample in -+ * the actual coded bitstream. -+ * -+ * This could be for example 4 for ADPCM -+ * For PCM formats this matches bits_per_raw_sample -+ * Can be 0 -+ */ -+ int bits_per_coded_sample; -+ -+ /** -+ * This is the number of valid bits in each output sample. If the -+ * sample format has more bits, the least significant bits are additional -+ * padding bits, which are always 0. Use right shifts to reduce the sample -+ * to its actual size. For example, audio formats with 24 bit samples will -+ * have bits_per_raw_sample set to 24, and format set to AV_SAMPLE_FMT_S32. -+ * To get the original sample use "(int32_t)sample >> 8"." -+ * -+ * For ADPCM this might be 12 or 16 or similar -+ * Can be 0 -+ */ -+ int bits_per_raw_sample; -+ -+ /** -+ * Codec-specific bitstream restrictions that the stream conforms to. -+ */ -+ int profile; -+ int level; -+ -+ /** -+ * Video only. The dimensions of the video frame in pixels. -+ */ -+ int width; -+ int height; -+ -+ /** -+ * Video only. The aspect ratio (width / height) which a single pixel -+ * should have when displayed. -+ * -+ * When the aspect ratio is unknown / undefined, the numerator should be -+ * set to 0 (the denominator may have any value). -+ */ -+ AVRational sample_aspect_ratio; -+ -+ /** -+ * Video only. The order of the fields in interlaced video. -+ */ -+ enum AVFieldOrder field_order; -+ -+ /** -+ * Video only. Additional colorspace characteristics. -+ */ -+ enum AVColorRange color_range; -+ enum AVColorPrimaries color_primaries; -+ enum AVColorTransferCharacteristic color_trc; -+ enum AVColorSpace color_space; -+ enum AVChromaLocation chroma_location; -+ -+ /** -+ * Video only. Number of delayed frames. -+ */ -+ int video_delay; -+ -+ /** -+ * Audio only. The channel layout bitmask. May be 0 if the channel layout is -+ * unknown or unspecified, otherwise the number of bits set must be equal to -+ * the channels field. -+ */ -+ uint64_t channel_layout; -+ /** -+ * Audio only. The number of audio channels. -+ */ -+ int channels; -+ /** -+ * Audio only. The number of audio samples per second. -+ */ -+ int sample_rate; -+ /** -+ * Audio only. The number of bytes per coded audio frame, required by some -+ * formats. -+ * -+ * Corresponds to nBlockAlign in WAVEFORMATEX. -+ */ -+ int block_align; -+ /** -+ * Audio only. Audio frame size, if known. Required by some formats to be -+ * static. -+ */ -+ int frame_size; -+ -+ /** -+ * Audio only. The amount of padding (in samples) inserted by the encoder at -+ * the beginning of the audio. I.e. this number of leading decoded samples -+ * must be discarded by the caller to get the original audio without leading -+ * padding. -+ */ -+ int initial_padding; -+ /** -+ * Audio only. The amount of padding (in samples) appended by the encoder to -+ * the end of the audio. I.e. this number of decoded samples must be -+ * discarded by the caller from the end of the stream to get the original -+ * audio without any trailing padding. -+ */ -+ int trailing_padding; -+ /** -+ * Audio only. Number of samples to skip after a discontinuity. -+ */ -+ int seek_preroll; -+} AVCodecParameters; -+ -+/** -+ * Allocate a new AVCodecParameters and set its fields to default values -+ * (unknown/invalid/0). The returned struct must be freed with -+ * avcodec_parameters_free(). -+ */ -+AVCodecParameters* avcodec_parameters_alloc(void); -+ -+/** -+ * Free an AVCodecParameters instance and everything associated with it and -+ * write NULL to the supplied pointer. -+ */ -+void avcodec_parameters_free(AVCodecParameters** par); -+ -+/** -+ * Copy the contents of src to dst. Any allocated fields in dst are freed and -+ * replaced with newly allocated duplicates of the corresponding fields in src. -+ * -+ * @return >= 0 on success, a negative AVERROR code on failure. -+ */ -+int avcodec_parameters_copy(AVCodecParameters* dst, -+ const AVCodecParameters* src); -+ -+/** -+ * This function is the same as av_get_audio_frame_duration(), except it works -+ * with AVCodecParameters instead of an AVCodecContext. -+ */ -+int av_get_audio_frame_duration2(AVCodecParameters* par, int frame_bytes); -+ -+/** -+ * @} -+ */ -+ -+#endif // AVCODEC_CODEC_PAR_H -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/defs.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/defs.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/defs.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/defs.h 2022-07-05 00:21:22.443315837 +0300 -@@ -0,0 +1,171 @@ -+/* -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_DEFS_H -+#define AVCODEC_DEFS_H -+ -+/** -+ * @file -+ * @ingroup libavc -+ * Misc types and constants that do not belong anywhere else. -+ */ -+ -+#include -+#include -+ -+/** -+ * @ingroup lavc_decoding -+ * Required number of additionally allocated bytes at the end of the input -+ * bitstream for decoding. This is mainly needed because some optimized -+ * bitstream readers read 32 or 64 bit at once and could read over the end.
-+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged -+ * MPEG bitstreams could cause overread and segfault. -+ */ -+#define AV_INPUT_BUFFER_PADDING_SIZE 64 -+ -+/** -+ * @ingroup lavc_decoding -+ */ -+enum AVDiscard { -+ /* We leave some space between them for extensions (drop some -+ * keyframes for intra-only or drop just some bidir frames). */ -+ AVDISCARD_NONE = -16, ///< discard nothing -+ AVDISCARD_DEFAULT = -+ 0, ///< discard useless packets like 0 size packets in avi -+ AVDISCARD_NONREF = 8, ///< discard all non reference -+ AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames -+ AVDISCARD_NONINTRA = 24, ///< discard all non intra frames -+ AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes -+ AVDISCARD_ALL = 48, ///< discard all -+}; -+ -+enum AVAudioServiceType { -+ AV_AUDIO_SERVICE_TYPE_MAIN = 0, -+ AV_AUDIO_SERVICE_TYPE_EFFECTS = 1, -+ AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2, -+ AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3, -+ AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4, -+ AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5, -+ AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6, -+ AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7, -+ AV_AUDIO_SERVICE_TYPE_KARAOKE = 8, -+ AV_AUDIO_SERVICE_TYPE_NB, ///< Not part of ABI -+}; -+ -+/** -+ * Pan Scan area. -+ * This specifies the area which should be displayed. -+ * Note there may be multiple such areas for one frame. -+ */ -+typedef struct AVPanScan { -+ /** -+ * id -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ int id; -+ -+ /** -+ * width and height in 1/16 pel -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ int width; -+ int height; -+ -+ /** -+ * position of the top left corner in 1/16 pel for up to 3 fields/frames -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ int16_t position[3][2]; -+} AVPanScan; -+ -+/** -+ * This structure describes the bitrate properties of an encoded bitstream. It -+ * roughly corresponds to a subset the VBV parameters for MPEG-2 or HRD -+ * parameters for H.264/HEVC. -+ */ -+typedef struct AVCPBProperties { -+ /** -+ * Maximum bitrate of the stream, in bits per second. -+ * Zero if unknown or unspecified. -+ */ -+ int64_t max_bitrate; -+ /** -+ * Minimum bitrate of the stream, in bits per second. -+ * Zero if unknown or unspecified. -+ */ -+ int64_t min_bitrate; -+ /** -+ * Average bitrate of the stream, in bits per second. -+ * Zero if unknown or unspecified. -+ */ -+ int64_t avg_bitrate; -+ -+ /** -+ * The size of the buffer to which the ratecontrol is applied, in bits. -+ * Zero if unknown or unspecified. -+ */ -+ int64_t buffer_size; -+ -+ /** -+ * The delay between the time the packet this structure is associated with -+ * is received and the time when it should be decoded, in periods of a 27MHz -+ * clock. -+ * -+ * UINT64_MAX when unknown or unspecified. -+ */ -+ uint64_t vbv_delay; -+} AVCPBProperties; -+ -+/** -+ * Allocate a CPB properties structure and initialize its fields to default -+ * values. -+ * -+ * @param size if non-NULL, the size of the allocated struct will be written -+ * here. This is useful for embedding it in side data. -+ * -+ * @return the newly allocated struct or NULL on failure -+ */ -+AVCPBProperties* av_cpb_properties_alloc(size_t* size); -+ -+/** -+ * This structure supplies correlation between a packet timestamp and a wall -+ * clock production time. The definition follows the Producer Reference Time -+ * ('prft') as defined in ISO/IEC 14496-12 -+ */ -+typedef struct AVProducerReferenceTime { -+ /** -+ * A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()). -+ */ -+ int64_t wallclock; -+ int flags; -+} AVProducerReferenceTime; -+ -+/** -+ * Encode extradata length to a buffer. Used by xiph codecs. -+ * -+ * @param s buffer to write to; must be at least (v/255+1) bytes long -+ * @param v size of extradata in bytes -+ * @return number of bytes written to the buffer. -+ */ -+unsigned int av_xiphlacing(unsigned char* s, unsigned int v); -+ -+#endif // AVCODEC_DEFS_H -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/packet.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/packet.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/packet.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/packet.h 2022-07-05 00:21:22.444315831 +0300 -@@ -0,0 +1,724 @@ -+/* -+ * AVPacket public API -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_PACKET_H -+#define AVCODEC_PACKET_H -+ -+#include -+#include -+ -+#include "libavutil/attributes.h" -+#include "libavutil/buffer.h" -+#include "libavutil/dict.h" -+#include "libavutil/rational.h" -+ -+#include "libavcodec/version.h" -+ -+/** -+ * @defgroup lavc_packet AVPacket -+ * -+ * Types and functions for working with AVPacket. -+ * @{ -+ */ -+enum AVPacketSideDataType { -+ /** -+ * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE -+ * bytes worth of palette. This side data signals that a new palette is -+ * present. -+ */ -+ AV_PKT_DATA_PALETTE, -+ -+ /** -+ * The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format -+ * that the extradata buffer was changed and the receiving side should -+ * act upon it appropriately. The new extradata is embedded in the side -+ * data buffer and should be immediately used for processing the current -+ * frame or packet. -+ */ -+ AV_PKT_DATA_NEW_EXTRADATA, -+ -+ /** -+ * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows: -+ * @code -+ * u32le param_flags -+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) -+ * s32le channel_count -+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) -+ * u64le channel_layout -+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) -+ * s32le sample_rate -+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) -+ * s32le width -+ * s32le height -+ * @endcode -+ */ -+ AV_PKT_DATA_PARAM_CHANGE, -+ -+ /** -+ * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of -+ * structures with info about macroblocks relevant to splitting the -+ * packet into smaller packets on macroblock edges (e.g. as for RFC 2190). -+ * That is, it does not necessarily contain info about all macroblocks, -+ * as long as the distance between macroblocks in the info is smaller -+ * than the target payload size. -+ * Each MB info structure is 12 bytes, and is laid out as follows: -+ * @code -+ * u32le bit offset from the start of the packet -+ * u8 current quantizer at the start of the macroblock -+ * u8 GOB number -+ * u16le macroblock address within the GOB -+ * u8 horizontal MV predictor -+ * u8 vertical MV predictor -+ * u8 horizontal MV predictor for block number 3 -+ * u8 vertical MV predictor for block number 3 -+ * @endcode -+ */ -+ AV_PKT_DATA_H263_MB_INFO, -+ -+ /** -+ * This side data should be associated with an audio stream and contains -+ * ReplayGain information in form of the AVReplayGain struct. -+ */ -+ AV_PKT_DATA_REPLAYGAIN, -+ -+ /** -+ * This side data contains a 3x3 transformation matrix describing an affine -+ * transformation that needs to be applied to the decoded video frames for -+ * correct presentation. -+ * -+ * See libavutil/display.h for a detailed description of the data. -+ */ -+ AV_PKT_DATA_DISPLAYMATRIX, -+ -+ /** -+ * This side data should be associated with a video stream and contains -+ * Stereoscopic 3D information in form of the AVStereo3D struct. -+ */ -+ AV_PKT_DATA_STEREO3D, -+ -+ /** -+ * This side data should be associated with an audio stream and corresponds -+ * to enum AVAudioServiceType. -+ */ -+ AV_PKT_DATA_AUDIO_SERVICE_TYPE, -+ -+ /** -+ * This side data contains quality related information from the encoder. -+ * @code -+ * u32le quality factor of the compressed frame. Allowed range is between 1 -+ * (good) and FF_LAMBDA_MAX (bad). u8 picture type u8 error count u16 -+ * reserved u64le[error count] sum of squared differences between encoder in -+ * and output -+ * @endcode -+ */ -+ AV_PKT_DATA_QUALITY_STATS, -+ -+ /** -+ * This side data contains an integer value representing the stream index -+ * of a "fallback" track. A fallback track indicates an alternate -+ * track to use when the current track can not be decoded for some reason. -+ * e.g. no decoder available for codec. -+ */ -+ AV_PKT_DATA_FALLBACK_TRACK, -+ -+ /** -+ * This side data corresponds to the AVCPBProperties struct. -+ */ -+ AV_PKT_DATA_CPB_PROPERTIES, -+ -+ /** -+ * Recommmends skipping the specified number of samples -+ * @code -+ * u32le number of samples to skip from start of this packet -+ * u32le number of samples to skip from end of this packet -+ * u8 reason for start skip -+ * u8 reason for end skip (0=padding silence, 1=convergence) -+ * @endcode -+ */ -+ AV_PKT_DATA_SKIP_SAMPLES, -+ -+ /** -+ * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that -+ * the packet may contain "dual mono" audio specific to Japanese DTV -+ * and if it is true, recommends only the selected channel to be used. -+ * @code -+ * u8 selected channels (0=mail/left, 1=sub/right, 2=both) -+ * @endcode -+ */ -+ AV_PKT_DATA_JP_DUALMONO, -+ -+ /** -+ * A list of zero terminated key/value strings. There is no end marker for -+ * the list, so it is required to rely on the side data size to stop. -+ */ -+ AV_PKT_DATA_STRINGS_METADATA, -+ -+ /** -+ * Subtitle event position -+ * @code -+ * u32le x1 -+ * u32le y1 -+ * u32le x2 -+ * u32le y2 -+ * @endcode -+ */ -+ AV_PKT_DATA_SUBTITLE_POSITION, -+ -+ /** -+ * Data found in BlockAdditional element of matroska container. There is -+ * no end marker for the data, so it is required to rely on the side data -+ * size to recognize the end. 8 byte id (as found in BlockAddId) followed -+ * by data. -+ */ -+ AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, -+ -+ /** -+ * The optional first identifier line of a WebVTT cue. -+ */ -+ AV_PKT_DATA_WEBVTT_IDENTIFIER, -+ -+ /** -+ * The optional settings (rendering instructions) that immediately -+ * follow the timestamp specifier of a WebVTT cue. -+ */ -+ AV_PKT_DATA_WEBVTT_SETTINGS, -+ -+ /** -+ * A list of zero terminated key/value strings. There is no end marker for -+ * the list, so it is required to rely on the side data size to stop. This -+ * side data includes updated metadata which appeared in the stream. -+ */ -+ AV_PKT_DATA_METADATA_UPDATE, -+ -+ /** -+ * MPEGTS stream ID as uint8_t, this is required to pass the stream ID -+ * information from the demuxer to the corresponding muxer. -+ */ -+ AV_PKT_DATA_MPEGTS_STREAM_ID, -+ -+ /** -+ * Mastering display metadata (based on SMPTE-2086:2014). This metadata -+ * should be associated with a video stream and contains data in the form -+ * of the AVMasteringDisplayMetadata struct. -+ */ -+ AV_PKT_DATA_MASTERING_DISPLAY_METADATA, -+ -+ /** -+ * This side data should be associated with a video stream and corresponds -+ * to the AVSphericalMapping structure. -+ */ -+ AV_PKT_DATA_SPHERICAL, -+ -+ /** -+ * Content light level (based on CTA-861.3). This metadata should be -+ * associated with a video stream and contains data in the form of the -+ * AVContentLightMetadata struct. -+ */ -+ AV_PKT_DATA_CONTENT_LIGHT_LEVEL, -+ -+ /** -+ * ATSC A53 Part 4 Closed Captions. This metadata should be associated with -+ * a video stream. A53 CC bitstream is stored as uint8_t in -+ * AVPacketSideData.data. The number of bytes of CC data is -+ * AVPacketSideData.size. -+ */ -+ AV_PKT_DATA_A53_CC, -+ -+ /** -+ * This side data is encryption initialization data. -+ * The format is not part of ABI, use av_encryption_init_info_* methods to -+ * access. -+ */ -+ AV_PKT_DATA_ENCRYPTION_INIT_INFO, -+ -+ /** -+ * This side data contains encryption info for how to decrypt the packet. -+ * The format is not part of ABI, use av_encryption_info_* methods to access. -+ */ -+ AV_PKT_DATA_ENCRYPTION_INFO, -+ -+ /** -+ * Active Format Description data consisting of a single byte as specified -+ * in ETSI TS 101 154 using AVActiveFormatDescription enum. -+ */ -+ AV_PKT_DATA_AFD, -+ -+ /** -+ * Producer Reference Time data corresponding to the AVProducerReferenceTime -+ * struct, usually exported by some encoders (on demand through the prft flag -+ * set in the AVCodecContext export_side_data field). -+ */ -+ AV_PKT_DATA_PRFT, -+ -+ /** -+ * ICC profile data consisting of an opaque octet buffer following the -+ * format described by ISO 15076-1. -+ */ -+ AV_PKT_DATA_ICC_PROFILE, -+ -+ /** -+ * DOVI configuration -+ * ref: -+ * dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.1.2, -+ * section 2.2 -+ * dolby-vision-bitstreams-in-mpeg-2-transport-stream-multiplex-v1.2, -+ * section 3.3 Tags are stored in struct AVDOVIDecoderConfigurationRecord. -+ */ -+ AV_PKT_DATA_DOVI_CONF, -+ -+ /** -+ * Timecode which conforms to SMPTE ST 12-1:2014. The data is an array of 4 -+ * uint32_t where the first uint32_t describes how many (1-3) of the other -+ * timecodes are used. The timecode format is described in the documentation -+ * of av_timecode_get_smpte_from_framenum() function in libavutil/timecode.h. -+ */ -+ AV_PKT_DATA_S12M_TIMECODE, -+ -+ /** -+ * HDR10+ dynamic metadata associated with a video frame. The metadata is in -+ * the form of the AVDynamicHDRPlus struct and contains -+ * information for color volume transform - application 4 of -+ * SMPTE 2094-40:2016 standard. -+ */ -+ AV_PKT_DATA_DYNAMIC_HDR10_PLUS, -+ -+ /** -+ * The number of side data types. -+ * This is not part of the public API/ABI in the sense that it may -+ * change when new side data types are added. -+ * This must stay the last enum value. -+ * If its value becomes huge, some code using it -+ * needs to be updated as it assumes it to be smaller than other limits. -+ */ -+ AV_PKT_DATA_NB -+}; -+ -+#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS // DEPRECATED -+ -+typedef struct AVPacketSideData { -+ uint8_t* data; -+ size_t size; -+ enum AVPacketSideDataType type; -+} AVPacketSideData; -+ -+/** -+ * This structure stores compressed data. It is typically exported by demuxers -+ * and then passed as input to decoders, or received as output from encoders and -+ * then passed to muxers. -+ * -+ * For video, it should typically contain one compressed frame. For audio it may -+ * contain several compressed frames. Encoders are allowed to output empty -+ * packets, with no compressed data, containing only side data -+ * (e.g. to update some stream parameters at the end of encoding). -+ * -+ * The semantics of data ownership depends on the buf field. -+ * If it is set, the packet data is dynamically allocated and is -+ * valid indefinitely until a call to av_packet_unref() reduces the -+ * reference count to 0. -+ * -+ * If the buf field is not set av_packet_ref() would make a copy instead -+ * of increasing the reference count. -+ * -+ * The side data is always allocated with av_malloc(), copied by -+ * av_packet_ref() and freed by av_packet_unref(). -+ * -+ * sizeof(AVPacket) being a part of the public ABI is deprecated. once -+ * av_init_packet() is removed, new packets will only be able to be allocated -+ * with av_packet_alloc(), and new fields may be added to the end of the struct -+ * with a minor bump. -+ * -+ * @see av_packet_alloc -+ * @see av_packet_ref -+ * @see av_packet_unref -+ */ -+typedef struct AVPacket { -+ /** -+ * A reference to the reference-counted buffer where the packet data is -+ * stored. -+ * May be NULL, then the packet data is not reference-counted. -+ */ -+ AVBufferRef* buf; -+ /** -+ * Presentation timestamp in AVStream->time_base units; the time at which -+ * the decompressed packet will be presented to the user. -+ * Can be AV_NOPTS_VALUE if it is not stored in the file. -+ * pts MUST be larger or equal to dts as presentation cannot happen before -+ * decompression, unless one wants to view hex dumps. Some formats misuse -+ * the terms dts and pts/cts to mean something different. Such timestamps -+ * must be converted to true pts/dts before they are stored in AVPacket. -+ */ -+ int64_t pts; -+ /** -+ * Decompression timestamp in AVStream->time_base units; the time at which -+ * the packet is decompressed. -+ * Can be AV_NOPTS_VALUE if it is not stored in the file. -+ */ -+ int64_t dts; -+ uint8_t* data; -+ int size; -+ int stream_index; -+ /** -+ * A combination of AV_PKT_FLAG values -+ */ -+ int flags; -+ /** -+ * Additional packet data that can be provided by the container. -+ * Packet can contain several types of side information. -+ */ -+ AVPacketSideData* side_data; -+ int side_data_elems; -+ -+ /** -+ * Duration of this packet in AVStream->time_base units, 0 if unknown. -+ * Equals next_pts - this_pts in presentation order. -+ */ -+ int64_t duration; -+ -+ int64_t pos; ///< byte position in stream, -1 if unknown -+ -+ /** -+ * for some private data of the user -+ */ -+ void* opaque; -+ -+ /** -+ * AVBufferRef for free use by the API user. FFmpeg will never check the -+ * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when -+ * the packet is unreferenced. av_packet_copy_props() calls create a new -+ * reference with av_buffer_ref() for the target packet's opaque_ref field. -+ * -+ * This is unrelated to the opaque field, although it serves a similar -+ * purpose. -+ */ -+ AVBufferRef* opaque_ref; -+ -+ /** -+ * Time base of the packet's timestamps. -+ * In the future, this field may be set on packets output by encoders or -+ * demuxers, but its value will be by default ignored on input to decoders -+ * or muxers. -+ */ -+ AVRational time_base; -+} AVPacket; -+ -+#if FF_API_INIT_PACKET -+attribute_deprecated typedef struct AVPacketList { -+ AVPacket pkt; -+ struct AVPacketList* next; -+} AVPacketList; -+#endif -+ -+#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe -+#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted -+/** -+ * Flag is used to discard packets which are required to maintain valid -+ * decoder state but are not required for output and should be dropped -+ * after decoding. -+ **/ -+#define AV_PKT_FLAG_DISCARD 0x0004 -+/** -+ * The packet comes from a trusted source. -+ * -+ * Otherwise-unsafe constructs such as arbitrary pointers to data -+ * outside the packet may be followed. -+ */ -+#define AV_PKT_FLAG_TRUSTED 0x0008 -+/** -+ * Flag is used to indicate packets that contain frames that can -+ * be discarded by the decoder. I.e. Non-reference frames. -+ */ -+#define AV_PKT_FLAG_DISPOSABLE 0x0010 -+ -+enum AVSideDataParamChangeFlags { -+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, -+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002, -+ AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004, -+ AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008, -+}; -+ -+/** -+ * Allocate an AVPacket and set its fields to default values. The resulting -+ * struct must be freed using av_packet_free(). -+ * -+ * @return An AVPacket filled with default values or NULL on failure. -+ * -+ * @note this only allocates the AVPacket itself, not the data buffers. Those -+ * must be allocated through other means such as av_new_packet. -+ * -+ * @see av_new_packet -+ */ -+AVPacket* av_packet_alloc(void); -+ -+/** -+ * Create a new packet that references the same data as src. -+ * -+ * This is a shortcut for av_packet_alloc()+av_packet_ref(). -+ * -+ * @return newly created AVPacket on success, NULL on error. -+ * -+ * @see av_packet_alloc -+ * @see av_packet_ref -+ */ -+AVPacket* av_packet_clone(const AVPacket* src); -+ -+/** -+ * Free the packet, if the packet is reference counted, it will be -+ * unreferenced first. -+ * -+ * @param pkt packet to be freed. The pointer will be set to NULL. -+ * @note passing NULL is a no-op. -+ */ -+void av_packet_free(AVPacket** pkt); -+ -+#if FF_API_INIT_PACKET -+/** -+ * Initialize optional fields of a packet with default values. -+ * -+ * Note, this does not touch the data and size members, which have to be -+ * initialized separately. -+ * -+ * @param pkt packet -+ * -+ * @see av_packet_alloc -+ * @see av_packet_unref -+ * -+ * @deprecated This function is deprecated. Once it's removed, -+ sizeof(AVPacket) will not be a part of the ABI anymore. -+ */ -+attribute_deprecated void av_init_packet(AVPacket* pkt); -+#endif -+ -+/** -+ * Allocate the payload of a packet and initialize its fields with -+ * default values. -+ * -+ * @param pkt packet -+ * @param size wanted payload size -+ * @return 0 if OK, AVERROR_xxx otherwise -+ */ -+int av_new_packet(AVPacket* pkt, int size); -+ -+/** -+ * Reduce packet size, correctly zeroing padding -+ * -+ * @param pkt packet -+ * @param size new size -+ */ -+void av_shrink_packet(AVPacket* pkt, int size); -+ -+/** -+ * Increase packet size, correctly zeroing padding -+ * -+ * @param pkt packet -+ * @param grow_by number of bytes by which to increase the size of the packet -+ */ -+int av_grow_packet(AVPacket* pkt, int grow_by); -+ -+/** -+ * Initialize a reference-counted packet from av_malloc()ed data. -+ * -+ * @param pkt packet to be initialized. This function will set the data, size, -+ * and buf fields, all others are left untouched. -+ * @param data Data allocated by av_malloc() to be used as packet data. If this -+ * function returns successfully, the data is owned by the underlying -+ * AVBuffer. The caller may not access the data through other means. -+ * @param size size of data in bytes, without the padding. I.e. the full buffer -+ * size is assumed to be size + AV_INPUT_BUFFER_PADDING_SIZE. -+ * -+ * @return 0 on success, a negative AVERROR on error -+ */ -+int av_packet_from_data(AVPacket* pkt, uint8_t* data, int size); -+ -+/** -+ * Allocate new information of a packet. -+ * -+ * @param pkt packet -+ * @param type side information type -+ * @param size side information size -+ * @return pointer to fresh allocated data or NULL otherwise -+ */ -+uint8_t* av_packet_new_side_data(AVPacket* pkt, enum AVPacketSideDataType type, -+ size_t size); -+ -+/** -+ * Wrap an existing array as a packet side data. -+ * -+ * @param pkt packet -+ * @param type side information type -+ * @param data the side data array. It must be allocated with the av_malloc() -+ * family of functions. The ownership of the data is transferred to -+ * pkt. -+ * @param size side information size -+ * @return a non-negative number on success, a negative AVERROR code on -+ * failure. On failure, the packet is unchanged and the data remains -+ * owned by the caller. -+ */ -+int av_packet_add_side_data(AVPacket* pkt, enum AVPacketSideDataType type, -+ uint8_t* data, size_t size); -+ -+/** -+ * Shrink the already allocated side data buffer -+ * -+ * @param pkt packet -+ * @param type side information type -+ * @param size new side information size -+ * @return 0 on success, < 0 on failure -+ */ -+int av_packet_shrink_side_data(AVPacket* pkt, enum AVPacketSideDataType type, -+ size_t size); -+ -+/** -+ * Get side information from packet. -+ * -+ * @param pkt packet -+ * @param type desired side information type -+ * @param size If supplied, *size will be set to the size of the side data -+ * or to zero if the desired side data is not present. -+ * @return pointer to data if present or NULL otherwise -+ */ -+uint8_t* av_packet_get_side_data(const AVPacket* pkt, -+ enum AVPacketSideDataType type, size_t* size); -+ -+const char* av_packet_side_data_name(enum AVPacketSideDataType type); -+ -+/** -+ * Pack a dictionary for use in side_data. -+ * -+ * @param dict The dictionary to pack. -+ * @param size pointer to store the size of the returned data -+ * @return pointer to data if successful, NULL otherwise -+ */ -+uint8_t* av_packet_pack_dictionary(AVDictionary* dict, size_t* size); -+/** -+ * Unpack a dictionary from side_data. -+ * -+ * @param data data from side_data -+ * @param size size of the data -+ * @param dict the metadata storage dictionary -+ * @return 0 on success, < 0 on failure -+ */ -+int av_packet_unpack_dictionary(const uint8_t* data, size_t size, -+ AVDictionary** dict); -+ -+/** -+ * Convenience function to free all the side data stored. -+ * All the other fields stay untouched. -+ * -+ * @param pkt packet -+ */ -+void av_packet_free_side_data(AVPacket* pkt); -+ -+/** -+ * Setup a new reference to the data described by a given packet -+ * -+ * If src is reference-counted, setup dst as a new reference to the -+ * buffer in src. Otherwise allocate a new buffer in dst and copy the -+ * data from src into it. -+ * -+ * All the other fields are copied from src. -+ * -+ * @see av_packet_unref -+ * -+ * @param dst Destination packet. Will be completely overwritten. -+ * @param src Source packet -+ * -+ * @return 0 on success, a negative AVERROR on error. On error, dst -+ * will be blank (as if returned by av_packet_alloc()). -+ */ -+int av_packet_ref(AVPacket* dst, const AVPacket* src); -+ -+/** -+ * Wipe the packet. -+ * -+ * Unreference the buffer referenced by the packet and reset the -+ * remaining packet fields to their default values. -+ * -+ * @param pkt The packet to be unreferenced. -+ */ -+void av_packet_unref(AVPacket* pkt); -+ -+/** -+ * Move every field in src to dst and reset src. -+ * -+ * @see av_packet_unref -+ * -+ * @param src Source packet, will be reset -+ * @param dst Destination packet -+ */ -+void av_packet_move_ref(AVPacket* dst, AVPacket* src); -+ -+/** -+ * Copy only "properties" fields from src to dst. -+ * -+ * Properties for the purpose of this function are all the fields -+ * beside those related to the packet data (buf, data, size) -+ * -+ * @param dst Destination packet -+ * @param src Source packet -+ * -+ * @return 0 on success AVERROR on failure. -+ */ -+int av_packet_copy_props(AVPacket* dst, const AVPacket* src); -+ -+/** -+ * Ensure the data described by a given packet is reference counted. -+ * -+ * @note This function does not ensure that the reference will be writable. -+ * Use av_packet_make_writable instead for that purpose. -+ * -+ * @see av_packet_ref -+ * @see av_packet_make_writable -+ * -+ * @param pkt packet whose data should be made reference counted. -+ * -+ * @return 0 on success, a negative AVERROR on error. On failure, the -+ * packet is unchanged. -+ */ -+int av_packet_make_refcounted(AVPacket* pkt); -+ -+/** -+ * Create a writable reference for the data described by a given packet, -+ * avoiding data copy if possible. -+ * -+ * @param pkt Packet whose data should be made writable. -+ * -+ * @return 0 on success, a negative AVERROR on failure. On failure, the -+ * packet is unchanged. -+ */ -+int av_packet_make_writable(AVPacket* pkt); -+ -+/** -+ * Convert valid timing fields (timestamps / durations) in a packet from one -+ * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be -+ * ignored. -+ * -+ * @param pkt packet on which the conversion will be performed -+ * @param tb_src source timebase, in which the timing fields in pkt are -+ * expressed -+ * @param tb_dst destination timebase, to which the timing fields will be -+ * converted -+ */ -+void av_packet_rescale_ts(AVPacket* pkt, AVRational tb_src, AVRational tb_dst); -+ -+/** -+ * @} -+ */ -+ -+#endif // AVCODEC_PACKET_H -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/vdpau.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/vdpau.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/vdpau.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/vdpau.h 2022-07-05 00:21:22.444315831 +0300 -@@ -0,0 +1,156 @@ -+/* -+ * The Video Decode and Presentation API for UNIX (VDPAU) is used for -+ * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1. -+ * -+ * Copyright (C) 2008 NVIDIA -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_VDPAU_H -+#define AVCODEC_VDPAU_H -+ -+/** -+ * @file -+ * @ingroup lavc_codec_hwaccel_vdpau -+ * Public libavcodec VDPAU header. -+ */ -+ -+/** -+ * @defgroup lavc_codec_hwaccel_vdpau VDPAU Decoder and Renderer -+ * @ingroup lavc_codec_hwaccel -+ * -+ * VDPAU hardware acceleration has two modules -+ * - VDPAU decoding -+ * - VDPAU presentation -+ * -+ * The VDPAU decoding module parses all headers using FFmpeg -+ * parsing mechanisms and uses VDPAU for the actual decoding. -+ * -+ * As per the current implementation, the actual decoding -+ * and rendering (API calls) are done as part of the VDPAU -+ * presentation (vo_vdpau.c) module. -+ * -+ * @{ -+ */ -+ -+#include -+ -+#include "libavutil/avconfig.h" -+#include "libavutil/attributes.h" -+ -+#include "avcodec.h" -+ -+struct AVCodecContext; -+struct AVFrame; -+ -+typedef int (*AVVDPAU_Render2)(struct AVCodecContext*, struct AVFrame*, -+ const VdpPictureInfo*, uint32_t, -+ const VdpBitstreamBuffer*); -+ -+/** -+ * This structure is used to share data between the libavcodec library and -+ * the client video application. -+ * The user shall allocate the structure via the av_alloc_vdpau_hwaccel -+ * function and make it available as -+ * AVCodecContext.hwaccel_context. Members can be set by the user once -+ * during initialization or through each AVCodecContext.get_buffer() -+ * function call. In any case, they must be valid prior to calling -+ * decoding functions. -+ * -+ * The size of this structure is not a part of the public ABI and must not -+ * be used outside of libavcodec. Use av_vdpau_alloc_context() to allocate an -+ * AVVDPAUContext. -+ */ -+typedef struct AVVDPAUContext { -+ /** -+ * VDPAU decoder handle -+ * -+ * Set by user. -+ */ -+ VdpDecoder decoder; -+ -+ /** -+ * VDPAU decoder render callback -+ * -+ * Set by the user. -+ */ -+ VdpDecoderRender* render; -+ -+ AVVDPAU_Render2 render2; -+} AVVDPAUContext; -+ -+/** -+ * @brief allocation function for AVVDPAUContext -+ * -+ * Allows extending the struct without breaking API/ABI -+ */ -+AVVDPAUContext* av_alloc_vdpaucontext(void); -+ -+AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext*); -+void av_vdpau_hwaccel_set_render2(AVVDPAUContext*, AVVDPAU_Render2); -+ -+/** -+ * Associate a VDPAU device with a codec context for hardware acceleration. -+ * This function is meant to be called from the get_format() codec callback, -+ * or earlier. It can also be called after avcodec_flush_buffers() to change -+ * the underlying VDPAU device mid-stream (e.g. to recover from non-transparent -+ * display preemption). -+ * -+ * @note get_format() must return AV_PIX_FMT_VDPAU if this function completes -+ * successfully. -+ * -+ * @param avctx decoding context whose get_format() callback is invoked -+ * @param device VDPAU device handle to use for hardware acceleration -+ * @param get_proc_address VDPAU device driver -+ * @param flags zero of more OR'd AV_HWACCEL_FLAG_* flags -+ * -+ * @return 0 on success, an AVERROR code on failure. -+ */ -+int av_vdpau_bind_context(AVCodecContext* avctx, VdpDevice device, -+ VdpGetProcAddress* get_proc_address, unsigned flags); -+ -+/** -+ * Gets the parameters to create an adequate VDPAU video surface for the codec -+ * context using VDPAU hardware decoding acceleration. -+ * -+ * @note Behavior is undefined if the context was not successfully bound to a -+ * VDPAU device using av_vdpau_bind_context(). -+ * -+ * @param avctx the codec context being used for decoding the stream -+ * @param type storage space for the VDPAU video surface chroma type -+ * (or NULL to ignore) -+ * @param width storage space for the VDPAU video surface pixel width -+ * (or NULL to ignore) -+ * @param height storage space for the VDPAU video surface pixel height -+ * (or NULL to ignore) -+ * -+ * @return 0 on success, a negative AVERROR code on failure. -+ */ -+int av_vdpau_get_surface_parameters(AVCodecContext* avctx, VdpChromaType* type, -+ uint32_t* width, uint32_t* height); -+ -+/** -+ * Allocate an AVVDPAUContext. -+ * -+ * @return Newly-allocated AVVDPAUContext or NULL on failure. -+ */ -+AVVDPAUContext* av_vdpau_alloc_context(void); -+ -+/* @}*/ -+ -+#endif /* AVCODEC_VDPAU_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/version.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/version.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/version.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavcodec/version.h 2022-07-05 00:21:22.444315831 +0300 -@@ -0,0 +1,67 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVCODEC_VERSION_H -+#define AVCODEC_VERSION_H -+ -+/** -+ * @file -+ * @ingroup libavc -+ * Libavcodec version macros. -+ */ -+ -+#include "libavutil/version.h" -+ -+#define LIBAVCODEC_VERSION_MAJOR 59 -+#define LIBAVCODEC_VERSION_MINOR 18 -+#define LIBAVCODEC_VERSION_MICRO 100 -+ -+#define LIBAVCODEC_VERSION_INT \ -+ AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, \ -+ LIBAVCODEC_VERSION_MICRO) -+#define LIBAVCODEC_VERSION \ -+ AV_VERSION(LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, \ -+ LIBAVCODEC_VERSION_MICRO) -+#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT -+ -+#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) -+ -+/** -+ * FF_API_* defines may be placed below to indicate public API that will be -+ * dropped at a future version bump. The defines themselves are not part of -+ * the public API and may change, break or disappear at any time. -+ * -+ * @note, when bumping the major version it is recommended to manually -+ * disable each FF_API_* in its own commit instead of disabling them all -+ * at once through the bump. This improves the git bisect-ability of the change. -+ */ -+ -+#define FF_API_OPENH264_SLICE_MODE (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_OPENH264_CABAC (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_UNUSED_CODEC_CAPS (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_THREAD_SAFE_CALLBACKS (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_GET_FRAME_CLASS (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_AUTO_THREADS (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_MPEGVIDEO_OPTS (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_FLAG_TRUNCATED (LIBAVCODEC_VERSION_MAJOR < 60) -+#define FF_API_SUB_TEXT_FORMAT (LIBAVCODEC_VERSION_MAJOR < 60) -+ -+#endif /* AVCODEC_VERSION_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/attributes.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/attributes.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/attributes.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/attributes.h 2022-07-05 00:21:22.445315825 +0300 -@@ -0,0 +1,173 @@ -+/* -+ * copyright (c) 2006 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * Macro definitions for various function/variable attributes -+ */ -+ -+#ifndef AVUTIL_ATTRIBUTES_H -+#define AVUTIL_ATTRIBUTES_H -+ -+#ifdef __GNUC__ -+# define AV_GCC_VERSION_AT_LEAST(x, y) \ -+ (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) -+# define AV_GCC_VERSION_AT_MOST(x, y) \ -+ (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y)) -+#else -+# define AV_GCC_VERSION_AT_LEAST(x, y) 0 -+# define AV_GCC_VERSION_AT_MOST(x, y) 0 -+#endif -+ -+#ifdef __has_builtin -+# define AV_HAS_BUILTIN(x) __has_builtin(x) -+#else -+# define AV_HAS_BUILTIN(x) 0 -+#endif -+ -+#ifndef av_always_inline -+# if AV_GCC_VERSION_AT_LEAST(3, 1) -+# define av_always_inline __attribute__((always_inline)) inline -+# elif defined(_MSC_VER) -+# define av_always_inline __forceinline -+# else -+# define av_always_inline inline -+# endif -+#endif -+ -+#ifndef av_extern_inline -+# if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__) -+# define av_extern_inline extern inline -+# else -+# define av_extern_inline inline -+# endif -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(3, 4) -+# define av_warn_unused_result __attribute__((warn_unused_result)) -+#else -+# define av_warn_unused_result -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(3, 1) -+# define av_noinline __attribute__((noinline)) -+#elif defined(_MSC_VER) -+# define av_noinline __declspec(noinline) -+#else -+# define av_noinline -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(3, 1) || defined(__clang__) -+# define av_pure __attribute__((pure)) -+#else -+# define av_pure -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(2, 6) || defined(__clang__) -+# define av_const __attribute__((const)) -+#else -+# define av_const -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(4, 3) || defined(__clang__) -+# define av_cold __attribute__((cold)) -+#else -+# define av_cold -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(4, 1) && !defined(__llvm__) -+# define av_flatten __attribute__((flatten)) -+#else -+# define av_flatten -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(3, 1) -+# define attribute_deprecated __attribute__((deprecated)) -+#elif defined(_MSC_VER) -+# define attribute_deprecated __declspec(deprecated) -+#else -+# define attribute_deprecated -+#endif -+ -+/** -+ * Disable warnings about deprecated features -+ * This is useful for sections of code kept for backward compatibility and -+ * scheduled for removal. -+ */ -+#ifndef AV_NOWARN_DEPRECATED -+# if AV_GCC_VERSION_AT_LEAST(4, 6) -+# define AV_NOWARN_DEPRECATED(code) \ -+ _Pragma("GCC diagnostic push") \ -+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ -+ code _Pragma("GCC diagnostic pop") -+# elif defined(_MSC_VER) -+# define AV_NOWARN_DEPRECATED(code) \ -+ __pragma(warning(push)) __pragma(warning(disable : 4996)) code; \ -+ __pragma(warning(pop)) -+# else -+# define AV_NOWARN_DEPRECATED(code) code -+# endif -+#endif -+ -+#if defined(__GNUC__) || defined(__clang__) -+# define av_unused __attribute__((unused)) -+#else -+# define av_unused -+#endif -+ -+/** -+ * Mark a variable as used and prevent the compiler from optimizing it -+ * away. This is useful for variables accessed only from inline -+ * assembler without the compiler being aware. -+ */ -+#if AV_GCC_VERSION_AT_LEAST(3, 1) || defined(__clang__) -+# define av_used __attribute__((used)) -+#else -+# define av_used -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(3, 3) || defined(__clang__) -+# define av_alias __attribute__((may_alias)) -+#else -+# define av_alias -+#endif -+ -+#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) -+# define av_uninit(x) x = x -+#else -+# define av_uninit(x) x -+#endif -+ -+#if defined(__GNUC__) || defined(__clang__) -+# define av_builtin_constant_p __builtin_constant_p -+# define av_printf_format(fmtpos, attrpos) \ -+ __attribute__((__format__(__printf__, fmtpos, attrpos))) -+#else -+# define av_builtin_constant_p(x) 0 -+# define av_printf_format(fmtpos, attrpos) -+#endif -+ -+#if AV_GCC_VERSION_AT_LEAST(2, 5) || defined(__clang__) -+# define av_noreturn __attribute__((noreturn)) -+#else -+# define av_noreturn -+#endif -+ -+#endif /* AVUTIL_ATTRIBUTES_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avconfig.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avconfig.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avconfig.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avconfig.h 2022-07-05 00:21:22.445315825 +0300 -@@ -0,0 +1,6 @@ -+/* Generated by ffmpeg configure */ -+#ifndef AVUTIL_AVCONFIG_H -+#define AVUTIL_AVCONFIG_H -+#define AV_HAVE_BIGENDIAN 0 -+#define AV_HAVE_FAST_UNALIGNED 1 -+#endif /* AVUTIL_AVCONFIG_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avutil.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avutil.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avutil.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/avutil.h 2022-07-05 00:21:22.445315825 +0300 -@@ -0,0 +1,366 @@ -+/* -+ * copyright (c) 2006 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_AVUTIL_H -+#define AVUTIL_AVUTIL_H -+ -+/** -+ * @file -+ * @ingroup lavu -+ * Convenience header that includes @ref lavu "libavutil"'s core. -+ */ -+ -+/** -+ * @mainpage -+ * -+ * @section ffmpeg_intro Introduction -+ * -+ * This document describes the usage of the different libraries -+ * provided by FFmpeg. -+ * -+ * @li @ref libavc "libavcodec" encoding/decoding library -+ * @li @ref lavfi "libavfilter" graph-based frame editing library -+ * @li @ref libavf "libavformat" I/O and muxing/demuxing library -+ * @li @ref lavd "libavdevice" special devices muxing/demuxing library -+ * @li @ref lavu "libavutil" common utility library -+ * @li @ref lswr "libswresample" audio resampling, format conversion and mixing -+ * @li @ref lpp "libpostproc" post processing library -+ * @li @ref libsws "libswscale" color conversion and scaling library -+ * -+ * @section ffmpeg_versioning Versioning and compatibility -+ * -+ * Each of the FFmpeg libraries contains a version.h header, which defines a -+ * major, minor and micro version number with the -+ * LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO} macros. The major version -+ * number is incremented with backward incompatible changes - e.g. removing -+ * parts of the public API, reordering public struct members, etc. The minor -+ * version number is incremented for backward compatible API changes or major -+ * new features - e.g. adding a new public function or a new decoder. The micro -+ * version number is incremented for smaller changes that a calling program -+ * might still want to check for - e.g. changing behavior in a previously -+ * unspecified situation. -+ * -+ * FFmpeg guarantees backward API and ABI compatibility for each library as long -+ * as its major version number is unchanged. This means that no public symbols -+ * will be removed or renamed. Types and names of the public struct members and -+ * values of public macros and enums will remain the same (unless they were -+ * explicitly declared as not part of the public API). Documented behavior will -+ * not change. -+ * -+ * In other words, any correct program that works with a given FFmpeg snapshot -+ * should work just as well without any changes with any later snapshot with the -+ * same major versions. This applies to both rebuilding the program against new -+ * FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program -+ * links against. -+ * -+ * However, new public symbols may be added and new members may be appended to -+ * public structs whose size is not part of public ABI (most public structs in -+ * FFmpeg). New macros and enum values may be added. Behavior in undocumented -+ * situations may change slightly (and be documented). All those are accompanied -+ * by an entry in doc/APIchanges and incrementing either the minor or micro -+ * version number. -+ */ -+ -+/** -+ * @defgroup lavu libavutil -+ * Common code shared across all FFmpeg libraries. -+ * -+ * @note -+ * libavutil is designed to be modular. In most cases, in order to use the -+ * functions provided by one component of libavutil you must explicitly include -+ * the specific header containing that feature. If you are only using -+ * media-related components, you could simply include libavutil/avutil.h, which -+ * brings in most of the "core" components. -+ * -+ * @{ -+ * -+ * @defgroup lavu_crypto Crypto and Hashing -+ * -+ * @{ -+ * @} -+ * -+ * @defgroup lavu_math Mathematics -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_string String Manipulation -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_mem Memory Management -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_data Data Structures -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_video Video related -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_audio Audio related -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_error Error Codes -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_log Logging Facility -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup lavu_misc Other -+ * -+ * @{ -+ * -+ * @defgroup preproc_misc Preprocessor String Macros -+ * -+ * @{ -+ * -+ * @} -+ * -+ * @defgroup version_utils Library Version Macros -+ * -+ * @{ -+ * -+ * @} -+ */ -+ -+/** -+ * @addtogroup lavu_ver -+ * @{ -+ */ -+ -+/** -+ * Return the LIBAVUTIL_VERSION_INT constant. -+ */ -+unsigned avutil_version(void); -+ -+/** -+ * Return an informative version string. This usually is the actual release -+ * version number or a git commit description. This string has no fixed format -+ * and can change any time. It should never be parsed by code. -+ */ -+const char* av_version_info(void); -+ -+/** -+ * Return the libavutil build-time configuration. -+ */ -+const char* avutil_configuration(void); -+ -+/** -+ * Return the libavutil license. -+ */ -+const char* avutil_license(void); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @addtogroup lavu_media Media Type -+ * @brief Media Type -+ */ -+ -+enum AVMediaType { -+ AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA -+ AVMEDIA_TYPE_VIDEO, -+ AVMEDIA_TYPE_AUDIO, -+ AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous -+ AVMEDIA_TYPE_SUBTITLE, -+ AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse -+ AVMEDIA_TYPE_NB -+}; -+ -+/** -+ * Return a string describing the media_type enum, NULL if media_type -+ * is unknown. -+ */ -+const char* av_get_media_type_string(enum AVMediaType media_type); -+ -+/** -+ * @defgroup lavu_const Constants -+ * @{ -+ * -+ * @defgroup lavu_enc Encoding specific -+ * -+ * @note those definition should move to avcodec -+ * @{ -+ */ -+ -+#define FF_LAMBDA_SHIFT 7 -+#define FF_LAMBDA_SCALE (1 << FF_LAMBDA_SHIFT) -+#define FF_QP2LAMBDA 118 ///< factor to convert from H.263 QP to lambda -+#define FF_LAMBDA_MAX (256 * 128 - 1) -+ -+#define FF_QUALITY_SCALE FF_LAMBDA_SCALE // FIXME maybe remove -+ -+/** -+ * @} -+ * @defgroup lavu_time Timestamp specific -+ * -+ * FFmpeg internal timebase and timestamp definitions -+ * -+ * @{ -+ */ -+ -+/** -+ * @brief Undefined timestamp value -+ * -+ * Usually reported by demuxer that work on containers that do not provide -+ * either pts or dts. -+ */ -+ -+#define AV_NOPTS_VALUE ((int64_t)UINT64_C(0x8000000000000000)) -+ -+/** -+ * Internal time base represented as integer -+ */ -+ -+#define AV_TIME_BASE 1000000 -+ -+/** -+ * Internal time base represented as fractional value -+ */ -+ -+#define AV_TIME_BASE_Q \ -+ (AVRational) { 1, AV_TIME_BASE } -+ -+/** -+ * @} -+ * @} -+ * @defgroup lavu_picture Image related -+ * -+ * AVPicture types, pixel formats and basic image planes manipulation. -+ * -+ * @{ -+ */ -+ -+enum AVPictureType { -+ AV_PICTURE_TYPE_NONE = 0, ///< Undefined -+ AV_PICTURE_TYPE_I, ///< Intra -+ AV_PICTURE_TYPE_P, ///< Predicted -+ AV_PICTURE_TYPE_B, ///< Bi-dir predicted -+ AV_PICTURE_TYPE_S, ///< S(GMC)-VOP MPEG-4 -+ AV_PICTURE_TYPE_SI, ///< Switching Intra -+ AV_PICTURE_TYPE_SP, ///< Switching Predicted -+ AV_PICTURE_TYPE_BI, ///< BI type -+}; -+ -+/** -+ * Return a single letter to describe the given picture type -+ * pict_type. -+ * -+ * @param[in] pict_type the picture type @return a single character -+ * representing the picture type, '?' if pict_type is unknown -+ */ -+char av_get_picture_type_char(enum AVPictureType pict_type); -+ -+/** -+ * @} -+ */ -+ -+#include "common.h" -+#include "error.h" -+#include "rational.h" -+#include "version.h" -+#include "macros.h" -+#include "mathematics.h" -+#include "log.h" -+#include "pixfmt.h" -+ -+/** -+ * Return x default pointer in case p is NULL. -+ */ -+static inline void* av_x_if_null(const void* p, const void* x) { -+ return (void*)(intptr_t)(p ? p : x); -+} -+ -+/** -+ * Compute the length of an integer list. -+ * -+ * @param elsize size in bytes of each list element (only 1, 2, 4 or 8) -+ * @param term list terminator (usually 0 or -1) -+ * @param list pointer to the list -+ * @return length of the list, in elements, not counting the terminator -+ */ -+unsigned av_int_list_length_for_size(unsigned elsize, const void* list, -+ uint64_t term) av_pure; -+ -+/** -+ * Compute the length of an integer list. -+ * -+ * @param term list terminator (usually 0 or -1) -+ * @param list pointer to the list -+ * @return length of the list, in elements, not counting the terminator -+ */ -+#define av_int_list_length(list, term) \ -+ av_int_list_length_for_size(sizeof(*(list)), list, term) -+ -+/** -+ * Open a file using a UTF-8 filename. -+ * The API of this function matches POSIX fopen(), errors are returned through -+ * errno. -+ */ -+FILE* av_fopen_utf8(const char* path, const char* mode); -+ -+/** -+ * Return the fractional representation of the internal time base. -+ */ -+AVRational av_get_time_base_q(void); -+ -+#define AV_FOURCC_MAX_STRING_SIZE 32 -+ -+#define av_fourcc2str(fourcc) \ -+ av_fourcc_make_string((char[AV_FOURCC_MAX_STRING_SIZE]){0}, fourcc) -+ -+/** -+ * Fill the provided buffer with a string containing a FourCC (four-character -+ * code) representation. -+ * -+ * @param buf a buffer with size in bytes of at least -+ * AV_FOURCC_MAX_STRING_SIZE -+ * @param fourcc the fourcc to represent -+ * @return the buffer in input -+ */ -+char* av_fourcc_make_string(char* buf, uint32_t fourcc); -+ -+/** -+ * @} -+ * @} -+ */ -+ -+#endif /* AVUTIL_AVUTIL_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/buffer.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/buffer.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/buffer.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/buffer.h 2022-07-05 00:21:22.446315819 +0300 -@@ -0,0 +1,324 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @ingroup lavu_buffer -+ * refcounted data buffer API -+ */ -+ -+#ifndef AVUTIL_BUFFER_H -+#define AVUTIL_BUFFER_H -+ -+#include -+#include -+ -+/** -+ * @defgroup lavu_buffer AVBuffer -+ * @ingroup lavu_data -+ * -+ * @{ -+ * AVBuffer is an API for reference-counted data buffers. -+ * -+ * There are two core objects in this API -- AVBuffer and AVBufferRef. AVBuffer -+ * represents the data buffer itself; it is opaque and not meant to be accessed -+ * by the caller directly, but only through AVBufferRef. However, the caller may -+ * e.g. compare two AVBuffer pointers to check whether two different references -+ * are describing the same data buffer. AVBufferRef represents a single -+ * reference to an AVBuffer and it is the object that may be manipulated by the -+ * caller directly. -+ * -+ * There are two functions provided for creating a new AVBuffer with a single -+ * reference -- av_buffer_alloc() to just allocate a new buffer, and -+ * av_buffer_create() to wrap an existing array in an AVBuffer. From an existing -+ * reference, additional references may be created with av_buffer_ref(). -+ * Use av_buffer_unref() to free a reference (this will automatically free the -+ * data once all the references are freed). -+ * -+ * The convention throughout this API and the rest of FFmpeg is such that the -+ * buffer is considered writable if there exists only one reference to it (and -+ * it has not been marked as read-only). The av_buffer_is_writable() function is -+ * provided to check whether this is true and av_buffer_make_writable() will -+ * automatically create a new writable buffer when necessary. -+ * Of course nothing prevents the calling code from violating this convention, -+ * however that is safe only when all the existing references are under its -+ * control. -+ * -+ * @note Referencing and unreferencing the buffers is thread-safe and thus -+ * may be done from multiple threads simultaneously without any need for -+ * additional locking. -+ * -+ * @note Two different references to the same buffer can point to different -+ * parts of the buffer (i.e. their AVBufferRef.data will not be equal). -+ */ -+ -+/** -+ * A reference counted buffer type. It is opaque and is meant to be used through -+ * references (AVBufferRef). -+ */ -+typedef struct AVBuffer AVBuffer; -+ -+/** -+ * A reference to a data buffer. -+ * -+ * The size of this struct is not a part of the public ABI and it is not meant -+ * to be allocated directly. -+ */ -+typedef struct AVBufferRef { -+ AVBuffer* buffer; -+ -+ /** -+ * The data buffer. It is considered writable if and only if -+ * this is the only reference to the buffer, in which case -+ * av_buffer_is_writable() returns 1. -+ */ -+ uint8_t* data; -+ /** -+ * Size of data in bytes. -+ */ -+ size_t size; -+} AVBufferRef; -+ -+/** -+ * Allocate an AVBuffer of the given size using av_malloc(). -+ * -+ * @return an AVBufferRef of given size or NULL when out of memory -+ */ -+AVBufferRef* av_buffer_alloc(size_t size); -+ -+/** -+ * Same as av_buffer_alloc(), except the returned buffer will be initialized -+ * to zero. -+ */ -+AVBufferRef* av_buffer_allocz(size_t size); -+ -+/** -+ * Always treat the buffer as read-only, even when it has only one -+ * reference. -+ */ -+#define AV_BUFFER_FLAG_READONLY (1 << 0) -+ -+/** -+ * Create an AVBuffer from an existing array. -+ * -+ * If this function is successful, data is owned by the AVBuffer. The caller may -+ * only access data through the returned AVBufferRef and references derived from -+ * it. -+ * If this function fails, data is left untouched. -+ * @param data data array -+ * @param size size of data in bytes -+ * @param free a callback for freeing this buffer's data -+ * @param opaque parameter to be got for processing or passed to free -+ * @param flags a combination of AV_BUFFER_FLAG_* -+ * -+ * @return an AVBufferRef referring to data on success, NULL on failure. -+ */ -+AVBufferRef* av_buffer_create(uint8_t* data, size_t size, -+ void (*free)(void* opaque, uint8_t* data), -+ void* opaque, int flags); -+ -+/** -+ * Default free callback, which calls av_free() on the buffer data. -+ * This function is meant to be passed to av_buffer_create(), not called -+ * directly. -+ */ -+void av_buffer_default_free(void* opaque, uint8_t* data); -+ -+/** -+ * Create a new reference to an AVBuffer. -+ * -+ * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on -+ * failure. -+ */ -+AVBufferRef* av_buffer_ref(const AVBufferRef* buf); -+ -+/** -+ * Free a given reference and automatically free the buffer if there are no more -+ * references to it. -+ * -+ * @param buf the reference to be freed. The pointer is set to NULL on return. -+ */ -+void av_buffer_unref(AVBufferRef** buf); -+ -+/** -+ * @return 1 if the caller may write to the data referred to by buf (which is -+ * true if and only if buf is the only reference to the underlying AVBuffer). -+ * Return 0 otherwise. -+ * A positive answer is valid until av_buffer_ref() is called on buf. -+ */ -+int av_buffer_is_writable(const AVBufferRef* buf); -+ -+/** -+ * @return the opaque parameter set by av_buffer_create. -+ */ -+void* av_buffer_get_opaque(const AVBufferRef* buf); -+ -+int av_buffer_get_ref_count(const AVBufferRef* buf); -+ -+/** -+ * Create a writable reference from a given buffer reference, avoiding data copy -+ * if possible. -+ * -+ * @param buf buffer reference to make writable. On success, buf is either left -+ * untouched, or it is unreferenced and a new writable AVBufferRef is -+ * written in its place. On failure, buf is left untouched. -+ * @return 0 on success, a negative AVERROR on failure. -+ */ -+int av_buffer_make_writable(AVBufferRef** buf); -+ -+/** -+ * Reallocate a given buffer. -+ * -+ * @param buf a buffer reference to reallocate. On success, buf will be -+ * unreferenced and a new reference with the required size will be -+ * written in its place. On failure buf will be left untouched. *buf -+ * may be NULL, then a new buffer is allocated. -+ * @param size required new buffer size. -+ * @return 0 on success, a negative AVERROR on failure. -+ * -+ * @note the buffer is actually reallocated with av_realloc() only if it was -+ * initially allocated through av_buffer_realloc(NULL) and there is only one -+ * reference to it (i.e. the one passed to this function). In all other cases -+ * a new buffer is allocated and the data is copied. -+ */ -+int av_buffer_realloc(AVBufferRef** buf, size_t size); -+ -+/** -+ * Ensure dst refers to the same data as src. -+ * -+ * When *dst is already equivalent to src, do nothing. Otherwise unreference dst -+ * and replace it with a new reference to src. -+ * -+ * @param dst Pointer to either a valid buffer reference or NULL. On success, -+ * this will point to a buffer reference equivalent to src. On -+ * failure, dst will be left untouched. -+ * @param src A buffer reference to replace dst with. May be NULL, then this -+ * function is equivalent to av_buffer_unref(dst). -+ * @return 0 on success -+ * AVERROR(ENOMEM) on memory allocation failure. -+ */ -+int av_buffer_replace(AVBufferRef** dst, const AVBufferRef* src); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @defgroup lavu_bufferpool AVBufferPool -+ * @ingroup lavu_data -+ * -+ * @{ -+ * AVBufferPool is an API for a lock-free thread-safe pool of AVBuffers. -+ * -+ * Frequently allocating and freeing large buffers may be slow. AVBufferPool is -+ * meant to solve this in cases when the caller needs a set of buffers of the -+ * same size (the most obvious use case being buffers for raw video or audio -+ * frames). -+ * -+ * At the beginning, the user must call av_buffer_pool_init() to create the -+ * buffer pool. Then whenever a buffer is needed, call av_buffer_pool_get() to -+ * get a reference to a new buffer, similar to av_buffer_alloc(). This new -+ * reference works in all aspects the same way as the one created by -+ * av_buffer_alloc(). However, when the last reference to this buffer is -+ * unreferenced, it is returned to the pool instead of being freed and will be -+ * reused for subsequent av_buffer_pool_get() calls. -+ * -+ * When the caller is done with the pool and no longer needs to allocate any new -+ * buffers, av_buffer_pool_uninit() must be called to mark the pool as freeable. -+ * Once all the buffers are released, it will automatically be freed. -+ * -+ * Allocating and releasing buffers with this API is thread-safe as long as -+ * either the default alloc callback is used, or the user-supplied one is -+ * thread-safe. -+ */ -+ -+/** -+ * The buffer pool. This structure is opaque and not meant to be accessed -+ * directly. It is allocated with av_buffer_pool_init() and freed with -+ * av_buffer_pool_uninit(). -+ */ -+typedef struct AVBufferPool AVBufferPool; -+ -+/** -+ * Allocate and initialize a buffer pool. -+ * -+ * @param size size of each buffer in this pool -+ * @param alloc a function that will be used to allocate new buffers when the -+ * pool is empty. May be NULL, then the default allocator will be used -+ * (av_buffer_alloc()). -+ * @return newly created buffer pool on success, NULL on error. -+ */ -+AVBufferPool* av_buffer_pool_init(size_t size, -+ AVBufferRef* (*alloc)(size_t size)); -+ -+/** -+ * Allocate and initialize a buffer pool with a more complex allocator. -+ * -+ * @param size size of each buffer in this pool -+ * @param opaque arbitrary user data used by the allocator -+ * @param alloc a function that will be used to allocate new buffers when the -+ * pool is empty. May be NULL, then the default allocator will be -+ * used (av_buffer_alloc()). -+ * @param pool_free a function that will be called immediately before the pool -+ * is freed. I.e. after av_buffer_pool_uninit() is called -+ * by the caller and all the frames are returned to the pool -+ * and freed. It is intended to uninitialize the user opaque -+ * data. May be NULL. -+ * @return newly created buffer pool on success, NULL on error. -+ */ -+AVBufferPool* av_buffer_pool_init2(size_t size, void* opaque, -+ AVBufferRef* (*alloc)(void* opaque, -+ size_t size), -+ void (*pool_free)(void* opaque)); -+ -+/** -+ * Mark the pool as being available for freeing. It will actually be freed only -+ * once all the allocated buffers associated with the pool are released. Thus it -+ * is safe to call this function while some of the allocated buffers are still -+ * in use. -+ * -+ * @param pool pointer to the pool to be freed. It will be set to NULL. -+ */ -+void av_buffer_pool_uninit(AVBufferPool** pool); -+ -+/** -+ * Allocate a new AVBuffer, reusing an old buffer from the pool when available. -+ * This function may be called simultaneously from multiple threads. -+ * -+ * @return a reference to the new buffer on success, NULL on error. -+ */ -+AVBufferRef* av_buffer_pool_get(AVBufferPool* pool); -+ -+/** -+ * Query the original opaque parameter of an allocated buffer in the pool. -+ * -+ * @param ref a buffer reference to a buffer returned by av_buffer_pool_get. -+ * @return the opaque parameter set by the buffer allocator function of the -+ * buffer pool. -+ * -+ * @note the opaque parameter of ref is used by the buffer pool implementation, -+ * therefore you have to use this function to access the original opaque -+ * parameter of an allocated buffer. -+ */ -+void* av_buffer_pool_buffer_get_opaque(const AVBufferRef* ref); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_BUFFER_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/channel_layout.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/channel_layout.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/channel_layout.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/channel_layout.h 2022-07-05 00:21:22.446315819 +0300 -@@ -0,0 +1,270 @@ -+/* -+ * Copyright (c) 2006 Michael Niedermayer -+ * Copyright (c) 2008 Peter Ross -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_CHANNEL_LAYOUT_H -+#define AVUTIL_CHANNEL_LAYOUT_H -+ -+#include -+ -+/** -+ * @file -+ * audio channel layout utility functions -+ */ -+ -+/** -+ * @addtogroup lavu_audio -+ * @{ -+ */ -+ -+/** -+ * @defgroup channel_masks Audio channel masks -+ * -+ * A channel layout is a 64-bits integer with a bit set for every channel. -+ * The number of bits set must be equal to the number of channels. -+ * The value 0 means that the channel layout is not known. -+ * @note this data structure is not powerful enough to handle channels -+ * combinations that have the same channel multiple times, such as -+ * dual-mono. -+ * -+ * @{ -+ */ -+#define AV_CH_FRONT_LEFT 0x00000001 -+#define AV_CH_FRONT_RIGHT 0x00000002 -+#define AV_CH_FRONT_CENTER 0x00000004 -+#define AV_CH_LOW_FREQUENCY 0x00000008 -+#define AV_CH_BACK_LEFT 0x00000010 -+#define AV_CH_BACK_RIGHT 0x00000020 -+#define AV_CH_FRONT_LEFT_OF_CENTER 0x00000040 -+#define AV_CH_FRONT_RIGHT_OF_CENTER 0x00000080 -+#define AV_CH_BACK_CENTER 0x00000100 -+#define AV_CH_SIDE_LEFT 0x00000200 -+#define AV_CH_SIDE_RIGHT 0x00000400 -+#define AV_CH_TOP_CENTER 0x00000800 -+#define AV_CH_TOP_FRONT_LEFT 0x00001000 -+#define AV_CH_TOP_FRONT_CENTER 0x00002000 -+#define AV_CH_TOP_FRONT_RIGHT 0x00004000 -+#define AV_CH_TOP_BACK_LEFT 0x00008000 -+#define AV_CH_TOP_BACK_CENTER 0x00010000 -+#define AV_CH_TOP_BACK_RIGHT 0x00020000 -+#define AV_CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. -+#define AV_CH_STEREO_RIGHT 0x40000000 ///< See AV_CH_STEREO_LEFT. -+#define AV_CH_WIDE_LEFT 0x0000000080000000ULL -+#define AV_CH_WIDE_RIGHT 0x0000000100000000ULL -+#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL -+#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL -+#define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL -+#define AV_CH_TOP_SIDE_LEFT 0x0000001000000000ULL -+#define AV_CH_TOP_SIDE_RIGHT 0x0000002000000000ULL -+#define AV_CH_BOTTOM_FRONT_CENTER 0x0000004000000000ULL -+#define AV_CH_BOTTOM_FRONT_LEFT 0x0000008000000000ULL -+#define AV_CH_BOTTOM_FRONT_RIGHT 0x0000010000000000ULL -+ -+/** Channel mask value used for AVCodecContext.request_channel_layout -+ to indicate that the user requests the channel order of the decoder output -+ to be the native codec channel order. */ -+#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL -+ -+/** -+ * @} -+ * @defgroup channel_mask_c Audio channel layouts -+ * @{ -+ * */ -+#define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER) -+#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT) -+#define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY) -+#define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO | AV_CH_BACK_CENTER) -+#define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER) -+#define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY) -+#define AV_CH_LAYOUT_4POINT0 (AV_CH_LAYOUT_SURROUND | AV_CH_BACK_CENTER) -+#define AV_CH_LAYOUT_4POINT1 (AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY) -+#define AV_CH_LAYOUT_2_2 \ -+ (AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT) -+#define AV_CH_LAYOUT_QUAD \ -+ (AV_CH_LAYOUT_STEREO | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT) -+#define AV_CH_LAYOUT_5POINT0 \ -+ (AV_CH_LAYOUT_SURROUND | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT) -+#define AV_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT0 | AV_CH_LOW_FREQUENCY) -+#define AV_CH_LAYOUT_5POINT0_BACK \ -+ (AV_CH_LAYOUT_SURROUND | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT) -+#define AV_CH_LAYOUT_5POINT1_BACK \ -+ (AV_CH_LAYOUT_5POINT0_BACK | AV_CH_LOW_FREQUENCY) -+#define AV_CH_LAYOUT_6POINT0 (AV_CH_LAYOUT_5POINT0 | AV_CH_BACK_CENTER) -+#define AV_CH_LAYOUT_6POINT0_FRONT \ -+ (AV_CH_LAYOUT_2_2 | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER) -+#define AV_CH_LAYOUT_HEXAGONAL (AV_CH_LAYOUT_5POINT0_BACK | AV_CH_BACK_CENTER) -+#define AV_CH_LAYOUT_6POINT1 (AV_CH_LAYOUT_5POINT1 | AV_CH_BACK_CENTER) -+#define AV_CH_LAYOUT_6POINT1_BACK \ -+ (AV_CH_LAYOUT_5POINT1_BACK | AV_CH_BACK_CENTER) -+#define AV_CH_LAYOUT_6POINT1_FRONT \ -+ (AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_LOW_FREQUENCY) -+#define AV_CH_LAYOUT_7POINT0 \ -+ (AV_CH_LAYOUT_5POINT0 | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT) -+#define AV_CH_LAYOUT_7POINT0_FRONT \ -+ (AV_CH_LAYOUT_5POINT0 | AV_CH_FRONT_LEFT_OF_CENTER | \ -+ AV_CH_FRONT_RIGHT_OF_CENTER) -+#define AV_CH_LAYOUT_7POINT1 \ -+ (AV_CH_LAYOUT_5POINT1 | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT) -+#define AV_CH_LAYOUT_7POINT1_WIDE \ -+ (AV_CH_LAYOUT_5POINT1 | AV_CH_FRONT_LEFT_OF_CENTER | \ -+ AV_CH_FRONT_RIGHT_OF_CENTER) -+#define AV_CH_LAYOUT_7POINT1_WIDE_BACK \ -+ (AV_CH_LAYOUT_5POINT1_BACK | AV_CH_FRONT_LEFT_OF_CENTER | \ -+ AV_CH_FRONT_RIGHT_OF_CENTER) -+#define AV_CH_LAYOUT_OCTAGONAL \ -+ (AV_CH_LAYOUT_5POINT0 | AV_CH_BACK_LEFT | AV_CH_BACK_CENTER | \ -+ AV_CH_BACK_RIGHT) -+#define AV_CH_LAYOUT_HEXADECAGONAL \ -+ (AV_CH_LAYOUT_OCTAGONAL | AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT | \ -+ AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT | AV_CH_TOP_BACK_CENTER | \ -+ AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT) -+#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT) -+#define AV_CH_LAYOUT_22POINT2 \ -+ (AV_CH_LAYOUT_5POINT1_BACK | AV_CH_FRONT_LEFT_OF_CENTER | \ -+ AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_BACK_CENTER | AV_CH_LOW_FREQUENCY_2 | \ -+ AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_TOP_FRONT_LEFT | \ -+ AV_CH_TOP_FRONT_RIGHT | AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_CENTER | \ -+ AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT | AV_CH_TOP_SIDE_LEFT | \ -+ AV_CH_TOP_SIDE_RIGHT | AV_CH_TOP_BACK_CENTER | AV_CH_BOTTOM_FRONT_CENTER | \ -+ AV_CH_BOTTOM_FRONT_LEFT | AV_CH_BOTTOM_FRONT_RIGHT) -+ -+enum AVMatrixEncoding { -+ AV_MATRIX_ENCODING_NONE, -+ AV_MATRIX_ENCODING_DOLBY, -+ AV_MATRIX_ENCODING_DPLII, -+ AV_MATRIX_ENCODING_DPLIIX, -+ AV_MATRIX_ENCODING_DPLIIZ, -+ AV_MATRIX_ENCODING_DOLBYEX, -+ AV_MATRIX_ENCODING_DOLBYHEADPHONE, -+ AV_MATRIX_ENCODING_NB -+}; -+ -+/** -+ * Return a channel layout id that matches name, or 0 if no match is found. -+ * -+ * name can be one or several of the following notations, -+ * separated by '+' or '|': -+ * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0, -+ * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix); -+ * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC, -+ * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR); -+ * - a number of channels, in decimal, followed by 'c', yielding -+ * the default channel layout for that number of channels (@see -+ * av_get_default_channel_layout); -+ * - a channel layout mask, in hexadecimal starting with "0x" (see the -+ * AV_CH_* macros). -+ * -+ * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" -+ */ -+uint64_t av_get_channel_layout(const char* name); -+ -+/** -+ * Return a channel layout and the number of channels based on the specified -+ * name. -+ * -+ * This function is similar to (@see av_get_channel_layout), but can also parse -+ * unknown channel layout specifications. -+ * -+ * @param[in] name channel layout specification string -+ * @param[out] channel_layout parsed channel layout (0 if unknown) -+ * @param[out] nb_channels number of channels -+ * -+ * @return 0 on success, AVERROR(EINVAL) if the parsing fails. -+ */ -+int av_get_extended_channel_layout(const char* name, uint64_t* channel_layout, -+ int* nb_channels); -+ -+/** -+ * Return a description of a channel layout. -+ * If nb_channels is <= 0, it is guessed from the channel_layout. -+ * -+ * @param buf put here the string containing the channel layout -+ * @param buf_size size in bytes of the buffer -+ */ -+void av_get_channel_layout_string(char* buf, int buf_size, int nb_channels, -+ uint64_t channel_layout); -+ -+struct AVBPrint; -+/** -+ * Append a description of a channel layout to a bprint buffer. -+ */ -+void av_bprint_channel_layout(struct AVBPrint* bp, int nb_channels, -+ uint64_t channel_layout); -+ -+/** -+ * Return the number of channels in the channel layout. -+ */ -+int av_get_channel_layout_nb_channels(uint64_t channel_layout); -+ -+/** -+ * Return default channel layout for a given number of channels. -+ */ -+int64_t av_get_default_channel_layout(int nb_channels); -+ -+/** -+ * Get the index of a channel in channel_layout. -+ * -+ * @param channel a channel layout describing exactly one channel which must be -+ * present in channel_layout. -+ * -+ * @return index of channel in channel_layout on success, a negative AVERROR -+ * on error. -+ */ -+int av_get_channel_layout_channel_index(uint64_t channel_layout, -+ uint64_t channel); -+ -+/** -+ * Get the channel with the given index in channel_layout. -+ */ -+uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index); -+ -+/** -+ * Get the name of a given channel. -+ * -+ * @return channel name on success, NULL on error. -+ */ -+const char* av_get_channel_name(uint64_t channel); -+ -+/** -+ * Get the description of a given channel. -+ * -+ * @param channel a channel layout with a single channel -+ * @return channel description on success, NULL on error -+ */ -+const char* av_get_channel_description(uint64_t channel); -+ -+/** -+ * Get the value and name of a standard channel layout. -+ * -+ * @param[in] index index in an internal list, starting at 0 -+ * @param[out] layout channel layout mask -+ * @param[out] name name of the layout -+ * @return 0 if the layout exists, -+ * <0 if index is beyond the limits -+ */ -+int av_get_standard_channel_layout(unsigned index, uint64_t* layout, -+ const char** name); -+ -+/** -+ * @} -+ * @} -+ */ -+ -+#endif /* AVUTIL_CHANNEL_LAYOUT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/common.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/common.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/common.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/common.h 2022-07-05 00:21:22.446315819 +0300 -@@ -0,0 +1,590 @@ -+/* -+ * copyright (c) 2006 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * common internal and external API header -+ */ -+ -+#ifndef AVUTIL_COMMON_H -+#define AVUTIL_COMMON_H -+ -+#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && \ -+ !defined(UINT64_C) -+# error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "attributes.h" -+#include "macros.h" -+#include "version.h" -+ -+// rounded division & shift -+#define RSHIFT(a, b) \ -+ ((a) > 0 ? ((a) + ((1 << (b)) >> 1)) >> (b) \ -+ : ((a) + ((1 << (b)) >> 1) - 1) >> (b)) -+/* assume b>0 */ -+#define ROUNDED_DIV(a, b) \ -+ (((a) >= 0 ? (a) + ((b) >> 1) : (a) - ((b) >> 1)) / (b)) -+/* Fast a/(1<=0 and b>=0 */ -+#define AV_CEIL_RSHIFT(a, b) \ -+ (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) : ((a) + (1 << (b)) - 1) >> (b)) -+/* Backwards compat. */ -+#define FF_CEIL_RSHIFT AV_CEIL_RSHIFT -+ -+#define FFUDIV(a, b) (((a) > 0 ? (a) : (a) - (b) + 1) / (b)) -+#define FFUMOD(a, b) ((a) - (b)*FFUDIV(a, b)) -+ -+/** -+ * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as -+ * they are not representable as absolute values of their type. This is the same -+ * as with *abs() -+ * @see FFNABS() -+ */ -+#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) -+#define FFSIGN(a) ((a) > 0 ? 1 : -1) -+ -+/** -+ * Negative Absolute value. -+ * this works for all integers of all types. -+ * As with many macros, this evaluates its argument twice, it thus must not have -+ * a sideeffect, that is FFNABS(x++) has undefined behavior. -+ */ -+#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) -+ -+/** -+ * Unsigned Absolute value. -+ * This takes the absolute value of a signed int and returns it as a unsigned. -+ * This also works with INT_MIN which would otherwise not be representable -+ * As with many macros, this evaluates its argument twice. -+ */ -+#define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a)) -+#define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a)) -+ -+/* misc math functions */ -+ -+#ifdef HAVE_AV_CONFIG_H -+# include "config.h" -+# include "intmath.h" -+#endif -+ -+#ifndef av_ceil_log2 -+# define av_ceil_log2 av_ceil_log2_c -+#endif -+#ifndef av_clip -+# define av_clip av_clip_c -+#endif -+#ifndef av_clip64 -+# define av_clip64 av_clip64_c -+#endif -+#ifndef av_clip_uint8 -+# define av_clip_uint8 av_clip_uint8_c -+#endif -+#ifndef av_clip_int8 -+# define av_clip_int8 av_clip_int8_c -+#endif -+#ifndef av_clip_uint16 -+# define av_clip_uint16 av_clip_uint16_c -+#endif -+#ifndef av_clip_int16 -+# define av_clip_int16 av_clip_int16_c -+#endif -+#ifndef av_clipl_int32 -+# define av_clipl_int32 av_clipl_int32_c -+#endif -+#ifndef av_clip_intp2 -+# define av_clip_intp2 av_clip_intp2_c -+#endif -+#ifndef av_clip_uintp2 -+# define av_clip_uintp2 av_clip_uintp2_c -+#endif -+#ifndef av_mod_uintp2 -+# define av_mod_uintp2 av_mod_uintp2_c -+#endif -+#ifndef av_sat_add32 -+# define av_sat_add32 av_sat_add32_c -+#endif -+#ifndef av_sat_dadd32 -+# define av_sat_dadd32 av_sat_dadd32_c -+#endif -+#ifndef av_sat_sub32 -+# define av_sat_sub32 av_sat_sub32_c -+#endif -+#ifndef av_sat_dsub32 -+# define av_sat_dsub32 av_sat_dsub32_c -+#endif -+#ifndef av_sat_add64 -+# define av_sat_add64 av_sat_add64_c -+#endif -+#ifndef av_sat_sub64 -+# define av_sat_sub64 av_sat_sub64_c -+#endif -+#ifndef av_clipf -+# define av_clipf av_clipf_c -+#endif -+#ifndef av_clipd -+# define av_clipd av_clipd_c -+#endif -+#ifndef av_popcount -+# define av_popcount av_popcount_c -+#endif -+#ifndef av_popcount64 -+# define av_popcount64 av_popcount64_c -+#endif -+#ifndef av_parity -+# define av_parity av_parity_c -+#endif -+ -+#ifndef av_log2 -+av_const int av_log2(unsigned v); -+#endif -+ -+#ifndef av_log2_16bit -+av_const int av_log2_16bit(unsigned v); -+#endif -+ -+/** -+ * Clip a signed integer value into the amin-amax range. -+ * @param a value to clip -+ * @param amin minimum value of the clip range -+ * @param amax maximum value of the clip range -+ * @return clipped value -+ */ -+static av_always_inline av_const int av_clip_c(int a, int amin, int amax) { -+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 -+ if (amin > amax) abort(); -+#endif -+ if (a < amin) -+ return amin; -+ else if (a > amax) -+ return amax; -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed 64bit integer value into the amin-amax range. -+ * @param a value to clip -+ * @param amin minimum value of the clip range -+ * @param amax maximum value of the clip range -+ * @return clipped value -+ */ -+static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, -+ int64_t amax) { -+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 -+ if (amin > amax) abort(); -+#endif -+ if (a < amin) -+ return amin; -+ else if (a > amax) -+ return amax; -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed integer value into the 0-255 range. -+ * @param a value to clip -+ * @return clipped value -+ */ -+static av_always_inline av_const uint8_t av_clip_uint8_c(int a) { -+ if (a & (~0xFF)) -+ return (~a) >> 31; -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed integer value into the -128,127 range. -+ * @param a value to clip -+ * @return clipped value -+ */ -+static av_always_inline av_const int8_t av_clip_int8_c(int a) { -+ if ((a + 0x80U) & ~0xFF) -+ return (a >> 31) ^ 0x7F; -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed integer value into the 0-65535 range. -+ * @param a value to clip -+ * @return clipped value -+ */ -+static av_always_inline av_const uint16_t av_clip_uint16_c(int a) { -+ if (a & (~0xFFFF)) -+ return (~a) >> 31; -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed integer value into the -32768,32767 range. -+ * @param a value to clip -+ * @return clipped value -+ */ -+static av_always_inline av_const int16_t av_clip_int16_c(int a) { -+ if ((a + 0x8000U) & ~0xFFFF) -+ return (a >> 31) ^ 0x7FFF; -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed 64-bit integer value into the -2147483648,2147483647 range. -+ * @param a value to clip -+ * @return clipped value -+ */ -+static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a) { -+ if ((a + 0x80000000u) & ~UINT64_C(0xFFFFFFFF)) -+ return (int32_t)((a >> 63) ^ 0x7FFFFFFF); -+ else -+ return (int32_t)a; -+} -+ -+/** -+ * Clip a signed integer into the -(2^p),(2^p-1) range. -+ * @param a value to clip -+ * @param p bit position to clip at -+ * @return clipped value -+ */ -+static av_always_inline av_const int av_clip_intp2_c(int a, int p) { -+ if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) -+ return (a >> 31) ^ ((1 << p) - 1); -+ else -+ return a; -+} -+ -+/** -+ * Clip a signed integer to an unsigned power of two range. -+ * @param a value to clip -+ * @param p bit position to clip at -+ * @return clipped value -+ */ -+static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) { -+ if (a & ~((1 << p) - 1)) -+ return (~a) >> 31 & ((1 << p) - 1); -+ else -+ return a; -+} -+ -+/** -+ * Clear high bits from an unsigned integer starting with specific bit position -+ * @param a value to clip -+ * @param p bit position to clip at -+ * @return clipped value -+ */ -+static av_always_inline av_const unsigned av_mod_uintp2_c(unsigned a, -+ unsigned p) { -+ return a & ((1U << p) - 1); -+} -+ -+/** -+ * Add two signed 32-bit values with saturation. -+ * -+ * @param a one value -+ * @param b another value -+ * @return sum with signed saturation -+ */ -+static av_always_inline int av_sat_add32_c(int a, int b) { -+ return av_clipl_int32((int64_t)a + b); -+} -+ -+/** -+ * Add a doubled value to another value with saturation at both stages. -+ * -+ * @param a first value -+ * @param b value doubled and added to a -+ * @return sum sat(a + sat(2*b)) with signed saturation -+ */ -+static av_always_inline int av_sat_dadd32_c(int a, int b) { -+ return av_sat_add32(a, av_sat_add32(b, b)); -+} -+ -+/** -+ * Subtract two signed 32-bit values with saturation. -+ * -+ * @param a one value -+ * @param b another value -+ * @return difference with signed saturation -+ */ -+static av_always_inline int av_sat_sub32_c(int a, int b) { -+ return av_clipl_int32((int64_t)a - b); -+} -+ -+/** -+ * Subtract a doubled value from another value with saturation at both stages. -+ * -+ * @param a first value -+ * @param b value doubled and subtracted from a -+ * @return difference sat(a - sat(2*b)) with signed saturation -+ */ -+static av_always_inline int av_sat_dsub32_c(int a, int b) { -+ return av_sat_sub32(a, av_sat_add32(b, b)); -+} -+ -+/** -+ * Add two signed 64-bit values with saturation. -+ * -+ * @param a one value -+ * @param b another value -+ * @return sum with signed saturation -+ */ -+static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) { -+#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5, 1)) || \ -+ AV_HAS_BUILTIN(__builtin_add_overflow) -+ int64_t tmp; -+ return !__builtin_add_overflow(a, b, &tmp) -+ ? tmp -+ : (tmp < 0 ? INT64_MAX : INT64_MIN); -+#else -+ int64_t s = a + (uint64_t)b; -+ if ((int64_t)(a ^ b | ~s ^ b) >= 0) return INT64_MAX ^ (b >> 63); -+ return s; -+#endif -+} -+ -+/** -+ * Subtract two signed 64-bit values with saturation. -+ * -+ * @param a one value -+ * @param b another value -+ * @return difference with signed saturation -+ */ -+static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { -+#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5, 1)) || \ -+ AV_HAS_BUILTIN(__builtin_sub_overflow) -+ int64_t tmp; -+ return !__builtin_sub_overflow(a, b, &tmp) -+ ? tmp -+ : (tmp < 0 ? INT64_MAX : INT64_MIN); -+#else -+ if (b <= 0 && a >= INT64_MAX + b) return INT64_MAX; -+ if (b >= 0 && a <= INT64_MIN + b) return INT64_MIN; -+ return a - b; -+#endif -+} -+ -+/** -+ * Clip a float value into the amin-amax range. -+ * If a is nan or -inf amin will be returned. -+ * If a is +inf amax will be returned. -+ * @param a value to clip -+ * @param amin minimum value of the clip range -+ * @param amax maximum value of the clip range -+ * @return clipped value -+ */ -+static av_always_inline av_const float av_clipf_c(float a, float amin, -+ float amax) { -+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 -+ if (amin > amax) abort(); -+#endif -+ return FFMIN(FFMAX(a, amin), amax); -+} -+ -+/** -+ * Clip a double value into the amin-amax range. -+ * If a is nan or -inf amin will be returned. -+ * If a is +inf amax will be returned. -+ * @param a value to clip -+ * @param amin minimum value of the clip range -+ * @param amax maximum value of the clip range -+ * @return clipped value -+ */ -+static av_always_inline av_const double av_clipd_c(double a, double amin, -+ double amax) { -+#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 -+ if (amin > amax) abort(); -+#endif -+ return FFMIN(FFMAX(a, amin), amax); -+} -+ -+/** Compute ceil(log2(x)). -+ * @param x value used to compute ceil(log2(x)) -+ * @return computed ceiling of log2(x) -+ */ -+static av_always_inline av_const int av_ceil_log2_c(int x) { -+ return av_log2((x - 1U) << 1); -+} -+ -+/** -+ * Count number of bits set to one in x -+ * @param x value to count bits of -+ * @return the number of bits set to one in x -+ */ -+static av_always_inline av_const int av_popcount_c(uint32_t x) { -+ x -= (x >> 1) & 0x55555555; -+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333); -+ x = (x + (x >> 4)) & 0x0F0F0F0F; -+ x += x >> 8; -+ return (x + (x >> 16)) & 0x3F; -+} -+ -+/** -+ * Count number of bits set to one in x -+ * @param x value to count bits of -+ * @return the number of bits set to one in x -+ */ -+static av_always_inline av_const int av_popcount64_c(uint64_t x) { -+ return av_popcount((uint32_t)x) + av_popcount((uint32_t)(x >> 32)); -+} -+ -+static av_always_inline av_const int av_parity_c(uint32_t v) { -+ return av_popcount(v) & 1; -+} -+ -+/** -+ * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. -+ * -+ * @param val Output value, must be an lvalue of type uint32_t. -+ * @param GET_BYTE Expression reading one byte from the input. -+ * Evaluated up to 7 times (4 for the currently -+ * assigned Unicode range). With a memory buffer -+ * input, this could be *ptr++, or if you want to make sure -+ * that *ptr stops at the end of a NULL terminated string then -+ * *ptr ? *ptr++ : 0 -+ * @param ERROR Expression to be evaluated on invalid input, -+ * typically a goto statement. -+ * -+ * @warning ERROR should not contain a loop control statement which -+ * could interact with the internal while loop, and should force an -+ * exit from the macro code (e.g. through a goto or a return) in order -+ * to prevent undefined results. -+ */ -+#define GET_UTF8(val, GET_BYTE, ERROR) \ -+ val = (GET_BYTE); \ -+ { \ -+ uint32_t top = (val & 128) >> 1; \ -+ if ((val & 0xc0) == 0x80 || val >= 0xFE) { \ -+ ERROR \ -+ } \ -+ while (val & top) { \ -+ unsigned int tmp = (GET_BYTE)-128; \ -+ if (tmp >> 6) { \ -+ ERROR \ -+ } \ -+ val = (val << 6) + tmp; \ -+ top <<= 5; \ -+ } \ -+ val &= (top << 1) - 1; \ -+ } -+ -+/** -+ * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form. -+ * -+ * @param val Output value, must be an lvalue of type uint32_t. -+ * @param GET_16BIT Expression returning two bytes of UTF-16 data converted -+ * to native byte order. Evaluated one or two times. -+ * @param ERROR Expression to be evaluated on invalid input, -+ * typically a goto statement. -+ */ -+#define GET_UTF16(val, GET_16BIT, ERROR) \ -+ val = (GET_16BIT); \ -+ { \ -+ unsigned int hi = val - 0xD800; \ -+ if (hi < 0x800) { \ -+ val = (GET_16BIT)-0xDC00; \ -+ if (val > 0x3FFU || hi > 0x3FFU) { \ -+ ERROR \ -+ } \ -+ val += (hi << 10) + 0x10000; \ -+ } \ -+ } -+ -+/** -+ * @def PUT_UTF8(val, tmp, PUT_BYTE) -+ * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes -+ * long). -+ * @param val is an input-only argument and should be of type uint32_t. It holds -+ * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If -+ * val is given as a function it is executed only once. -+ * @param tmp is a temporary variable and should be of type uint8_t. It -+ * represents an intermediate value during conversion that is to be -+ * output by PUT_BYTE. -+ * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. -+ * It could be a function or a statement, and uses tmp as the input byte. -+ * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be -+ * executed up to 4 times for values in the valid UTF-8 range and up to -+ * 7 times in the general case, depending on the length of the converted -+ * Unicode character. -+ */ -+#define PUT_UTF8(val, tmp, PUT_BYTE) \ -+ { \ -+ int bytes, shift; \ -+ uint32_t in = val; \ -+ if (in < 0x80) { \ -+ tmp = in; \ -+ PUT_BYTE \ -+ } else { \ -+ bytes = (av_log2(in) + 4) / 5; \ -+ shift = (bytes - 1) * 6; \ -+ tmp = (256 - (256 >> bytes)) | (in >> shift); \ -+ PUT_BYTE \ -+ while (shift >= 6) { \ -+ shift -= 6; \ -+ tmp = 0x80 | ((in >> shift) & 0x3f); \ -+ PUT_BYTE \ -+ } \ -+ } \ -+ } -+ -+/** -+ * @def PUT_UTF16(val, tmp, PUT_16BIT) -+ * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). -+ * @param val is an input-only argument and should be of type uint32_t. It holds -+ * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If -+ * val is given as a function it is executed only once. -+ * @param tmp is a temporary variable and should be of type uint16_t. It -+ * represents an intermediate value during conversion that is to be -+ * output by PUT_16BIT. -+ * @param PUT_16BIT writes the converted UTF-16 data to any proper destination -+ * in desired endianness. It could be a function or a statement, and uses tmp -+ * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" -+ * PUT_BYTE will be executed 1 or 2 times depending on input character. -+ */ -+#define PUT_UTF16(val, tmp, PUT_16BIT) \ -+ { \ -+ uint32_t in = val; \ -+ if (in < 0x10000) { \ -+ tmp = in; \ -+ PUT_16BIT \ -+ } else { \ -+ tmp = 0xD800 | ((in - 0x10000) >> 10); \ -+ PUT_16BIT \ -+ tmp = 0xDC00 | ((in - 0x10000) & 0x3FF); \ -+ PUT_16BIT \ -+ } \ -+ } -+ -+#include "mem.h" -+ -+#ifdef HAVE_AV_CONFIG_H -+# include "internal.h" -+#endif /* HAVE_AV_CONFIG_H */ -+ -+#endif /* AVUTIL_COMMON_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/cpu.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/cpu.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/cpu.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/cpu.h 2022-07-05 00:21:22.447315813 +0300 -@@ -0,0 +1,138 @@ -+/* -+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_CPU_H -+#define AVUTIL_CPU_H -+ -+#include -+ -+#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */ -+ -+/* lower 16 bits - CPU features */ -+#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX -+#define AV_CPU_FLAG_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext -+#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext -+#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW -+#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions -+#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions -+#define AV_CPU_FLAG_SSE2SLOW \ -+ 0x40000000 ///< SSE2 supported, but usually not faster -+ ///< than regular MMX/SSE (e.g. Core1) -+#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt -+#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions -+#define AV_CPU_FLAG_SSE3SLOW \ -+ 0x20000000 ///< SSE3 supported, but usually not faster -+ ///< than regular MMX/SSE (e.g. Core1) -+#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions -+#define AV_CPU_FLAG_SSSE3SLOW \ -+ 0x4000000 ///< SSSE3 supported, but usually not faster -+#define AV_CPU_FLAG_ATOM \ -+ 0x10000000 ///< Atom processor, some SSSE3 instructions are slower -+#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions -+#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions -+#define AV_CPU_FLAG_AESNI 0x80000 ///< Advanced Encryption Standard functions -+#define AV_CPU_FLAG_AVX \ -+ 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't -+ ///< used -+#define AV_CPU_FLAG_AVXSLOW \ -+ 0x8000000 ///< AVX supported, but slow when using YMM registers (e.g. -+ ///< Bulldozer) -+#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions -+#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions -+#define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction -+#define AV_CPU_FLAG_AVX2 \ -+ 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't -+ ///< used -+#define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions -+#define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 -+#define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 -+#define AV_CPU_FLAG_AVX512 \ -+ 0x100000 ///< AVX-512 functions: requires OS support even if YMM/ZMM -+ ///< registers aren't used -+#define AV_CPU_FLAG_SLOW_GATHER 0x2000000 ///< CPU has slow gathers. -+ -+#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard -+#define AV_CPU_FLAG_VSX 0x0002 ///< ISA 2.06 -+#define AV_CPU_FLAG_POWER8 0x0004 ///< ISA 2.07 -+ -+#define AV_CPU_FLAG_ARMV5TE (1 << 0) -+#define AV_CPU_FLAG_ARMV6 (1 << 1) -+#define AV_CPU_FLAG_ARMV6T2 (1 << 2) -+#define AV_CPU_FLAG_VFP (1 << 3) -+#define AV_CPU_FLAG_VFPV3 (1 << 4) -+#define AV_CPU_FLAG_NEON (1 << 5) -+#define AV_CPU_FLAG_ARMV8 (1 << 6) -+#define AV_CPU_FLAG_VFP_VM \ -+ (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in -+ ///< various CPUs implementations -+#define AV_CPU_FLAG_SETEND (1 << 16) -+ -+#define AV_CPU_FLAG_MMI (1 << 0) -+#define AV_CPU_FLAG_MSA (1 << 1) -+ -+// Loongarch SIMD extension. -+#define AV_CPU_FLAG_LSX (1 << 0) -+#define AV_CPU_FLAG_LASX (1 << 1) -+ -+/** -+ * Return the flags which specify extensions supported by the CPU. -+ * The returned value is affected by av_force_cpu_flags() if that was used -+ * before. So av_get_cpu_flags() can easily be used in an application to -+ * detect the enabled cpu flags. -+ */ -+int av_get_cpu_flags(void); -+ -+/** -+ * Disables cpu detection and forces the specified flags. -+ * -1 is a special case that disables forcing of specific flags. -+ */ -+void av_force_cpu_flags(int flags); -+ -+/** -+ * Parse CPU caps from a string and update the given AV_CPU_* flags based on -+ * that. -+ * -+ * @return negative on error. -+ */ -+int av_parse_cpu_caps(unsigned* flags, const char* s); -+ -+/** -+ * @return the number of logical CPU cores present. -+ */ -+int av_cpu_count(void); -+ -+/** -+ * Overrides cpu count detection and forces the specified count. -+ * Count < 1 disables forcing of specific count. -+ */ -+void av_cpu_force_count(int count); -+ -+/** -+ * Get the maximum data alignment that may be required by FFmpeg. -+ * -+ * Note that this is affected by the build configuration and the CPU flags mask, -+ * so e.g. if the CPU supports AVX, but libavutil has been built with -+ * --disable-avx or the AV_CPU_FLAG_AVX flag has been disabled through -+ * av_set_cpu_flags_mask(), then this function will behave as if AVX is not -+ * present. -+ */ -+size_t av_cpu_max_align(void); -+ -+#endif /* AVUTIL_CPU_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/dict.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/dict.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/dict.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/dict.h 2022-07-05 00:21:22.447315813 +0300 -@@ -0,0 +1,215 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * Public dictionary API. -+ * @deprecated -+ * AVDictionary is provided for compatibility with libav. It is both in -+ * implementation as well as API inefficient. It does not scale and is -+ * extremely slow with large dictionaries. -+ * It is recommended that new code uses our tree container from tree.c/h -+ * where applicable, which uses AVL trees to achieve O(log n) performance. -+ */ -+ -+#ifndef AVUTIL_DICT_H -+#define AVUTIL_DICT_H -+ -+#include -+ -+/** -+ * @addtogroup lavu_dict AVDictionary -+ * @ingroup lavu_data -+ * -+ * @brief Simple key:value store -+ * -+ * @{ -+ * Dictionaries are used for storing key:value pairs. To create -+ * an AVDictionary, simply pass an address of a NULL pointer to -+ * av_dict_set(). NULL can be used as an empty dictionary wherever -+ * a pointer to an AVDictionary is required. -+ * Use av_dict_get() to retrieve an entry or iterate over all -+ * entries and finally av_dict_free() to free the dictionary -+ * and all its contents. -+ * -+ @code -+ AVDictionary *d = NULL; // "create" an empty dictionary -+ AVDictionaryEntry *t = NULL; -+ -+ av_dict_set(&d, "foo", "bar", 0); // add an entry -+ -+ char *k = av_strdup("key"); // if your strings are already allocated, -+ char *v = av_strdup("value"); // you can avoid copying them like this -+ av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); -+ -+ while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) { -+ <....> // iterate over all entries in d -+ } -+ av_dict_free(&d); -+ @endcode -+ */ -+ -+#define AV_DICT_MATCH_CASE \ -+ 1 /**< Only get an entry with exact-case key match. Only relevant in \ -+ av_dict_get(). */ -+#define AV_DICT_IGNORE_SUFFIX \ -+ 2 /**< Return first entry in a dictionary whose first part corresponds to \ -+ the search key, ignoring the suffix of the found key string. Only \ -+ relevant in av_dict_get(). */ -+#define AV_DICT_DONT_STRDUP_KEY \ -+ 4 /**< Take ownership of a key that's been \ -+ allocated with av_malloc() or another memory allocation function. */ -+#define AV_DICT_DONT_STRDUP_VAL \ -+ 8 /**< Take ownership of a value that's been \ -+ allocated with av_malloc() or another memory allocation function. */ -+#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. -+#define AV_DICT_APPEND \ -+ 32 /**< If the entry already exists, append to it. Note that no \ -+ delimiter is added, the strings are simply concatenated. */ -+#define AV_DICT_MULTIKEY \ -+ 64 /**< Allow to store several equal keys in the dictionary */ -+ -+typedef struct AVDictionaryEntry { -+ char* key; -+ char* value; -+} AVDictionaryEntry; -+ -+typedef struct AVDictionary AVDictionary; -+ -+/** -+ * Get a dictionary entry with matching key. -+ * -+ * The returned entry key or value must not be changed, or it will -+ * cause undefined behavior. -+ * -+ * To iterate through all the dictionary entries, you can set the matching key -+ * to the null string "" and set the AV_DICT_IGNORE_SUFFIX flag. -+ * -+ * @param prev Set to the previous matching element to find the next. -+ * If set to NULL the first matching element is returned. -+ * @param key matching key -+ * @param flags a collection of AV_DICT_* flags controlling how the entry is -+ * retrieved -+ * @return found entry or NULL in case no matching entry was found in the -+ * dictionary -+ */ -+AVDictionaryEntry* av_dict_get(const AVDictionary* m, const char* key, -+ const AVDictionaryEntry* prev, int flags); -+ -+/** -+ * Get number of entries in dictionary. -+ * -+ * @param m dictionary -+ * @return number of entries in dictionary -+ */ -+int av_dict_count(const AVDictionary* m); -+ -+/** -+ * Set the given entry in *pm, overwriting an existing entry. -+ * -+ * Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set, -+ * these arguments will be freed on error. -+ * -+ * Warning: Adding a new entry to a dictionary invalidates all existing entries -+ * previously returned with av_dict_get. -+ * -+ * @param pm pointer to a pointer to a dictionary struct. If *pm is NULL -+ * a dictionary struct is allocated and put in *pm. -+ * @param key entry key to add to *pm (will either be av_strduped or added as a -+ * new key depending on flags) -+ * @param value entry value to add to *pm (will be av_strduped or added as a new -+ * key depending on flags). Passing a NULL value will cause an existing entry to -+ * be deleted. -+ * @return >= 0 on success otherwise an error code <0 -+ */ -+int av_dict_set(AVDictionary** pm, const char* key, const char* value, -+ int flags); -+ -+/** -+ * Convenience wrapper for av_dict_set that converts the value to a string -+ * and stores it. -+ * -+ * Note: If AV_DICT_DONT_STRDUP_KEY is set, key will be freed on error. -+ */ -+int av_dict_set_int(AVDictionary** pm, const char* key, int64_t value, -+ int flags); -+ -+/** -+ * Parse the key/value pairs list and add the parsed entries to a dictionary. -+ * -+ * In case of failure, all the successfully set entries are stored in -+ * *pm. You may need to manually free the created dictionary. -+ * -+ * @param key_val_sep a 0-terminated list of characters used to separate -+ * key from value -+ * @param pairs_sep a 0-terminated list of characters used to separate -+ * two pairs from each other -+ * @param flags flags to use when adding to dictionary. -+ * AV_DICT_DONT_STRDUP_KEY and AV_DICT_DONT_STRDUP_VAL -+ * are ignored since the key/value tokens will always -+ * be duplicated. -+ * @return 0 on success, negative AVERROR code on failure -+ */ -+int av_dict_parse_string(AVDictionary** pm, const char* str, -+ const char* key_val_sep, const char* pairs_sep, -+ int flags); -+ -+/** -+ * Copy entries from one AVDictionary struct into another. -+ * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL, -+ * this function will allocate a struct for you and put it in *dst -+ * @param src pointer to source AVDictionary struct -+ * @param flags flags to use when setting entries in *dst -+ * @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag -+ * @return 0 on success, negative AVERROR code on failure. If dst was allocated -+ * by this function, callers should free the associated memory. -+ */ -+int av_dict_copy(AVDictionary** dst, const AVDictionary* src, int flags); -+ -+/** -+ * Free all the memory allocated for an AVDictionary struct -+ * and all keys and values. -+ */ -+void av_dict_free(AVDictionary** m); -+ -+/** -+ * Get dictionary entries as a string. -+ * -+ * Create a string containing dictionary's entries. -+ * Such string may be passed back to av_dict_parse_string(). -+ * @note String is escaped with backslashes ('\'). -+ * -+ * @param[in] m dictionary -+ * @param[out] buffer Pointer to buffer that will be allocated with -+ * string containg entries. Buffer must be freed by the caller when is no longer -+ * needed. -+ * @param[in] key_val_sep character used to separate key from value -+ * @param[in] pairs_sep character used to separate two pairs from each -+ * other -+ * @return >= 0 on success, negative on error -+ * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the -+ * same. -+ */ -+int av_dict_get_string(const AVDictionary* m, char** buffer, -+ const char key_val_sep, const char pairs_sep); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_DICT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/error.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/error.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/error.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/error.h 2022-07-05 00:21:22.447315813 +0300 -@@ -0,0 +1,158 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * error code definitions -+ */ -+ -+#ifndef AVUTIL_ERROR_H -+#define AVUTIL_ERROR_H -+ -+#include -+#include -+ -+#include "macros.h" -+ -+/** -+ * @addtogroup lavu_error -+ * -+ * @{ -+ */ -+ -+/* error handling */ -+#if EDOM > 0 -+# define AVERROR(e) \ -+ (-(e)) ///< Returns a negative error code from a POSIX error code, to -+ ///< return from library functions. -+# define AVUNERROR(e) \ -+ (-(e)) ///< Returns a POSIX error code from a library function error return -+ ///< value. -+#else -+/* Some platforms have E* and errno already negated. */ -+# define AVERROR(e) (e) -+# define AVUNERROR(e) (e) -+#endif -+ -+#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) -+ -+#define AVERROR_BSF_NOT_FOUND \ -+ FFERRTAG(0xF8, 'B', 'S', 'F') ///< Bitstream filter not found -+#define AVERROR_BUG \ -+ FFERRTAG('B', 'U', 'G', '!') ///< Internal bug, also see AVERROR_BUG2 -+#define AVERROR_BUFFER_TOO_SMALL \ -+ FFERRTAG('B', 'U', 'F', 'S') ///< Buffer too small -+#define AVERROR_DECODER_NOT_FOUND \ -+ FFERRTAG(0xF8, 'D', 'E', 'C') ///< Decoder not found -+#define AVERROR_DEMUXER_NOT_FOUND \ -+ FFERRTAG(0xF8, 'D', 'E', 'M') ///< Demuxer not found -+#define AVERROR_ENCODER_NOT_FOUND \ -+ FFERRTAG(0xF8, 'E', 'N', 'C') ///< Encoder not found -+#define AVERROR_EOF FFERRTAG('E', 'O', 'F', ' ') ///< End of file -+#define AVERROR_EXIT \ -+ FFERRTAG('E', 'X', 'I', 'T') ///< Immediate exit was requested; the called -+ ///< function should not be restarted -+#define AVERROR_EXTERNAL \ -+ FFERRTAG('E', 'X', 'T', ' ') ///< Generic error in an external library -+#define AVERROR_FILTER_NOT_FOUND \ -+ FFERRTAG(0xF8, 'F', 'I', 'L') ///< Filter not found -+#define AVERROR_INVALIDDATA \ -+ FFERRTAG('I', 'N', 'D', 'A') ///< Invalid data found when processing input -+#define AVERROR_MUXER_NOT_FOUND \ -+ FFERRTAG(0xF8, 'M', 'U', 'X') ///< Muxer not found -+#define AVERROR_OPTION_NOT_FOUND \ -+ FFERRTAG(0xF8, 'O', 'P', 'T') ///< Option not found -+#define AVERROR_PATCHWELCOME \ -+ FFERRTAG('P', 'A', 'W', \ -+ 'E') ///< Not yet implemented in FFmpeg, patches welcome -+#define AVERROR_PROTOCOL_NOT_FOUND \ -+ FFERRTAG(0xF8, 'P', 'R', 'O') ///< Protocol not found -+ -+#define AVERROR_STREAM_NOT_FOUND \ -+ FFERRTAG(0xF8, 'S', 'T', 'R') ///< Stream not found -+/** -+ * This is semantically identical to AVERROR_BUG -+ * it has been introduced in Libav after our AVERROR_BUG and with a modified -+ * value. -+ */ -+#define AVERROR_BUG2 FFERRTAG('B', 'U', 'G', ' ') -+#define AVERROR_UNKNOWN \ -+ FFERRTAG('U', 'N', 'K', \ -+ 'N') ///< Unknown error, typically from an external library -+#define AVERROR_EXPERIMENTAL \ -+ (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set -+ ///< strict_std_compliance if you really want to use it. -+#define AVERROR_INPUT_CHANGED \ -+ (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. -+ ///< (can be OR-ed with AVERROR_OUTPUT_CHANGED) -+#define AVERROR_OUTPUT_CHANGED \ -+ (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. -+ ///< (can be OR-ed with AVERROR_INPUT_CHANGED) -+/* HTTP & RTSP errors */ -+#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8, '4', '0', '0') -+#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8, '4', '0', '1') -+#define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8, '4', '0', '3') -+#define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8, '4', '0', '4') -+#define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8, '4', 'X', 'X') -+#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8, '5', 'X', 'X') -+ -+#define AV_ERROR_MAX_STRING_SIZE 64 -+ -+/** -+ * Put a description of the AVERROR code errnum in errbuf. -+ * In case of failure the global variable errno is set to indicate the -+ * error. Even in case of failure av_strerror() will print a generic -+ * error message indicating the errnum provided to errbuf. -+ * -+ * @param errnum error code to describe -+ * @param errbuf buffer to which description is written -+ * @param errbuf_size the size in bytes of errbuf -+ * @return 0 on success, a negative value if a description for errnum -+ * cannot be found -+ */ -+int av_strerror(int errnum, char* errbuf, size_t errbuf_size); -+ -+/** -+ * Fill the provided buffer with a string containing an error string -+ * corresponding to the AVERROR code errnum. -+ * -+ * @param errbuf a buffer -+ * @param errbuf_size size in bytes of errbuf -+ * @param errnum error code to describe -+ * @return the buffer in input, filled with the error description -+ * @see av_strerror() -+ */ -+static inline char* av_make_error_string(char* errbuf, size_t errbuf_size, -+ int errnum) { -+ av_strerror(errnum, errbuf, errbuf_size); -+ return errbuf; -+} -+ -+/** -+ * Convenience macro, the return value should be used only directly in -+ * function arguments but never stand-alone. -+ */ -+#define av_err2str(errnum) \ -+ av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, \ -+ AV_ERROR_MAX_STRING_SIZE, errnum) -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_ERROR_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/frame.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/frame.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/frame.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/frame.h 2022-07-05 00:21:22.448315807 +0300 -@@ -0,0 +1,927 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @ingroup lavu_frame -+ * reference-counted frame API -+ */ -+ -+#ifndef AVUTIL_FRAME_H -+#define AVUTIL_FRAME_H -+ -+#include -+#include -+ -+#include "avutil.h" -+#include "buffer.h" -+#include "dict.h" -+#include "rational.h" -+#include "samplefmt.h" -+#include "pixfmt.h" -+#include "version.h" -+ -+/** -+ * @defgroup lavu_frame AVFrame -+ * @ingroup lavu_data -+ * -+ * @{ -+ * AVFrame is an abstraction for reference-counted raw multimedia data. -+ */ -+ -+enum AVFrameSideDataType { -+ /** -+ * The data is the AVPanScan struct defined in libavcodec. -+ */ -+ AV_FRAME_DATA_PANSCAN, -+ /** -+ * ATSC A53 Part 4 Closed Captions. -+ * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data. -+ * The number of bytes of CC data is AVFrameSideData.size. -+ */ -+ AV_FRAME_DATA_A53_CC, -+ /** -+ * Stereoscopic 3d metadata. -+ * The data is the AVStereo3D struct defined in libavutil/stereo3d.h. -+ */ -+ AV_FRAME_DATA_STEREO3D, -+ /** -+ * The data is the AVMatrixEncoding enum defined in -+ * libavutil/channel_layout.h. -+ */ -+ AV_FRAME_DATA_MATRIXENCODING, -+ /** -+ * Metadata relevant to a downmix procedure. -+ * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. -+ */ -+ AV_FRAME_DATA_DOWNMIX_INFO, -+ /** -+ * ReplayGain information in the form of the AVReplayGain struct. -+ */ -+ AV_FRAME_DATA_REPLAYGAIN, -+ /** -+ * This side data contains a 3x3 transformation matrix describing an affine -+ * transformation that needs to be applied to the frame for correct -+ * presentation. -+ * -+ * See libavutil/display.h for a detailed description of the data. -+ */ -+ AV_FRAME_DATA_DISPLAYMATRIX, -+ /** -+ * Active Format Description data consisting of a single byte as specified -+ * in ETSI TS 101 154 using AVActiveFormatDescription enum. -+ */ -+ AV_FRAME_DATA_AFD, -+ /** -+ * Motion vectors exported by some codecs (on demand through the export_mvs -+ * flag set in the libavcodec AVCodecContext flags2 option). -+ * The data is the AVMotionVector struct defined in -+ * libavutil/motion_vector.h. -+ */ -+ AV_FRAME_DATA_MOTION_VECTORS, -+ /** -+ * Recommmends skipping the specified number of samples. This is exported -+ * only if the "skip_manual" AVOption is set in libavcodec. -+ * This has the same format as AV_PKT_DATA_SKIP_SAMPLES. -+ * @code -+ * u32le number of samples to skip from start of this packet -+ * u32le number of samples to skip from end of this packet -+ * u8 reason for start skip -+ * u8 reason for end skip (0=padding silence, 1=convergence) -+ * @endcode -+ */ -+ AV_FRAME_DATA_SKIP_SAMPLES, -+ /** -+ * This side data must be associated with an audio frame and corresponds to -+ * enum AVAudioServiceType defined in avcodec.h. -+ */ -+ AV_FRAME_DATA_AUDIO_SERVICE_TYPE, -+ /** -+ * Mastering display metadata associated with a video frame. The payload is -+ * an AVMasteringDisplayMetadata type and contains information about the -+ * mastering display color volume. -+ */ -+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, -+ /** -+ * The GOP timecode in 25 bit timecode format. Data format is 64-bit integer. -+ * This is set on the first frame of a GOP that has a temporal reference of 0. -+ */ -+ AV_FRAME_DATA_GOP_TIMECODE, -+ -+ /** -+ * The data represents the AVSphericalMapping structure defined in -+ * libavutil/spherical.h. -+ */ -+ AV_FRAME_DATA_SPHERICAL, -+ -+ /** -+ * Content light level (based on CTA-861.3). This payload contains data in -+ * the form of the AVContentLightMetadata struct. -+ */ -+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, -+ -+ /** -+ * The data contains an ICC profile as an opaque octet buffer following the -+ * format described by ISO 15076-1 with an optional name defined in the -+ * metadata key entry "name". -+ */ -+ AV_FRAME_DATA_ICC_PROFILE, -+ -+ /** -+ * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 -+ * uint32_t where the first uint32_t describes how many (1-3) of the other -+ * timecodes are used. The timecode format is described in the documentation -+ * of av_timecode_get_smpte_from_framenum() function in libavutil/timecode.h. -+ */ -+ AV_FRAME_DATA_S12M_TIMECODE, -+ -+ /** -+ * HDR dynamic metadata associated with a video frame. The payload is -+ * an AVDynamicHDRPlus type and contains information for color -+ * volume transform - application 4 of SMPTE 2094-40:2016 standard. -+ */ -+ AV_FRAME_DATA_DYNAMIC_HDR_PLUS, -+ -+ /** -+ * Regions Of Interest, the data is an array of AVRegionOfInterest type, the -+ * number of array element is implied by AVFrameSideData.size / -+ * AVRegionOfInterest.self_size. -+ */ -+ AV_FRAME_DATA_REGIONS_OF_INTEREST, -+ -+ /** -+ * Encoding parameters for a video frame, as described by AVVideoEncParams. -+ */ -+ AV_FRAME_DATA_VIDEO_ENC_PARAMS, -+ -+ /** -+ * User data unregistered metadata associated with a video frame. -+ * This is the H.26[45] UDU SEI message, and shouldn't be used for any other -+ * purpose The data is stored as uint8_t in AVFrameSideData.data which is 16 -+ * bytes of uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of -+ * user_data_payload_byte. -+ */ -+ AV_FRAME_DATA_SEI_UNREGISTERED, -+ -+ /** -+ * Film grain parameters for a frame, described by AVFilmGrainParams. -+ * Must be present for every frame which should have film grain applied. -+ */ -+ AV_FRAME_DATA_FILM_GRAIN_PARAMS, -+ -+ /** -+ * Bounding boxes for object detection and classification, -+ * as described by AVDetectionBBoxHeader. -+ */ -+ AV_FRAME_DATA_DETECTION_BBOXES, -+ -+ /** -+ * Dolby Vision RPU raw data, suitable for passing to x265 -+ * or other libraries. Array of uint8_t, with NAL emulation -+ * bytes intact. -+ */ -+ AV_FRAME_DATA_DOVI_RPU_BUFFER, -+ -+ /** -+ * Parsed Dolby Vision metadata, suitable for passing to a software -+ * implementation. The payload is the AVDOVIMetadata struct defined in -+ * libavutil/dovi_meta.h. -+ */ -+ AV_FRAME_DATA_DOVI_METADATA, -+}; -+ -+enum AVActiveFormatDescription { -+ AV_AFD_SAME = 8, -+ AV_AFD_4_3 = 9, -+ AV_AFD_16_9 = 10, -+ AV_AFD_14_9 = 11, -+ AV_AFD_4_3_SP_14_9 = 13, -+ AV_AFD_16_9_SP_14_9 = 14, -+ AV_AFD_SP_4_3 = 15, -+}; -+ -+/** -+ * Structure to hold side data for an AVFrame. -+ * -+ * sizeof(AVFrameSideData) is not a part of the public ABI, so new fields may be -+ * added to the end with a minor bump. -+ */ -+typedef struct AVFrameSideData { -+ enum AVFrameSideDataType type; -+ uint8_t* data; -+ size_t size; -+ AVDictionary* metadata; -+ AVBufferRef* buf; -+} AVFrameSideData; -+ -+/** -+ * Structure describing a single Region Of Interest. -+ * -+ * When multiple regions are defined in a single side-data block, they -+ * should be ordered from most to least important - some encoders are only -+ * capable of supporting a limited number of distinct regions, so will have -+ * to truncate the list. -+ * -+ * When overlapping regions are defined, the first region containing a given -+ * area of the frame applies. -+ */ -+typedef struct AVRegionOfInterest { -+ /** -+ * Must be set to the size of this data structure (that is, -+ * sizeof(AVRegionOfInterest)). -+ */ -+ uint32_t self_size; -+ /** -+ * Distance in pixels from the top edge of the frame to the top and -+ * bottom edges and from the left edge of the frame to the left and -+ * right edges of the rectangle defining this region of interest. -+ * -+ * The constraints on a region are encoder dependent, so the region -+ * actually affected may be slightly larger for alignment or other -+ * reasons. -+ */ -+ int top; -+ int bottom; -+ int left; -+ int right; -+ /** -+ * Quantisation offset. -+ * -+ * Must be in the range -1 to +1. A value of zero indicates no quality -+ * change. A negative value asks for better quality (less quantisation), -+ * while a positive value asks for worse quality (greater quantisation). -+ * -+ * The range is calibrated so that the extreme values indicate the -+ * largest possible offset - if the rest of the frame is encoded with the -+ * worst possible quality, an offset of -1 indicates that this region -+ * should be encoded with the best possible quality anyway. Intermediate -+ * values are then interpolated in some codec-dependent way. -+ * -+ * For example, in 10-bit H.264 the quantisation parameter varies between -+ * -12 and 51. A typical qoffset value of -1/10 therefore indicates that -+ * this region should be encoded with a QP around one-tenth of the full -+ * range better than the rest of the frame. So, if most of the frame -+ * were to be encoded with a QP of around 30, this region would get a QP -+ * of around 24 (an offset of approximately -1/10 * (51 - -12) = -6.3). -+ * An extreme value of -1 would indicate that this region should be -+ * encoded with the best possible quality regardless of the treatment of -+ * the rest of the frame - that is, should be encoded at a QP of -12. -+ */ -+ AVRational qoffset; -+} AVRegionOfInterest; -+ -+/** -+ * This structure describes decoded (raw) audio or video data. -+ * -+ * AVFrame must be allocated using av_frame_alloc(). Note that this only -+ * allocates the AVFrame itself, the buffers for the data must be managed -+ * through other means (see below). -+ * AVFrame must be freed with av_frame_free(). -+ * -+ * AVFrame is typically allocated once and then reused multiple times to hold -+ * different data (e.g. a single AVFrame to hold frames received from a -+ * decoder). In such a case, av_frame_unref() will free any references held by -+ * the frame and reset it to its original clean state before it -+ * is reused again. -+ * -+ * The data described by an AVFrame is usually reference counted through the -+ * AVBuffer API. The underlying buffer references are stored in AVFrame.buf / -+ * AVFrame.extended_buf. An AVFrame is considered to be reference counted if at -+ * least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case, -+ * every single data plane must be contained in one of the buffers in -+ * AVFrame.buf or AVFrame.extended_buf. -+ * There may be a single buffer for all the data, or one separate buffer for -+ * each plane, or anything in between. -+ * -+ * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added -+ * to the end with a minor bump. -+ * -+ * Fields can be accessed through AVOptions, the name string used, matches the -+ * C structure field name for fields accessible through AVOptions. The AVClass -+ * for AVFrame can be obtained from avcodec_get_frame_class() -+ */ -+typedef struct AVFrame { -+#define AV_NUM_DATA_POINTERS 8 -+ /** -+ * pointer to the picture/channel planes. -+ * This might be different from the first allocated byte. For video, -+ * it could even point to the end of the image data. -+ * -+ * All pointers in data and extended_data must point into one of the -+ * AVBufferRef in buf or extended_buf. -+ * -+ * Some decoders access areas outside 0,0 - width,height, please -+ * see avcodec_align_dimensions2(). Some filters and swscale can read -+ * up to 16 bytes beyond the planes, if these filters are to be used, -+ * then 16 extra bytes must be allocated. -+ * -+ * NOTE: Pointers not needed by the format MUST be set to NULL. -+ * -+ * @attention In case of video, the data[] pointers can point to the -+ * end of image data in order to reverse line order, when used in -+ * combination with negative values in the linesize[] array. -+ */ -+ uint8_t* data[AV_NUM_DATA_POINTERS]; -+ -+ /** -+ * For video, a positive or negative value, which is typically indicating -+ * the size in bytes of each picture line, but it can also be: -+ * - the negative byte size of lines for vertical flipping -+ * (with data[n] pointing to the end of the data -+ * - a positive or negative multiple of the byte size as for accessing -+ * even and odd fields of a frame (possibly flipped) -+ * -+ * For audio, only linesize[0] may be set. For planar audio, each channel -+ * plane must be the same size. -+ * -+ * For video the linesizes should be multiples of the CPUs alignment -+ * preference, this is 16 or 32 for modern desktop CPUs. -+ * Some code requires such alignment other code can be slower without -+ * correct alignment, for yet other it makes no difference. -+ * -+ * @note The linesize may be larger than the size of usable data -- there -+ * may be extra padding present for performance reasons. -+ * -+ * @attention In case of video, line size values can be negative to achieve -+ * a vertically inverted iteration over image lines. -+ */ -+ int linesize[AV_NUM_DATA_POINTERS]; -+ -+ /** -+ * pointers to the data planes/channels. -+ * -+ * For video, this should simply point to data[]. -+ * -+ * For planar audio, each channel has a separate data pointer, and -+ * linesize[0] contains the size of each channel buffer. -+ * For packed audio, there is just one data pointer, and linesize[0] -+ * contains the total size of the buffer for all channels. -+ * -+ * Note: Both data and extended_data should always be set in a valid frame, -+ * but for planar audio with more channels that can fit in data, -+ * extended_data must be used in order to access all channels. -+ */ -+ uint8_t** extended_data; -+ -+ /** -+ * @name Video dimensions -+ * Video frames only. The coded dimensions (in pixels) of the video frame, -+ * i.e. the size of the rectangle that contains some well-defined values. -+ * -+ * @note The part of the frame intended for display/presentation is further -+ * restricted by the @ref cropping "Cropping rectangle". -+ * @{ -+ */ -+ int width, height; -+ /** -+ * @} -+ */ -+ -+ /** -+ * number of audio samples (per channel) described by this frame -+ */ -+ int nb_samples; -+ -+ /** -+ * format of the frame, -1 if unknown or unset -+ * Values correspond to enum AVPixelFormat for video frames, -+ * enum AVSampleFormat for audio) -+ */ -+ int format; -+ -+ /** -+ * 1 -> keyframe, 0-> not -+ */ -+ int key_frame; -+ -+ /** -+ * Picture type of the frame. -+ */ -+ enum AVPictureType pict_type; -+ -+ /** -+ * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified. -+ */ -+ AVRational sample_aspect_ratio; -+ -+ /** -+ * Presentation timestamp in time_base units (time when frame should be shown -+ * to user). -+ */ -+ int64_t pts; -+ -+ /** -+ * DTS copied from the AVPacket that triggered returning this frame. (if frame -+ * threading isn't used) This is also the Presentation time of this AVFrame -+ * calculated from only AVPacket.dts values without pts values. -+ */ -+ int64_t pkt_dts; -+ -+ /** -+ * Time base for the timestamps in this frame. -+ * In the future, this field may be set on frames output by decoders or -+ * filters, but its value will be by default ignored on input to encoders -+ * or filters. -+ */ -+ AVRational time_base; -+ -+ /** -+ * picture number in bitstream order -+ */ -+ int coded_picture_number; -+ /** -+ * picture number in display order -+ */ -+ int display_picture_number; -+ -+ /** -+ * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) -+ */ -+ int quality; -+ -+ /** -+ * for some private data of the user -+ */ -+ void* opaque; -+ -+ /** -+ * When decoding, this signals how much the picture must be delayed. -+ * extra_delay = repeat_pict / (2*fps) -+ */ -+ int repeat_pict; -+ -+ /** -+ * The content of the picture is interlaced. -+ */ -+ int interlaced_frame; -+ -+ /** -+ * If the content is interlaced, is top field displayed first. -+ */ -+ int top_field_first; -+ -+ /** -+ * Tell user application that palette has changed from previous frame. -+ */ -+ int palette_has_changed; -+ -+ /** -+ * reordered opaque 64 bits (generally an integer or a double precision float -+ * PTS but can be anything). -+ * The user sets AVCodecContext.reordered_opaque to represent the input at -+ * that time, -+ * the decoder reorders values as needed and sets AVFrame.reordered_opaque -+ * to exactly one of the values provided by the user through -+ * AVCodecContext.reordered_opaque -+ */ -+ int64_t reordered_opaque; -+ -+ /** -+ * Sample rate of the audio data. -+ */ -+ int sample_rate; -+ -+ /** -+ * Channel layout of the audio data. -+ */ -+ uint64_t channel_layout; -+ -+ /** -+ * AVBuffer references backing the data for this frame. All the pointers in -+ * data and extended_data must point inside one of the buffers in buf or -+ * extended_buf. This array must be filled contiguously -- if buf[i] is -+ * non-NULL then buf[j] must also be non-NULL for all j < i. -+ * -+ * There may be at most one AVBuffer per data plane, so for video this array -+ * always contains all the references. For planar audio with more than -+ * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in -+ * this array. Then the extra AVBufferRef pointers are stored in the -+ * extended_buf array. -+ */ -+ AVBufferRef* buf[AV_NUM_DATA_POINTERS]; -+ -+ /** -+ * For planar audio which requires more than AV_NUM_DATA_POINTERS -+ * AVBufferRef pointers, this array will hold all the references which -+ * cannot fit into AVFrame.buf. -+ * -+ * Note that this is different from AVFrame.extended_data, which always -+ * contains all the pointers. This array only contains the extra pointers, -+ * which cannot fit into AVFrame.buf. -+ * -+ * This array is always allocated using av_malloc() by whoever constructs -+ * the frame. It is freed in av_frame_unref(). -+ */ -+ AVBufferRef** extended_buf; -+ /** -+ * Number of elements in extended_buf. -+ */ -+ int nb_extended_buf; -+ -+ AVFrameSideData** side_data; -+ int nb_side_data; -+ -+/** -+ * @defgroup lavu_frame_flags AV_FRAME_FLAGS -+ * @ingroup lavu_frame -+ * Flags describing additional frame properties. -+ * -+ * @{ -+ */ -+ -+/** -+ * The frame data may be corrupted, e.g. due to decoding errors. -+ */ -+#define AV_FRAME_FLAG_CORRUPT (1 << 0) -+/** -+ * A flag to mark the frames which need to be decoded, but shouldn't be output. -+ */ -+#define AV_FRAME_FLAG_DISCARD (1 << 2) -+ /** -+ * @} -+ */ -+ -+ /** -+ * Frame flags, a combination of @ref lavu_frame_flags -+ */ -+ int flags; -+ -+ /** -+ * MPEG vs JPEG YUV range. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVColorRange color_range; -+ -+ enum AVColorPrimaries color_primaries; -+ -+ enum AVColorTransferCharacteristic color_trc; -+ -+ /** -+ * YUV colorspace type. -+ * - encoding: Set by user -+ * - decoding: Set by libavcodec -+ */ -+ enum AVColorSpace colorspace; -+ -+ enum AVChromaLocation chroma_location; -+ -+ /** -+ * frame timestamp estimated using various heuristics, in stream time base -+ * - encoding: unused -+ * - decoding: set by libavcodec, read by user. -+ */ -+ int64_t best_effort_timestamp; -+ -+ /** -+ * reordered pos from the last AVPacket that has been input into the decoder -+ * - encoding: unused -+ * - decoding: Read by user. -+ */ -+ int64_t pkt_pos; -+ -+ /** -+ * duration of the corresponding packet, expressed in -+ * AVStream->time_base units, 0 if unknown. -+ * - encoding: unused -+ * - decoding: Read by user. -+ */ -+ int64_t pkt_duration; -+ -+ /** -+ * metadata. -+ * - encoding: Set by user. -+ * - decoding: Set by libavcodec. -+ */ -+ AVDictionary* metadata; -+ -+ /** -+ * decode error flags of the frame, set to a combination of -+ * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there -+ * were errors during the decoding. -+ * - encoding: unused -+ * - decoding: set by libavcodec, read by user. -+ */ -+ int decode_error_flags; -+#define FF_DECODE_ERROR_INVALID_BITSTREAM 1 -+#define FF_DECODE_ERROR_MISSING_REFERENCE 2 -+#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 -+#define FF_DECODE_ERROR_DECODE_SLICES 8 -+ -+ /** -+ * number of audio channels, only used for audio. -+ * - encoding: unused -+ * - decoding: Read by user. -+ */ -+ int channels; -+ -+ /** -+ * size of the corresponding packet containing the compressed -+ * frame. -+ * It is set to a negative value if unknown. -+ * - encoding: unused -+ * - decoding: set by libavcodec, read by user. -+ */ -+ int pkt_size; -+ -+ /** -+ * For hwaccel-format frames, this should be a reference to the -+ * AVHWFramesContext describing the frame. -+ */ -+ AVBufferRef* hw_frames_ctx; -+ -+ /** -+ * AVBufferRef for free use by the API user. FFmpeg will never check the -+ * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when -+ * the frame is unreferenced. av_frame_copy_props() calls create a new -+ * reference with av_buffer_ref() for the target frame's opaque_ref field. -+ * -+ * This is unrelated to the opaque field, although it serves a similar -+ * purpose. -+ */ -+ AVBufferRef* opaque_ref; -+ -+ /** -+ * @anchor cropping -+ * @name Cropping -+ * Video frames only. The number of pixels to discard from the the -+ * top/bottom/left/right border of the frame to obtain the sub-rectangle of -+ * the frame intended for presentation. -+ * @{ -+ */ -+ size_t crop_top; -+ size_t crop_bottom; -+ size_t crop_left; -+ size_t crop_right; -+ /** -+ * @} -+ */ -+ -+ /** -+ * AVBufferRef for internal use by a single libav* library. -+ * Must not be used to transfer data between libraries. -+ * Has to be NULL when ownership of the frame leaves the respective library. -+ * -+ * Code outside the FFmpeg libs should never check or change the contents of -+ * the buffer ref. -+ * -+ * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. -+ * av_frame_copy_props() calls create a new reference with av_buffer_ref() -+ * for the target frame's private_ref field. -+ */ -+ AVBufferRef* private_ref; -+} AVFrame; -+ -+#if FF_API_COLORSPACE_NAME -+/** -+ * Get the name of a colorspace. -+ * @return a static string identifying the colorspace; can be NULL. -+ * @deprecated use av_color_space_name() -+ */ -+attribute_deprecated const char* av_get_colorspace_name(enum AVColorSpace val); -+#endif -+/** -+ * Allocate an AVFrame and set its fields to default values. The resulting -+ * struct must be freed using av_frame_free(). -+ * -+ * @return An AVFrame filled with default values or NULL on failure. -+ * -+ * @note this only allocates the AVFrame itself, not the data buffers. Those -+ * must be allocated through other means, e.g. with av_frame_get_buffer() or -+ * manually. -+ */ -+AVFrame* av_frame_alloc(void); -+ -+/** -+ * Free the frame and any dynamically allocated objects in it, -+ * e.g. extended_data. If the frame is reference counted, it will be -+ * unreferenced first. -+ * -+ * @param frame frame to be freed. The pointer will be set to NULL. -+ */ -+void av_frame_free(AVFrame** frame); -+ -+/** -+ * Set up a new reference to the data described by the source frame. -+ * -+ * Copy frame properties from src to dst and create a new reference for each -+ * AVBufferRef from src. -+ * -+ * If src is not reference counted, new buffers are allocated and the data is -+ * copied. -+ * -+ * @warning: dst MUST have been either unreferenced with av_frame_unref(dst), -+ * or newly allocated with av_frame_alloc() before calling this -+ * function, or undefined behavior will occur. -+ * -+ * @return 0 on success, a negative AVERROR on error -+ */ -+int av_frame_ref(AVFrame* dst, const AVFrame* src); -+ -+/** -+ * Create a new frame that references the same data as src. -+ * -+ * This is a shortcut for av_frame_alloc()+av_frame_ref(). -+ * -+ * @return newly created AVFrame on success, NULL on error. -+ */ -+AVFrame* av_frame_clone(const AVFrame* src); -+ -+/** -+ * Unreference all the buffers referenced by frame and reset the frame fields. -+ */ -+void av_frame_unref(AVFrame* frame); -+ -+/** -+ * Move everything contained in src to dst and reset src. -+ * -+ * @warning: dst is not unreferenced, but directly overwritten without reading -+ * or deallocating its contents. Call av_frame_unref(dst) manually -+ * before calling this function to ensure that no memory is leaked. -+ */ -+void av_frame_move_ref(AVFrame* dst, AVFrame* src); -+ -+/** -+ * Allocate new buffer(s) for audio or video data. -+ * -+ * The following fields must be set on frame before calling this function: -+ * - format (pixel format for video, sample format for audio) -+ * - width and height for video -+ * - nb_samples and channel_layout for audio -+ * -+ * This function will fill AVFrame.data and AVFrame.buf arrays and, if -+ * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. -+ * For planar formats, one buffer will be allocated for each plane. -+ * -+ * @warning: if frame already has been allocated, calling this function will -+ * leak memory. In addition, undefined behavior can occur in certain -+ * cases. -+ * -+ * @param frame frame in which to store the new buffers. -+ * @param align Required buffer size alignment. If equal to 0, alignment will be -+ * chosen automatically for the current CPU. It is highly -+ * recommended to pass 0 here unless you know what you are doing. -+ * -+ * @return 0 on success, a negative AVERROR on error. -+ */ -+int av_frame_get_buffer(AVFrame* frame, int align); -+ -+/** -+ * Check if the frame data is writable. -+ * -+ * @return A positive value if the frame data is writable (which is true if and -+ * only if each of the underlying buffers has only one reference, namely the one -+ * stored in this frame). Return 0 otherwise. -+ * -+ * If 1 is returned the answer is valid until av_buffer_ref() is called on any -+ * of the underlying AVBufferRefs (e.g. through av_frame_ref() or directly). -+ * -+ * @see av_frame_make_writable(), av_buffer_is_writable() -+ */ -+int av_frame_is_writable(AVFrame* frame); -+ -+/** -+ * Ensure that the frame data is writable, avoiding data copy if possible. -+ * -+ * Do nothing if the frame is writable, allocate new buffers and copy the data -+ * if it is not. -+ * -+ * @return 0 on success, a negative AVERROR on error. -+ * -+ * @see av_frame_is_writable(), av_buffer_is_writable(), -+ * av_buffer_make_writable() -+ */ -+int av_frame_make_writable(AVFrame* frame); -+ -+/** -+ * Copy the frame data from src to dst. -+ * -+ * This function does not allocate anything, dst must be already initialized and -+ * allocated with the same parameters as src. -+ * -+ * This function only copies the frame data (i.e. the contents of the data / -+ * extended data arrays), not any other properties. -+ * -+ * @return >= 0 on success, a negative AVERROR on error. -+ */ -+int av_frame_copy(AVFrame* dst, const AVFrame* src); -+ -+/** -+ * Copy only "metadata" fields from src to dst. -+ * -+ * Metadata for the purpose of this function are those fields that do not affect -+ * the data layout in the buffers. E.g. pts, sample rate (for audio) or sample -+ * aspect ratio (for video), but not width/height or channel layout. -+ * Side data is also copied. -+ */ -+int av_frame_copy_props(AVFrame* dst, const AVFrame* src); -+ -+/** -+ * Get the buffer reference a given data plane is stored in. -+ * -+ * @param plane index of the data plane of interest in frame->extended_data. -+ * -+ * @return the buffer reference that contains the plane or NULL if the input -+ * frame is not valid. -+ */ -+AVBufferRef* av_frame_get_plane_buffer(AVFrame* frame, int plane); -+ -+/** -+ * Add a new side data to a frame. -+ * -+ * @param frame a frame to which the side data should be added -+ * @param type type of the added side data -+ * @param size size of the side data -+ * -+ * @return newly added side data on success, NULL on error -+ */ -+AVFrameSideData* av_frame_new_side_data(AVFrame* frame, -+ enum AVFrameSideDataType type, -+ size_t size); -+ -+/** -+ * Add a new side data to a frame from an existing AVBufferRef -+ * -+ * @param frame a frame to which the side data should be added -+ * @param type the type of the added side data -+ * @param buf an AVBufferRef to add as side data. The ownership of -+ * the reference is transferred to the frame. -+ * -+ * @return newly added side data on success, NULL on error. On failure -+ * the frame is unchanged and the AVBufferRef remains owned by -+ * the caller. -+ */ -+AVFrameSideData* av_frame_new_side_data_from_buf(AVFrame* frame, -+ enum AVFrameSideDataType type, -+ AVBufferRef* buf); -+ -+/** -+ * @return a pointer to the side data of a given type on success, NULL if there -+ * is no side data with such type in this frame. -+ */ -+AVFrameSideData* av_frame_get_side_data(const AVFrame* frame, -+ enum AVFrameSideDataType type); -+ -+/** -+ * Remove and free all side data instances of the given type. -+ */ -+void av_frame_remove_side_data(AVFrame* frame, enum AVFrameSideDataType type); -+ -+/** -+ * Flags for frame cropping. -+ */ -+enum { -+ /** -+ * Apply the maximum possible cropping, even if it requires setting the -+ * AVFrame.data[] entries to unaligned pointers. Passing unaligned data -+ * to FFmpeg API is generally not allowed, and causes undefined behavior -+ * (such as crashes). You can pass unaligned data only to FFmpeg APIs that -+ * are explicitly documented to accept it. Use this flag only if you -+ * absolutely know what you are doing. -+ */ -+ AV_FRAME_CROP_UNALIGNED = 1 << 0, -+}; -+ -+/** -+ * Crop the given video AVFrame according to its crop_left/crop_top/crop_right/ -+ * crop_bottom fields. If cropping is successful, the function will adjust the -+ * data pointers and the width/height fields, and set the crop fields to 0. -+ * -+ * In all cases, the cropping boundaries will be rounded to the inherent -+ * alignment of the pixel format. In some cases, such as for opaque hwaccel -+ * formats, the left/top cropping is ignored. The crop fields are set to 0 even -+ * if the cropping was rounded or ignored. -+ * -+ * @param frame the frame which should be cropped -+ * @param flags Some combination of AV_FRAME_CROP_* flags, or 0. -+ * -+ * @return >= 0 on success, a negative AVERROR on error. If the cropping fields -+ * were invalid, AVERROR(ERANGE) is returned, and nothing is changed. -+ */ -+int av_frame_apply_cropping(AVFrame* frame, int flags); -+ -+/** -+ * @return a string identifying the side data type -+ */ -+const char* av_frame_side_data_name(enum AVFrameSideDataType type); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_FRAME_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext.h 2022-07-05 00:21:22.449315801 +0300 -@@ -0,0 +1,601 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_HWCONTEXT_H -+#define AVUTIL_HWCONTEXT_H -+ -+#include "buffer.h" -+#include "frame.h" -+#include "log.h" -+#include "pixfmt.h" -+ -+enum AVHWDeviceType { -+ AV_HWDEVICE_TYPE_NONE, -+ AV_HWDEVICE_TYPE_VDPAU, -+ AV_HWDEVICE_TYPE_CUDA, -+ AV_HWDEVICE_TYPE_VAAPI, -+ AV_HWDEVICE_TYPE_DXVA2, -+ AV_HWDEVICE_TYPE_QSV, -+ AV_HWDEVICE_TYPE_VIDEOTOOLBOX, -+ AV_HWDEVICE_TYPE_D3D11VA, -+ AV_HWDEVICE_TYPE_DRM, -+ AV_HWDEVICE_TYPE_OPENCL, -+ AV_HWDEVICE_TYPE_MEDIACODEC, -+ AV_HWDEVICE_TYPE_VULKAN, -+}; -+ -+typedef struct AVHWDeviceInternal AVHWDeviceInternal; -+ -+/** -+ * This struct aggregates all the (hardware/vendor-specific) "high-level" state, -+ * i.e. state that is not tied to a concrete processing configuration. -+ * E.g., in an API that supports hardware-accelerated encoding and decoding, -+ * this struct will (if possible) wrap the state that is common to both encoding -+ * and decoding and from which specific instances of encoders or decoders can be -+ * derived. -+ * -+ * This struct is reference-counted with the AVBuffer mechanism. The -+ * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field -+ * points to the actual AVHWDeviceContext. Further objects derived from -+ * AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with -+ * specific properties) will hold an internal reference to it. After all the -+ * references are released, the AVHWDeviceContext itself will be freed, -+ * optionally invoking a user-specified callback for uninitializing the hardware -+ * state. -+ */ -+typedef struct AVHWDeviceContext { -+ /** -+ * A class for logging. Set by av_hwdevice_ctx_alloc(). -+ */ -+ const AVClass* av_class; -+ -+ /** -+ * Private data used internally by libavutil. Must not be accessed in any -+ * way by the caller. -+ */ -+ AVHWDeviceInternal* internal; -+ -+ /** -+ * This field identifies the underlying API used for hardware access. -+ * -+ * This field is set when this struct is allocated and never changed -+ * afterwards. -+ */ -+ enum AVHWDeviceType type; -+ -+ /** -+ * The format-specific data, allocated and freed by libavutil along with -+ * this context. -+ * -+ * Should be cast by the user to the format-specific context defined in the -+ * corresponding header (hwcontext_*.h) and filled as described in the -+ * documentation before calling av_hwdevice_ctx_init(). -+ * -+ * After calling av_hwdevice_ctx_init() this struct should not be modified -+ * by the caller. -+ */ -+ void* hwctx; -+ -+ /** -+ * This field may be set by the caller before calling av_hwdevice_ctx_init(). -+ * -+ * If non-NULL, this callback will be called when the last reference to -+ * this context is unreferenced, immediately before it is freed. -+ * -+ * @note when other objects (e.g an AVHWFramesContext) are derived from this -+ * struct, this callback will be invoked after all such child objects -+ * are fully uninitialized and their respective destructors invoked. -+ */ -+ void (*free)(struct AVHWDeviceContext* ctx); -+ -+ /** -+ * Arbitrary user data, to be used e.g. by the free() callback. -+ */ -+ void* user_opaque; -+} AVHWDeviceContext; -+ -+typedef struct AVHWFramesInternal AVHWFramesInternal; -+ -+/** -+ * This struct describes a set or pool of "hardware" frames (i.e. those with -+ * data not located in normal system memory). All the frames in the pool are -+ * assumed to be allocated in the same way and interchangeable. -+ * -+ * This struct is reference-counted with the AVBuffer mechanism and tied to a -+ * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor -+ * yields a reference, whose data field points to the actual AVHWFramesContext -+ * struct. -+ */ -+typedef struct AVHWFramesContext { -+ /** -+ * A class for logging. -+ */ -+ const AVClass* av_class; -+ -+ /** -+ * Private data used internally by libavutil. Must not be accessed in any -+ * way by the caller. -+ */ -+ AVHWFramesInternal* internal; -+ -+ /** -+ * A reference to the parent AVHWDeviceContext. This reference is owned and -+ * managed by the enclosing AVHWFramesContext, but the caller may derive -+ * additional references from it. -+ */ -+ AVBufferRef* device_ref; -+ -+ /** -+ * The parent AVHWDeviceContext. This is simply a pointer to -+ * device_ref->data provided for convenience. -+ * -+ * Set by libavutil in av_hwframe_ctx_init(). -+ */ -+ AVHWDeviceContext* device_ctx; -+ -+ /** -+ * The format-specific data, allocated and freed automatically along with -+ * this context. -+ * -+ * Should be cast by the user to the format-specific context defined in the -+ * corresponding header (hwframe_*.h) and filled as described in the -+ * documentation before calling av_hwframe_ctx_init(). -+ * -+ * After any frames using this context are created, the contents of this -+ * struct should not be modified by the caller. -+ */ -+ void* hwctx; -+ -+ /** -+ * This field may be set by the caller before calling av_hwframe_ctx_init(). -+ * -+ * If non-NULL, this callback will be called when the last reference to -+ * this context is unreferenced, immediately before it is freed. -+ */ -+ void (*free)(struct AVHWFramesContext* ctx); -+ -+ /** -+ * Arbitrary user data, to be used e.g. by the free() callback. -+ */ -+ void* user_opaque; -+ -+ /** -+ * A pool from which the frames are allocated by av_hwframe_get_buffer(). -+ * This field may be set by the caller before calling av_hwframe_ctx_init(). -+ * The buffers returned by calling av_buffer_pool_get() on this pool must -+ * have the properties described in the documentation in the corresponding hw -+ * type's header (hwcontext_*.h). The pool will be freed strictly before -+ * this struct's free() callback is invoked. -+ * -+ * This field may be NULL, then libavutil will attempt to allocate a pool -+ * internally. Note that certain device types enforce pools allocated at -+ * fixed size (frame count), which cannot be extended dynamically. In such a -+ * case, initial_pool_size must be set appropriately. -+ */ -+ AVBufferPool* pool; -+ -+ /** -+ * Initial size of the frame pool. If a device type does not support -+ * dynamically resizing the pool, then this is also the maximum pool size. -+ * -+ * May be set by the caller before calling av_hwframe_ctx_init(). Must be -+ * set if pool is NULL and the device type does not support dynamic pools. -+ */ -+ int initial_pool_size; -+ -+ /** -+ * The pixel format identifying the underlying HW surface type. -+ * -+ * Must be a hwaccel format, i.e. the corresponding descriptor must have the -+ * AV_PIX_FMT_FLAG_HWACCEL flag set. -+ * -+ * Must be set by the user before calling av_hwframe_ctx_init(). -+ */ -+ enum AVPixelFormat format; -+ -+ /** -+ * The pixel format identifying the actual data layout of the hardware -+ * frames. -+ * -+ * Must be set by the caller before calling av_hwframe_ctx_init(). -+ * -+ * @note when the underlying API does not provide the exact data layout, but -+ * only the colorspace/bit depth, this field should be set to the fully -+ * planar version of that format (e.g. for 8-bit 420 YUV it should be -+ * AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else). -+ */ -+ enum AVPixelFormat sw_format; -+ -+ /** -+ * The allocated dimensions of the frames in this pool. -+ * -+ * Must be set by the user before calling av_hwframe_ctx_init(). -+ */ -+ int width, height; -+} AVHWFramesContext; -+ -+/** -+ * Look up an AVHWDeviceType by name. -+ * -+ * @param name String name of the device type (case-insensitive). -+ * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if -+ * not found. -+ */ -+enum AVHWDeviceType av_hwdevice_find_type_by_name(const char* name); -+ -+/** Get the string name of an AVHWDeviceType. -+ * -+ * @param type Type from enum AVHWDeviceType. -+ * @return Pointer to a static string containing the name, or NULL if the type -+ * is not valid. -+ */ -+const char* av_hwdevice_get_type_name(enum AVHWDeviceType type); -+ -+/** -+ * Iterate over supported device types. -+ * -+ * @param type AV_HWDEVICE_TYPE_NONE initially, then the previous type -+ * returned by this function in subsequent iterations. -+ * @return The next usable device type from enum AVHWDeviceType, or -+ * AV_HWDEVICE_TYPE_NONE if there are no more. -+ */ -+enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev); -+ -+/** -+ * Allocate an AVHWDeviceContext for a given hardware type. -+ * -+ * @param type the type of the hardware device to allocate. -+ * @return a reference to the newly created AVHWDeviceContext on success or NULL -+ * on failure. -+ */ -+AVBufferRef* av_hwdevice_ctx_alloc(enum AVHWDeviceType type); -+ -+/** -+ * Finalize the device context before use. This function must be called after -+ * the context is filled with all the required information and before it is -+ * used in any way. -+ * -+ * @param ref a reference to the AVHWDeviceContext -+ * @return 0 on success, a negative AVERROR code on failure -+ */ -+int av_hwdevice_ctx_init(AVBufferRef* ref); -+ -+/** -+ * Open a device of the specified type and create an AVHWDeviceContext for it. -+ * -+ * This is a convenience function intended to cover the simple cases. Callers -+ * who need to fine-tune device creation/management should open the device -+ * manually and then wrap it in an AVHWDeviceContext using -+ * av_hwdevice_ctx_alloc()/av_hwdevice_ctx_init(). -+ * -+ * The returned context is already initialized and ready for use, the caller -+ * should not call av_hwdevice_ctx_init() on it. The user_opaque/free fields of -+ * the created AVHWDeviceContext are set by this function and should not be -+ * touched by the caller. -+ * -+ * @param device_ctx On success, a reference to the newly-created device context -+ * will be written here. The reference is owned by the caller -+ * and must be released with av_buffer_unref() when no longer -+ * needed. On failure, NULL will be written to this pointer. -+ * @param type The type of the device to create. -+ * @param device A type-specific string identifying the device to open. -+ * @param opts A dictionary of additional (type-specific) options to use in -+ * opening the device. The dictionary remains owned by the caller. -+ * @param flags currently unused -+ * -+ * @return 0 on success, a negative AVERROR code on failure. -+ */ -+int av_hwdevice_ctx_create(AVBufferRef** device_ctx, enum AVHWDeviceType type, -+ const char* device, AVDictionary* opts, int flags); -+ -+/** -+ * Create a new device of the specified type from an existing device. -+ * -+ * If the source device is a device of the target type or was originally -+ * derived from such a device (possibly through one or more intermediate -+ * devices of other types), then this will return a reference to the -+ * existing device of the same type as is requested. -+ * -+ * Otherwise, it will attempt to derive a new device from the given source -+ * device. If direct derivation to the new type is not implemented, it will -+ * attempt the same derivation from each ancestor of the source device in -+ * turn looking for an implemented derivation method. -+ * -+ * @param dst_ctx On success, a reference to the newly-created -+ * AVHWDeviceContext. -+ * @param type The type of the new device to create. -+ * @param src_ctx A reference to an existing AVHWDeviceContext which will be -+ * used to create the new device. -+ * @param flags Currently unused; should be set to zero. -+ * @return Zero on success, a negative AVERROR code on failure. -+ */ -+int av_hwdevice_ctx_create_derived(AVBufferRef** dst_ctx, -+ enum AVHWDeviceType type, -+ AVBufferRef* src_ctx, int flags); -+ -+/** -+ * Create a new device of the specified type from an existing device. -+ * -+ * This function performs the same action as av_hwdevice_ctx_create_derived, -+ * however, it is able to set options for the new device to be derived. -+ * -+ * @param dst_ctx On success, a reference to the newly-created -+ * AVHWDeviceContext. -+ * @param type The type of the new device to create. -+ * @param src_ctx A reference to an existing AVHWDeviceContext which will be -+ * used to create the new device. -+ * @param options Options for the new device to create, same format as in -+ * av_hwdevice_ctx_create. -+ * @param flags Currently unused; should be set to zero. -+ * @return Zero on success, a negative AVERROR code on failure. -+ */ -+int av_hwdevice_ctx_create_derived_opts(AVBufferRef** dst_ctx, -+ enum AVHWDeviceType type, -+ AVBufferRef* src_ctx, -+ AVDictionary* options, int flags); -+ -+/** -+ * Allocate an AVHWFramesContext tied to a given device context. -+ * -+ * @param device_ctx a reference to a AVHWDeviceContext. This function will make -+ * a new reference for internal use, the one passed to the -+ * function remains owned by the caller. -+ * @return a reference to the newly created AVHWFramesContext on success or NULL -+ * on failure. -+ */ -+AVBufferRef* av_hwframe_ctx_alloc(AVBufferRef* device_ctx); -+ -+/** -+ * Finalize the context before use. This function must be called after the -+ * context is filled with all the required information and before it is attached -+ * to any frames. -+ * -+ * @param ref a reference to the AVHWFramesContext -+ * @return 0 on success, a negative AVERROR code on failure -+ */ -+int av_hwframe_ctx_init(AVBufferRef* ref); -+ -+/** -+ * Allocate a new frame attached to the given AVHWFramesContext. -+ * -+ * @param hwframe_ctx a reference to an AVHWFramesContext -+ * @param frame an empty (freshly allocated or unreffed) frame to be filled with -+ * newly allocated buffers. -+ * @param flags currently unused, should be set to zero -+ * @return 0 on success, a negative AVERROR code on failure -+ */ -+int av_hwframe_get_buffer(AVBufferRef* hwframe_ctx, AVFrame* frame, int flags); -+ -+/** -+ * Copy data to or from a hw surface. At least one of dst/src must have an -+ * AVHWFramesContext attached. -+ * -+ * If src has an AVHWFramesContext attached, then the format of dst (if set) -+ * must use one of the formats returned by av_hwframe_transfer_get_formats(src, -+ * AV_HWFRAME_TRANSFER_DIRECTION_FROM). -+ * If dst has an AVHWFramesContext attached, then the format of src must use one -+ * of the formats returned by av_hwframe_transfer_get_formats(dst, -+ * AV_HWFRAME_TRANSFER_DIRECTION_TO) -+ * -+ * dst may be "clean" (i.e. with data/buf pointers unset), in which case the -+ * data buffers will be allocated by this function using av_frame_get_buffer(). -+ * If dst->format is set, then this format will be used, otherwise (when -+ * dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen. -+ * -+ * The two frames must have matching allocated dimensions (i.e. equal to -+ * AVHWFramesContext.width/height), since not all device types support -+ * transferring a sub-rectangle of the whole surface. The display dimensions -+ * (i.e. AVFrame.width/height) may be smaller than the allocated dimensions, but -+ * also have to be equal for both frames. When the display dimensions are -+ * smaller than the allocated dimensions, the content of the padding in the -+ * destination frame is unspecified. -+ * -+ * @param dst the destination frame. dst is not touched on failure. -+ * @param src the source frame. -+ * @param flags currently unused, should be set to zero -+ * @return 0 on success, a negative AVERROR error code on failure. -+ */ -+int av_hwframe_transfer_data(AVFrame* dst, const AVFrame* src, int flags); -+ -+enum AVHWFrameTransferDirection { -+ /** -+ * Transfer the data from the queried hw frame. -+ */ -+ AV_HWFRAME_TRANSFER_DIRECTION_FROM, -+ -+ /** -+ * Transfer the data to the queried hw frame. -+ */ -+ AV_HWFRAME_TRANSFER_DIRECTION_TO, -+}; -+ -+/** -+ * Get a list of possible source or target formats usable in -+ * av_hwframe_transfer_data(). -+ * -+ * @param hwframe_ctx the frame context to obtain the information for -+ * @param dir the direction of the transfer -+ * @param formats the pointer to the output format list will be written here. -+ * The list is terminated with AV_PIX_FMT_NONE and must be freed -+ * by the caller when no longer needed using av_free(). -+ * If this function returns successfully, the format list will -+ * have at least one item (not counting the terminator). -+ * On failure, the contents of this pointer are unspecified. -+ * @param flags currently unused, should be set to zero -+ * @return 0 on success, a negative AVERROR code on failure. -+ */ -+int av_hwframe_transfer_get_formats(AVBufferRef* hwframe_ctx, -+ enum AVHWFrameTransferDirection dir, -+ enum AVPixelFormat** formats, int flags); -+ -+/** -+ * This struct describes the constraints on hardware frames attached to -+ * a given device with a hardware-specific configuration. This is returned -+ * by av_hwdevice_get_hwframe_constraints() and must be freed by -+ * av_hwframe_constraints_free() after use. -+ */ -+typedef struct AVHWFramesConstraints { -+ /** -+ * A list of possible values for format in the hw_frames_ctx, -+ * terminated by AV_PIX_FMT_NONE. This member will always be filled. -+ */ -+ enum AVPixelFormat* valid_hw_formats; -+ -+ /** -+ * A list of possible values for sw_format in the hw_frames_ctx, -+ * terminated by AV_PIX_FMT_NONE. Can be NULL if this information is -+ * not known. -+ */ -+ enum AVPixelFormat* valid_sw_formats; -+ -+ /** -+ * The minimum size of frames in this hw_frames_ctx. -+ * (Zero if not known.) -+ */ -+ int min_width; -+ int min_height; -+ -+ /** -+ * The maximum size of frames in this hw_frames_ctx. -+ * (INT_MAX if not known / no limit.) -+ */ -+ int max_width; -+ int max_height; -+} AVHWFramesConstraints; -+ -+/** -+ * Allocate a HW-specific configuration structure for a given HW device. -+ * After use, the user must free all members as required by the specific -+ * hardware structure being used, then free the structure itself with -+ * av_free(). -+ * -+ * @param device_ctx a reference to the associated AVHWDeviceContext. -+ * @return The newly created HW-specific configuration structure on -+ * success or NULL on failure. -+ */ -+void* av_hwdevice_hwconfig_alloc(AVBufferRef* device_ctx); -+ -+/** -+ * Get the constraints on HW frames given a device and the HW-specific -+ * configuration to be used with that device. If no HW-specific -+ * configuration is provided, returns the maximum possible capabilities -+ * of the device. -+ * -+ * @param ref a reference to the associated AVHWDeviceContext. -+ * @param hwconfig a filled HW-specific configuration structure, or NULL -+ * to return the maximum possible capabilities of the device. -+ * @return AVHWFramesConstraints structure describing the constraints -+ * on the device, or NULL if not available. -+ */ -+AVHWFramesConstraints* av_hwdevice_get_hwframe_constraints( -+ AVBufferRef* ref, const void* hwconfig); -+ -+/** -+ * Free an AVHWFrameConstraints structure. -+ * -+ * @param constraints The (filled or unfilled) AVHWFrameConstraints structure. -+ */ -+void av_hwframe_constraints_free(AVHWFramesConstraints** constraints); -+ -+/** -+ * Flags to apply to frame mappings. -+ */ -+enum { -+ /** -+ * The mapping must be readable. -+ */ -+ AV_HWFRAME_MAP_READ = 1 << 0, -+ /** -+ * The mapping must be writeable. -+ */ -+ AV_HWFRAME_MAP_WRITE = 1 << 1, -+ /** -+ * The mapped frame will be overwritten completely in subsequent -+ * operations, so the current frame data need not be loaded. Any values -+ * which are not overwritten are unspecified. -+ */ -+ AV_HWFRAME_MAP_OVERWRITE = 1 << 2, -+ /** -+ * The mapping must be direct. That is, there must not be any copying in -+ * the map or unmap steps. Note that performance of direct mappings may -+ * be much lower than normal memory. -+ */ -+ AV_HWFRAME_MAP_DIRECT = 1 << 3, -+}; -+ -+/** -+ * Map a hardware frame. -+ * -+ * This has a number of different possible effects, depending on the format -+ * and origin of the src and dst frames. On input, src should be a usable -+ * frame with valid buffers and dst should be blank (typically as just created -+ * by av_frame_alloc()). src should have an associated hwframe context, and -+ * dst may optionally have a format and associated hwframe context. -+ * -+ * If src was created by mapping a frame from the hwframe context of dst, -+ * then this function undoes the mapping - dst is replaced by a reference to -+ * the frame that src was originally mapped from. -+ * -+ * If both src and dst have an associated hwframe context, then this function -+ * attempts to map the src frame from its hardware context to that of dst and -+ * then fill dst with appropriate data to be usable there. This will only be -+ * possible if the hwframe contexts and associated devices are compatible - -+ * given compatible devices, av_hwframe_ctx_create_derived() can be used to -+ * create a hwframe context for dst in which mapping should be possible. -+ * -+ * If src has a hwframe context but dst does not, then the src frame is -+ * mapped to normal memory and should thereafter be usable as a normal frame. -+ * If the format is set on dst, then the mapping will attempt to create dst -+ * with that format and fail if it is not possible. If format is unset (is -+ * AV_PIX_FMT_NONE) then dst will be mapped with whatever the most appropriate -+ * format to use is (probably the sw_format of the src hwframe context). -+ * -+ * A return value of AVERROR(ENOSYS) indicates that the mapping is not -+ * possible with the given arguments and hwframe setup, while other return -+ * values indicate that it failed somehow. -+ * -+ * @param dst Destination frame, to contain the mapping. -+ * @param src Source frame, to be mapped. -+ * @param flags Some combination of AV_HWFRAME_MAP_* flags. -+ * @return Zero on success, negative AVERROR code on failure. -+ */ -+int av_hwframe_map(AVFrame* dst, const AVFrame* src, int flags); -+ -+/** -+ * Create and initialise an AVHWFramesContext as a mapping of another existing -+ * AVHWFramesContext on a different device. -+ * -+ * av_hwframe_ctx_init() should not be called after this. -+ * -+ * @param derived_frame_ctx On success, a reference to the newly created -+ * AVHWFramesContext. -+ * @param derived_device_ctx A reference to the device to create the new -+ * AVHWFramesContext on. -+ * @param source_frame_ctx A reference to an existing AVHWFramesContext -+ * which will be mapped to the derived context. -+ * @param flags Some combination of AV_HWFRAME_MAP_* flags, defining the -+ * mapping parameters to apply to frames which are allocated -+ * in the derived device. -+ * @return Zero on success, negative AVERROR code on failure. -+ */ -+int av_hwframe_ctx_create_derived(AVBufferRef** derived_frame_ctx, -+ enum AVPixelFormat format, -+ AVBufferRef* derived_device_ctx, -+ AVBufferRef* source_frame_ctx, int flags); -+ -+#endif /* AVUTIL_HWCONTEXT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext_vaapi.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext_vaapi.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext_vaapi.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/hwcontext_vaapi.h 2022-07-05 00:21:22.449315801 +0300 -@@ -0,0 +1,117 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_HWCONTEXT_VAAPI_H -+#define AVUTIL_HWCONTEXT_VAAPI_H -+ -+#include -+ -+/** -+ * @file -+ * API-specific header for AV_HWDEVICE_TYPE_VAAPI. -+ * -+ * Dynamic frame pools are supported, but note that any pool used as a render -+ * target is required to be of fixed size in order to be be usable as an -+ * argument to vaCreateContext(). -+ * -+ * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs -+ * with the data pointer set to a VASurfaceID. -+ */ -+ -+enum { -+ /** -+ * The quirks field has been set by the user and should not be detected -+ * automatically by av_hwdevice_ctx_init(). -+ */ -+ AV_VAAPI_DRIVER_QUIRK_USER_SET = (1 << 0), -+ /** -+ * The driver does not destroy parameter buffers when they are used by -+ * vaRenderPicture(). Additional code will be required to destroy them -+ * separately afterwards. -+ */ -+ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1), -+ -+ /** -+ * The driver does not support the VASurfaceAttribMemoryType attribute, -+ * so the surface allocation code will not try to use it. -+ */ -+ AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), -+ -+ /** -+ * The driver does not support surface attributes at all. -+ * The surface allocation code will never pass them to surface allocation, -+ * and the results of the vaQuerySurfaceAttributes() call will be faked. -+ */ -+ AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES = (1 << 3), -+}; -+ -+/** -+ * VAAPI connection details. -+ * -+ * Allocated as AVHWDeviceContext.hwctx -+ */ -+typedef struct AVVAAPIDeviceContext { -+ /** -+ * The VADisplay handle, to be filled by the user. -+ */ -+ VADisplay display; -+ /** -+ * Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), -+ * with reference to a table of known drivers, unless the -+ * AV_VAAPI_DRIVER_QUIRK_USER_SET bit is already present. The user -+ * may need to refer to this field when performing any later -+ * operations using VAAPI with the same VADisplay. -+ */ -+ unsigned int driver_quirks; -+} AVVAAPIDeviceContext; -+ -+/** -+ * VAAPI-specific data associated with a frame pool. -+ * -+ * Allocated as AVHWFramesContext.hwctx. -+ */ -+typedef struct AVVAAPIFramesContext { -+ /** -+ * Set by the user to apply surface attributes to all surfaces in -+ * the frame pool. If null, default settings are used. -+ */ -+ VASurfaceAttrib* attributes; -+ int nb_attributes; -+ /** -+ * The surfaces IDs of all surfaces in the pool after creation. -+ * Only valid if AVHWFramesContext.initial_pool_size was positive. -+ * These are intended to be used as the render_targets arguments to -+ * vaCreateContext(). -+ */ -+ VASurfaceID* surface_ids; -+ int nb_surfaces; -+} AVVAAPIFramesContext; -+ -+/** -+ * VAAPI hardware pipeline configuration details. -+ * -+ * Allocated with av_hwdevice_hwconfig_alloc(). -+ */ -+typedef struct AVVAAPIHWConfig { -+ /** -+ * ID of a VAAPI pipeline configuration. -+ */ -+ VAConfigID config_id; -+} AVVAAPIHWConfig; -+ -+#endif /* AVUTIL_HWCONTEXT_VAAPI_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/intfloat.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/intfloat.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/intfloat.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/intfloat.h 2022-07-05 00:21:22.449315801 +0300 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (c) 2011 Mans Rullgard -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_INTFLOAT_H -+#define AVUTIL_INTFLOAT_H -+ -+#include -+#include "attributes.h" -+ -+union av_intfloat32 { -+ uint32_t i; -+ float f; -+}; -+ -+union av_intfloat64 { -+ uint64_t i; -+ double f; -+}; -+ -+/** -+ * Reinterpret a 32-bit integer as a float. -+ */ -+static av_always_inline float av_int2float(uint32_t i) { -+ union av_intfloat32 v; -+ v.i = i; -+ return v.f; -+} -+ -+/** -+ * Reinterpret a float as a 32-bit integer. -+ */ -+static av_always_inline uint32_t av_float2int(float f) { -+ union av_intfloat32 v; -+ v.f = f; -+ return v.i; -+} -+ -+/** -+ * Reinterpret a 64-bit integer as a double. -+ */ -+static av_always_inline double av_int2double(uint64_t i) { -+ union av_intfloat64 v; -+ v.i = i; -+ return v.f; -+} -+ -+/** -+ * Reinterpret a double as a 64-bit integer. -+ */ -+static av_always_inline uint64_t av_double2int(double f) { -+ union av_intfloat64 v; -+ v.f = f; -+ return v.i; -+} -+ -+#endif /* AVUTIL_INTFLOAT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/log.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/log.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/log.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/log.h 2022-07-05 00:21:22.450315795 +0300 -@@ -0,0 +1,388 @@ -+/* -+ * copyright (c) 2006 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_LOG_H -+#define AVUTIL_LOG_H -+ -+#include -+#include "avutil.h" -+#include "attributes.h" -+ -+typedef enum { -+ AV_CLASS_CATEGORY_NA = 0, -+ AV_CLASS_CATEGORY_INPUT, -+ AV_CLASS_CATEGORY_OUTPUT, -+ AV_CLASS_CATEGORY_MUXER, -+ AV_CLASS_CATEGORY_DEMUXER, -+ AV_CLASS_CATEGORY_ENCODER, -+ AV_CLASS_CATEGORY_DECODER, -+ AV_CLASS_CATEGORY_FILTER, -+ AV_CLASS_CATEGORY_BITSTREAM_FILTER, -+ AV_CLASS_CATEGORY_SWSCALER, -+ AV_CLASS_CATEGORY_SWRESAMPLER, -+ AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, -+ AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, -+ AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, -+ AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, -+ AV_CLASS_CATEGORY_DEVICE_OUTPUT, -+ AV_CLASS_CATEGORY_DEVICE_INPUT, -+ AV_CLASS_CATEGORY_NB ///< not part of ABI/API -+} AVClassCategory; -+ -+#define AV_IS_INPUT_DEVICE(category) \ -+ (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \ -+ ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \ -+ ((category) == AV_CLASS_CATEGORY_DEVICE_INPUT)) -+ -+#define AV_IS_OUTPUT_DEVICE(category) \ -+ (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT) || \ -+ ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT) || \ -+ ((category) == AV_CLASS_CATEGORY_DEVICE_OUTPUT)) -+ -+struct AVOptionRanges; -+ -+/** -+ * Describe the class of an AVClass context structure. That is an -+ * arbitrary struct of which the first field is a pointer to an -+ * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). -+ */ -+typedef struct AVClass { -+ /** -+ * The name of the class; usually it is the same name as the -+ * context structure type to which the AVClass is associated. -+ */ -+ const char* class_name; -+ -+ /** -+ * A pointer to a function which returns the name of a context -+ * instance ctx associated with the class. -+ */ -+ const char* (*item_name)(void* ctx); -+ -+ /** -+ * a pointer to the first option specified in the class if any or NULL -+ * -+ * @see av_set_default_options() -+ */ -+ const struct AVOption* option; -+ -+ /** -+ * LIBAVUTIL_VERSION with which this structure was created. -+ * This is used to allow fields to be added without requiring major -+ * version bumps everywhere. -+ */ -+ -+ int version; -+ -+ /** -+ * Offset in the structure where log_level_offset is stored. -+ * 0 means there is no such variable -+ */ -+ int log_level_offset_offset; -+ -+ /** -+ * Offset in the structure where a pointer to the parent context for -+ * logging is stored. For example a decoder could pass its AVCodecContext -+ * to eval as such a parent context, which an av_log() implementation -+ * could then leverage to display the parent context. -+ * The offset can be NULL. -+ */ -+ int parent_log_context_offset; -+ -+ /** -+ * Category used for visualization (like color) -+ * This is only set if the category is equal for all objects using this class. -+ * available since version (51 << 16 | 56 << 8 | 100) -+ */ -+ AVClassCategory category; -+ -+ /** -+ * Callback to return the category. -+ * available since version (51 << 16 | 59 << 8 | 100) -+ */ -+ AVClassCategory (*get_category)(void* ctx); -+ -+ /** -+ * Callback to return the supported/allowed ranges. -+ * available since version (52.12) -+ */ -+ int (*query_ranges)(struct AVOptionRanges**, void* obj, const char* key, -+ int flags); -+ -+ /** -+ * Return next AVOptions-enabled child or NULL -+ */ -+ void* (*child_next)(void* obj, void* prev); -+ -+ /** -+ * Iterate over the AVClasses corresponding to potential AVOptions-enabled -+ * children. -+ * -+ * @param iter pointer to opaque iteration state. The caller must initialize -+ * *iter to NULL before the first call. -+ * @return AVClass for the next AVOptions-enabled child or NULL if there are -+ * no more such children. -+ * -+ * @note The difference between child_next and this is that child_next -+ * iterates over _already existing_ objects, while child_class_iterate -+ * iterates over _all possible_ children. -+ */ -+ const struct AVClass* (*child_class_iterate)(void** iter); -+} AVClass; -+ -+/** -+ * @addtogroup lavu_log -+ * -+ * @{ -+ * -+ * @defgroup lavu_log_constants Logging Constants -+ * -+ * @{ -+ */ -+ -+/** -+ * Print no output. -+ */ -+#define AV_LOG_QUIET -8 -+ -+/** -+ * Something went really wrong and we will crash now. -+ */ -+#define AV_LOG_PANIC 0 -+ -+/** -+ * Something went wrong and recovery is not possible. -+ * For example, no header was found for a format which depends -+ * on headers or an illegal combination of parameters is used. -+ */ -+#define AV_LOG_FATAL 8 -+ -+/** -+ * Something went wrong and cannot losslessly be recovered. -+ * However, not all future data is affected. -+ */ -+#define AV_LOG_ERROR 16 -+ -+/** -+ * Something somehow does not look correct. This may or may not -+ * lead to problems. An example would be the use of '-vstrict -2'. -+ */ -+#define AV_LOG_WARNING 24 -+ -+/** -+ * Standard information. -+ */ -+#define AV_LOG_INFO 32 -+ -+/** -+ * Detailed information. -+ */ -+#define AV_LOG_VERBOSE 40 -+ -+/** -+ * Stuff which is only useful for libav* developers. -+ */ -+#define AV_LOG_DEBUG 48 -+ -+/** -+ * Extremely verbose debugging, useful for libav* development. -+ */ -+#define AV_LOG_TRACE 56 -+ -+#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) -+ -+/** -+ * @} -+ */ -+ -+/** -+ * Sets additional colors for extended debugging sessions. -+ * @code -+ av_log(ctx, AV_LOG_DEBUG|AV_LOG_C(134), "Message in purple\n"); -+ @endcode -+ * Requires 256color terminal support. Uses outside debugging is not -+ * recommended. -+ */ -+#define AV_LOG_C(x) ((x) << 8) -+ -+/** -+ * Send the specified message to the log if the level is less than or equal -+ * to the current av_log_level. By default, all logging messages are sent to -+ * stderr. This behavior can be altered by setting a different logging callback -+ * function. -+ * @see av_log_set_callback -+ * -+ * @param avcl A pointer to an arbitrary struct of which the first field is a -+ * pointer to an AVClass struct or NULL if general log. -+ * @param level The importance level of the message expressed using a @ref -+ * lavu_log_constants "Logging Constant". -+ * @param fmt The format string (printf-compatible) that specifies how -+ * subsequent arguments are converted to output. -+ */ -+void av_log(void* avcl, int level, const char* fmt, ...) av_printf_format(3, 4); -+ -+/** -+ * Send the specified message to the log once with the initial_level and then -+ * with the subsequent_level. By default, all logging messages are sent to -+ * stderr. This behavior can be altered by setting a different logging callback -+ * function. -+ * @see av_log -+ * -+ * @param avcl A pointer to an arbitrary struct of which the first field is a -+ * pointer to an AVClass struct or NULL if general log. -+ * @param initial_level importance level of the message expressed using a @ref -+ * lavu_log_constants "Logging Constant" for the first occurance. -+ * @param subsequent_level importance level of the message expressed using a -+ * @ref lavu_log_constants "Logging Constant" after the first occurance. -+ * @param fmt The format string (printf-compatible) that specifies how -+ * subsequent arguments are converted to output. -+ * @param state a variable to keep trak of if a message has already been printed -+ * this must be initialized to 0 before the first use. The same state -+ * must not be accessed by 2 Threads simultaneously. -+ */ -+void av_log_once(void* avcl, int initial_level, int subsequent_level, -+ int* state, const char* fmt, ...) av_printf_format(5, 6); -+ -+/** -+ * Send the specified message to the log if the level is less than or equal -+ * to the current av_log_level. By default, all logging messages are sent to -+ * stderr. This behavior can be altered by setting a different logging callback -+ * function. -+ * @see av_log_set_callback -+ * -+ * @param avcl A pointer to an arbitrary struct of which the first field is a -+ * pointer to an AVClass struct. -+ * @param level The importance level of the message expressed using a @ref -+ * lavu_log_constants "Logging Constant". -+ * @param fmt The format string (printf-compatible) that specifies how -+ * subsequent arguments are converted to output. -+ * @param vl The arguments referenced by the format string. -+ */ -+void av_vlog(void* avcl, int level, const char* fmt, va_list vl); -+ -+/** -+ * Get the current log level -+ * -+ * @see lavu_log_constants -+ * -+ * @return Current log level -+ */ -+int av_log_get_level(void); -+ -+/** -+ * Set the log level -+ * -+ * @see lavu_log_constants -+ * -+ * @param level Logging level -+ */ -+void av_log_set_level(int level); -+ -+/** -+ * Set the logging callback -+ * -+ * @note The callback must be thread safe, even if the application does not use -+ * threads itself as some codecs are multithreaded. -+ * -+ * @see av_log_default_callback -+ * -+ * @param callback A logging function with a compatible signature. -+ */ -+void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)); -+ -+/** -+ * Default logging callback -+ * -+ * It prints the message to stderr, optionally colorizing it. -+ * -+ * @param avcl A pointer to an arbitrary struct of which the first field is a -+ * pointer to an AVClass struct. -+ * @param level The importance level of the message expressed using a @ref -+ * lavu_log_constants "Logging Constant". -+ * @param fmt The format string (printf-compatible) that specifies how -+ * subsequent arguments are converted to output. -+ * @param vl The arguments referenced by the format string. -+ */ -+void av_log_default_callback(void* avcl, int level, const char* fmt, -+ va_list vl); -+ -+/** -+ * Return the context name -+ * -+ * @param ctx The AVClass context -+ * -+ * @return The AVClass class_name -+ */ -+const char* av_default_item_name(void* ctx); -+AVClassCategory av_default_get_category(void* ptr); -+ -+/** -+ * Format a line of log the same way as the default callback. -+ * @param line buffer to receive the formatted line -+ * @param line_size size of the buffer -+ * @param print_prefix used to store whether the prefix must be printed; -+ * must point to a persistent integer initially set to 1 -+ */ -+void av_log_format_line(void* ptr, int level, const char* fmt, va_list vl, -+ char* line, int line_size, int* print_prefix); -+ -+/** -+ * Format a line of log the same way as the default callback. -+ * @param line buffer to receive the formatted line; -+ * may be NULL if line_size is 0 -+ * @param line_size size of the buffer; at most line_size-1 characters will -+ * be written to the buffer, plus one null terminator -+ * @param print_prefix used to store whether the prefix must be printed; -+ * must point to a persistent integer initially set to 1 -+ * @return Returns a negative value if an error occurred, otherwise returns -+ * the number of characters that would have been written for a -+ * sufficiently large buffer, not including the terminating null -+ * character. If the return value is not less than line_size, it means -+ * that the log message was truncated to fit the buffer. -+ */ -+int av_log_format_line2(void* ptr, int level, const char* fmt, va_list vl, -+ char* line, int line_size, int* print_prefix); -+ -+/** -+ * Skip repeated messages, this requires the user app to use av_log() instead of -+ * (f)printf as the 2 would otherwise interfere and lead to -+ * "Last message repeated x times" messages below (f)printf messages with some -+ * bad luck. -+ * Also to receive the last, "last repeated" line if any, the user app must -+ * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end -+ */ -+#define AV_LOG_SKIP_REPEATED 1 -+ -+/** -+ * Include the log severity in messages originating from codecs. -+ * -+ * Results in messages such as: -+ * [rawvideo @ 0xDEADBEEF] [error] encode did not produce valid pts -+ */ -+#define AV_LOG_PRINT_LEVEL 2 -+ -+void av_log_set_flags(int arg); -+int av_log_get_flags(void); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_LOG_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/macros.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/macros.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/macros.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/macros.h 2022-07-05 00:21:22.450315795 +0300 -@@ -0,0 +1,87 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @ingroup lavu -+ * Utility Preprocessor macros -+ */ -+ -+#ifndef AVUTIL_MACROS_H -+#define AVUTIL_MACROS_H -+ -+#include "libavutil/avconfig.h" -+ -+#if AV_HAVE_BIGENDIAN -+# define AV_NE(be, le) (be) -+#else -+# define AV_NE(be, le) (le) -+#endif -+ -+/** -+ * Comparator. -+ * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 -+ * if x == y. This is useful for instance in a qsort comparator callback. -+ * Furthermore, compilers are able to optimize this to branchless code, and -+ * there is no risk of overflow with signed types. -+ * As with many macros, this evaluates its argument multiple times, it thus -+ * must not have a side-effect. -+ */ -+#define FFDIFFSIGN(x, y) (((x) > (y)) - ((x) < (y))) -+ -+#define FFMAX(a, b) ((a) > (b) ? (a) : (b)) -+#define FFMAX3(a, b, c) FFMAX(FFMAX(a, b), c) -+#define FFMIN(a, b) ((a) > (b) ? (b) : (a)) -+#define FFMIN3(a, b, c) FFMIN(FFMIN(a, b), c) -+ -+#define FFSWAP(type, a, b) \ -+ do { \ -+ type SWAP_tmp = b; \ -+ b = a; \ -+ a = SWAP_tmp; \ -+ } while (0) -+#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) -+ -+#define MKTAG(a, b, c, d) \ -+ ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) -+#define MKBETAG(a, b, c, d) \ -+ ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24)) -+ -+/** -+ * @addtogroup preproc_misc Preprocessor String Macros -+ * -+ * String manipulation macros -+ * -+ * @{ -+ */ -+ -+#define AV_STRINGIFY(s) AV_TOSTRING(s) -+#define AV_TOSTRING(s) #s -+ -+#define AV_GLUE(a, b) a##b -+#define AV_JOIN(a, b) AV_GLUE(a, b) -+ -+/** -+ * @} -+ */ -+ -+#define AV_PRAGMA(s) _Pragma(#s) -+ -+#define FFALIGN(x, a) (((x) + (a)-1) & ~((a)-1)) -+ -+#endif /* AVUTIL_MACROS_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mathematics.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mathematics.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mathematics.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mathematics.h 2022-07-05 00:21:22.450315795 +0300 -@@ -0,0 +1,247 @@ -+/* -+ * copyright (c) 2005-2012 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @addtogroup lavu_math -+ * Mathematical utilities for working with timestamp and time base. -+ */ -+ -+#ifndef AVUTIL_MATHEMATICS_H -+#define AVUTIL_MATHEMATICS_H -+ -+#include -+#include -+#include "attributes.h" -+#include "rational.h" -+#include "intfloat.h" -+ -+#ifndef M_E -+# define M_E 2.7182818284590452354 /* e */ -+#endif -+#ifndef M_LN2 -+# define M_LN2 0.69314718055994530942 /* log_e 2 */ -+#endif -+#ifndef M_LN10 -+# define M_LN10 2.30258509299404568402 /* log_e 10 */ -+#endif -+#ifndef M_LOG2_10 -+# define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ -+#endif -+#ifndef M_PHI -+# define M_PHI 1.61803398874989484820 /* phi / golden ratio */ -+#endif -+#ifndef M_PI -+# define M_PI 3.14159265358979323846 /* pi */ -+#endif -+#ifndef M_PI_2 -+# define M_PI_2 1.57079632679489661923 /* pi/2 */ -+#endif -+#ifndef M_SQRT1_2 -+# define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -+#endif -+#ifndef M_SQRT2 -+# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -+#endif -+#ifndef NAN -+# define NAN av_int2float(0x7fc00000) -+#endif -+#ifndef INFINITY -+# define INFINITY av_int2float(0x7f800000) -+#endif -+ -+/** -+ * @addtogroup lavu_math -+ * -+ * @{ -+ */ -+ -+/** -+ * Rounding methods. -+ */ -+enum AVRounding { -+ AV_ROUND_ZERO = 0, ///< Round toward zero. -+ AV_ROUND_INF = 1, ///< Round away from zero. -+ AV_ROUND_DOWN = 2, ///< Round toward -infinity. -+ AV_ROUND_UP = 3, ///< Round toward +infinity. -+ AV_ROUND_NEAR_INF = -+ 5, ///< Round to nearest and halfway cases away from zero. -+ /** -+ * Flag telling rescaling functions to pass `INT64_MIN`/`MAX` through -+ * unchanged, avoiding special cases for #AV_NOPTS_VALUE. -+ * -+ * Unlike other values of the enumeration AVRounding, this value is a -+ * bitmask that must be used in conjunction with another value of the -+ * enumeration through a bitwise OR, in order to set behavior for normal -+ * cases. -+ * -+ * @code{.c} -+ * av_rescale_rnd(3, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); -+ * // Rescaling 3: -+ * // Calculating 3 * 1 / 2 -+ * // 3 / 2 is rounded up to 2 -+ * // => 2 -+ * -+ * av_rescale_rnd(AV_NOPTS_VALUE, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); -+ * // Rescaling AV_NOPTS_VALUE: -+ * // AV_NOPTS_VALUE == INT64_MIN -+ * // AV_NOPTS_VALUE is passed through -+ * // => AV_NOPTS_VALUE -+ * @endcode -+ */ -+ AV_ROUND_PASS_MINMAX = 8192, -+}; -+ -+/** -+ * Compute the greatest common divisor of two integer operands. -+ * -+ * @param a,b Operands -+ * @return GCD of a and b up to sign; if a >= 0 and b >= 0, return value is >= -+ * 0; if a == 0 and b == 0, returns 0. -+ */ -+int64_t av_const av_gcd(int64_t a, int64_t b); -+ -+/** -+ * Rescale a 64-bit integer with rounding to nearest. -+ * -+ * The operation is mathematically equivalent to `a * b / c`, but writing that -+ * directly can overflow. -+ * -+ * This function is equivalent to av_rescale_rnd() with #AV_ROUND_NEAR_INF. -+ * -+ * @see av_rescale_rnd(), av_rescale_q(), av_rescale_q_rnd() -+ */ -+int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; -+ -+/** -+ * Rescale a 64-bit integer with specified rounding. -+ * -+ * The operation is mathematically equivalent to `a * b / c`, but writing that -+ * directly can overflow, and does not support different rounding methods. -+ * If the result is not representable then INT64_MIN is returned. -+ * -+ * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() -+ */ -+int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, -+ enum AVRounding rnd) av_const; -+ -+/** -+ * Rescale a 64-bit integer by 2 rational numbers. -+ * -+ * The operation is mathematically equivalent to `a * bq / cq`. -+ * -+ * This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF. -+ * -+ * @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd() -+ */ -+int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; -+ -+/** -+ * Rescale a 64-bit integer by 2 rational numbers with specified rounding. -+ * -+ * The operation is mathematically equivalent to `a * bq / cq`. -+ * -+ * @see av_rescale(), av_rescale_rnd(), av_rescale_q() -+ */ -+int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, -+ enum AVRounding rnd) av_const; -+ -+/** -+ * Compare two timestamps each in its own time base. -+ * -+ * @return One of the following values: -+ * - -1 if `ts_a` is before `ts_b` -+ * - 1 if `ts_a` is after `ts_b` -+ * - 0 if they represent the same position -+ * -+ * @warning -+ * The result of the function is undefined if one of the timestamps is outside -+ * the `int64_t` range when represented in the other's timebase. -+ */ -+int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); -+ -+/** -+ * Compare the remainders of two integer operands divided by a common divisor. -+ * -+ * In other words, compare the least significant `log2(mod)` bits of integers -+ * `a` and `b`. -+ * -+ * @code{.c} -+ * av_compare_mod(0x11, 0x02, 0x10) < 0 // since 0x11 % 0x10 (0x1) < 0x02 % -+ * 0x10 (0x2) av_compare_mod(0x11, 0x02, 0x20) > 0 // since 0x11 % 0x20 (0x11) -+ * > 0x02 % 0x20 (0x02) -+ * @endcode -+ * -+ * @param a,b Operands -+ * @param mod Divisor; must be a power of 2 -+ * @return -+ * - a negative value if `a % mod < b % mod` -+ * - a positive value if `a % mod > b % mod` -+ * - zero if `a % mod == b % mod` -+ */ -+int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod); -+ -+/** -+ * Rescale a timestamp while preserving known durations. -+ * -+ * This function is designed to be called per audio packet to scale the input -+ * timestamp to a different time base. Compared to a simple av_rescale_q() -+ * call, this function is robust against possible inconsistent frame durations. -+ * -+ * The `last` parameter is a state variable that must be preserved for all -+ * subsequent calls for the same stream. For the first call, `*last` should be -+ * initialized to #AV_NOPTS_VALUE. -+ * -+ * @param[in] in_tb Input time base -+ * @param[in] in_ts Input timestamp -+ * @param[in] fs_tb Duration time base; typically this is finer-grained -+ * (greater) than `in_tb` and `out_tb` -+ * @param[in] duration Duration till the next call to this function (i.e. -+ * duration of the current packet/frame) -+ * @param[in,out] last Pointer to a timestamp expressed in terms of -+ * `fs_tb`, acting as a state variable -+ * @param[in] out_tb Output timebase -+ * @return Timestamp expressed in terms of `out_tb` -+ * -+ * @note In the context of this function, "duration" is in term of samples, not -+ * seconds. -+ */ -+int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, -+ int duration, int64_t* last, AVRational out_tb); -+ -+/** -+ * Add a value to a timestamp. -+ * -+ * This function guarantees that when the same value is repeatly added that -+ * no accumulation of rounding errors occurs. -+ * -+ * @param[in] ts Input timestamp -+ * @param[in] ts_tb Input timestamp time base -+ * @param[in] inc Value to be added -+ * @param[in] inc_tb Time base of `inc` -+ */ -+int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, -+ int64_t inc); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_MATHEMATICS_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mem.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mem.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mem.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/mem.h 2022-07-05 00:21:22.451315789 +0300 -@@ -0,0 +1,708 @@ -+/* -+ * copyright (c) 2006 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @ingroup lavu_mem -+ * Memory handling functions -+ */ -+ -+#ifndef AVUTIL_MEM_H -+#define AVUTIL_MEM_H -+ -+#include -+#include -+ -+#include "attributes.h" -+#include "avutil.h" -+#include "version.h" -+ -+/** -+ * @addtogroup lavu_mem -+ * Utilities for manipulating memory. -+ * -+ * FFmpeg has several applications of memory that are not required of a typical -+ * program. For example, the computing-heavy components like video decoding and -+ * encoding can be sped up significantly through the use of aligned memory. -+ * -+ * However, for each of FFmpeg's applications of memory, there might not be a -+ * recognized or standardized API for that specific use. Memory alignment, for -+ * instance, varies wildly depending on operating systems, architectures, and -+ * compilers. Hence, this component of @ref libavutil is created to make -+ * dealing with memory consistently possible on all platforms. -+ * -+ * @{ -+ */ -+ -+#if FF_API_DECLARE_ALIGNED -+/** -+ * -+ * @defgroup lavu_mem_macros Alignment Macros -+ * Helper macros for declaring aligned variables. -+ * @{ -+ */ -+ -+/** -+ * @def DECLARE_ALIGNED(n,t,v) -+ * Declare a variable that is aligned in memory. -+ * -+ * @code{.c} -+ * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; -+ * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; -+ * -+ * // The default-alignment equivalent would be -+ * uint16_t aligned_int = 42; -+ * uint8_t aligned_array[128]; -+ * @endcode -+ * -+ * @param n Minimum alignment in bytes -+ * @param t Type of the variable (or array element) -+ * @param v Name of the variable -+ */ -+ -+/** -+ * @def DECLARE_ASM_ALIGNED(n,t,v) -+ * Declare an aligned variable appropriate for use in inline assembly code. -+ * -+ * @code{.c} -+ * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); -+ * @endcode -+ * -+ * @param n Minimum alignment in bytes -+ * @param t Type of the variable (or array element) -+ * @param v Name of the variable -+ */ -+ -+/** -+ * @def DECLARE_ASM_CONST(n,t,v) -+ * Declare a static constant aligned variable appropriate for use in inline -+ * assembly code. -+ * -+ * @code{.c} -+ * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); -+ * @endcode -+ * -+ * @param n Minimum alignment in bytes -+ * @param t Type of the variable (or array element) -+ * @param v Name of the variable -+ */ -+ -+# if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || \ -+ defined(__SUNPRO_C) -+# define DECLARE_ALIGNED(n, t, v) t __attribute__((aligned(n))) v -+# define DECLARE_ASM_ALIGNED(n, t, v) t __attribute__((aligned(n))) v -+# define DECLARE_ASM_CONST(n, t, v) const t __attribute__((aligned(n))) v -+# elif defined(__DJGPP__) -+# define DECLARE_ALIGNED(n, t, v) t __attribute__((aligned(FFMIN(n, 16)))) v -+# define DECLARE_ASM_ALIGNED(n, t, v) \ -+ t av_used __attribute__((aligned(FFMIN(n, 16)))) v -+# define DECLARE_ASM_CONST(n, t, v) \ -+ static const t av_used __attribute__((aligned(FFMIN(n, 16)))) v -+# elif defined(__GNUC__) || defined(__clang__) -+# define DECLARE_ALIGNED(n, t, v) t __attribute__((aligned(n))) v -+# define DECLARE_ASM_ALIGNED(n, t, v) t av_used __attribute__((aligned(n))) v -+# define DECLARE_ASM_CONST(n, t, v) \ -+ static const t av_used __attribute__((aligned(n))) v -+# elif defined(_MSC_VER) -+# define DECLARE_ALIGNED(n, t, v) __declspec(align(n)) t v -+# define DECLARE_ASM_ALIGNED(n, t, v) __declspec(align(n)) t v -+# define DECLARE_ASM_CONST(n, t, v) __declspec(align(n)) static const t v -+# else -+# define DECLARE_ALIGNED(n, t, v) t v -+# define DECLARE_ASM_ALIGNED(n, t, v) t v -+# define DECLARE_ASM_CONST(n, t, v) static const t v -+# endif -+ -+/** -+ * @} -+ */ -+#endif -+ -+/** -+ * @defgroup lavu_mem_attrs Function Attributes -+ * Function attributes applicable to memory handling functions. -+ * -+ * These function attributes can help compilers emit more useful warnings, or -+ * generate better code. -+ * @{ -+ */ -+ -+/** -+ * @def av_malloc_attrib -+ * Function attribute denoting a malloc-like function. -+ * -+ * @see Function -+ * attribute `malloc` in GCC's documentation -+ */ -+ -+#if AV_GCC_VERSION_AT_LEAST(3, 1) -+# define av_malloc_attrib __attribute__((__malloc__)) -+#else -+# define av_malloc_attrib -+#endif -+ -+/** -+ * @def av_alloc_size(...) -+ * Function attribute used on a function that allocates memory, whose size is -+ * given by the specified parameter(s). -+ * -+ * @code{.c} -+ * void *av_malloc(size_t size) av_alloc_size(1); -+ * void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2); -+ * @endcode -+ * -+ * @param ... One or two parameter indexes, separated by a comma -+ * -+ * @see Function -+ * attribute `alloc_size` in GCC's documentation -+ */ -+ -+#if AV_GCC_VERSION_AT_LEAST(4, 3) -+# define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) -+#else -+# define av_alloc_size(...) -+#endif -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @defgroup lavu_mem_funcs Heap Management -+ * Functions responsible for allocating, freeing, and copying memory. -+ * -+ * All memory allocation functions have a built-in upper limit of `INT_MAX` -+ * bytes. This may be changed with av_max_alloc(), although exercise extreme -+ * caution when doing so. -+ * -+ * @{ -+ */ -+ -+/** -+ * Allocate a memory block with alignment suitable for all memory accesses -+ * (including vectors if available on the CPU). -+ * -+ * @param size Size in bytes for the memory block to be allocated -+ * @return Pointer to the allocated block, or `NULL` if the block cannot -+ * be allocated -+ * @see av_mallocz() -+ */ -+void* av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); -+ -+/** -+ * Allocate a memory block with alignment suitable for all memory accesses -+ * (including vectors if available on the CPU) and zero all the bytes of the -+ * block. -+ * -+ * @param size Size in bytes for the memory block to be allocated -+ * @return Pointer to the allocated block, or `NULL` if it cannot be allocated -+ * @see av_malloc() -+ */ -+void* av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); -+ -+/** -+ * Allocate a memory block for an array with av_malloc(). -+ * -+ * The allocated memory will have size `size * nmemb` bytes. -+ * -+ * @param nmemb Number of element -+ * @param size Size of a single element -+ * @return Pointer to the allocated block, or `NULL` if the block cannot -+ * be allocated -+ * @see av_malloc() -+ */ -+av_alloc_size(1, 2) void* av_malloc_array(size_t nmemb, size_t size); -+ -+/** -+ * Allocate a memory block for an array with av_mallocz(). -+ * -+ * The allocated memory will have size `size * nmemb` bytes. -+ * -+ * @param nmemb Number of elements -+ * @param size Size of the single element -+ * @return Pointer to the allocated block, or `NULL` if the block cannot -+ * be allocated -+ * -+ * @see av_mallocz() -+ * @see av_malloc_array() -+ */ -+void* av_calloc(size_t nmemb, size_t size) av_malloc_attrib av_alloc_size(1, 2); -+ -+#if FF_API_AV_MALLOCZ_ARRAY -+/** -+ * @deprecated use av_calloc() -+ */ -+attribute_deprecated void* av_mallocz_array(size_t nmemb, -+ size_t size) av_malloc_attrib -+ av_alloc_size(1, 2); -+#endif -+ -+/** -+ * Allocate, reallocate, or free a block of memory. -+ * -+ * If `ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is -+ * zero, free the memory block pointed to by `ptr`. Otherwise, expand or -+ * shrink that block of memory according to `size`. -+ * -+ * @param ptr Pointer to a memory block already allocated with -+ * av_realloc() or `NULL` -+ * @param size Size in bytes of the memory block to be allocated or -+ * reallocated -+ * -+ * @return Pointer to a newly-reallocated block or `NULL` if the block -+ * cannot be reallocated or the function is used to free the memory -+ * block -+ * -+ * @warning Unlike av_malloc(), the returned pointer is not guaranteed to be -+ * correctly aligned. -+ * @see av_fast_realloc() -+ * @see av_reallocp() -+ */ -+void* av_realloc(void* ptr, size_t size) av_alloc_size(2); -+ -+/** -+ * Allocate, reallocate, or free a block of memory through a pointer to a -+ * pointer. -+ * -+ * If `*ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is -+ * zero, free the memory block pointed to by `*ptr`. Otherwise, expand or -+ * shrink that block of memory according to `size`. -+ * -+ * @param[in,out] ptr Pointer to a pointer to a memory block already allocated -+ * with av_realloc(), or a pointer to `NULL`. The pointer -+ * is updated on success, or freed on failure. -+ * @param[in] size Size in bytes for the memory block to be allocated or -+ * reallocated -+ * -+ * @return Zero on success, an AVERROR error code on failure -+ * -+ * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be -+ * correctly aligned. -+ */ -+av_warn_unused_result int av_reallocp(void* ptr, size_t size); -+ -+/** -+ * Allocate, reallocate, or free a block of memory. -+ * -+ * This function does the same thing as av_realloc(), except: -+ * - It takes two size arguments and allocates `nelem * elsize` bytes, -+ * after checking the result of the multiplication for integer overflow. -+ * - It frees the input block in case of failure, thus avoiding the memory -+ * leak with the classic -+ * @code{.c} -+ * buf = realloc(buf); -+ * if (!buf) -+ * return -1; -+ * @endcode -+ * pattern. -+ */ -+void* av_realloc_f(void* ptr, size_t nelem, size_t elsize); -+ -+/** -+ * Allocate, reallocate, or free an array. -+ * -+ * If `ptr` is `NULL` and `nmemb` > 0, allocate a new block. If -+ * `nmemb` is zero, free the memory block pointed to by `ptr`. -+ * -+ * @param ptr Pointer to a memory block already allocated with -+ * av_realloc() or `NULL` -+ * @param nmemb Number of elements in the array -+ * @param size Size of the single element of the array -+ * -+ * @return Pointer to a newly-reallocated block or NULL if the block -+ * cannot be reallocated or the function is used to free the memory -+ * block -+ * -+ * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be -+ * correctly aligned. -+ * @see av_reallocp_array() -+ */ -+av_alloc_size(2, 3) void* av_realloc_array(void* ptr, size_t nmemb, -+ size_t size); -+ -+/** -+ * Allocate, reallocate, or free an array through a pointer to a pointer. -+ * -+ * If `*ptr` is `NULL` and `nmemb` > 0, allocate a new block. If `nmemb` is -+ * zero, free the memory block pointed to by `*ptr`. -+ * -+ * @param[in,out] ptr Pointer to a pointer to a memory block already -+ * allocated with av_realloc(), or a pointer to `NULL`. -+ * The pointer is updated on success, or freed on failure. -+ * @param[in] nmemb Number of elements -+ * @param[in] size Size of the single element -+ * -+ * @return Zero on success, an AVERROR error code on failure -+ * -+ * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be -+ * correctly aligned. -+ */ -+int av_reallocp_array(void* ptr, size_t nmemb, size_t size); -+ -+/** -+ * Reallocate the given buffer if it is not large enough, otherwise do nothing. -+ * -+ * If the given buffer is `NULL`, then a new uninitialized buffer is allocated. -+ * -+ * If the given buffer is not large enough, and reallocation fails, `NULL` is -+ * returned and `*size` is set to 0, but the original buffer is not changed or -+ * freed. -+ * -+ * A typical use pattern follows: -+ * -+ * @code{.c} -+ * uint8_t *buf = ...; -+ * uint8_t *new_buf = av_fast_realloc(buf, ¤t_size, size_needed); -+ * if (!new_buf) { -+ * // Allocation failed; clean up original buffer -+ * av_freep(&buf); -+ * return AVERROR(ENOMEM); -+ * } -+ * @endcode -+ * -+ * @param[in,out] ptr Already allocated buffer, or `NULL` -+ * @param[in,out] size Pointer to the size of buffer `ptr`. `*size` is -+ * updated to the new allocated size, in particular 0 -+ * in case of failure. -+ * @param[in] min_size Desired minimal size of buffer `ptr` -+ * @return `ptr` if the buffer is large enough, a pointer to newly reallocated -+ * buffer if the buffer was not large enough, or `NULL` in case of -+ * error -+ * @see av_realloc() -+ * @see av_fast_malloc() -+ */ -+void* av_fast_realloc(void* ptr, unsigned int* size, size_t min_size); -+ -+/** -+ * Allocate a buffer, reusing the given one if large enough. -+ * -+ * Contrary to av_fast_realloc(), the current buffer contents might not be -+ * preserved and on error the old buffer is freed, thus no special handling to -+ * avoid memleaks is necessary. -+ * -+ * `*ptr` is allowed to be `NULL`, in which case allocation always happens if -+ * `size_needed` is greater than 0. -+ * -+ * @code{.c} -+ * uint8_t *buf = ...; -+ * av_fast_malloc(&buf, ¤t_size, size_needed); -+ * if (!buf) { -+ * // Allocation failed; buf already freed -+ * return AVERROR(ENOMEM); -+ * } -+ * @endcode -+ * -+ * @param[in,out] ptr Pointer to pointer to an already allocated buffer. -+ * `*ptr` will be overwritten with pointer to new -+ * buffer on success or `NULL` on failure -+ * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is -+ * updated to the new allocated size, in particular 0 -+ * in case of failure. -+ * @param[in] min_size Desired minimal size of buffer `*ptr` -+ * @see av_realloc() -+ * @see av_fast_mallocz() -+ */ -+void av_fast_malloc(void* ptr, unsigned int* size, size_t min_size); -+ -+/** -+ * Allocate and clear a buffer, reusing the given one if large enough. -+ * -+ * Like av_fast_malloc(), but all newly allocated space is initially cleared. -+ * Reused buffer is not cleared. -+ * -+ * `*ptr` is allowed to be `NULL`, in which case allocation always happens if -+ * `size_needed` is greater than 0. -+ * -+ * @param[in,out] ptr Pointer to pointer to an already allocated buffer. -+ * `*ptr` will be overwritten with pointer to new -+ * buffer on success or `NULL` on failure -+ * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is -+ * updated to the new allocated size, in particular 0 -+ * in case of failure. -+ * @param[in] min_size Desired minimal size of buffer `*ptr` -+ * @see av_fast_malloc() -+ */ -+void av_fast_mallocz(void* ptr, unsigned int* size, size_t min_size); -+ -+/** -+ * Free a memory block which has been allocated with a function of av_malloc() -+ * or av_realloc() family. -+ * -+ * @param ptr Pointer to the memory block which should be freed. -+ * -+ * @note `ptr = NULL` is explicitly allowed. -+ * @note It is recommended that you use av_freep() instead, to prevent leaving -+ * behind dangling pointers. -+ * @see av_freep() -+ */ -+void av_free(void* ptr); -+ -+/** -+ * Free a memory block which has been allocated with a function of av_malloc() -+ * or av_realloc() family, and set the pointer pointing to it to `NULL`. -+ * -+ * @code{.c} -+ * uint8_t *buf = av_malloc(16); -+ * av_free(buf); -+ * // buf now contains a dangling pointer to freed memory, and accidental -+ * // dereference of buf will result in a use-after-free, which may be a -+ * // security risk. -+ * -+ * uint8_t *buf = av_malloc(16); -+ * av_freep(&buf); -+ * // buf is now NULL, and accidental dereference will only result in a -+ * // NULL-pointer dereference. -+ * @endcode -+ * -+ * @param ptr Pointer to the pointer to the memory block which should be freed -+ * @note `*ptr = NULL` is safe and leads to no action. -+ * @see av_free() -+ */ -+void av_freep(void* ptr); -+ -+/** -+ * Duplicate a string. -+ * -+ * @param s String to be duplicated -+ * @return Pointer to a newly-allocated string containing a -+ * copy of `s` or `NULL` if the string cannot be allocated -+ * @see av_strndup() -+ */ -+char* av_strdup(const char* s) av_malloc_attrib; -+ -+/** -+ * Duplicate a substring of a string. -+ * -+ * @param s String to be duplicated -+ * @param len Maximum length of the resulting string (not counting the -+ * terminating byte) -+ * @return Pointer to a newly-allocated string containing a -+ * substring of `s` or `NULL` if the string cannot be allocated -+ */ -+char* av_strndup(const char* s, size_t len) av_malloc_attrib; -+ -+/** -+ * Duplicate a buffer with av_malloc(). -+ * -+ * @param p Buffer to be duplicated -+ * @param size Size in bytes of the buffer copied -+ * @return Pointer to a newly allocated buffer containing a -+ * copy of `p` or `NULL` if the buffer cannot be allocated -+ */ -+void* av_memdup(const void* p, size_t size); -+ -+/** -+ * Overlapping memcpy() implementation. -+ * -+ * @param dst Destination buffer -+ * @param back Number of bytes back to start copying (i.e. the initial size of -+ * the overlapping window); must be > 0 -+ * @param cnt Number of bytes to copy; must be >= 0 -+ * -+ * @note `cnt > back` is valid, this will copy the bytes we just copied, -+ * thus creating a repeating pattern with a period length of `back`. -+ */ -+void av_memcpy_backptr(uint8_t* dst, int back, int cnt); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @defgroup lavu_mem_dynarray Dynamic Array -+ * -+ * Utilities to make an array grow when needed. -+ * -+ * Sometimes, the programmer would want to have an array that can grow when -+ * needed. The libavutil dynamic array utilities fill that need. -+ * -+ * libavutil supports two systems of appending elements onto a dynamically -+ * allocated array, the first one storing the pointer to the value in the -+ * array, and the second storing the value directly. In both systems, the -+ * caller is responsible for maintaining a variable containing the length of -+ * the array, as well as freeing of the array after use. -+ * -+ * The first system stores pointers to values in a block of dynamically -+ * allocated memory. Since only pointers are stored, the function does not need -+ * to know the size of the type. Both av_dynarray_add() and -+ * av_dynarray_add_nofree() implement this system. -+ * -+ * @code -+ * type **array = NULL; //< an array of pointers to values -+ * int nb = 0; //< a variable to keep track of the length of the array -+ * -+ * type to_be_added = ...; -+ * type to_be_added2 = ...; -+ * -+ * av_dynarray_add(&array, &nb, &to_be_added); -+ * if (nb == 0) -+ * return AVERROR(ENOMEM); -+ * -+ * av_dynarray_add(&array, &nb, &to_be_added2); -+ * if (nb == 0) -+ * return AVERROR(ENOMEM); -+ * -+ * // Now: -+ * // nb == 2 -+ * // &to_be_added == array[0] -+ * // &to_be_added2 == array[1] -+ * -+ * av_freep(&array); -+ * @endcode -+ * -+ * The second system stores the value directly in a block of memory. As a -+ * result, the function has to know the size of the type. av_dynarray2_add() -+ * implements this mechanism. -+ * -+ * @code -+ * type *array = NULL; //< an array of values -+ * int nb = 0; //< a variable to keep track of the length of the array -+ * -+ * type to_be_added = ...; -+ * type to_be_added2 = ...; -+ * -+ * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), NULL); -+ * if (!addr) -+ * return AVERROR(ENOMEM); -+ * memcpy(addr, &to_be_added, sizeof(to_be_added)); -+ * -+ * // Shortcut of the above. -+ * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), -+ * (const void *)&to_be_added2); -+ * if (!addr) -+ * return AVERROR(ENOMEM); -+ * -+ * // Now: -+ * // nb == 2 -+ * // to_be_added == array[0] -+ * // to_be_added2 == array[1] -+ * -+ * av_freep(&array); -+ * @endcode -+ * -+ * @{ -+ */ -+ -+/** -+ * Add the pointer to an element to a dynamic array. -+ * -+ * The array to grow is supposed to be an array of pointers to -+ * structures, and the element to add must be a pointer to an already -+ * allocated structure. -+ * -+ * The array is reallocated when its size reaches powers of 2. -+ * Therefore, the amortized cost of adding an element is constant. -+ * -+ * In case of success, the pointer to the array is updated in order to -+ * point to the new grown array, and the number pointed to by `nb_ptr` -+ * is incremented. -+ * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and -+ * `*nb_ptr` is set to 0. -+ * -+ * @param[in,out] tab_ptr Pointer to the array to grow -+ * @param[in,out] nb_ptr Pointer to the number of elements in the array -+ * @param[in] elem Element to add -+ * @see av_dynarray_add_nofree(), av_dynarray2_add() -+ */ -+void av_dynarray_add(void* tab_ptr, int* nb_ptr, void* elem); -+ -+/** -+ * Add an element to a dynamic array. -+ * -+ * Function has the same functionality as av_dynarray_add(), -+ * but it doesn't free memory on fails. It returns error code -+ * instead and leave current buffer untouched. -+ * -+ * @return >=0 on success, negative otherwise -+ * @see av_dynarray_add(), av_dynarray2_add() -+ */ -+av_warn_unused_result int av_dynarray_add_nofree(void* tab_ptr, int* nb_ptr, -+ void* elem); -+ -+/** -+ * Add an element of size `elem_size` to a dynamic array. -+ * -+ * The array is reallocated when its number of elements reaches powers of 2. -+ * Therefore, the amortized cost of adding an element is constant. -+ * -+ * In case of success, the pointer to the array is updated in order to -+ * point to the new grown array, and the number pointed to by `nb_ptr` -+ * is incremented. -+ * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and -+ * `*nb_ptr` is set to 0. -+ * -+ * @param[in,out] tab_ptr Pointer to the array to grow -+ * @param[in,out] nb_ptr Pointer to the number of elements in the array -+ * @param[in] elem_size Size in bytes of an element in the array -+ * @param[in] elem_data Pointer to the data of the element to add. If -+ * `NULL`, the space of the newly added element is -+ * allocated but left uninitialized. -+ * -+ * @return Pointer to the data of the element to copy in the newly allocated -+ * space -+ * @see av_dynarray_add(), av_dynarray_add_nofree() -+ */ -+void* av_dynarray2_add(void** tab_ptr, int* nb_ptr, size_t elem_size, -+ const uint8_t* elem_data); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @defgroup lavu_mem_misc Miscellaneous Functions -+ * -+ * Other functions related to memory allocation. -+ * -+ * @{ -+ */ -+ -+/** -+ * Multiply two `size_t` values checking for overflow. -+ * -+ * @param[in] a,b Operands of multiplication -+ * @param[out] r Pointer to the result of the operation -+ * @return 0 on success, AVERROR(EINVAL) on overflow -+ */ -+int av_size_mult(size_t a, size_t b, size_t* r); -+ -+/** -+ * Set the maximum size that may be allocated in one block. -+ * -+ * The value specified with this function is effective for all libavutil's @ref -+ * lavu_mem_funcs "heap management functions." -+ * -+ * By default, the max value is defined as `INT_MAX`. -+ * -+ * @param max Value to be set as the new maximum size -+ * -+ * @warning Exercise extreme caution when using this function. Don't touch -+ * this if you do not understand the full consequence of doing so. -+ */ -+void av_max_alloc(size_t max); -+ -+/** -+ * @} -+ * @} -+ */ -+ -+#endif /* AVUTIL_MEM_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/pixfmt.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/pixfmt.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/pixfmt.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/pixfmt.h 2022-07-05 00:21:22.452315783 +0300 -@@ -0,0 +1,808 @@ -+/* -+ * copyright (c) 2006 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_PIXFMT_H -+#define AVUTIL_PIXFMT_H -+ -+/** -+ * @file -+ * pixel format definitions -+ */ -+ -+#include "libavutil/avconfig.h" -+#include "version.h" -+ -+#define AVPALETTE_SIZE 1024 -+#define AVPALETTE_COUNT 256 -+ -+/** -+ * Pixel format. -+ * -+ * @note -+ * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA -+ * color is put together as: -+ * (A << 24) | (R << 16) | (G << 8) | B -+ * This is stored as BGRA on little-endian CPU architectures and ARGB on -+ * big-endian CPUs. -+ * -+ * @note -+ * If the resolution is not a multiple of the chroma subsampling factor -+ * then the chroma plane resolution must be rounded up. -+ * -+ * @par -+ * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized -+ * image data is stored in AVFrame.data[0]. The palette is transported in -+ * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is -+ * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is -+ * also endian-specific). Note also that the individual RGB32 palette -+ * components stored in AVFrame.data[1] should be in the range 0..255. -+ * This is important as many custom PAL8 video codecs that were designed -+ * to run on the IBM VGA graphics adapter use 6-bit palette components. -+ * -+ * @par -+ * For all the 8 bits per pixel formats, an RGB32 palette is in data[1] like -+ * for pal8. This palette is filled in automatically by the function -+ * allocating the picture. -+ */ -+enum AVPixelFormat { -+ AV_PIX_FMT_NONE = -1, -+ AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y -+ ///< samples) -+ AV_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr -+ AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... -+ AV_PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... -+ AV_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y -+ ///< samples) -+ AV_PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y -+ ///< samples) -+ AV_PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y -+ ///< samples) -+ AV_PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y -+ ///< samples) -+ AV_PIX_FMT_GRAY8, ///< Y , 8bpp -+ AV_PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, -+ ///< in each byte pixels are ordered from the -+ ///< msb to the lsb -+ AV_PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, -+ ///< in each byte pixels are ordered from the -+ ///< msb to the lsb -+ AV_PIX_FMT_PAL8, ///< 8 bits with AV_PIX_FMT_RGB32 palette -+ AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), -+ ///< deprecated in favor of AV_PIX_FMT_YUV420P and -+ ///< setting color_range -+ AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), -+ ///< deprecated in favor of AV_PIX_FMT_YUV422P and -+ ///< setting color_range -+ AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), -+ ///< deprecated in favor of AV_PIX_FMT_YUV444P and -+ ///< setting color_range -+ AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 -+ AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 -+ AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) -+ AV_PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), -+ ///< a byte contains two pixels, the first pixel in the byte -+ ///< is the one composed by the 4 msb bits -+ AV_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) -+ AV_PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) -+ AV_PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), -+ ///< a byte contains two pixels, the first pixel in the byte -+ ///< is the one composed by the 4 msb bits -+ AV_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) -+ AV_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for -+ ///< the UV components, which are interleaved (first byte U -+ ///< and the following byte V) -+ AV_PIX_FMT_NV21, ///< as above, but U and V bytes are swapped -+ -+ AV_PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... -+ AV_PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... -+ AV_PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... -+ AV_PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... -+ -+ AV_PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian -+ AV_PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian -+ AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y -+ ///< samples) -+ AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in -+ ///< favor of AV_PIX_FMT_YUV440P and setting color_range -+ AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 -+ ///< Y & A samples) -+ AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the -+ ///< 2-byte value for each R/G/B component is stored as -+ ///< big-endian -+ AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the -+ ///< 2-byte value for each R/G/B component is stored as -+ ///< little-endian -+ -+ AV_PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), -+ ///< big-endian -+ AV_PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), -+ ///< little-endian -+ AV_PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), -+ ///< big-endian , X=unused/undefined -+ AV_PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), -+ ///< little-endian, X=unused/undefined -+ -+ AV_PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), -+ ///< big-endian -+ AV_PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), -+ ///< little-endian -+ AV_PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), -+ ///< big-endian , X=unused/undefined -+ AV_PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), -+ ///< little-endian, X=unused/undefined -+ -+ /** -+ * Hardware acceleration through VA-API, data[3] contains a -+ * VASurfaceID. -+ */ -+ AV_PIX_FMT_VAAPI, -+ -+ AV_PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), little-endian -+ AV_PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), big-endian -+ AV_PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), little-endian -+ AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), big-endian -+ AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), little-endian -+ AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), big-endian -+ AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] -+ ///< contains a LPDIRECT3DSURFACE9 pointer -+ -+ AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), -+ ///< little-endian, X=unused/undefined -+ AV_PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), -+ ///< big-endian, X=unused/undefined -+ AV_PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), -+ ///< little-endian, X=unused/undefined -+ AV_PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), -+ ///< big-endian, X=unused/undefined -+ AV_PIX_FMT_YA8, ///< 8 bits gray, 8 bits alpha -+ -+ AV_PIX_FMT_Y400A = AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 -+ AV_PIX_FMT_GRAY8A = AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 -+ -+ AV_PIX_FMT_BGR48BE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the -+ ///< 2-byte value for each R/G/B component is stored as -+ ///< big-endian -+ AV_PIX_FMT_BGR48LE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the -+ ///< 2-byte value for each R/G/B component is stored as -+ ///< little-endian -+ -+ /** -+ * The following 12 formats have the disadvantage of needing 1 format for each -+ * bit depth. Notice that each 9/10 bits sample is stored in 16 bits with -+ * extra padding. If you want to support multiple bit depths, then using -+ * AV_PIX_FMT_YUV420P16* with the bpp stored separately is better. -+ */ -+ AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), big-endian -+ AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), little-endian -+ AV_PIX_FMT_YUV420P10BE, ///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), big-endian -+ AV_PIX_FMT_YUV420P10LE, ///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), little-endian -+ AV_PIX_FMT_YUV422P10BE, ///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), big-endian -+ AV_PIX_FMT_YUV422P10LE, ///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), little-endian -+ AV_PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), big-endian -+ AV_PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), little-endian -+ AV_PIX_FMT_YUV444P10BE, ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), big-endian -+ AV_PIX_FMT_YUV444P10LE, ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), little-endian -+ AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), big-endian -+ AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), little-endian -+ AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp -+ AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP -+ AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian -+ AV_PIX_FMT_GBRP9LE, ///< planar GBR 4:4:4 27bpp, little-endian -+ AV_PIX_FMT_GBRP10BE, ///< planar GBR 4:4:4 30bpp, big-endian -+ AV_PIX_FMT_GBRP10LE, ///< planar GBR 4:4:4 30bpp, little-endian -+ AV_PIX_FMT_GBRP16BE, ///< planar GBR 4:4:4 48bpp, big-endian -+ AV_PIX_FMT_GBRP16LE, ///< planar GBR 4:4:4 48bpp, little-endian -+ AV_PIX_FMT_YUVA422P, ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y -+ ///< & A samples) -+ AV_PIX_FMT_YUVA444P, ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y -+ ///< & A samples) -+ AV_PIX_FMT_YUVA420P9BE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y & A samples), big-endian -+ AV_PIX_FMT_YUVA420P9LE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y & A samples), little-endian -+ AV_PIX_FMT_YUVA422P9BE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y & A samples), big-endian -+ AV_PIX_FMT_YUVA422P9LE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y & A samples), little-endian -+ AV_PIX_FMT_YUVA444P9BE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y & A samples), big-endian -+ AV_PIX_FMT_YUVA444P9LE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y & A samples), little-endian -+ AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y & A samples, big-endian) -+ AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y & A samples, little-endian) -+ AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y & A samples, big-endian) -+ AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y & A samples, little-endian) -+ AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y & A samples, big-endian) -+ AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y & A samples, little-endian) -+ AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y & A samples, big-endian) -+ AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y & A samples, little-endian) -+ AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y & A samples, big-endian) -+ AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y & A samples, little-endian) -+ AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y & A samples, big-endian) -+ AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y & A samples, little-endian) -+ -+ AV_PIX_FMT_VDPAU, ///< HW acceleration through VDPAU, Picture.data[3] -+ ///< contains a VdpVideoSurface -+ -+ AV_PIX_FMT_XYZ12LE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), -+ ///< the 2-byte value for each X/Y/Z is stored as -+ ///< little-endian, the 4 lower bits are set to 0 -+ AV_PIX_FMT_XYZ12BE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), -+ ///< the 2-byte value for each X/Y/Z is stored as -+ ///< big-endian, the 4 lower bits are set to 0 -+ AV_PIX_FMT_NV16, ///< interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample -+ ///< per 2x1 Y samples) -+ AV_PIX_FMT_NV20LE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb -+ ///< sample per 2x1 Y samples), little-endian -+ AV_PIX_FMT_NV20BE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb -+ ///< sample per 2x1 Y samples), big-endian -+ -+ AV_PIX_FMT_RGBA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, -+ ///< the 2-byte value for each R/G/B/A component is -+ ///< stored as big-endian -+ AV_PIX_FMT_RGBA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, -+ ///< the 2-byte value for each R/G/B/A component is -+ ///< stored as little-endian -+ AV_PIX_FMT_BGRA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, -+ ///< the 2-byte value for each R/G/B/A component is -+ ///< stored as big-endian -+ AV_PIX_FMT_BGRA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, -+ ///< the 2-byte value for each R/G/B/A component is -+ ///< stored as little-endian -+ -+ AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb -+ -+ AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) -+ AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) -+ -+ AV_PIX_FMT_GBRAP, ///< planar GBRA 4:4:4:4 32bpp -+ AV_PIX_FMT_GBRAP16BE, ///< planar GBRA 4:4:4:4 64bpp, big-endian -+ AV_PIX_FMT_GBRAP16LE, ///< planar GBRA 4:4:4:4 64bpp, little-endian -+ /** -+ * HW acceleration through QSV, data[3] contains a pointer to the -+ * mfxFrameSurface1 structure. -+ */ -+ AV_PIX_FMT_QSV, -+ /** -+ * HW acceleration though MMAL, data[3] contains a pointer to the -+ * MMAL_BUFFER_HEADER_T structure. -+ */ -+ AV_PIX_FMT_MMAL, -+ -+ AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11 via old API, -+ ///< Picture.data[3] contains a -+ ///< ID3D11VideoDecoderOutputView pointer -+ -+ /** -+ * HW acceleration through CUDA. data[i] contain CUdeviceptr pointers -+ * exactly as for system memory frames. -+ */ -+ AV_PIX_FMT_CUDA, -+ -+ AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined -+ AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined -+ AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined -+ AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined -+ -+ AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), big-endian -+ AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), little-endian -+ AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), big-endian -+ AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per -+ ///< 2x2 Y samples), little-endian -+ AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), big-endian -+ AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), little-endian -+ AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), big-endian -+ AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), little-endian -+ AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), big-endian -+ AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), little-endian -+ AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), big-endian -+ AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), little-endian -+ AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian -+ AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian -+ AV_PIX_FMT_GBRP14BE, ///< planar GBR 4:4:4 42bpp, big-endian -+ AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian -+ AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 -+ ///< Y samples) full scale (JPEG), deprecated in favor -+ ///< of AV_PIX_FMT_YUV411P and setting color_range -+ -+ AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), -+ ///< 8-bit samples -+ AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), -+ ///< 8-bit samples -+ AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), -+ ///< 8-bit samples -+ AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), -+ ///< 8-bit samples -+ AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), -+ ///< 16-bit samples, little-endian -+ AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), -+ ///< 16-bit samples, big-endian -+ AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), -+ ///< 16-bit samples, little-endian -+ AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), -+ ///< 16-bit samples, big-endian -+ AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), -+ ///< 16-bit samples, little-endian -+ AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), -+ ///< 16-bit samples, big-endian -+ AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), -+ ///< 16-bit samples, little-endian -+ AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), -+ ///< 16-bit samples, big-endian -+ -+ AV_PIX_FMT_XVMC, ///< XVideo Motion Acceleration via common packet passing -+ -+ AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per -+ ///< 1x2 Y samples), little-endian -+ AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per -+ ///< 1x2 Y samples), big-endian -+ AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per -+ ///< 1x2 Y samples), little-endian -+ AV_PIX_FMT_YUV440P12BE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per -+ ///< 1x2 Y samples), big-endian -+ AV_PIX_FMT_AYUV64LE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y -+ ///< & A samples), little-endian -+ AV_PIX_FMT_AYUV64BE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y -+ ///< & A samples), big-endian -+ -+ AV_PIX_FMT_VIDEOTOOLBOX, ///< hardware decoding through Videotoolbox -+ -+ AV_PIX_FMT_P010LE, ///< like NV12, with 10bpp per component, data in the high -+ ///< bits, zeros in the low bits, little-endian -+ AV_PIX_FMT_P010BE, ///< like NV12, with 10bpp per component, data in the high -+ ///< bits, zeros in the low bits, big-endian -+ -+ AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian -+ AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian -+ -+ AV_PIX_FMT_GBRAP10BE, ///< planar GBR 4:4:4:4 40bpp, big-endian -+ AV_PIX_FMT_GBRAP10LE, ///< planar GBR 4:4:4:4 40bpp, little-endian -+ -+ AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec -+ -+ AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian -+ AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian -+ AV_PIX_FMT_GRAY10BE, ///< Y , 10bpp, big-endian -+ AV_PIX_FMT_GRAY10LE, ///< Y , 10bpp, little-endian -+ -+ AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian -+ AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian -+ -+ /** -+ * Hardware surfaces for Direct3D11. -+ * -+ * This is preferred over the legacy AV_PIX_FMT_D3D11VA_VLD. The new D3D11 -+ * hwaccel API and filtering support AV_PIX_FMT_D3D11 only. -+ * -+ * data[0] contains a ID3D11Texture2D pointer, and data[1] contains the -+ * texture array index of the frame as intptr_t if the ID3D11Texture2D is -+ * an array texture (or always 0 if it's a normal texture). -+ */ -+ AV_PIX_FMT_D3D11, -+ -+ AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian -+ AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian -+ -+ AV_PIX_FMT_GBRPF32BE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, -+ ///< big-endian -+ AV_PIX_FMT_GBRPF32LE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, -+ ///< little-endian -+ AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, -+ ///< 128bpp, big-endian -+ AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, -+ ///< 128bpp, little-endian -+ -+ /** -+ * DRM-managed buffers exposed through PRIME buffer sharing. -+ * -+ * data[0] points to an AVDRMFrameDescriptor. -+ */ -+ AV_PIX_FMT_DRM_PRIME, -+ /** -+ * Hardware surfaces for OpenCL. -+ * -+ * data[i] contain 2D image objects (typed in C as cl_mem, used -+ * in OpenCL as image2d_t) for each plane of the surface. -+ */ -+ AV_PIX_FMT_OPENCL, -+ -+ AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian -+ AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, little-endian -+ -+ AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian -+ AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian -+ -+ AV_PIX_FMT_YUVA422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), 12b alpha, big-endian -+ AV_PIX_FMT_YUVA422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per -+ ///< 2x1 Y samples), 12b alpha, little-endian -+ AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), 12b alpha, big-endian -+ AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per -+ ///< 1x1 Y samples), 12b alpha, little-endian -+ -+ AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for -+ ///< the UV components, which are interleaved (first byte U -+ ///< and the following byte V) -+ AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped -+ -+ /** -+ * Vulkan hardware images. -+ * -+ * data[0] points to an AVVkFrame -+ */ -+ AV_PIX_FMT_VULKAN, -+ -+ AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the -+ ///< high bits, big-endian -+ AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the -+ ///< high bits, little-endian -+ -+ AV_PIX_FMT_X2RGB10LE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G -+ ///< 10B(lsb), little-endian, X=unused/undefined -+ AV_PIX_FMT_X2RGB10BE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G -+ ///< 10B(lsb), big-endian, X=unused/undefined -+ AV_PIX_FMT_X2BGR10LE, ///< packed BGR 10:10:10, 30bpp, (msb)2X 10B 10G -+ ///< 10R(lsb), little-endian, X=unused/undefined -+ AV_PIX_FMT_X2BGR10BE, ///< packed BGR 10:10:10, 30bpp, (msb)2X 10B 10G -+ ///< 10R(lsb), big-endian, X=unused/undefined -+ -+ AV_PIX_FMT_P210BE, ///< interleaved chroma YUV 4:2:2, 20bpp, data in the high -+ ///< bits, big-endian -+ AV_PIX_FMT_P210LE, ///< interleaved chroma YUV 4:2:2, 20bpp, data in the high -+ ///< bits, little-endian -+ -+ AV_PIX_FMT_P410BE, ///< interleaved chroma YUV 4:4:4, 30bpp, data in the high -+ ///< bits, big-endian -+ AV_PIX_FMT_P410LE, ///< interleaved chroma YUV 4:4:4, 30bpp, data in the high -+ ///< bits, little-endian -+ -+ AV_PIX_FMT_P216BE, ///< interleaved chroma YUV 4:2:2, 32bpp, big-endian -+ AV_PIX_FMT_P216LE, ///< interleaved chroma YUV 4:2:2, 32bpp, liddle-endian -+ -+ AV_PIX_FMT_P416BE, ///< interleaved chroma YUV 4:4:4, 48bpp, big-endian -+ AV_PIX_FMT_P416LE, ///< interleaved chroma YUV 4:4:4, 48bpp, little-endian -+ -+ AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to -+ ///< link with shared libav* because the number of formats -+ ///< might differ between versions -+}; -+ -+#if AV_HAVE_BIGENDIAN -+# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be -+#else -+# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##le -+#endif -+ -+#define AV_PIX_FMT_RGB32 AV_PIX_FMT_NE(ARGB, BGRA) -+#define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR) -+#define AV_PIX_FMT_BGR32 AV_PIX_FMT_NE(ABGR, RGBA) -+#define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB) -+#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0) -+#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0) -+ -+#define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) -+#define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) -+#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) -+#define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) -+#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) -+#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) -+#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) -+#define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE) -+#define AV_PIX_FMT_RGB555 AV_PIX_FMT_NE(RGB555BE, RGB555LE) -+#define AV_PIX_FMT_RGB444 AV_PIX_FMT_NE(RGB444BE, RGB444LE) -+#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE) -+#define AV_PIX_FMT_BGR48 AV_PIX_FMT_NE(BGR48BE, BGR48LE) -+#define AV_PIX_FMT_BGR565 AV_PIX_FMT_NE(BGR565BE, BGR565LE) -+#define AV_PIX_FMT_BGR555 AV_PIX_FMT_NE(BGR555BE, BGR555LE) -+#define AV_PIX_FMT_BGR444 AV_PIX_FMT_NE(BGR444BE, BGR444LE) -+#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE) -+ -+#define AV_PIX_FMT_YUV420P9 AV_PIX_FMT_NE(YUV420P9BE, YUV420P9LE) -+#define AV_PIX_FMT_YUV422P9 AV_PIX_FMT_NE(YUV422P9BE, YUV422P9LE) -+#define AV_PIX_FMT_YUV444P9 AV_PIX_FMT_NE(YUV444P9BE, YUV444P9LE) -+#define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE) -+#define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) -+#define AV_PIX_FMT_YUV440P10 AV_PIX_FMT_NE(YUV440P10BE, YUV440P10LE) -+#define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) -+#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) -+#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) -+#define AV_PIX_FMT_YUV440P12 AV_PIX_FMT_NE(YUV440P12BE, YUV440P12LE) -+#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE) -+#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE) -+#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE) -+#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE) -+#define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) -+#define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) -+#define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) -+ -+#define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE, GBRP9LE) -+#define AV_PIX_FMT_GBRP10 AV_PIX_FMT_NE(GBRP10BE, GBRP10LE) -+#define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) -+#define AV_PIX_FMT_GBRP14 AV_PIX_FMT_NE(GBRP14BE, GBRP14LE) -+#define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) -+#define AV_PIX_FMT_GBRAP10 AV_PIX_FMT_NE(GBRAP10BE, GBRAP10LE) -+#define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) -+#define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) -+ -+#define AV_PIX_FMT_BAYER_BGGR16 AV_PIX_FMT_NE(BAYER_BGGR16BE, BAYER_BGGR16LE) -+#define AV_PIX_FMT_BAYER_RGGB16 AV_PIX_FMT_NE(BAYER_RGGB16BE, BAYER_RGGB16LE) -+#define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) -+#define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) -+ -+#define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) -+#define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) -+ -+#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) -+ -+#define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE, YUVA420P9LE) -+#define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE, YUVA422P9LE) -+#define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE, YUVA444P9LE) -+#define AV_PIX_FMT_YUVA420P10 AV_PIX_FMT_NE(YUVA420P10BE, YUVA420P10LE) -+#define AV_PIX_FMT_YUVA422P10 AV_PIX_FMT_NE(YUVA422P10BE, YUVA422P10LE) -+#define AV_PIX_FMT_YUVA444P10 AV_PIX_FMT_NE(YUVA444P10BE, YUVA444P10LE) -+#define AV_PIX_FMT_YUVA422P12 AV_PIX_FMT_NE(YUVA422P12BE, YUVA422P12LE) -+#define AV_PIX_FMT_YUVA444P12 AV_PIX_FMT_NE(YUVA444P12BE, YUVA444P12LE) -+#define AV_PIX_FMT_YUVA420P16 AV_PIX_FMT_NE(YUVA420P16BE, YUVA420P16LE) -+#define AV_PIX_FMT_YUVA422P16 AV_PIX_FMT_NE(YUVA422P16BE, YUVA422P16LE) -+#define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE) -+ -+#define AV_PIX_FMT_XYZ12 AV_PIX_FMT_NE(XYZ12BE, XYZ12LE) -+#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE) -+#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE) -+#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) -+#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) -+ -+#define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) -+#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE) -+#define AV_PIX_FMT_X2BGR10 AV_PIX_FMT_NE(X2BGR10BE, X2BGR10LE) -+ -+#define AV_PIX_FMT_P210 AV_PIX_FMT_NE(P210BE, P210LE) -+#define AV_PIX_FMT_P410 AV_PIX_FMT_NE(P410BE, P410LE) -+#define AV_PIX_FMT_P216 AV_PIX_FMT_NE(P216BE, P216LE) -+#define AV_PIX_FMT_P416 AV_PIX_FMT_NE(P416BE, P416LE) -+ -+/** -+ * Chromaticity coordinates of the source primaries. -+ * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.1 and -+ * ITU-T H.273. -+ */ -+enum AVColorPrimaries { -+ AVCOL_PRI_RESERVED0 = 0, -+ AVCOL_PRI_BT709 = -+ 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B -+ AVCOL_PRI_UNSPECIFIED = 2, -+ AVCOL_PRI_RESERVED = 3, -+ AVCOL_PRI_BT470M = -+ 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) -+ -+ AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R -+ ///< BT1700 625 PAL & SECAM -+ AVCOL_PRI_SMPTE170M = -+ 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC -+ AVCOL_PRI_SMPTE240M = -+ 7, ///< identical to above, also called "SMPTE C" even though it uses D65 -+ AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C -+ AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 -+ AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) -+ AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, -+ AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 -+ AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 -+ AVCOL_PRI_EBU3213 = 22, ///< EBU Tech. 3213-E (nothing there) / one of JEDEC -+ ///< P22 group phosphors -+ AVCOL_PRI_JEDEC_P22 = AVCOL_PRI_EBU3213, -+ AVCOL_PRI_NB ///< Not part of ABI -+}; -+ -+/** -+ * Color Transfer Characteristic. -+ * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.2. -+ */ -+enum AVColorTransferCharacteristic { -+ AVCOL_TRC_RESERVED0 = 0, -+ AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 -+ AVCOL_TRC_UNSPECIFIED = 2, -+ AVCOL_TRC_RESERVED = 3, -+ AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM -+ AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG -+ AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 -+ ///< 525 or 625 / ITU-R BT1700 NTSC -+ AVCOL_TRC_SMPTE240M = 7, -+ AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" -+ AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" -+ AVCOL_TRC_LOG_SQRT = -+ 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" -+ AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 -+ AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut -+ AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) -+ AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system -+ AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system -+ AVCOL_TRC_SMPTE2084 = -+ 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems -+ AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084, -+ AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1 -+ AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, -+ AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" -+ AVCOL_TRC_NB ///< Not part of ABI -+}; -+ -+/** -+ * YUV colorspace type. -+ * These values match the ones defined by ISO/IEC 23091-2_2019 subclause 8.3. -+ */ -+enum AVColorSpace { -+ AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC -+ ///< 61966-2-1 (sRGB), YZX and ST 428-1 -+ AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / -+ ///< derived in SMPTE RP 177 Annex B -+ AVCOL_SPC_UNSPECIFIED = 2, -+ AVCOL_SPC_RESERVED = -+ 3, ///< reserved for future use by ITU-T and ISO/IEC just like 15-255 are -+ AVCOL_SPC_FCC = -+ 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) -+ AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R -+ ///< BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 -+ AVCOL_SPC_SMPTE170M = -+ 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / -+ ///< functionally identical to above -+ AVCOL_SPC_SMPTE240M = -+ 7, ///< derived from 170M primaries and D65 white point, 170M is derived -+ ///< from BT470 System M's primaries -+ AVCOL_SPC_YCGCO = -+ 8, ///< used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 -+ AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, -+ AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system -+ AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system -+ AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x -+ AVCOL_SPC_CHROMA_DERIVED_NCL = -+ 12, ///< Chromaticity-derived non-constant luminance system -+ AVCOL_SPC_CHROMA_DERIVED_CL = -+ 13, ///< Chromaticity-derived constant luminance system -+ AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp -+ AVCOL_SPC_NB ///< Not part of ABI -+}; -+ -+/** -+ * Visual content value range. -+ * -+ * These values are based on definitions that can be found in multiple -+ * specifications, such as ITU-T BT.709 (3.4 - Quantization of RGB, luminance -+ * and colour-difference signals), ITU-T BT.2020 (Table 5 - Digital -+ * Representation) as well as ITU-T BT.2100 (Table 9 - Digital 10- and 12-bit -+ * integer representation). At the time of writing, the BT.2100 one is -+ * recommended, as it also defines the full range representation. -+ * -+ * Common definitions: -+ * - For RGB and luma planes such as Y in YCbCr and I in ICtCp, -+ * 'E' is the original value in range of 0.0 to 1.0. -+ * - For chroma planes such as Cb,Cr and Ct,Cp, 'E' is the original -+ * value in range of -0.5 to 0.5. -+ * - 'n' is the output bit depth. -+ * - For additional definitions such as rounding and clipping to valid n -+ * bit unsigned integer range, please refer to BT.2100 (Table 9). -+ */ -+enum AVColorRange { -+ AVCOL_RANGE_UNSPECIFIED = 0, -+ -+ /** -+ * Narrow or limited range content. -+ * -+ * - For luma planes: -+ * -+ * (219 * E + 16) * 2^(n-8) -+ * -+ * F.ex. the range of 16-235 for 8 bits -+ * -+ * - For chroma planes: -+ * -+ * (224 * E + 128) * 2^(n-8) -+ * -+ * F.ex. the range of 16-240 for 8 bits -+ */ -+ AVCOL_RANGE_MPEG = 1, -+ -+ /** -+ * Full range content. -+ * -+ * - For RGB and luma planes: -+ * -+ * (2^n - 1) * E -+ * -+ * F.ex. the range of 0-255 for 8 bits -+ * -+ * - For chroma planes: -+ * -+ * (2^n - 1) * E + 2^(n - 1) -+ * -+ * F.ex. the range of 1-255 for 8 bits -+ */ -+ AVCOL_RANGE_JPEG = 2, -+ AVCOL_RANGE_NB ///< Not part of ABI -+}; -+ -+/** -+ * Location of chroma samples. -+ * -+ * Illustration showing the location of the first (top left) chroma sample of -+ *the image, the left shows only luma, the right shows the location of the -+ *chroma sample, the 2 could be imagined to overlay each other but are drawn -+ *separately due to limitations of ASCII -+ * -+ * 1st 2nd 1st 2nd horizontal luma sample positions -+ * v v v v -+ * ______ ______ -+ *1st luma line > |X X ... |3 4 X ... X are luma samples, -+ * | |1 2 1-6 are possible chroma positions -+ *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position -+ */ -+enum AVChromaLocation { -+ AVCHROMA_LOC_UNSPECIFIED = 0, -+ AVCHROMA_LOC_LEFT = 1, ///< MPEG-2/4 4:2:0, H.264 default for 4:2:0 -+ AVCHROMA_LOC_CENTER = 2, ///< MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0 -+ AVCHROMA_LOC_TOPLEFT = -+ 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 -+ AVCHROMA_LOC_TOP = 4, -+ AVCHROMA_LOC_BOTTOMLEFT = 5, -+ AVCHROMA_LOC_BOTTOM = 6, -+ AVCHROMA_LOC_NB ///< Not part of ABI -+}; -+ -+#endif /* AVUTIL_PIXFMT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/rational.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/rational.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/rational.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/rational.h 2022-07-05 00:21:22.452315783 +0300 -@@ -0,0 +1,221 @@ -+/* -+ * rational numbers -+ * Copyright (c) 2003 Michael Niedermayer -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @ingroup lavu_math_rational -+ * Utilties for rational number calculation. -+ * @author Michael Niedermayer -+ */ -+ -+#ifndef AVUTIL_RATIONAL_H -+#define AVUTIL_RATIONAL_H -+ -+#include -+#include -+#include "attributes.h" -+ -+/** -+ * @defgroup lavu_math_rational AVRational -+ * @ingroup lavu_math -+ * Rational number calculation. -+ * -+ * While rational numbers can be expressed as floating-point numbers, the -+ * conversion process is a lossy one, so are floating-point operations. On the -+ * other hand, the nature of FFmpeg demands highly accurate calculation of -+ * timestamps. This set of rational number utilities serves as a generic -+ * interface for manipulating rational numbers as pairs of numerators and -+ * denominators. -+ * -+ * Many of the functions that operate on AVRational's have the suffix `_q`, in -+ * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all -+ * rational numbers. -+ * -+ * @{ -+ */ -+ -+/** -+ * Rational number (pair of numerator and denominator). -+ */ -+typedef struct AVRational { -+ int num; ///< Numerator -+ int den; ///< Denominator -+} AVRational; -+ -+/** -+ * Create an AVRational. -+ * -+ * Useful for compilers that do not support compound literals. -+ * -+ * @note The return value is not reduced. -+ * @see av_reduce() -+ */ -+static inline AVRational av_make_q(int num, int den) { -+ AVRational r = {num, den}; -+ return r; -+} -+ -+/** -+ * Compare two rationals. -+ * -+ * @param a First rational -+ * @param b Second rational -+ * -+ * @return One of the following values: -+ * - 0 if `a == b` -+ * - 1 if `a > b` -+ * - -1 if `a < b` -+ * - `INT_MIN` if one of the values is of the form `0 / 0` -+ */ -+static inline int av_cmp_q(AVRational a, AVRational b) { -+ const int64_t tmp = a.num * (int64_t)b.den - b.num * (int64_t)a.den; -+ -+ if (tmp) -+ return (int)((tmp ^ a.den ^ b.den) >> 63) | 1; -+ else if (b.den && a.den) -+ return 0; -+ else if (a.num && b.num) -+ return (a.num >> 31) - (b.num >> 31); -+ else -+ return INT_MIN; -+} -+ -+/** -+ * Convert an AVRational to a `double`. -+ * @param a AVRational to convert -+ * @return `a` in floating-point form -+ * @see av_d2q() -+ */ -+static inline double av_q2d(AVRational a) { return a.num / (double)a.den; } -+ -+/** -+ * Reduce a fraction. -+ * -+ * This is useful for framerate calculations. -+ * -+ * @param[out] dst_num Destination numerator -+ * @param[out] dst_den Destination denominator -+ * @param[in] num Source numerator -+ * @param[in] den Source denominator -+ * @param[in] max Maximum allowed values for `dst_num` & `dst_den` -+ * @return 1 if the operation is exact, 0 otherwise -+ */ -+int av_reduce(int* dst_num, int* dst_den, int64_t num, int64_t den, -+ int64_t max); -+ -+/** -+ * Multiply two rationals. -+ * @param b First rational -+ * @param c Second rational -+ * @return b*c -+ */ -+AVRational av_mul_q(AVRational b, AVRational c) av_const; -+ -+/** -+ * Divide one rational by another. -+ * @param b First rational -+ * @param c Second rational -+ * @return b/c -+ */ -+AVRational av_div_q(AVRational b, AVRational c) av_const; -+ -+/** -+ * Add two rationals. -+ * @param b First rational -+ * @param c Second rational -+ * @return b+c -+ */ -+AVRational av_add_q(AVRational b, AVRational c) av_const; -+ -+/** -+ * Subtract one rational from another. -+ * @param b First rational -+ * @param c Second rational -+ * @return b-c -+ */ -+AVRational av_sub_q(AVRational b, AVRational c) av_const; -+ -+/** -+ * Invert a rational. -+ * @param q value -+ * @return 1 / q -+ */ -+static av_always_inline AVRational av_inv_q(AVRational q) { -+ AVRational r = {q.den, q.num}; -+ return r; -+} -+ -+/** -+ * Convert a double precision floating point number to a rational. -+ * -+ * In case of infinity, the returned value is expressed as `{1, 0}` or -+ * `{-1, 0}` depending on the sign. -+ * -+ * @param d `double` to convert -+ * @param max Maximum allowed numerator and denominator -+ * @return `d` in AVRational form -+ * @see av_q2d() -+ */ -+AVRational av_d2q(double d, int max) av_const; -+ -+/** -+ * Find which of the two rationals is closer to another rational. -+ * -+ * @param q Rational to be compared against -+ * @param q1,q2 Rationals to be tested -+ * @return One of the following values: -+ * - 1 if `q1` is nearer to `q` than `q2` -+ * - -1 if `q2` is nearer to `q` than `q1` -+ * - 0 if they have the same distance -+ */ -+int av_nearer_q(AVRational q, AVRational q1, AVRational q2); -+ -+/** -+ * Find the value in a list of rationals nearest a given reference rational. -+ * -+ * @param q Reference rational -+ * @param q_list Array of rationals terminated by `{0, 0}` -+ * @return Index of the nearest value found in the array -+ */ -+int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); -+ -+/** -+ * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point -+ * format. -+ * -+ * @param q Rational to be converted -+ * @return Equivalent floating-point value, expressed as an unsigned 32-bit -+ * integer. -+ * @note The returned value is platform-indepedant. -+ */ -+uint32_t av_q2intfloat(AVRational q); -+ -+/** -+ * Return the best rational so that a and b are multiple of it. -+ * If the resulting denominator is larger than max_den, return def. -+ */ -+AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def); -+ -+/** -+ * @} -+ */ -+ -+#endif /* AVUTIL_RATIONAL_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/samplefmt.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/samplefmt.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/samplefmt.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/samplefmt.h 2022-07-05 00:21:22.452315783 +0300 -@@ -0,0 +1,276 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef AVUTIL_SAMPLEFMT_H -+#define AVUTIL_SAMPLEFMT_H -+ -+#include -+ -+#include "avutil.h" -+#include "attributes.h" -+ -+/** -+ * @addtogroup lavu_audio -+ * @{ -+ * -+ * @defgroup lavu_sampfmts Audio sample formats -+ * -+ * Audio sample format enumeration and related convenience functions. -+ * @{ -+ */ -+ -+/** -+ * Audio sample formats -+ * -+ * - The data described by the sample format is always in native-endian order. -+ * Sample values can be expressed by native C types, hence the lack of a -+ * signed 24-bit sample format even though it is a common raw audio data format. -+ * -+ * - The floating-point formats are based on full volume being in the range -+ * [-1.0, 1.0]. Any values outside this range are beyond full volume level. -+ * -+ * - The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg -+ * (such as AVFrame in libavcodec) is as follows: -+ * -+ * @par -+ * For planar sample formats, each audio channel is in a separate data plane, -+ * and linesize is the buffer size, in bytes, for a single plane. All data -+ * planes must be the same size. For packed sample formats, only the first data -+ * plane is used, and samples for each channel are interleaved. In this case, -+ * linesize is the buffer size, in bytes, for the 1 plane. -+ * -+ */ -+enum AVSampleFormat { -+ AV_SAMPLE_FMT_NONE = -1, -+ AV_SAMPLE_FMT_U8, ///< unsigned 8 bits -+ AV_SAMPLE_FMT_S16, ///< signed 16 bits -+ AV_SAMPLE_FMT_S32, ///< signed 32 bits -+ AV_SAMPLE_FMT_FLT, ///< float -+ AV_SAMPLE_FMT_DBL, ///< double -+ -+ AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar -+ AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar -+ AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar -+ AV_SAMPLE_FMT_FLTP, ///< float, planar -+ AV_SAMPLE_FMT_DBLP, ///< double, planar -+ AV_SAMPLE_FMT_S64, ///< signed 64 bits -+ AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar -+ -+ AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking -+ ///< dynamically -+}; -+ -+/** -+ * Return the name of sample_fmt, or NULL if sample_fmt is not -+ * recognized. -+ */ -+const char* av_get_sample_fmt_name(enum AVSampleFormat sample_fmt); -+ -+/** -+ * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE -+ * on error. -+ */ -+enum AVSampleFormat av_get_sample_fmt(const char* name); -+ -+/** -+ * Return the planar<->packed alternative form of the given sample format, or -+ * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the -+ * requested planar/packed format, the format returned is the same as the -+ * input. -+ */ -+enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, -+ int planar); -+ -+/** -+ * Get the packed alternative form of the given sample format. -+ * -+ * If the passed sample_fmt is already in packed format, the format returned is -+ * the same as the input. -+ * -+ * @return the packed alternative form of the given sample format or -+ AV_SAMPLE_FMT_NONE on error. -+ */ -+enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt); -+ -+/** -+ * Get the planar alternative form of the given sample format. -+ * -+ * If the passed sample_fmt is already in planar format, the format returned is -+ * the same as the input. -+ * -+ * @return the planar alternative form of the given sample format or -+ AV_SAMPLE_FMT_NONE on error. -+ */ -+enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); -+ -+/** -+ * Generate a string corresponding to the sample format with -+ * sample_fmt, or a header if sample_fmt is negative. -+ * -+ * @param buf the buffer where to write the string -+ * @param buf_size the size of buf -+ * @param sample_fmt the number of the sample format to print the -+ * corresponding info string, or a negative value to print the -+ * corresponding header. -+ * @return the pointer to the filled buffer or NULL if sample_fmt is -+ * unknown or in case of other errors -+ */ -+char* av_get_sample_fmt_string(char* buf, int buf_size, -+ enum AVSampleFormat sample_fmt); -+ -+/** -+ * Return number of bytes per sample. -+ * -+ * @param sample_fmt the sample format -+ * @return number of bytes per sample or zero if unknown for the given -+ * sample format -+ */ -+int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt); -+ -+/** -+ * Check if the sample format is planar. -+ * -+ * @param sample_fmt the sample format to inspect -+ * @return 1 if the sample format is planar, 0 if it is interleaved -+ */ -+int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); -+ -+/** -+ * Get the required buffer size for the given audio parameters. -+ * -+ * @param[out] linesize calculated linesize, may be NULL -+ * @param nb_channels the number of channels -+ * @param nb_samples the number of samples in a single channel -+ * @param sample_fmt the sample format -+ * @param align buffer size alignment (0 = default, 1 = no alignment) -+ * @return required buffer size, or negative error code on failure -+ */ -+int av_samples_get_buffer_size(int* linesize, int nb_channels, int nb_samples, -+ enum AVSampleFormat sample_fmt, int align); -+ -+/** -+ * @} -+ * -+ * @defgroup lavu_sampmanip Samples manipulation -+ * -+ * Functions that manipulate audio samples -+ * @{ -+ */ -+ -+/** -+ * Fill plane data pointers and linesize for samples with sample -+ * format sample_fmt. -+ * -+ * The audio_data array is filled with the pointers to the samples data planes: -+ * for planar, set the start point of each channel's data within the buffer, -+ * for packed, set the start point of the entire buffer only. -+ * -+ * The value pointed to by linesize is set to the aligned size of each -+ * channel's data buffer for planar layout, or to the aligned size of the -+ * buffer for all channels for packed layout. -+ * -+ * The buffer in buf must be big enough to contain all the samples -+ * (use av_samples_get_buffer_size() to compute its minimum size), -+ * otherwise the audio_data pointers will point to invalid data. -+ * -+ * @see enum AVSampleFormat -+ * The documentation for AVSampleFormat describes the data layout. -+ * -+ * @param[out] audio_data array to be filled with the pointer for each channel -+ * @param[out] linesize calculated linesize, may be NULL -+ * @param buf the pointer to a buffer containing the samples -+ * @param nb_channels the number of channels -+ * @param nb_samples the number of samples in a single channel -+ * @param sample_fmt the sample format -+ * @param align buffer size alignment (0 = default, 1 = no alignment) -+ * @return minimum size in bytes required for the buffer on -+ * success, or a negative error code on failure -+ */ -+int av_samples_fill_arrays(uint8_t** audio_data, int* linesize, -+ const uint8_t* buf, int nb_channels, int nb_samples, -+ enum AVSampleFormat sample_fmt, int align); -+ -+/** -+ * Allocate a samples buffer for nb_samples samples, and fill data pointers and -+ * linesize accordingly. -+ * The allocated samples buffer can be freed by using av_freep(&audio_data[0]) -+ * Allocated data will be initialized to silence. -+ * -+ * @see enum AVSampleFormat -+ * The documentation for AVSampleFormat describes the data layout. -+ * -+ * @param[out] audio_data array to be filled with the pointer for each channel -+ * @param[out] linesize aligned size for audio buffer(s), may be NULL -+ * @param nb_channels number of audio channels -+ * @param nb_samples number of samples per channel -+ * @param align buffer size alignment (0 = default, 1 = no alignment) -+ * @return >=0 on success or a negative error code on failure -+ * @todo return the size of the allocated buffer in case of success at the next -+ * bump -+ * @see av_samples_fill_arrays() -+ * @see av_samples_alloc_array_and_samples() -+ */ -+int av_samples_alloc(uint8_t** audio_data, int* linesize, int nb_channels, -+ int nb_samples, enum AVSampleFormat sample_fmt, int align); -+ -+/** -+ * Allocate a data pointers array, samples buffer for nb_samples -+ * samples, and fill data pointers and linesize accordingly. -+ * -+ * This is the same as av_samples_alloc(), but also allocates the data -+ * pointers array. -+ * -+ * @see av_samples_alloc() -+ */ -+int av_samples_alloc_array_and_samples(uint8_t*** audio_data, int* linesize, -+ int nb_channels, int nb_samples, -+ enum AVSampleFormat sample_fmt, -+ int align); -+ -+/** -+ * Copy samples from src to dst. -+ * -+ * @param dst destination array of pointers to data planes -+ * @param src source array of pointers to data planes -+ * @param dst_offset offset in samples at which the data will be written to dst -+ * @param src_offset offset in samples at which the data will be read from src -+ * @param nb_samples number of samples to be copied -+ * @param nb_channels number of audio channels -+ * @param sample_fmt audio sample format -+ */ -+int av_samples_copy(uint8_t** dst, uint8_t* const* src, int dst_offset, -+ int src_offset, int nb_samples, int nb_channels, -+ enum AVSampleFormat sample_fmt); -+ -+/** -+ * Fill an audio buffer with silence. -+ * -+ * @param audio_data array of pointers to data planes -+ * @param offset offset in samples at which to start filling -+ * @param nb_samples number of samples to fill -+ * @param nb_channels number of audio channels -+ * @param sample_fmt audio sample format -+ */ -+int av_samples_set_silence(uint8_t** audio_data, int offset, int nb_samples, -+ int nb_channels, enum AVSampleFormat sample_fmt); -+ -+/** -+ * @} -+ * @} -+ */ -+#endif /* AVUTIL_SAMPLEFMT_H */ -diff -Nrbu mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/version.h mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/version.h ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/version.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/include/libavutil/version.h 2022-07-05 00:21:22.453315777 +0300 -@@ -0,0 +1,118 @@ -+/* -+ * copyright (c) 2003 Fabrice Bellard -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/** -+ * @file -+ * @ingroup lavu -+ * Libavutil version macros -+ */ -+ -+#ifndef AVUTIL_VERSION_H -+#define AVUTIL_VERSION_H -+ -+#include "macros.h" -+ -+/** -+ * @addtogroup version_utils -+ * -+ * Useful to check and match library version in order to maintain -+ * backward compatibility. -+ * -+ * The FFmpeg libraries follow a versioning sheme very similar to -+ * Semantic Versioning (http://semver.org/) -+ * The difference is that the component called PATCH is called MICRO in FFmpeg -+ * and its value is reset to 100 instead of 0 to keep it above or equal to 100. -+ * Also we do not increase MICRO for every bugfix or change in git master. -+ * -+ * Prior to FFmpeg 3.2 point releases did not change any lib version number to -+ * avoid aliassing different git master checkouts. -+ * Starting with FFmpeg 3.2, the released library versions will occupy -+ * a separate MAJOR.MINOR that is not used on the master development branch. -+ * That is if we branch a release of master 55.10.123 we will bump to 55.11.100 -+ * for the release and master will continue at 55.12.100 after it. Each new -+ * point release will then bump the MICRO improving the usefulness of the lib -+ * versions. -+ * -+ * @{ -+ */ -+ -+#define AV_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c)) -+#define AV_VERSION_DOT(a, b, c) a##.##b##.##c -+#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) -+ -+/** -+ * Extract version components from the full ::AV_VERSION_INT int as returned -+ * by functions like ::avformat_version() and ::avcodec_version() -+ */ -+#define AV_VERSION_MAJOR(a) ((a) >> 16) -+#define AV_VERSION_MINOR(a) (((a)&0x00FF00) >> 8) -+#define AV_VERSION_MICRO(a) ((a)&0xFF) -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @defgroup lavu_ver Version and Build diagnostics -+ * -+ * Macros and function useful to check at compiletime and at runtime -+ * which version of libavutil is in use. -+ * -+ * @{ -+ */ -+ -+#define LIBAVUTIL_VERSION_MAJOR 57 -+#define LIBAVUTIL_VERSION_MINOR 17 -+#define LIBAVUTIL_VERSION_MICRO 100 -+ -+#define LIBAVUTIL_VERSION_INT \ -+ AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, \ -+ LIBAVUTIL_VERSION_MICRO) -+#define LIBAVUTIL_VERSION \ -+ AV_VERSION(LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, \ -+ LIBAVUTIL_VERSION_MICRO) -+#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT -+ -+#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) -+ -+/** -+ * @defgroup lavu_depr_guards Deprecation Guards -+ * FF_API_* defines may be placed below to indicate public API that will be -+ * dropped at a future version bump. The defines themselves are not part of -+ * the public API and may change, break or disappear at any time. -+ * -+ * @note, when bumping the major version it is recommended to manually -+ * disable each FF_API_* in its own commit instead of disabling them all -+ * at once through the bump. This improves the git bisect-ability of the change. -+ * -+ * @{ -+ */ -+ -+#define FF_API_D2STR (LIBAVUTIL_VERSION_MAJOR < 58) -+#define FF_API_DECLARE_ALIGNED (LIBAVUTIL_VERSION_MAJOR < 58) -+#define FF_API_COLORSPACE_NAME (LIBAVUTIL_VERSION_MAJOR < 58) -+#define FF_API_AV_MALLOCZ_ARRAY (LIBAVUTIL_VERSION_MAJOR < 58) -+ -+/** -+ * @} -+ * @} -+ */ -+ -+#endif /* AVUTIL_VERSION_H */ -diff -Nrup mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/moz.build mozilla/dom/media/platforms/ffmpeg/ffmpeg59/moz.build ---- mozilla-OLD/dom/media/platforms/ffmpeg/ffmpeg59/moz.build 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/ffmpeg59/moz.build 2020-02-18 02:37:49.000000000 +0300 -@@ -0,0 +1,25 @@ -+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -+# vim: set filetype=python: -+# This Source Code Form is subject to the terms of the Mozilla Public -+# License, v. 2.0. If a copy of the MPL was not distributed with this -+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ -+UNIFIED_SOURCES += [ -+ '../FFmpegAudioDecoder.cpp', -+ '../FFmpegDataDecoder.cpp', -+ '../FFmpegDecoderModule.cpp', -+ '../FFmpegVideoDecoder.cpp', -+] -+LOCAL_INCLUDES += [ -+ '..', -+ 'include', -+] -+ -+if CONFIG['CC_TYPE'] in ('clang', 'gcc'): -+ CXXFLAGS += [ '-Wno-deprecated-declarations' ] -+if CONFIG['CC_TYPE'] == 'clang': -+ CXXFLAGS += [ -+ '-Wno-unknown-attributes', -+ ] -+ -+FINAL_LIBRARY = 'xul' diff --git a/seamonkey-2.53.13-regexp.patch b/seamonkey-2.53.13-regexp.patch deleted file mode 100644 index 397c97b..0000000 --- a/seamonkey-2.53.13-regexp.patch +++ /dev/null @@ -1,15297 +0,0 @@ -diff -Nrup mozilla/.clang-format-ignore mozilla-OK/.clang-format-ignore ---- mozilla/.clang-format-ignore 2022-04-13 21:14:20.000000000 +0300 -+++ mozilla-OK/.clang-format-ignore 2022-06-15 23:58:18.549601723 +0300 -@@ -134,3 +134,7 @@ toolkit/components/jsoncpp/.* - toolkit/components/protobuf/.* - toolkit/crashreporter/google-breakpad/.* - tools/fuzzing/libfuzzer.* -+ -+# Don't want to reformat irregexp (third-party code) -+js/src/irregexp/imported/.* -+ -diff -Nrup mozilla/config/system-headers.mozbuild mozilla-OK/config/system-headers.mozbuild ---- mozilla/config/system-headers.mozbuild 2022-06-16 00:25:27.474529274 +0300 -+++ mozilla-OK/config/system-headers.mozbuild 2022-06-16 00:20:44.288456655 +0300 -@@ -1349,6 +1349,7 @@ if CONFIG['MOZ_SYSTEM_ICU']: - 'unicode/udatpg.h', - 'unicode/udisplaycontext.h', - 'unicode/uenum.h', -+ 'unicode/uniset.h', - 'unicode/unistr.h', - 'unicode/unorm.h', - 'unicode/unum.h', -diff -Nrup mozilla/dom/base/nsContentUtils.cpp mozilla-OK/dom/base/nsContentUtils.cpp ---- mozilla/dom/base/nsContentUtils.cpp 2022-06-08 22:10:26.000000000 +0300 -+++ mozilla-OK/dom/base/nsContentUtils.cpp 2022-06-15 22:52:50.242218526 +0300 -@@ -20,6 +20,7 @@ - #include "imgRequestProxy.h" - #include "jsapi.h" - #include "jsfriendapi.h" -+#include "js/RegExp.h" - #include "js/Value.h" - #include "Layers.h" - #include "nsAppRunner.h" -@@ -7164,28 +7165,17 @@ nsContentUtils::FindInternalContentViewe - } - - static void --ReportPatternCompileFailure(nsAString& aPattern, nsIDocument* aDocument, -+ReportPatternCompileFailure(nsAString& aPattern, -+ nsIDocument* aDocument, -+ JS::MutableHandle error, - JSContext* cx) - { -- MOZ_ASSERT(JS_IsExceptionPending(cx)); -- -- JS::RootedValue exn(cx); -- if (!JS_GetPendingException(cx, &exn)) { -- return; -- } -- if (!exn.isObject()) { -- // If pending exception is not an object, it should be OOM. -- return; -- } -- - JS::AutoSaveExceptionState savedExc(cx); -- JS::RootedObject exnObj(cx, &exn.toObject()); -+ JS::RootedObject exnObj(cx, &error.toObject()); - JS::RootedValue messageVal(cx); - if (!JS_GetProperty(cx, exnObj, "message", &messageVal)) { - return; - } -- MOZ_ASSERT(messageVal.isString()); -- - JS::RootedString messageStr(cx, messageVal.toString()); - MOZ_ASSERT(messageStr); - -@@ -7219,25 +7209,36 @@ nsContentUtils::IsPatternMatching(nsAStr - // regexp evaluation, not actual script execution. - JSAutoCompartment ac(cx, xpc::UnprivilegedJunkScope()); - -+ // Check if the pattern by itself is valid first, and not that it only becomes -+ // valid once we add ^(?: and )$. -+ JS::RootedValue error(cx); -+ if (!JS::CheckRegExpSyntax( -+ cx, static_cast(aPattern.BeginWriting()), -+ aPattern.Length(), JS::RegExpFlag::Unicode, &error)) { -+ return true; -+ } -+ -+ if (!error.isUndefined()) { -+ ReportPatternCompileFailure(aPattern, aDocument, &error, cx); -+ return true; -+ } -+ - // The pattern has to match the entire value. - aPattern.InsertLiteral(u"^(?:", 0); - aPattern.AppendLiteral(")$"); - - JS::Rooted re(cx, -- JS_NewUCRegExpObject(cx, -+ JS::NewUCRegExpObject(cx, - static_cast(aPattern.BeginWriting()), -- aPattern.Length(), JSREG_UNICODE)); -+ aPattern.Length(), JS::RegExpFlag::Unicode)); -+ - if (!re) { -- // Remove extra patterns added above to report with the original pattern. -- aPattern.Cut(0, 4); -- aPattern.Cut(aPattern.Length() - 2, 2); -- ReportPatternCompileFailure(aPattern, aDocument, cx); - return true; - } - - JS::Rooted rval(cx, JS::NullValue()); - size_t idx = 0; -- if (!JS_ExecuteRegExpNoStatics(cx, re, -+ if (!JS::ExecuteRegExpNoStatics(cx, re, - static_cast(aValue.BeginWriting()), - aValue.Length(), &idx, true, &rval)) { - return true; -diff -Nrup mozilla/js/ipc/WrapperAnswer.cpp mozilla-OK/js/ipc/WrapperAnswer.cpp ---- mozilla/js/ipc/WrapperAnswer.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/ipc/WrapperAnswer.cpp 2022-06-15 21:39:37.363986145 +0300 -@@ -12,6 +12,7 @@ - #include "mozilla/dom/ScriptSettings.h" - #include "xpcprivate.h" - #include "js/Class.h" -+#include "js/RegExp.h" - #include "jsfriendapi.h" - - using namespace JS; -@@ -681,7 +682,7 @@ WrapperAnswer::RecvRegExpToShared(const - if (!obj) - return deadCPOW(jsapi, rs); - -- RootedString sourceJSStr(cx, JS_GetRegExpSource(cx, obj)); -+ RootedString sourceJSStr(cx, JS::GetRegExpSource(cx, obj)); - if (!sourceJSStr) - return fail(jsapi, rs); - nsAutoJSString sourceStr; -@@ -689,7 +690,7 @@ WrapperAnswer::RecvRegExpToShared(const - return fail(jsapi, rs); - source->Assign(sourceStr); - -- *flags = JS_GetRegExpFlags(cx, obj); -+ *flags = JS::GetRegExpFlags(cx, obj).value(); - - return ok(rs); - } -diff -Nrup mozilla/js/ipc/WrapperOwner.cpp mozilla-OK/js/ipc/WrapperOwner.cpp ---- mozilla/js/ipc/WrapperOwner.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/ipc/WrapperOwner.cpp 2022-06-15 21:39:37.364986138 +0300 -@@ -11,6 +11,8 @@ - #include "mozilla/dom/BindingUtils.h" - #include "jsfriendapi.h" - #include "js/CharacterEncoding.h" -+#include "js/RegExp.h" -+#include "js/RegExpFlags.h" - #include "xpcprivate.h" - #include "CPOWTimer.h" - #include "WrapperFactory.h" -@@ -877,7 +879,8 @@ WrapperOwner::regexp_toShared(JSContext* - return nullptr; - - RootedObject regexp(cx); -- regexp = JS_NewUCRegExpObject(cx, source.get(), source.Length(), flags); -+ regexp = JS::NewUCRegExpObject( -+ cx, source.get(), source.Length(), RegExpFlags(flags)); - if (!regexp) - return nullptr; - -diff -Nrup mozilla/js/moz.configure mozilla-OK/js/moz.configure ---- mozilla/js/moz.configure 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/moz.configure 2022-06-15 23:52:50.099830874 +0300 -@@ -431,16 +431,3 @@ def enable_pipeline_operator(value): - - set_config('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator) - set_define('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator) -- --# Initial support for new regexp engine --# ================================================== -- --js_option('--enable-new-regexp', default=False, help='Enable new regexp engine') -- --@depends('--enable-new-regexp') --def enable_new_regexp(value): -- if value: -- return True -- --set_config('ENABLE_NEW_REGEXP', enable_new_regexp) --set_define('ENABLE_NEW_REGEXP', enable_new_regexp) -diff -Nrup mozilla/js/public/Class.h mozilla-OK/js/public/Class.h ---- mozilla/js/public/Class.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/public/Class.h 2022-06-15 23:35:21.882940573 +0300 -@@ -851,7 +851,7 @@ static const uint32_t JSCLASS_FOREGROUND - // application. - static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5; - static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT = -- JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 38; -+ JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 39; - - #define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \ - (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) -diff -Nrup mozilla/js/public/RegExp.h mozilla-OK/js/public/RegExp.h ---- mozilla/js/public/RegExp.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/public/RegExp.h 2022-06-15 22:52:50.238218553 +0300 -@@ -0,0 +1,107 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * This Source Code Form is "Incompatible With Secondary Licenses", as -+ * defined by the Mozilla Public License, v. 2.0. -+ */ -+ -+/* Public JS API for Regular Expressions. */ -+ -+#ifndef js_RegExp_h -+#define js_RegExp_h -+ -+#include // size_t -+ -+#include "jstypes.h" // JS_PUBLIC_API -+ -+#include "js/RegExpFlags.h" // JS::RegExpFlags -+#include "js/RootingAPI.h" // JS::{,Mutable}Handle -+#include "js/Value.h" // JS::Value -+ -+struct JSContext; -+class JSString; -+ -+namespace JS { -+ -+/* -+ * Create a new RegExp for the given Latin-1-encoded source and flags. -+ */ -+extern JS_PUBLIC_API(JSObject*) NewRegExpObject(JSContext* cx, -+ const char* bytes, -+ size_t length, -+ RegExpFlags flags); -+ -+/* -+ * Create a new RegExp for the given UC source and flags. -+ */ -+extern JS_PUBLIC_API(JSObject*) NewUCRegExpObject(JSContext* cx, -+ const char16_t* chars, -+ size_t length, -+ RegExpFlags flags); -+ -+extern JS_PUBLIC_API(bool) -+ SetRegExpInput(JSContext* cx, Handle obj, Handle input); -+ -+extern JS_PUBLIC_API(bool) -+ ClearRegExpStatics(JSContext* cx, Handle obj); -+ -+/* RegExp interface for callers with a global object. */ -+ -+extern JS_PUBLIC_API(bool) ExecuteRegExp(JSContext* cx, -+ Handle obj, -+ Handle reobj, -+ char16_t* chars, -+ size_t length, -+ size_t* indexp, -+ bool test, -+ MutableHandle rval); -+ -+/* RegExp interface for callers without a global object. */ -+ -+extern JS_PUBLIC_API(bool) ExecuteRegExpNoStatics(JSContext* cx, -+ Handle reobj, -+ char16_t* chars, -+ size_t length, -+ size_t* indexp, -+ bool test, -+ MutableHandle rval); -+ -+/* -+ * Returns true on success, setting |*isRegExp| to true if |obj| is a RegExp -+ * object or a wrapper around one, or to false if not. Returns false on failure. -+ * -+ * This method returns true with |*isRegExp == false| when passed an ES6 proxy -+ * whose target is a RegExp, or when passed a revoked proxy. -+ */ -+extern JS_PUBLIC_API(bool) -+ ObjectIsRegExp(JSContext* cx, Handle obj, bool* isRegExp); -+ -+/* -+ * Given a RegExp object (or a wrapper around one), return all JS::RegExpFlag::* for it. -+ */ -+extern JS_PUBLIC_API(RegExpFlags) -+ GetRegExpFlags(JSContext* cx, Handle obj); -+ -+/* -+ * Return the source text for a RegExp object (or a wrapper around one), or null on failure. -+ */ -+extern JS_PUBLIC_API(JSString*) -+ GetRegExpSource(JSContext* cx, Handle obj); -+ -+/** -+ * Check whether the given source is a valid regexp. If the regexp parses -+ * successfully, returns true and sets |error| to undefined. If the regexp -+ * has a syntax error, returns true, sets |error| to that error object, and -+ * clears the exception. Returns false on OOM or over-recursion. -+ */ -+extern JS_PUBLIC_API(bool) CheckRegExpSyntax(JSContext* cx, -+ const char16_t* chars, -+ size_t length, -+ RegExpFlags flags, -+ MutableHandle error); -+ -+} // namespace JS -+ -+#endif // js_RegExp_h -diff -Nrup mozilla/js/public/RegExpFlags.h mozilla-OK/js/public/RegExpFlags.h ---- mozilla/js/public/RegExpFlags.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/public/RegExpFlags.h 2022-06-15 22:50:35.818129064 +0300 -@@ -0,0 +1,171 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * This Source Code Form is "Incompatible With Secondary Licenses", as -+ * defined by the Mozilla Public License, v. 2.0. -+ */ -+ -+/* Regular Expression flags. */ -+ -+#ifndef js_RegExpFlags_h -+#define js_RegExpFlags_h -+ -+#include "mozilla/Assertions.h" // for MOZ_ASSERT -+#include "mozilla/Attributes.h" // for MOZ_IMPLICIT -+#include -+ -+namespace JS { -+ -+/* -+ * Regular Expression flag values, suitable for initializing a collection of -+ * regular expression flags as defined below in |RegExpFlags|. -+ * Flags are listed in alphabetical order by syntax: /g, /i, /m, /s, /u, /y. -+ */ -+ -+class RegExpFlag -+{ -+ // WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can change): -+ // -+ // Flag-bit values appear in XDR and structured clone data formats, so none of -+ // these values can be changed (including to assign values in numerically -+ // ascending order) unless you also add a translation layer. -+public: -+ /** -+ * Act globally and find *all* matches (rather than stopping after just the -+ * first one), i.e. /g. -+ */ -+ static uint8_t const Global = 0x02; -+ -+ /** -+ * Interpret regular expression source text case-insensitively by folding -+ * uppercase letters to lowercase, i.e. /i. -+ */ -+ static uint8_t const IgnoreCase = 0x01; -+ -+ /** Treat ^ and $ as begin and end of line, i.e. /m. */ -+ static uint8_t const Multiline = 0x04; -+ -+ /** Match '.' to any character including newlines, i.e. /s. */ -+ static uint8_t const DotAll = 0x20; -+ -+ /** Use Unicode semantics, i.e. /u. */ -+ static uint8_t const Unicode = 0x10; -+ -+ /** Only match starting from .lastIndex, i.e. /y. */ -+ static uint8_t const Sticky = 0x08; -+ -+ /** No regular expression flags. */ -+ static uint8_t const NoFlags = 0x00; -+ -+ /** All regular expression flags. */ -+ static uint8_t const AllFlags = 0x3F; //All supported bits set: 0b11'1111 -+}; -+ -+/* -+ * A collection of regular expression flags. Individual flag values may be -+ * combined into a collection using bitwise operators. -+ */ -+class RegExpFlags -+{ -+public: -+ using Flag = uint8_t; -+ -+private: -+ Flag flags_; -+ -+public: -+ RegExpFlags() = default; -+ -+ MOZ_IMPLICIT RegExpFlags(Flag flags) -+ : flags_(flags) -+ { -+ MOZ_ASSERT((flags & RegExpFlag::AllFlags) == flags, -+ "flags must not contain unrecognized flags"); -+ } -+ -+ RegExpFlags(const RegExpFlags&) = default; -+ -+ bool operator==(const RegExpFlags& other) const -+ { -+ return flags_ == other.flags_; -+ } -+ -+ bool operator!=(const RegExpFlags& other) const { return !(*this == other); } -+ -+ RegExpFlags& operator&=(const RegExpFlags& rhs) -+ { -+ flags_ &= rhs.flags_; -+ return *this; -+ } -+ -+ RegExpFlags& operator|=(const RegExpFlags& rhs) -+ { -+ flags_ |= rhs.flags_; -+ return *this; -+ } -+ -+ RegExpFlags operator&(Flag flag) const { return RegExpFlags(flags_ & flag); } -+ -+ RegExpFlags operator|(Flag flag) const { return RegExpFlags(flags_ | flag); } -+ -+ RegExpFlags operator^(Flag flag) const { return RegExpFlags(flags_ ^ flag); } -+ -+ RegExpFlags operator~() const -+ { -+ return RegExpFlags(~flags_ & RegExpFlag::AllFlags); -+ } -+ -+ bool global() const { return flags_ & RegExpFlag::Global; } -+ bool ignoreCase() const { return flags_ & RegExpFlag::IgnoreCase; } -+ bool multiline() const { return flags_ & RegExpFlag::Multiline; } -+ bool dotAll() const { return flags_ & RegExpFlag::DotAll; } -+ bool unicode() const { return flags_ & RegExpFlag::Unicode; } -+ bool sticky() const { return flags_ & RegExpFlag::Sticky; } -+ -+ explicit operator bool() const { return flags_ != 0; } -+ -+ Flag value() const { return flags_; } -+}; -+ -+inline RegExpFlags& -+operator&=(RegExpFlags& flags, RegExpFlags::Flag flag) -+{ -+ flags = flags & flag; -+ return flags; -+} -+ -+inline RegExpFlags& -+operator|=(RegExpFlags& flags, RegExpFlags::Flag flag) -+{ -+ flags = flags | flag; -+ return flags; -+} -+ -+inline RegExpFlags& -+operator^=(RegExpFlags& flags, RegExpFlags::Flag flag) -+{ -+ flags = flags ^ flag; -+ return flags; -+} -+ -+inline RegExpFlags -+operator&(const RegExpFlags& lhs, const RegExpFlags& rhs) -+{ -+ RegExpFlags result = lhs; -+ result &= rhs; -+ return lhs; -+} -+ -+inline RegExpFlags -+operator|(const RegExpFlags& lhs, const RegExpFlags& rhs) -+{ -+ RegExpFlags result = lhs; -+ result |= rhs; -+ return result; -+} -+ -+} // namespace JS -+ -+#endif // js_RegExpFlags_h -diff -Nrup mozilla/js/public/Value.h mozilla-OK/js/public/Value.h ---- mozilla/js/public/Value.h 2021-10-26 19:49:54.000000000 +0300 -+++ mozilla-OK/js/public/Value.h 2022-06-15 22:52:13.969464215 +0300 -@@ -691,7 +691,7 @@ class MOZ_NON_PARAM alignas(8) Value - return data.s.payload.u32; - } - -- uint64_t asRawBits() const { -+ constexpr uint64_t asRawBits() const { - return data.asBits; - } - -diff -Nrup mozilla/js/src/.clang-format mozilla-OK/js/src/.clang-format ---- mozilla/js/src/.clang-format 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/.clang-format 1970-01-01 03:00:00.000000000 +0300 -@@ -1,10 +0,0 @@ --# Clang-format style for SpiderMonkey code which is different than the standard Mozilla style. --BasedOnStyle: Mozilla --ColumnLimit: 99 --IndentWidth: 4 -- --# Ignore all comments because they aren't reflowed properly. --# We require 80-col comments and 99-col code. --CommentPragmas: "^" -- --SortIncludes: false -diff -Nrup mozilla/js/src/builtin/RegExp.cpp mozilla-OK/js/src/builtin/RegExp.cpp ---- mozilla/js/src/builtin/RegExp.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/builtin/RegExp.cpp 2022-06-16 00:04:24.707115634 +0300 -@@ -6,14 +6,17 @@ - - #include "builtin/RegExp.h" - -+#include "mozilla/Casting.h" - #include "mozilla/CheckedInt.h" - #include "mozilla/TypeTraits.h" - - #include "jscntxt.h" - - #include "frontend/TokenStream.h" --#include "irregexp/RegExpParser.h" -+#include "irregexp/RegExpAPI.h" - #include "jit/InlinableNatives.h" -+#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags -+#include "vm/NativeObject-inl.h" - #include "vm/RegExpStatics.h" - #include "vm/SelfHosting.h" - #include "vm/StringBuffer.h" -@@ -28,17 +31,25 @@ using namespace js; - using namespace js::unicode; - - using mozilla::ArrayLength; -+using mozilla::AssertedCast; - using mozilla::CheckedInt; - using mozilla::Maybe; - -+using JS::RegExpFlag; -+using JS::RegExpFlags; -+ - /* -- * ES 2017 draft rev 6a13789aa9e7c6de4e96b7d3e24d9e6eba6584ad 21.2.5.2.2 -- * steps 3, 16-25. -+ * ES 2021 draft 21.2.5.2.2: Steps 16-28 -+ * https://tc39.es/ecma262/#sec-regexpbuiltinexec - */ - bool --js::CreateRegExpMatchResult(JSContext* cx, HandleString input, const MatchPairs& matches, -+js::CreateRegExpMatchResult(JSContext* cx, -+ HandleRegExpShared re, -+ HandleString input, -+ const MatchPairs& matches, - MutableHandleValue rval) - { -+ MOZ_ASSERT(re); - MOZ_ASSERT(input); - - /* -@@ -49,23 +60,42 @@ js::CreateRegExpMatchResult(JSContext* c - * 1..pairCount-1: paren matches - * input: input string - * index: start index for the match -+ * groups: named capture groups for the match - */ - - /* Get the templateObject that defines the shape and type of the output object */ - JSObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx); -- if (!templateObject) -+ if (!templateObject) { - return false; -+ } - -+ // Step 16 - size_t numPairs = matches.length(); - MOZ_ASSERT(numPairs > 0); - -- /* Step 17. */ -+ // Steps 18-19 - RootedArrayObject arr(cx, NewDenseFullyAllocatedArrayWithTemplate(cx, numPairs, templateObject)); -- if (!arr) -+ if (!arr) { - return false; -+ } - -- /* Steps 22-24. -- * Store a Value for each pair. */ -+ // Step 24 (reordered) -+ RootedNativeObject groups(cx); -+ bool groupsInDictionaryMode = false; -+ if (re->numNamedCaptures() > 0) { -+ RootedNativeObject groupsTemplate(cx, re->getGroupsTemplate()); -+ if (groupsTemplate->inDictionaryMode()) { -+ groups = NewObjectWithGivenProto(cx, nullptr); -+ groups->setGroup(groupsTemplate->group()); -+ groupsInDictionaryMode = true; -+ } else { -+ JS_TRY_VAR_OR_RETURN_FALSE( -+ cx, groups, NativeObject::createWithTemplate(cx, gc::DefaultHeap, groupsTemplate)); -+ } -+ } -+ -+ // Steps 22-23 and 27 a-e. -+ // Store a Value for each pair. - for (size_t i = 0; i < numPairs; i++) { - const MatchPair& pair = matches[i]; - -@@ -82,6 +112,36 @@ js::CreateRegExpMatchResult(JSContext* c - } - } - -+ // Step 27 f. -+ // The groups template object stores the names of the named captures in the -+ // the order in which they are defined. The named capture indices vector -+ // stores the corresponding capture indices. If we are not in dictionary mode, -+ // we simply fill in the slots with the correct values. In dictionary mode, -+ // we have to define the properties explicitly. -+ if (!groupsInDictionaryMode) { -+ for (uint32_t i = 0; i < re->numNamedCaptures(); i++) { -+ uint32_t idx = re->getNamedCaptureIndex(i); -+ groups->setSlot(i, arr->getDenseElement(idx)); -+ } -+ } else { -+ AutoIdVector keys(cx); -+ RootedPlainObject groupsTemplate(cx, re->getGroupsTemplate()); -+ if (!GetPropertyKeys(cx, groupsTemplate, 0, &keys)) { -+ return false; -+ } -+ MOZ_ASSERT(keys.length() == re->numNamedCaptures()); -+ RootedId key(cx); -+ RootedValue val(cx); -+ for (uint32_t i = 0; i < keys.length(); i++) { -+ key = keys[i]; -+ uint32_t idx = re->getNamedCaptureIndex(i); -+ val = arr->getDenseElement(idx); -+ if (!NativeDefineProperty(cx, groups, key, val, nullptr, nullptr, JSPROP_ENUMERATE)) { -+ return false; -+ } -+ } -+ } -+ - /* Step 20 (reordered). - * Set the |index| property. (TemplateObject positions it in slot 0) */ - arr->setSlot(0, Int32Value(matches[0].start)); -@@ -90,6 +150,10 @@ js::CreateRegExpMatchResult(JSContext* c - * Set the |input| property. (TemplateObject positions it in slot 1) */ - arr->setSlot(1, StringValue(input)); - -+ // Steps 25-26 (reordered) -+ // Set the |groups| property. -+ arr->setSlot(2, groups ? ObjectValue(*groups) : UndefinedValue()); -+ - #ifdef DEBUG - RootedValue test(cx); - RootedId id(cx, NameToId(cx->names().index)); -@@ -102,7 +166,7 @@ js::CreateRegExpMatchResult(JSContext* c - MOZ_ASSERT(test == arr->getSlot(1)); - #endif - -- /* Step 25. */ -+ // Step 28. - rval.setObject(*arr); - return true; - } -@@ -123,19 +187,19 @@ CreateRegExpSearchResult(const MatchPair - * steps 3, 9-14, except 12.a.i, 12.c.i.1. - */ - static RegExpRunStatus --ExecuteRegExpImpl(JSContext* cx, RegExpStatics* res, MutableHandleRegExpShared re, -- HandleLinearString input, size_t searchIndex, MatchPairs* matches, -- size_t* endIndex) -+ExecuteRegExpImpl(JSContext* cx, -+ RegExpStatics* res, -+ MutableHandleRegExpShared re, -+ HandleLinearString input, -+ size_t searchIndex, -+ MatchPairs* matches) - { -- RegExpRunStatus status = RegExpShared::execute(cx, re, input, searchIndex, matches, endIndex); -+ RegExpRunStatus status = RegExpShared::execute(cx, re, input, searchIndex, matches); - - /* Out of spec: Update RegExpStatics. */ - if (status == RegExpRunStatus_Success && res) { -- if (matches) { -- if (!res->updateFromMatchPairs(cx, input, *matches)) -- return RegExpRunStatus_Error; -- } else { -- res->updateLazily(cx, input, re, searchIndex); -+ if (!res->updateFromMatchPairs(cx, input, *matches)) { -+ return RegExpRunStatus_Error; - } - } - return status; -@@ -154,7 +218,7 @@ js::ExecuteRegExpLegacy(JSContext* cx, R - ScopedMatchPairs matches(&cx->tempLifoAlloc()); - - RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &shared, input, *lastIndex, -- &matches, nullptr); -+ &matches); - if (status == RegExpRunStatus_Error) - return false; - -@@ -172,25 +236,25 @@ js::ExecuteRegExpLegacy(JSContext* cx, R - return true; - } - -- return CreateRegExpMatchResult(cx, input, matches, rval); -+ return CreateRegExpMatchResult(cx, shared, input, matches, rval); - } - - static bool --CheckPatternSyntaxSlow(JSContext* cx, HandleAtom pattern, RegExpFlag flags) -+CheckPatternSyntaxSlow(JSContext* cx, HandleAtom pattern, RegExpFlags flags) - { - CompileOptions options(cx); - frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); -- return irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern, -- flags & UnicodeFlag); -+ return irregexp::CheckPatternSyntax(cx, dummyTokenStream, pattern, flags); - } - - static RegExpShared* --CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags) -+CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlags flags) - { - // If we already have a RegExpShared for this pattern/flags, we can - // avoid the much slower CheckPatternSyntaxSlow call. - -- if (RegExpShared* shared = cx->zone()->regExps.maybeGet(pattern, flags)) { -+ RootedRegExpShared shared(cx, cx->zone()->regExps.maybeGet(pattern, flags)); -+ if (shared) { - #ifdef DEBUG - // Assert the pattern is valid. - if (!CheckPatternSyntaxSlow(cx, pattern, flags)) { -@@ -240,7 +304,7 @@ RegExpInitializeIgnoringLastIndex(JSCont - } - - /* Step 3. */ -- RegExpFlag flags = RegExpFlag(0); -+ RegExpFlags flags = RegExpFlag::NoFlags; - if (!flagsValue.isUndefined()) { - /* Step 4. */ - RootedString flagStr(cx, ToString(cx, flagsValue)); -@@ -343,12 +407,11 @@ regexp_compile_impl(JSContext* cx, const - } - - // Beware! |patternObj| might be a proxy into another compartment, so -- // don't assume |patternObj.is()|. For the same reason, -- // don't reuse the RegExpShared below. -+ // don't assume |patternObj.is()|. - RootedObject patternObj(cx, &patternValue.toObject()); - - RootedAtom sourceAtom(cx); -- RegExpFlag flags; -+ RegExpFlags flags = RegExpFlag::NoFlags; - { - // Step 3b. - RegExpShared* shared = RegExpToShared(cx, patternObj); -@@ -442,7 +505,7 @@ js::regexp_construct(JSContext* cx, unsi - RootedObject patternObj(cx, &patternValue.toObject()); - - RootedAtom sourceAtom(cx); -- RegExpFlag flags; -+ RegExpFlags flags; - RootedRegExpShared shared(cx); - { - // Step 4.a. -@@ -472,7 +535,7 @@ js::regexp_construct(JSContext* cx, unsi - // Step 8. - if (args.hasDefined(1)) { - // Step 4.c / 21.2.3.2.2 RegExpInitialize step 4. -- RegExpFlag flagsArg = RegExpFlag(0); -+ RegExpFlags flagsArg = RegExpFlag::NoFlags; - RootedString flagStr(cx, ToString(cx, args[1])); - if (!flagStr) - return false; -@@ -483,7 +546,7 @@ js::regexp_construct(JSContext* cx, unsi - if (flags != flagsArg) - shared = nullptr; - -- if (!(flags & UnicodeFlag) && flagsArg & UnicodeFlag) { -+ if (!flags.unicode() && flagsArg.unicode()) { - // Have to check syntax again when adding 'u' flag. - - // ES 2017 draft rev 9b49a888e9dfe2667008a01b2754c3662059ae56 -@@ -562,7 +625,7 @@ js::regexp_construct_raw_flags(JSContext - return false; - - // Step 4.c. -- int32_t flags = int32_t(args[1].toNumber()); -+ RegExpFlags flags = AssertedCast(int32_t(args[1].toNumber())); - - // Step 7. - RegExpObject* regexp = RegExpAlloc(cx, GenericObject); -@@ -570,7 +633,7 @@ js::regexp_construct_raw_flags(JSContext - return false; - - // Step 8. -- regexp->initAndZeroLastIndex(sourceAtom, RegExpFlag(flags), cx); -+ regexp->initAndZeroLastIndex(sourceAtom, flags, cx); - args.rval().setObject(*regexp); - return true; - } -@@ -702,6 +765,33 @@ regexp_source(JSContext* cx, unsigned ar - return CallNonGenericMethod(cx, args); - } - -+// ES 2018 dotAll -+MOZ_ALWAYS_INLINE bool -+regexp_dotAll_impl(JSContext* cx, const CallArgs& args) -+{ -+ MOZ_ASSERT(IsRegExpObject(args.thisv())); -+ -+ // Steps 4-6. -+ RegExpObject* reObj = &args.thisv().toObject().as(); -+ args.rval().setBoolean(reObj->dotAll()); -+ return true; -+} -+ -+bool -+js::regexp_dotAll(JSContext* cx, unsigned argc, JS::Value* vp) -+{ -+ CallArgs args = CallArgsFromVp(argc, vp); -+ -+ // Step 3.a. -+ if (IsRegExpPrototype(args.thisv())) { -+ args.rval().setUndefined(); -+ return true; -+ } -+ -+ // Steps 1-3. -+ return CallNonGenericMethod(cx, args); -+} -+ - // ES 2017 draft 21.2.5.12. - MOZ_ALWAYS_INLINE bool - regexp_sticky_impl(JSContext* cx, const CallArgs& args) -@@ -764,6 +854,7 @@ const JSPropertySpec js::regexp_properti - JS_PSG("source", regexp_source, 0), - JS_PSG("sticky", regexp_sticky, 0), - JS_PSG("unicode", regexp_unicode, 0), -+ JS_PSG("dotAll", regexp_dotAll, 0), - JS_PS_END - }; - -@@ -776,6 +867,7 @@ const JSFunctionSpec js::regexp_methods[ - JS_SELF_HOSTED_FN("exec", "RegExp_prototype_Exec", 1,0), - JS_SELF_HOSTED_FN("test", "RegExpTest" , 1,0), - JS_SELF_HOSTED_SYM_FN(match, "RegExpMatch", 1,0), -+ JS_SELF_HOSTED_SYM_FN(matchAll, "RegExpMatchAll", 1, 0), - JS_SELF_HOSTED_SYM_FN(replace, "RegExpReplace", 2,0), - JS_SELF_HOSTED_SYM_FN(search, "RegExpSearch", 1,0), - JS_SELF_HOSTED_SYM_FN(split, "RegExpSplit", 2,0), -@@ -910,7 +1002,7 @@ IsTrailSurrogateWithLeadSurrogate(Handle - */ - static RegExpRunStatus - ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string, int32_t lastIndex, -- MatchPairs* matches, size_t* endIndex) -+ MatchPairs* matches) - { - /* - * WARNING: Despite the presence of spec step comment numbers, this -@@ -967,7 +1059,7 @@ ExecuteRegExp(JSContext* cx, HandleObjec - } - - /* Steps 3, 11-14, except 12.a.i, 12.c.i.1. */ -- RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &re, input, lastIndex, matches, endIndex); -+ RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &re, input, lastIndex, matches); - if (status == RegExpRunStatus_Error) - return RegExpRunStatus_Error; - -@@ -988,7 +1080,7 @@ RegExpMatcherImpl(JSContext* cx, HandleO - ScopedMatchPairs matches(&cx->tempLifoAlloc()); - - /* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */ -- RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr); -+ RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches); - if (status == RegExpRunStatus_Error) - return false; - -@@ -999,7 +1091,8 @@ RegExpMatcherImpl(JSContext* cx, HandleO - } - - /* Steps 16-25 */ -- return CreateRegExpMatchResult(cx, string, matches, rval); -+ RootedRegExpShared shared(cx, regexp->as().getShared()); -+ return CreateRegExpMatchResult(cx, shared, string, matches, rval); - } - - /* -@@ -1038,8 +1131,11 @@ js::RegExpMatcherRaw(JSContext* cx, Hand - - // The MatchPairs will always be passed in, but RegExp execution was - // successful only if the pairs have actually been filled in. -- if (maybeMatches && maybeMatches->pairsRaw()[0] >= 0) -- return CreateRegExpMatchResult(cx, input, *maybeMatches, output); -+ if (maybeMatches && maybeMatches->pairsRaw()[0] >= 0) { -+ RootedRegExpShared shared(cx, regexp->as().getShared()); -+ return CreateRegExpMatchResult(cx, shared, input, *maybeMatches, output); -+ } -+ - return RegExpMatcherImpl(cx, regexp, input, lastIndex, output); - } - -@@ -1057,7 +1153,7 @@ RegExpSearcherImpl(JSContext* cx, Handle - ScopedMatchPairs matches(&cx->tempLifoAlloc()); - - /* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */ -- RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr); -+ RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches); - if (status == RegExpRunStatus_Error) - return false; - -@@ -1139,15 +1235,15 @@ js::RegExpTester(JSContext* cx, unsigned - MOZ_ALWAYS_TRUE(ToInt32(cx, args[2], &lastIndex)); - - /* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */ -- size_t endIndex = 0; -- RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, nullptr, &endIndex); -+ ScopedMatchPairs matches(&cx->tempLifoAlloc()); -+ RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches); - - if (status == RegExpRunStatus_Error) - return false; - - if (status == RegExpRunStatus_Success) { -- MOZ_ASSERT(endIndex <= INT32_MAX); -- args.rval().setInt32(int32_t(endIndex)); -+ int32_t endIndex = matches[0].limit; -+ args.rval().setInt32(endIndex); - } else { - args.rval().setInt32(-1); - } -@@ -1164,12 +1260,11 @@ js::RegExpTesterRaw(JSContext* cx, Handl - { - MOZ_ASSERT(lastIndex >= 0); - -- size_t endIndexTmp = 0; -- RegExpRunStatus status = ExecuteRegExp(cx, regexp, input, lastIndex, nullptr, &endIndexTmp); -+ ScopedMatchPairs matches(&cx->tempLifoAlloc()); -+ RegExpRunStatus status = ExecuteRegExp(cx, regexp, input, lastIndex, &matches); - - if (status == RegExpRunStatus_Success) { -- MOZ_ASSERT(endIndexTmp <= INT32_MAX); -- *endIndex = int32_t(endIndexTmp); -+ *endIndex = matches[0].limit; - return true; - } - if (status == RegExpRunStatus_Success_NotFound) { -@@ -1212,13 +1307,21 @@ GetParen(JSLinearString* matched, const - out->init(&captureLinear, 0, captureLinear.length()); - } - --template -+template - static bool --InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position, size_t tailPos, -- Handle captures, JSLinearString* replacement, -- const CharT* replacementBegin, const CharT* currentDollar, -+InterpretDollar(JSLinearString* matched, -+ JSLinearString* string, -+ size_t position, -+ size_t tailPos, -+ Handle captures, -+ Handle namedCaptures, -+ JSLinearString* replacement, -+ const CharT* replacementBegin, -+ const CharT* currentDollar, - const CharT* replacementEnd, -- JSSubString* out, size_t* skip) -+ JSSubString* out, -+ size_t* skip, -+ uint32_t* currentNamedCapture) - { - MOZ_ASSERT(*currentDollar == '$'); - -@@ -1226,13 +1329,14 @@ InterpretDollar(JSLinearString* matched, - if (currentDollar + 1 >= replacementEnd) - return false; - -- /* ES 2016 draft Mar 25, 2016 Table 46. */ -+ // ES 2021 Table 52 -+ // https://tc39.es/ecma262/#table-45 (sic) - char16_t c = currentDollar[1]; - if (JS7_ISDEC(c)) { - /* $n, $nn */ - unsigned num = JS7_UNDEC(c); - if (num > captures.length()) { -- // The result is implementation-defined, do not substitute. -+ // The result is implementation-defined. Do not substitute. - return false; - } - -@@ -1251,8 +1355,7 @@ InterpretDollar(JSLinearString* matched, - } - - if (num == 0) { -- // The result is implementation-defined. -- // Do not substitute. -+ // The result is implementation-defined. Do not substitute. - return false; - } - -@@ -1264,7 +1367,35 @@ InterpretDollar(JSLinearString* matched, - return true; - } - -- *skip = 2; -+ // '$<': Named Captures -+ if (c == '<') { -+ // Step 1. -+ if (namedCaptures.length() == 0) { -+ return false; -+ } -+ -+ // Step 2.b -+ const CharT* nameStart = currentDollar + 2; -+ const CharT* nameEnd = js_strchr_limit(nameStart, '>', replacementEnd); -+ -+ // Step 2.c -+ if (!nameEnd) { -+ return false; -+ } -+ -+ // Step 2.d -+ // We precompute named capture replacements in InitNamedCaptures. -+ // They are stored in the order in which we will need them, so here -+ // we can just take the next one in the list. -+ size_t nameLength = nameEnd - nameStart; -+ *skip = nameLength + 3; // $<...> -+ -+ // Steps 2.d.iii-iv -+ GetParen(matched, namedCaptures[*currentNamedCapture], out); -+ *currentNamedCapture += 1; -+ return true; -+ } -+ - switch (c) { - default: - return false; -@@ -1288,14 +1419,23 @@ InterpretDollar(JSLinearString* matched, - out->init(string, tailPos, string->length() - tailPos); - break; - } -+ -+ *skip = 2; - return true; - } - --template -+template - static bool --FindReplaceLengthString(JSContext* cx, HandleLinearString matched, HandleLinearString string, -- size_t position, size_t tailPos, Handle captures, -- HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep) -+FindReplaceLengthString(JSContext* cx, -+ HandleLinearString matched, -+ HandleLinearString string, -+ size_t position, -+ size_t tailPos, -+ Handle captures, -+ Handle namedCaptures, -+ HandleLinearString replacement, -+ size_t firstDollarIndex, -+ size_t* sizep) - { - CheckedInt replen = replacement->length(); - -@@ -1304,12 +1444,23 @@ FindReplaceLengthString(JSContext* cx, H - const CharT* replacementBegin = replacement->chars(nogc); - const CharT* currentDollar = replacementBegin + firstDollarIndex; - const CharT* replacementEnd = replacementBegin + replacement->length(); -+ uint32_t currentNamedCapture = 0; - do { - JSSubString sub; - size_t skip; -- if (InterpretDollar(matched, string, position, tailPos, captures, replacement, -- replacementBegin, currentDollar, replacementEnd, &sub, &skip)) -- { -+ if (InterpretDollar(matched, -+ string, -+ position, -+ tailPos, -+ captures, -+ namedCaptures, -+ replacement, -+ replacementBegin, -+ currentDollar, -+ replacementEnd, -+ &sub, -+ &skip, -+ ¤tNamedCapture)) { - if (sub.length > skip) - replen += sub.length - skip; - else -@@ -1332,15 +1483,37 @@ FindReplaceLengthString(JSContext* cx, H - } - - static bool --FindReplaceLength(JSContext* cx, HandleLinearString matched, HandleLinearString string, -- size_t position, size_t tailPos, Handle captures, -- HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep) --{ -- return replacement->hasLatin1Chars() -- ? FindReplaceLengthString(cx, matched, string, position, tailPos, captures, -- replacement, firstDollarIndex, sizep) -- : FindReplaceLengthString(cx, matched, string, position, tailPos, captures, -- replacement, firstDollarIndex, sizep); -+FindReplaceLength(JSContext* cx, -+ HandleLinearString matched, -+ HandleLinearString string, -+ size_t position, -+ size_t tailPos, -+ Handle captures, -+ Handle namedCaptures, -+ HandleLinearString replacement, -+ size_t firstDollarIndex, -+ size_t* sizep) -+{ -+ return replacement->hasLatin1Chars() ? FindReplaceLengthString(cx, -+ matched, -+ string, -+ position, -+ tailPos, -+ captures, -+ namedCaptures, -+ replacement, -+ firstDollarIndex, -+ sizep) -+ : FindReplaceLengthString(cx, -+ matched, -+ string, -+ position, -+ tailPos, -+ captures, -+ namedCaptures, -+ replacement, -+ firstDollarIndex, -+ sizep); - } - - /* -@@ -1348,11 +1521,17 @@ FindReplaceLength(JSContext* cx, HandleL - * derived from FindReplaceLength), and has been inflated to TwoByte if - * necessary. - */ --template -+template - static void --DoReplace(HandleLinearString matched, HandleLinearString string, -- size_t position, size_t tailPos, Handle captures, -- HandleLinearString replacement, size_t firstDollarIndex, StringBuffer &sb) -+DoReplace(HandleLinearString matched, -+ HandleLinearString string, -+ size_t position, -+ size_t tailPos, -+ Handle captures, -+ Handle namedCaptures, -+ HandleLinearString replacement, -+ size_t firstDollarIndex, -+ StringBuffer& sb) - { - JS::AutoCheckCannotGC nogc; - const CharT* replacementBegin = replacement->chars(nogc); -@@ -1361,6 +1540,7 @@ DoReplace(HandleLinearString matched, Ha - MOZ_ASSERT(firstDollarIndex < replacement->length()); - const CharT* currentDollar = replacementBegin + firstDollarIndex; - const CharT* replacementEnd = replacementBegin + replacement->length(); -+ uint32_t currentNamedCapture = 0; - do { - /* Move one of the constant portions of the replacement value. */ - size_t len = currentDollar - currentChar; -@@ -1369,9 +1549,19 @@ DoReplace(HandleLinearString matched, Ha - - JSSubString sub; - size_t skip; -- if (InterpretDollar(matched, string, position, tailPos, captures, replacement, -- replacementBegin, currentDollar, replacementEnd, &sub, &skip)) -- { -+ if (InterpretDollar(matched, -+ string, -+ position, -+ tailPos, -+ captures, -+ namedCaptures, -+ replacement, -+ replacementBegin, -+ currentDollar, -+ replacementEnd, -+ &sub, -+ &skip, -+ ¤tNamedCapture)) { - sb.infallibleAppendSubstring(sub.base, sub.offset, sub.length); - currentChar += skip; - currentDollar += skip; -@@ -1384,9 +1574,120 @@ DoReplace(HandleLinearString matched, Ha - sb.infallibleAppend(currentChar, replacement->length() - (currentChar - replacementBegin)); - } - -+/* -+ * This function finds the list of named captures of the form -+ * "$" in a replacement string and converts them into jsids, for -+ * use in InitNamedReplacements. -+ */ -+template -+static bool CollectNames(JSContext* cx, HandleLinearString replacement, -+ size_t firstDollarIndex, -+ MutableHandle> names) { -+ JS::AutoCheckCannotGC nogc; -+ MOZ_ASSERT(firstDollarIndex < replacement->length()); -+ -+ const CharT* replacementBegin = replacement->chars(nogc); -+ const CharT* currentDollar = replacementBegin + firstDollarIndex; -+ const CharT* replacementEnd = replacementBegin + replacement->length(); -+ -+ // https://tc39.es/ecma262/#table-45, "$<" section -+ while (currentDollar && currentDollar + 1 < replacementEnd) { -+ if (currentDollar[1] == '<') { -+ // Step 2.b -+ const CharT* nameStart = currentDollar + 2; -+ const CharT* nameEnd = js_strchr_limit(nameStart, '>', replacementEnd); -+ -+ // Step 2.c -+ if (!nameEnd) { -+ return true; -+ } -+ -+ // Step 2.d.i -+ size_t nameLength = nameEnd - nameStart; -+ JSAtom* atom = AtomizeChars(cx, nameStart, nameLength); -+ if (!atom || !names.append(AtomToId(atom))) { -+ return false; -+ } -+ currentDollar = nameEnd + 1; -+ } else { -+ currentDollar += 2; -+ } -+ currentDollar = js_strchr_limit(currentDollar, '$', replacementEnd); -+ } -+ return true; -+} -+ -+/* -+ * When replacing named captures, the spec requires us to perform -+ * `Get(match.groups, name)` for each "$". These `Get`s can be -+ * script-visible; for example, RegExp can be extended with an `exec` -+ * method that wraps `groups` in a proxy. To make sure that we do the -+ * right thing, if a regexp has named captures, we find the named -+ * capture replacements before beginning the actual replacement. -+ * This guarantees that we will call GetProperty once and only once for -+ * each "$" in the replacement string, in the correct order. -+ * -+ * This function precomputes the results of step 2 of the '$<' case -+ * here: https://tc39.es/proposal-regexp-named-groups/#table-45, so -+ * that when we need to access the nth named capture in InterpretDollar, -+ * we can just use the nth value stored in namedCaptures. -+ */ -+static bool InitNamedCaptures(JSContext* cx, HandleLinearString replacement, -+ HandleObject groups, size_t firstDollarIndex, -+ MutableHandle namedCaptures) { -+ Rooted> names(cx, GCVector(cx)); -+ if (replacement->hasLatin1Chars()) { -+ if (!CollectNames(cx, replacement, firstDollarIndex, &names)) { -+ return false; -+ } -+ } else { -+ if (!CollectNames(cx, replacement, firstDollarIndex, &names)) { -+ return false; -+ } -+ } -+ -+ // https://tc39.es/ecma262/#table-45, "$<" section -+ RootedId id(cx); -+ RootedValue capture(cx); -+ for (uint32_t i = 0; i < names.length(); i++) { -+ // Step 2.d.i -+ id = names[i]; -+ -+ // Step 2.d.ii -+ if (!GetProperty(cx, groups, groups, id, &capture)) { -+ return false; -+ } -+ -+ // Step 2.d.iii -+ if (capture.isUndefined()) { -+ if (!namedCaptures.append(capture)) { -+ return false; -+ } -+ } else { -+ // Step 2.d.iv -+ JSString* str = ToString(cx, capture); -+ if (!str) { -+ return false; -+ } -+ JSLinearString* linear = str->ensureLinear(cx); -+ if (!linear) { -+ return false; -+ } -+ if (!namedCaptures.append(StringValue(linear))) { -+ return false; -+ } -+ } -+ } -+ -+ return true; -+} -+ - static bool --NeedTwoBytes(HandleLinearString string, HandleLinearString replacement, -- HandleLinearString matched, Handle captures) -+NeedTwoBytes(HandleLinearString string, -+ HandleLinearString replacement, -+ HandleLinearString matched, -+ Handle captures, -+ Handle namedCaptures) - { - if (string->hasTwoByteChars()) - return true; -@@ -1395,22 +1696,36 @@ NeedTwoBytes(HandleLinearString string, - if (matched->hasTwoByteChars()) - return true; - -- for (size_t i = 0, len = captures.length(); i < len; i++) { -- const Value& capture = captures[i]; -+ for (const Value& capture : captures) { - if (capture.isUndefined()) - continue; - if (capture.toString()->hasTwoByteChars()) - return true; - } - -+ for (const Value& capture : namedCaptures) { -+ if (capture.isUndefined()) { -+ continue; -+ } -+ if (capture.toString()->hasTwoByteChars()) { -+ return true; -+ } -+ } -+ - return false; - } - --/* ES 2016 draft Mar 25, 2016 21.1.3.14.1. */ -+/* ES 2021 21.1.3.17.1 */ -+// https://tc39.es/ecma262/#sec-getsubstitution - bool --js::RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLinearString string, -- size_t position, HandleLinearString replacement, -- size_t firstDollarIndex, MutableHandleValue rval) -+js::RegExpGetSubstitution(JSContext* cx, -+ HandleArrayObject matchResult, -+ HandleLinearString string, -+ size_t position, -+ HandleLinearString replacement, -+ size_t firstDollarIndex, -+ HandleValue groups, -+ MutableHandleValue rval) - { - MOZ_ASSERT(firstDollarIndex < replacement->length()); - -@@ -1454,6 +1769,16 @@ js::RegExpGetSubstitution(JSContext* cx, - captures.infallibleAppend(StringValue(captureLinear)); - } - -+ Rooted namedCaptures(cx, CapturesVector(cx)); -+ if (groups.isObject()) { -+ RootedObject groupsObj(cx, &groups.toObject()); -+ if (!InitNamedCaptures(cx, replacement, groupsObj, firstDollarIndex, &namedCaptures)) { -+ return false; -+ } -+ } else { -+ MOZ_ASSERT(groups.isUndefined()); -+ } -+ - // Step 8 (skipped). - - // Step 9. -@@ -1468,27 +1793,36 @@ js::RegExpGetSubstitution(JSContext* cx, - - // Step 11. - size_t reserveLength; -- if (!FindReplaceLength(cx, matched, string, position, tailPos, captures, replacement, -- firstDollarIndex, &reserveLength)) -- { -+ if (!FindReplaceLength(cx, -+ matched, -+ string, -+ position, -+ tailPos, -+ captures, -+ namedCaptures, -+ replacement, -+ firstDollarIndex, -+ &reserveLength)) { - return false; - } - - StringBuffer result(cx); -- if (NeedTwoBytes(string, replacement, matched, captures)) { -- if (!result.ensureTwoByteChars()) -+ if (NeedTwoBytes(string, replacement, matched, captures, namedCaptures)) { -+ if (!result.ensureTwoByteChars()) { - return false; -+ } - } - -- if (!result.reserve(reserveLength)) -+ if (!result.reserve(reserveLength)) { - return false; -+ } - - if (replacement->hasLatin1Chars()) { - DoReplace(matched, string, position, tailPos, captures, -- replacement, firstDollarIndex, result); -+ namedCaptures, replacement, firstDollarIndex, result); - } else { - DoReplace(matched, string, position, tailPos, captures, -- replacement, firstDollarIndex, result); -+ namedCaptures, replacement, firstDollarIndex, result); - } - - // Step 12. -@@ -1623,6 +1957,13 @@ js::RegExpPrototypeOptimizableRaw(JSCont - if (unicodeGetter != regexp_unicode) - return false; - -+ JSNative dotAllGetter; -+ if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().dotAll), &dotAllGetter)) -+ return false; -+ -+ if (dotAllGetter != regexp_dotAll) -+ return false; -+ - // Check if @@match, @@search, and exec are own data properties, - // those values should be tested in selfhosted JS. - bool has = false; -diff -Nrup mozilla/js/src/builtin/RegExp.h mozilla-OK/js/src/builtin/RegExp.h ---- mozilla/js/src/builtin/RegExp.h 2021-10-26 19:49:54.000000000 +0300 -+++ mozilla-OK/js/src/builtin/RegExp.h 2022-06-15 23:02:24.231330506 +0300 -@@ -33,7 +33,10 @@ ExecuteRegExpLegacy(JSContext* cx, RegEx - - /* Translation from MatchPairs to a JS array in regexp_exec()'s output format. */ - MOZ_MUST_USE bool --CreateRegExpMatchResult(JSContext* cx, HandleString input, const MatchPairs& matches, -+CreateRegExpMatchResult(JSContext* cx, -+ HandleRegExpShared re, -+ HandleString input, -+ const MatchPairs& matches, - MutableHandleValue rval); - - extern MOZ_MUST_USE bool -@@ -100,7 +103,7 @@ RegExpInstanceOptimizableRaw(JSContext* - extern MOZ_MUST_USE bool - RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLinearString string, - size_t position, HandleLinearString replacement, size_t firstDollarIndex, -- MutableHandleValue rval); -+ HandleValue namedCaptures, MutableHandleValue rval); - - extern MOZ_MUST_USE bool - GetFirstDollarIndex(JSContext* cx, unsigned argc, Value* vp); -@@ -129,6 +132,8 @@ extern MOZ_MUST_USE bool - regexp_sticky(JSContext* cx, unsigned argc, JS::Value* vp); - extern MOZ_MUST_USE bool - regexp_unicode(JSContext* cx, unsigned argc, JS::Value* vp); -+extern MOZ_MUST_USE bool -+regexp_dotAll(JSContext* cx, unsigned argc, JS::Value* vp); - - } /* namespace js */ - -diff -Nrup mozilla/js/src/builtin/RegExp.js mozilla-OK/js/src/builtin/RegExp.js ---- mozilla/js/src/builtin/RegExp.js 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/builtin/RegExp.js 2022-06-16 00:04:51.608932958 +0300 -@@ -2,7 +2,8 @@ - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - --// ES6 draft rev34 (2015/02/20) 21.2.5.3 get RegExp.prototype.flags -+// ECMAScript 2020 draft (2020/03/12) 21.2.5.4 get RegExp.prototype.flags -+// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags - function RegExpFlagsGetter() { - // Steps 1-2. - var R = this; -@@ -12,27 +13,31 @@ function RegExpFlagsGetter() { - // Step 3. - var result = ""; - -- // Steps 4-6. -+ // Steps 4-5. - if (R.global) - result += "g"; - -- // Steps 7-9. -+ // Steps 6-7. - if (R.ignoreCase) - result += "i"; - -- // Steps 10-12. -+ // Steps 8-9. - if (R.multiline) - result += "m"; - -- // Steps 13-15. -+ // Steps 10-11. -+ if (R.dotAll) -+ result += "s"; -+ -+ // Steps 12-13. - if (R.unicode) - result += "u"; - -- // Steps 16-18. -+ // Steps 14-15. - if (R.sticky) - result += "y"; - -- // Step 19. -+ // Step 16. - return result; - } - _SetCanonicalName(RegExpFlagsGetter, "get flags"); -@@ -225,6 +230,7 @@ function RegExpGlobalMatchOpt(rx, S, ful - // * global - // * ignoreCase - // * multiline -+// * dotAll - // * sticky - // * unicode - // * exec -@@ -389,7 +395,7 @@ function RegExpReplaceSlowPath(rx, S, le - - var n, capN, replacement; - if (functionalReplace || firstDollarIndex !== -1) { -- // Steps 14.g-j. -+ // Steps 14.g-k. - replacement = RegExpGetComplexReplacement(result, matched, S, position, - nCaptures, replaceValue, - functionalReplace, firstDollarIndex); -@@ -404,16 +410,22 @@ function RegExpReplaceSlowPath(rx, S, le - if (capN !== undefined) - ToString(capN); - } -+ // Step 14.j, 14.l., GetSubstitution Step 11. -+ // We don't need namedCaptures, but ToObject is visible to script. -+ var namedCaptures = result.groups; -+ if (namedCaptures !== undefined) -+ ToObject(namedCaptures); -+ - replacement = replaceValue; - } - -- // Step 14.l. -+ // Step 14.m. - if (position >= nextSourcePosition) { -- // Step 14.l.ii. -+ // Step 14.m.ii. - accumulatedResult += Substring(S, nextSourcePosition, - position - nextSourcePosition) + replacement; - -- // Step 14.l.iii. -+ // Step 14.m.iii. - nextSourcePosition = position + matchLength; - } - } -@@ -426,8 +438,9 @@ function RegExpReplaceSlowPath(rx, S, le - return accumulatedResult + Substring(S, nextSourcePosition, lengthS - nextSourcePosition); - } - --// ES 2017 draft rev 03bfda119d060aca4099d2b77cf43f6d4f11cfa2 21.2.5.8 --// steps 14.g-k. -+// ES 2021 draft 21.2.5.10 -+// https://tc39.es/ecma262/#sec-regexp.prototype-@@replace -+// steps 14.g-l. - // Calculates functional/substitution replacement from match result. - // Used in the following functions: - // * RegExpReplaceSlowPath -@@ -439,7 +452,7 @@ function RegExpGetComplexReplacement(res - var captures = new_List(); - var capturesLength = 0; - -- // Step 14.j.i (reordered). -+ // Step 14.k.i (reordered). - _DefineDataProperty(captures, capturesLength++, matched); - - // Step 14.g, 14.i, 14.i.iv. -@@ -456,34 +469,46 @@ function RegExpGetComplexReplacement(res - } - - // Step 14.j. -+ var namedCaptures = result.groups; -+ -+ // Step 14.k. - if (functionalReplace) { - // For `nCaptures` <= 4 case, call `replaceValue` directly, otherwise - // use `std_Function_apply` with all arguments stored in `captures`. -- switch (nCaptures) { -- case 0: -- return ToString(replaceValue(SPREAD(captures, 1), position, S)); -- case 1: -- return ToString(replaceValue(SPREAD(captures, 2), position, S)); -- case 2: -- return ToString(replaceValue(SPREAD(captures, 3), position, S)); -- case 3: -- return ToString(replaceValue(SPREAD(captures, 4), position, S)); -- case 4: -- return ToString(replaceValue(SPREAD(captures, 5), position, S)); -- default: -- // Steps 14.j.ii-v. -- _DefineDataProperty(captures, capturesLength++, position); -- _DefineDataProperty(captures, capturesLength++, S); -- return ToString(callFunction(std_Function_apply, replaceValue, undefined, captures)); -+ if (namedCaptures === undefined) { -+ switch (nCaptures) { -+ case 0: -+ return ToString(replaceValue(SPREAD(captures, 1), position, S)); -+ case 1: -+ return ToString(replaceValue(SPREAD(captures, 2), position, S)); -+ case 2: -+ return ToString(replaceValue(SPREAD(captures, 3), position, S)); -+ case 3: -+ return ToString(replaceValue(SPREAD(captures, 4), position, S)); -+ case 4: -+ return ToString(replaceValue(SPREAD(captures, 5), position, S)); -+ } - } -+ // Steps 14.k.ii-v. -+ _DefineDataProperty(captures, capturesLength++, position); -+ _DefineDataProperty(captures, capturesLength++, S); -+ if (namedCaptures !== undefined) { -+ _DefineDataProperty(captures, capturesLength++, namedCaptures); -+ } -+ return ToString(callFunction(std_Function_apply, replaceValue, undefined, captures)); - } - -- // Steps 14.k.i. -- return RegExpGetSubstitution(captures, S, position, replaceValue, firstDollarIndex); -+ // Step 14.l. -+ if (namedCaptures !== undefined) { -+ namedCaptures = ToObject(namedCaptures); -+ } -+ return RegExpGetSubstitution(captures, S, position, replaceValue, firstDollarIndex, -+ namedCaptures); - } - --// ES 2017 draft rev 03bfda119d060aca4099d2b77cf43f6d4f11cfa2 21.2.5.8 --// steps 14.g-j. -+// ES 2021 draft 21.2.5.10 -+// https://tc39.es/ecma262/#sec-regexp.prototype-@@replace -+// steps 14.g-k. - // Calculates functional replacement from match result. - // Used in the following functions: - // * RegExpGlobalReplaceOptFunc -@@ -495,20 +520,25 @@ function RegExpGetFunctionalReplacement( - assert(result.length >= 1, "RegExpMatcher doesn't return an empty array"); - var nCaptures = result.length - 1; - -- switch (nCaptures) { -- case 0: -- return ToString(replaceValue(SPREAD(result, 1), position, S)); -- case 1: -- return ToString(replaceValue(SPREAD(result, 2), position, S)); -- case 2: -- return ToString(replaceValue(SPREAD(result, 3), position, S)); -- case 3: -- return ToString(replaceValue(SPREAD(result, 4), position, S)); -- case 4: -- return ToString(replaceValue(SPREAD(result, 5), position, S)); -+ // Step 14.j (reordered) -+ var namedCaptures = result.groups; -+ -+ if (namedCaptures === undefined) { -+ switch (nCaptures) { -+ case 0: -+ return ToString(replaceValue(SPREAD(result, 1), position, S)); -+ case 1: -+ return ToString(replaceValue(SPREAD(result, 2), position, S)); -+ case 2: -+ return ToString(replaceValue(SPREAD(result, 3), position, S)); -+ case 3: -+ return ToString(replaceValue(SPREAD(result, 4), position, S)); -+ case 4: -+ return ToString(replaceValue(SPREAD(result, 5), position, S)); -+ } - } - -- // Steps 14.g-i, 14.j.i-ii. -+ // Steps 14.g-i, 14.k.i-ii. - var captures = new_List(); - for (var n = 0; n <= nCaptures; n++) { - assert(typeof result[n] === "string" || result[n] === undefined, -@@ -516,11 +546,16 @@ function RegExpGetFunctionalReplacement( - _DefineDataProperty(captures, n, result[n]); - } - -- // Step 14.j.iii. -+ // Step 14.k.iii. - _DefineDataProperty(captures, nCaptures + 1, position); - _DefineDataProperty(captures, nCaptures + 2, S); - -- // Steps 14.j.iv-v. -+ // Step 14.k.iv. -+ if (namedCaptures !== undefined) { -+ _DefineDataProperty(captures, nCaptures + 3, namedCaptures); -+ } -+ -+ // Steps 14.k.v-vi. - return ToString(callFunction(std_Function_apply, replaceValue, undefined, captures)); - } - -@@ -975,7 +1010,7 @@ function RegExpExec(R, S, forTest) { - var result = callContentFunction(exec, R, S); - - // Step 5.c. -- if (typeof result !== "object") -+ if (result !== null && !IsObject(result)) - ThrowTypeError(JSMSG_EXEC_NOT_OBJORNULL); - - // Step 5.d. -@@ -1095,3 +1130,235 @@ function RegExpSpecies() { - return this; - } - _SetCanonicalName(RegExpSpecies, "get [Symbol.species]"); -+ -+function IsRegExpMatchAllOptimizable(rx, C) { -+ if (!IsRegExpObject(rx)) -+ return false; -+ -+ var RegExpCtor = GetBuiltinConstructor("RegExp"); -+ if (C !== RegExpCtor) -+ return false; -+ -+ var RegExpProto = RegExpCtor.prototype; -+ return RegExpPrototypeOptimizable(RegExpProto) && -+ RegExpInstanceOptimizable(rx, RegExpProto); -+} -+ -+// String.prototype.matchAll proposal. -+// -+// RegExp.prototype [ @@matchAll ] ( string ) -+function RegExpMatchAll(string) { -+ // Step 1. -+ var rx = this; -+ -+ // Step 2. -+ if (!IsObject(rx)) -+ ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, rx === null ? "null" : typeof rx); -+ -+ // Step 3. -+ var str = ToString(string); -+ -+ // Step 4. -+ var C = SpeciesConstructor(rx, GetBuiltinConstructor("RegExp")); -+ -+ var source, flags, matcher, lastIndex; -+ if (IsRegExpMatchAllOptimizable(rx, C)) { -+ // Step 5, 9-12. -+ source = UnsafeGetStringFromReservedSlot(rx, REGEXP_SOURCE_SLOT); -+ flags = UnsafeGetInt32FromReservedSlot(rx, REGEXP_FLAGS_SLOT); -+ -+ // Step 6. -+ matcher = rx; -+ -+ // Step 7. -+ lastIndex = ToLength(rx.lastIndex); -+ -+ // Step 8 (not applicable for the optimized path). -+ } else { -+ // Step 5. -+ source = ""; -+ flags = ToString(rx.flags); -+ -+ // Step 6. -+ matcher = new C(rx, flags); -+ -+ // Steps 7-8. -+ matcher.lastIndex = ToLength(rx.lastIndex); -+ -+ // Steps 9-12. -+ flags = (callFunction(std_String_includes, flags, "g") ? REGEXP_GLOBAL_FLAG : 0); -+// XXXX (callFunction(std_String_includes, flags, "u") ? REGEXP_UNICODE_FLAG : 0); -+ -+ // Take the non-optimized path. -+ lastIndex = REGEXP_STRING_ITERATOR_LASTINDEX_SLOW; -+ } -+ -+ // Step 13. -+ return CreateRegExpStringIterator(matcher, str, source, flags, lastIndex); -+} -+ -+// String.prototype.matchAll proposal. -+// -+// CreateRegExpStringIterator ( R, S, global, fullUnicode ) -+function CreateRegExpStringIterator(regexp, string, source, flags, lastIndex) { -+ // Step 1. -+ assert(typeof string === "string", "|string| is a string value"); -+ -+ // Steps 2-3. -+ assert(typeof flags === "number", "|flags| is a number value"); -+ -+ assert(typeof source === "string", "|source| is a string value"); -+ assert(typeof lastIndex === "number", "|lastIndex| is a number value"); -+ -+ // Steps 4-9. -+ var iterator = NewRegExpStringIterator(); -+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_REGEXP_SLOT, regexp); -+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_STRING_SLOT, string); -+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_SOURCE_SLOT, source); -+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_FLAGS_SLOT, flags | 0); -+ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, lastIndex); -+ -+ // Step 10. -+ return iterator; -+} -+ -+function IsRegExpStringIteratorNextOptimizable() { -+ var RegExpProto = GetBuiltinPrototype("RegExp"); -+ // If RegExpPrototypeOptimizable succeeds, `RegExpProto.exec` is -+ // guaranteed to be a data property. -+ return RegExpPrototypeOptimizable(RegExpProto) && -+ RegExpProto.exec === RegExp_prototype_Exec; -+} -+ -+// String.prototype.matchAll proposal. -+// -+// %RegExpStringIteratorPrototype%.next ( ) -+function RegExpStringIteratorNext() { -+ // Steps 1-3. -+ if (!IsObject(this) || !GuardToRegExpStringIterator(this)) { -+ return callFunction(CallRegExpStringIteratorMethodIfWrapped, this, -+ "RegExpStringIteratorNext"); -+ } -+ -+ var result = { value: undefined, done: false }; -+ -+ // Step 4. -+ var lastIndex = UnsafeGetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT); -+ if (lastIndex === REGEXP_STRING_ITERATOR_LASTINDEX_DONE) { -+ result.done = true; -+ return result; -+ } -+ -+ // Step 5. -+ var regexp = UnsafeGetObjectFromReservedSlot(this, REGEXP_STRING_ITERATOR_REGEXP_SLOT); -+ -+ // Step 6. -+ var string = UnsafeGetStringFromReservedSlot(this, REGEXP_STRING_ITERATOR_STRING_SLOT); -+ -+ // Steps 7-8. -+ var flags = UnsafeGetInt32FromReservedSlot(this, REGEXP_STRING_ITERATOR_FLAGS_SLOT); -+ var global = !!(flags & REGEXP_GLOBAL_FLAG); -+ var fullUnicode = !!(flags & REGEXP_UNICODE_FLAG); -+ -+ if (lastIndex >= 0) { -+ assert(IsRegExpObject(regexp), "|regexp| is a RegExp object"); -+ -+ var source = UnsafeGetStringFromReservedSlot(this, REGEXP_STRING_ITERATOR_SOURCE_SLOT); -+ if (IsRegExpStringIteratorNextOptimizable() && -+ UnsafeGetStringFromReservedSlot(regexp, REGEXP_SOURCE_SLOT) === source && -+ UnsafeGetInt32FromReservedSlot(regexp, REGEXP_FLAGS_SLOT) === flags) -+ { -+ // Step 9 (Inlined RegExpBuiltinExec). -+ var globalOrSticky = !!(flags & (REGEXP_GLOBAL_FLAG | REGEXP_STICKY_FLAG)); -+ if (!globalOrSticky) -+ lastIndex = 0; -+ -+ var match = (lastIndex <= string.length) -+ ? RegExpMatcher(regexp, string, lastIndex) -+ : null; -+ -+ // Step 10. -+ if (match === null) { -+ // Step 10.a. -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, -+ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); -+ -+ // Step 10.b. -+ result.done = true; -+ return result; -+ } -+ -+ // Step 11.a. -+ if (global) { -+ // Step 11.a.i. -+ var matchLength = match[0].length; -+ lastIndex = match.index + matchLength; -+ -+ // Step 11.a.ii. -+ if (matchLength === 0) { -+ // Steps 11.a.ii.1-3. -+ lastIndex = fullUnicode ? AdvanceStringIndex(string, lastIndex) : lastIndex + 1; -+ } -+ -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, lastIndex); -+ } else { -+ // Step 11.b.i. -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, -+ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); -+ } -+ -+ // Steps 11.a.iii and 11.b.ii. -+ result.value = match; -+ return result; -+ } -+ -+ // Reify the RegExp object. -+ regexp = regexp_construct_raw_flags(source, flags); -+ regexp.lastIndex = lastIndex; -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_REGEXP_SLOT, regexp); -+ -+ // Mark the iterator as no longer optimizable. -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, -+ REGEXP_STRING_ITERATOR_LASTINDEX_SLOW); -+ } -+ -+ // Step 9. -+ var match = RegExpExec(regexp, string, false); -+ -+ // Step 10. -+ if (match === null) { -+ // Step 10.a. -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, -+ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); -+ -+ // Step 10.b. -+ result.done = true; -+ return result; -+ } -+ -+ // Step 11.a. -+ if (global) { -+ // Step 11.a.i. -+ var matchStr = ToString(match[0]); -+ -+ // Step 11.a.ii. -+ if (matchStr.length === 0) { -+ // Step 11.a.ii.1. -+ var thisIndex = ToLength(regexp.lastIndex); -+ -+ // Step 11.a.ii.2. -+ var nextIndex = fullUnicode ? AdvanceStringIndex(string, thisIndex) : thisIndex + 1; -+ -+ // Step 11.a.ii.3. -+ regexp.lastIndex = nextIndex; -+ } -+ } else { -+ // Step 11.b.i. -+ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, -+ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); -+ } -+ -+ // Steps 11.a.iii and 11.b.ii. -+ result.value = match; -+ return result; -+} -diff -Nrup mozilla/js/src/builtin/RegExpGlobalReplaceOpt.h.js mozilla-OK/js/src/builtin/RegExpGlobalReplaceOpt.h.js ---- mozilla/js/src/builtin/RegExpGlobalReplaceOpt.h.js 2021-05-25 21:33:37.000000000 +0300 -+++ mozilla-OK/js/src/builtin/RegExpGlobalReplaceOpt.h.js 2022-06-15 23:02:24.232330499 +0300 -@@ -69,12 +69,19 @@ function FUNC_NAME(rx, S, lengthS, repla - var position = result.index | 0; - lastIndex = position + matchLength; - -- // Steps g-k. -+ // Steps g-l. - var replacement; - #if defined(FUNCTIONAL) - replacement = RegExpGetFunctionalReplacement(result, S, position, replaceValue); - #elif defined(SUBSTITUTION) -- replacement = RegExpGetSubstitution(result, S, position, replaceValue, firstDollarIndex); -+ // Step l.i -+ var namedCaptures = result.groups; -+ if (namedCaptures !== undefined) { -+ namedCaptures = ToObject(namedCaptures); -+ } -+ // Step l.ii -+ replacement = RegExpGetSubstitution(result, S, position, replaceValue, -+ firstDollarIndex, namedCaptures); - #elif defined(ELEMBASE) - if (IsObject(elemBase)) { - var prop = GetStringDataProperty(elemBase, matched); -@@ -93,11 +100,11 @@ function FUNC_NAME(rx, S, lengthS, repla - replacement = replaceValue; - #endif - -- // Step 14.l.ii. -+ // Step 14.m.ii. - accumulatedResult += Substring(S, nextSourcePosition, - position - nextSourcePosition) + replacement; - -- // Step 14.l.iii. -+ // Step 14.m.iii. - nextSourcePosition = lastIndex; - - // Step 11.c.iii.2. -diff -Nrup mozilla/js/src/builtin/RegExpLocalReplaceOpt.h.js mozilla-OK/js/src/builtin/RegExpLocalReplaceOpt.h.js ---- mozilla/js/src/builtin/RegExpLocalReplaceOpt.h.js 2021-05-25 21:33:37.000000000 +0300 -+++ mozilla-OK/js/src/builtin/RegExpLocalReplaceOpt.h.js 2022-06-15 23:02:24.233330493 +0300 -@@ -91,7 +91,7 @@ function FUNC_NAME(rx, S, lengthS, repla - // Step 14.e-f. - var position = result.index; - -- // Step 14.l.iii (reordered) -+ // Step 14.m.iii (reordered) - // To set rx.lastIndex before RegExpGetFunctionalReplacement. - var nextSourcePosition = position + matchLength; - #else -@@ -109,16 +109,23 @@ function FUNC_NAME(rx, S, lengthS, repla - rx.lastIndex = nextSourcePosition; - - var replacement; -- // Steps g-j. -+ // Steps g-l. - #if defined(FUNCTIONAL) - replacement = RegExpGetFunctionalReplacement(result, S, position, replaceValue); - #elif defined(SUBSTITUTION) -- replacement = RegExpGetSubstitution(result, S, position, replaceValue, firstDollarIndex); -+ // Step l.i -+ var namedCaptures = result.groups; -+ if (namedCaptures !== undefined) { -+ namedCaptures = ToObject(namedCaptures); -+ } -+ // Step l.ii -+ replacement = RegExpGetSubstitution(result, S, position, replaceValue, firstDollarIndex, -+ namedCaptures); - #else - replacement = replaceValue; - #endif - -- // Step 14.l.ii. -+ // Step 14.m.ii. - var accumulatedResult = Substring(S, 0, position) + replacement; - - // Step 15. -diff -Nrup mozilla/js/src/builtin/SelfHostingDefines.h mozilla-OK/js/src/builtin/SelfHostingDefines.h ---- mozilla/js/src/builtin/SelfHostingDefines.h 2021-10-26 19:49:54.000000000 +0300 -+++ mozilla-OK/js/src/builtin/SelfHostingDefines.h 2022-06-15 23:27:12.201259955 +0300 -@@ -99,6 +99,16 @@ - #define REGEXP_MULTILINE_FLAG 0x04 - #define REGEXP_STICKY_FLAG 0x08 - #define REGEXP_UNICODE_FLAG 0x10 -+#define REGEXP_DOTALL_FLAG 0x20 -+ -+#define REGEXP_STRING_ITERATOR_REGEXP_SLOT 0 -+#define REGEXP_STRING_ITERATOR_STRING_SLOT 1 -+#define REGEXP_STRING_ITERATOR_SOURCE_SLOT 2 -+#define REGEXP_STRING_ITERATOR_FLAGS_SLOT 3 -+#define REGEXP_STRING_ITERATOR_LASTINDEX_SLOT 4 -+ -+#define REGEXP_STRING_ITERATOR_LASTINDEX_DONE -1 -+#define REGEXP_STRING_ITERATOR_LASTINDEX_SLOW -2 - - #define MODULE_OBJECT_ENVIRONMENT_SLOT 1 - #define MODULE_OBJECT_STATUS_SLOT 3 -diff -Nrup mozilla/js/src/builtin/String.js mozilla-OK/js/src/builtin/String.js ---- mozilla/js/src/builtin/String.js 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/builtin/String.js 2022-06-15 23:50:05.198949461 +0300 -@@ -62,6 +62,49 @@ function String_generic_match(thisValue, - return callFunction(String_match, thisValue, regexp); - } - -+// String.prototype.matchAll proposal. -+// -+// String.prototype.matchAll ( regexp ) -+function String_matchAll(regexp) { -+ // Step 1. -+ RequireObjectCoercible(this); -+ -+ // Step 2. -+ if (regexp !== undefined && regexp !== null) { -+ // Steps 2.a-b. -+ if (IsRegExp(regexp)) { -+ // Step 2.b.i. -+ var flags = regexp.flags; -+ -+ // Step 2.b.ii. -+ if (flags === undefined || flags === null) { -+ ThrowTypeError(JSMSG_FLAGS_UNDEFINED_OR_NULL); -+ } -+ -+ // Step 2.b.iii. -+ if (!callFunction(std_String_includes, ToString(flags), "g")) { -+ ThrowTypeError(JSMSG_REQUIRES_GLOBAL_REGEXP, "matchAll"); -+ } -+ } -+ -+ // Step 2.c. -+ var matcher = GetMethod(regexp, std_matchAll); -+ -+ // Step 2.d. -+ if (matcher !== undefined) -+ return callContentFunction(matcher, regexp, this); -+ } -+ -+ // Step 3. -+ var string = ToString(this); -+ -+ // Step 4. -+ var rx = RegExpCreate(regexp, "g"); -+ -+ // Step 5. -+ return callContentFunction(GetMethod(rx, std_matchAll), rx, string); -+} -+ - /** - * A helper function implementing the logic for both String.prototype.padStart - * and String.prototype.padEnd as described in ES7 Draft March 29, 2016 -diff -Nrup mozilla/js/src/builtin/TestingFunctions.cpp mozilla-OK/js/src/builtin/TestingFunctions.cpp ---- mozilla/js/src/builtin/TestingFunctions.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/builtin/TestingFunctions.cpp 2022-06-15 23:52:50.102830854 +0300 -@@ -30,13 +30,11 @@ - #include "builtin/SelfHostingDefines.h" - #ifdef DEBUG - #include "frontend/TokenStream.h" --#include "irregexp/RegExpAST.h" --#include "irregexp/RegExpEngine.h" --#include "irregexp/RegExpParser.h" - #endif - #include "jit/InlinableNatives.h" - #include "js/Debug.h" - #include "js/HashTable.h" -+#include "js/RegExpFlags.h" - #include "js/StructuredClone.h" - #include "js/UbiNode.h" - #include "js/UbiNodeBreadthFirst.h" -@@ -71,6 +69,9 @@ using namespace js; - using mozilla::ArrayLength; - using mozilla::Move; - -+using JS::RegExpFlag; -+using JS::RegExpFlags; -+ - // If fuzzingSafe is set, remove functionality that could cause problems with - // fuzzers. Set this via the environment variable MOZ_FUZZING_SAFE. - static mozilla::Atomic fuzzingSafe(false); -@@ -4262,372 +4263,6 @@ GetModuleEnvironmentValue(JSContext* cx, - return true; - } - --#ifdef DEBUG --static const char* --AssertionTypeToString(irregexp::RegExpAssertion::AssertionType type) --{ -- switch (type) { -- case irregexp::RegExpAssertion::START_OF_LINE: -- return "START_OF_LINE"; -- case irregexp::RegExpAssertion::START_OF_INPUT: -- return "START_OF_INPUT"; -- case irregexp::RegExpAssertion::END_OF_LINE: -- return "END_OF_LINE"; -- case irregexp::RegExpAssertion::END_OF_INPUT: -- return "END_OF_INPUT"; -- case irregexp::RegExpAssertion::BOUNDARY: -- return "BOUNDARY"; -- case irregexp::RegExpAssertion::NON_BOUNDARY: -- return "NON_BOUNDARY"; -- case irregexp::RegExpAssertion::NOT_AFTER_LEAD_SURROGATE: -- return "NOT_AFTER_LEAD_SURROGATE"; -- case irregexp::RegExpAssertion::NOT_IN_SURROGATE_PAIR: -- return "NOT_IN_SURROGATE_PAIR"; -- } -- MOZ_CRASH("unexpected AssertionType"); --} -- --static JSObject* --ConvertRegExpTreeToObject(JSContext* cx, irregexp::RegExpTree* tree) --{ -- RootedObject obj(cx, JS_NewPlainObject(cx)); -- if (!obj) -- return nullptr; -- -- auto IntProp = [](JSContext* cx, HandleObject obj, -- const char* name, int32_t value) { -- RootedValue val(cx, Int32Value(value)); -- return JS_SetProperty(cx, obj, name, val); -- }; -- -- auto BooleanProp = [](JSContext* cx, HandleObject obj, -- const char* name, bool value) { -- RootedValue val(cx, BooleanValue(value)); -- return JS_SetProperty(cx, obj, name, val); -- }; -- -- auto StringProp = [](JSContext* cx, HandleObject obj, -- const char* name, const char* value) { -- RootedString valueStr(cx, JS_NewStringCopyZ(cx, value)); -- if (!valueStr) -- return false; -- -- RootedValue val(cx, StringValue(valueStr)); -- return JS_SetProperty(cx, obj, name, val); -- }; -- -- auto ObjectProp = [](JSContext* cx, HandleObject obj, -- const char* name, HandleObject value) { -- RootedValue val(cx, ObjectValue(*value)); -- return JS_SetProperty(cx, obj, name, val); -- }; -- -- auto CharVectorProp = [](JSContext* cx, HandleObject obj, -- const char* name, const irregexp::CharacterVector& data) { -- RootedString valueStr(cx, JS_NewUCStringCopyN(cx, data.begin(), data.length())); -- if (!valueStr) -- return false; -- -- RootedValue val(cx, StringValue(valueStr)); -- return JS_SetProperty(cx, obj, name, val); -- }; -- -- auto TreeProp = [&ObjectProp](JSContext* cx, HandleObject obj, -- const char* name, irregexp::RegExpTree* tree) { -- RootedObject treeObj(cx, ConvertRegExpTreeToObject(cx, tree)); -- if (!treeObj) -- return false; -- return ObjectProp(cx, obj, name, treeObj); -- }; -- -- auto TreeVectorProp = [&ObjectProp](JSContext* cx, HandleObject obj, -- const char* name, -- const irregexp::RegExpTreeVector& nodes) { -- size_t len = nodes.length(); -- RootedObject array(cx, JS_NewArrayObject(cx, len)); -- if (!array) -- return false; -- -- for (size_t i = 0; i < len; i++) { -- RootedObject child(cx, ConvertRegExpTreeToObject(cx, nodes[i])); -- if (!child) -- return false; -- -- RootedValue childVal(cx, ObjectValue(*child)); -- if (!JS_SetElement(cx, array, i, childVal)) -- return false; -- } -- return ObjectProp(cx, obj, name, array); -- }; -- -- auto CharRangesProp = [&ObjectProp](JSContext* cx, HandleObject obj, -- const char* name, -- const irregexp::CharacterRangeVector& ranges) { -- size_t len = ranges.length(); -- RootedObject array(cx, JS_NewArrayObject(cx, len)); -- if (!array) -- return false; -- -- for (size_t i = 0; i < len; i++) { -- const irregexp::CharacterRange& range = ranges[i]; -- RootedObject rangeObj(cx, JS_NewPlainObject(cx)); -- if (!rangeObj) -- return false; -- -- auto CharProp = [](JSContext* cx, HandleObject obj, -- const char* name, char16_t c) { -- RootedString valueStr(cx, JS_NewUCStringCopyN(cx, &c, 1)); -- if (!valueStr) -- return false; -- RootedValue val(cx, StringValue(valueStr)); -- return JS_SetProperty(cx, obj, name, val); -- }; -- -- if (!CharProp(cx, rangeObj, "from", range.from())) -- return false; -- if (!CharProp(cx, rangeObj, "to", range.to())) -- return false; -- -- RootedValue rangeVal(cx, ObjectValue(*rangeObj)); -- if (!JS_SetElement(cx, array, i, rangeVal)) -- return false; -- } -- return ObjectProp(cx, obj, name, array); -- }; -- -- auto ElemProp = [&ObjectProp](JSContext* cx, HandleObject obj, -- const char* name, const irregexp::TextElementVector& elements) { -- size_t len = elements.length(); -- RootedObject array(cx, JS_NewArrayObject(cx, len)); -- if (!array) -- return false; -- -- for (size_t i = 0; i < len; i++) { -- const irregexp::TextElement& element = elements[i]; -- RootedObject elemTree(cx, ConvertRegExpTreeToObject(cx, element.tree())); -- if (!elemTree) -- return false; -- -- RootedValue elemTreeVal(cx, ObjectValue(*elemTree)); -- if (!JS_SetElement(cx, array, i, elemTreeVal)) -- return false; -- } -- return ObjectProp(cx, obj, name, array); -- }; -- -- if (tree->IsDisjunction()) { -- if (!StringProp(cx, obj, "type", "Disjunction")) -- return nullptr; -- irregexp::RegExpDisjunction* t = tree->AsDisjunction(); -- if (!TreeVectorProp(cx, obj, "alternatives", t->alternatives())) -- return nullptr; -- return obj; -- } -- if (tree->IsAlternative()) { -- if (!StringProp(cx, obj, "type", "Alternative")) -- return nullptr; -- irregexp::RegExpAlternative* t = tree->AsAlternative(); -- if (!TreeVectorProp(cx, obj, "nodes", t->nodes())) -- return nullptr; -- return obj; -- } -- if (tree->IsAssertion()) { -- if (!StringProp(cx, obj, "type", "Assertion")) -- return nullptr; -- irregexp::RegExpAssertion* t = tree->AsAssertion(); -- if (!StringProp(cx, obj, "assertion_type", AssertionTypeToString(t->assertion_type()))) -- return nullptr; -- return obj; -- } -- if (tree->IsCharacterClass()) { -- if (!StringProp(cx, obj, "type", "CharacterClass")) -- return nullptr; -- irregexp::RegExpCharacterClass* t = tree->AsCharacterClass(); -- if (!BooleanProp(cx, obj, "is_negated", t->is_negated())) -- return nullptr; -- LifoAlloc* alloc = &cx->tempLifoAlloc(); -- if (!CharRangesProp(cx, obj, "ranges", t->ranges(alloc))) -- return nullptr; -- return obj; -- } -- if (tree->IsAtom()) { -- if (!StringProp(cx, obj, "type", "Atom")) -- return nullptr; -- irregexp::RegExpAtom* t = tree->AsAtom(); -- if (!CharVectorProp(cx, obj, "data", t->data())) -- return nullptr; -- return obj; -- } -- if (tree->IsText()) { -- if (!StringProp(cx, obj, "type", "Text")) -- return nullptr; -- irregexp::RegExpText* t = tree->AsText(); -- if (!ElemProp(cx, obj, "elements", t->elements())) -- return nullptr; -- return obj; -- } -- if (tree->IsQuantifier()) { -- if (!StringProp(cx, obj, "type", "Quantifier")) -- return nullptr; -- irregexp::RegExpQuantifier* t = tree->AsQuantifier(); -- if (!IntProp(cx, obj, "min", t->min())) -- return nullptr; -- if (!IntProp(cx, obj, "max", t->max())) -- return nullptr; -- if (!StringProp(cx, obj, "quantifier_type", -- t->is_possessive() ? "POSSESSIVE" -- : t->is_non_greedy() ? "NON_GREEDY" -- : "GREEDY")) -- return nullptr; -- if (!TreeProp(cx, obj, "body", t->body())) -- return nullptr; -- return obj; -- } -- if (tree->IsCapture()) { -- if (!StringProp(cx, obj, "type", "Capture")) -- return nullptr; -- irregexp::RegExpCapture* t = tree->AsCapture(); -- if (!IntProp(cx, obj, "index", t->index())) -- return nullptr; -- if (!TreeProp(cx, obj, "body", t->body())) -- return nullptr; -- return obj; -- } -- if (tree->IsLookahead()) { -- if (!StringProp(cx, obj, "type", "Lookahead")) -- return nullptr; -- irregexp::RegExpLookahead* t = tree->AsLookahead(); -- if (!BooleanProp(cx, obj, "is_positive", t->is_positive())) -- return nullptr; -- if (!TreeProp(cx, obj, "body", t->body())) -- return nullptr; -- return obj; -- } -- if (tree->IsBackReference()) { -- if (!StringProp(cx, obj, "type", "BackReference")) -- return nullptr; -- irregexp::RegExpBackReference* t = tree->AsBackReference(); -- if (!IntProp(cx, obj, "index", t->index())) -- return nullptr; -- return obj; -- } -- if (tree->IsEmpty()) { -- if (!StringProp(cx, obj, "type", "Empty")) -- return nullptr; -- return obj; -- } -- -- MOZ_CRASH("unexpected RegExpTree type"); --} -- --static bool --ParseRegExp(JSContext* cx, unsigned argc, Value* vp) --{ -- CallArgs args = CallArgsFromVp(argc, vp); -- RootedObject callee(cx, &args.callee()); -- -- if (args.length() == 0) { -- ReportUsageErrorASCII(cx, callee, "Wrong number of arguments"); -- return false; -- } -- -- if (!args[0].isString()) { -- ReportUsageErrorASCII(cx, callee, "First argument must be a String"); -- return false; -- } -- -- RegExpFlag flags = RegExpFlag(0); -- if (!args.get(1).isUndefined()) { -- if (!args.get(1).isString()) { -- ReportUsageErrorASCII(cx, callee, "Second argument, if present, must be a String"); -- return false; -- } -- RootedString flagStr(cx, args[1].toString()); -- if (!ParseRegExpFlags(cx, flagStr, &flags)) -- return false; -- } -- -- bool match_only = false; -- if (!args.get(2).isUndefined()) { -- if (!args.get(2).isBoolean()) { -- ReportUsageErrorASCII(cx, callee, "Third argument, if present, must be a Boolean"); -- return false; -- } -- match_only = args[2].toBoolean(); -- } -- -- RootedAtom pattern(cx, AtomizeString(cx, args[0].toString())); -- if (!pattern) -- return false; -- -- CompileOptions options(cx); -- frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); -- -- irregexp::RegExpCompileData data; -- if (!irregexp::ParsePattern(dummyTokenStream, cx->tempLifoAlloc(), pattern, -- flags & MultilineFlag, match_only, -- flags & UnicodeFlag, flags & IgnoreCaseFlag, -- flags & GlobalFlag, flags & StickyFlag, -- &data)) -- { -- return false; -- } -- -- RootedObject obj(cx, ConvertRegExpTreeToObject(cx, data.tree)); -- if (!obj) -- return false; -- -- args.rval().setObject(*obj); -- return true; --} -- --static bool --DisRegExp(JSContext* cx, unsigned argc, Value* vp) --{ -- CallArgs args = CallArgsFromVp(argc, vp); -- RootedObject callee(cx, &args.callee()); -- -- if (args.length() == 0) { -- ReportUsageErrorASCII(cx, callee, "Wrong number of arguments"); -- return false; -- } -- -- if (!args[0].isObject() || !args[0].toObject().is()) { -- ReportUsageErrorASCII(cx, callee, "First argument must be a RegExp"); -- return false; -- } -- -- Rooted reobj(cx, &args[0].toObject().as()); -- -- bool match_only = false; -- if (!args.get(1).isUndefined()) { -- if (!args.get(1).isBoolean()) { -- ReportUsageErrorASCII(cx, callee, "Second argument, if present, must be a Boolean"); -- return false; -- } -- match_only = args[1].toBoolean(); -- } -- -- RootedLinearString input(cx, cx->runtime()->emptyString); -- if (!args.get(2).isUndefined()) { -- if (!args.get(2).isString()) { -- ReportUsageErrorASCII(cx, callee, "Third argument, if present, must be a String"); -- return false; -- } -- RootedString inputStr(cx, args[2].toString()); -- input = inputStr->ensureLinear(cx); -- if (!input) -- return false; -- } -- -- if (!RegExpObject::dumpBytecode(cx, reobj, match_only, input)) -- return false; -- -- args.rval().setUndefined(); -- return true; --} --#endif // DEBUG -- - static bool - EnableForEach(JSContext* cx, unsigned argc, Value* vp) - { -@@ -5536,16 +5171,6 @@ gc::ZealModeHelpText), - }; - - static const JSFunctionSpecWithHelp FuzzingUnsafeTestingFunctions[] = { --#ifdef DEBUG -- JS_FN_HELP("parseRegExp", ParseRegExp, 3, 0, --"parseRegExp(pattern[, flags[, match_only])", --" Parses a RegExp pattern and returns a tree, potentially throwing."), -- -- JS_FN_HELP("disRegExp", DisRegExp, 3, 0, --"disRegExp(regexp[, match_only[, input]])", --" Dumps RegExp bytecode."), --#endif -- - JS_FN_HELP("getErrorNotes", GetErrorNotes, 1, 0, - "getErrorNotes(error)", - " Returns an array of error notes."), -diff -Nrup mozilla/js/src/builtin/intl/RelativeTimeFormat.cpp mozilla-OK/js/src/builtin/intl/RelativeTimeFormat.cpp ---- mozilla/js/src/builtin/intl/RelativeTimeFormat.cpp 2021-10-26 19:49:54.000000000 +0300 -+++ mozilla-OK/js/src/builtin/intl/RelativeTimeFormat.cpp 2022-06-15 22:50:43.698075697 +0300 -@@ -127,7 +127,7 @@ RelativeTimeFormat(JSContext* cx, unsign - void - js::RelativeTimeFormatObject::finalize(FreeOp* fop, JSObject* obj) - { -- MOZ_ASSERT(fop->onActiveCooperatingThread()); -+ MOZ_ASSERT(fop->onMainThread()); - - const Value& slot = - obj->as().getReservedSlot(RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT); -diff -Nrup mozilla/js/src/devtools/rootAnalysis/annotations.js mozilla-OK/js/src/devtools/rootAnalysis/annotations.js ---- mozilla/js/src/devtools/rootAnalysis/annotations.js 2022-04-13 21:14:22.000000000 +0300 -+++ mozilla-OK/js/src/devtools/rootAnalysis/annotations.js 2022-06-15 22:52:13.970464208 +0300 -@@ -241,6 +241,9 @@ var ignoreFunctions = { - "uint8 nsContentUtils::IsExpandedPrincipal(nsIPrincipal*)" : true, - - "void mozilla::AutoProfilerLabel::~AutoProfilerLabel(int32)" : true, -+ -+ // Calls MergeSort -+ "uint8 v8::internal::RegExpDisjunction::SortConsecutiveAtoms(v8::internal::RegExpCompiler*)": true, - }; - - function extraGCFunctions() { -@@ -267,6 +270,12 @@ function isGTest(name) - return name.match(/\btesting::/); - } - -+function isICU(name) -+{ -+ return name.match(/\bicu_\d+::/) || -+ name.match(/u(prv_malloc|prv_realloc|prv_free|case_toFullLower)_\d+/) -+} -+ - function ignoreGCFunction(mangled) - { - assert(mangled in readableNames, mangled + " not in readableNames"); -@@ -277,8 +286,9 @@ function ignoreGCFunction(mangled) - - // The protobuf library, and [de]serialization code generated by the - // protobuf compiler, uses a _ton_ of function pointers but they are all -- // internal. Easiest to just ignore that mess here. -- if (isProtobuf(fun)) -+ // internal. The same is true for ICU. Easiest to just ignore that mess -+ // here. -+ if (isProtobuf(fun) || isICU(fun)) - return true; - - // Ignore anything that goes through heap snapshot GTests or mocked classes -diff -Nrup mozilla/js/src/frontend/Parser.cpp mozilla-OK/js/src/frontend/Parser.cpp ---- mozilla/js/src/frontend/Parser.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/frontend/Parser.cpp 2022-06-15 23:52:50.104830841 +0300 -@@ -34,7 +34,8 @@ - #include "frontend/BytecodeCompiler.h" - #include "frontend/FoldConstants.h" - #include "frontend/TokenStream.h" --#include "irregexp/RegExpParser.h" -+#include "irregexp/RegExpAPI.h" -+#include "js/RegExpFlags.h" - #include "vm/RegExpObject.h" - #include "wasm/AsmJS.h" - -@@ -55,6 +56,7 @@ using mozilla::PodZero; - using mozilla::Some; - - using JS::AutoGCRooter; -+using JS::RegExpFlags; - - namespace js { - namespace frontend { -@@ -9139,7 +9141,7 @@ Parser::newR - // Create the regexp and check its syntax. - const char16_t* chars = tokenStream.getTokenbuf().begin(); - size_t length = tokenStream.getTokenbuf().length(); -- RegExpFlag flags = anyChars.currentToken().regExpFlags(); -+ RegExpFlags flags = anyChars.currentToken().regExpFlags(); - - Rooted reobj(context); - reobj = RegExpObject::create(context, chars, length, flags, anyChars, alloc, TenuredObject); -@@ -9158,12 +9160,12 @@ Parser::ne - // Only check the regexp's syntax, but don't create a regexp object. - const char16_t* chars = tokenStream.getTokenbuf().begin(); - size_t length = tokenStream.getTokenbuf().length(); -- RegExpFlag flags = anyChars.currentToken().regExpFlags(); -+ RegExpFlags flags = anyChars.currentToken().regExpFlags(); - - mozilla::Range source(chars, length); -- if (!js::irregexp::ParsePatternSyntax(anyChars, alloc, source, flags & UnicodeFlag)) -- return null(); -- -+ if (!irregexp::CheckPatternSyntax(context, anyChars, source, flags)) { -+ return null(); -+ } - return handler.newRegExp(SyntaxParseHandler::NodeGeneric, pos(), *this); - } - -diff -Nrup mozilla/js/src/frontend/TokenStream.cpp mozilla-OK/js/src/frontend/TokenStream.cpp ---- mozilla/js/src/frontend/TokenStream.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/frontend/TokenStream.cpp 2022-06-15 21:39:37.371986091 +0300 -@@ -26,6 +26,7 @@ - #include "frontend/Parser.h" - #include "frontend/ReservedWords.h" - #include "js/CharacterEncoding.h" -+#include "js/RegExpFlags.h" // JS::RegExpFlags - #include "js/UniquePtr.h" - #include "vm/HelperThreads.h" - #include "vm/StringBuffer.h" -@@ -38,6 +39,9 @@ using mozilla::PodAssign; - using mozilla::PodCopy; - using mozilla::PodZero; - -+using JS::RegExpFlag; -+using JS::RegExpFlags; -+ - struct ReservedWordInfo - { - const char* chars; // C string with reserved word text -@@ -2010,21 +2014,23 @@ TokenStreamSpecific - { -@@ -1419,6 +1417,12 @@ class MOZ_STACK_CLASS TokenStream final - {} - }; - -+class MOZ_STACK_CLASS DummyTokenStream final : public TokenStream { -+ public: -+ DummyTokenStream(JSContext* cx, const JS::ReadOnlyCompileOptions& options) -+ : TokenStream(cx, options, nullptr, 0, nullptr) {} -+}; -+ - template - /* static */ inline TokenStreamAnyChars& - TokenStreamAnyCharsAccess::anyChars(TokenStreamSpecific* tss) -diff -Nrup mozilla/js/src/irregexp/IRREGEXP_VERSION mozilla-OK/js/src/irregexp/IRREGEXP_VERSION ---- mozilla/js/src/irregexp/IRREGEXP_VERSION 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/IRREGEXP_VERSION 2022-06-16 00:06:40.922190766 +0300 -@@ -0,0 +1,2 @@ -+Imported using import-irregexp.py from: -+https://github.com/v8/v8/tree/8732b2ee52b567ad4e15ca91d141fd6e27499e99/src/regexp -diff -Nrup mozilla/js/src/irregexp/RegExpAPI.cpp mozilla-OK/js/src/irregexp/RegExpAPI.cpp ---- mozilla/js/src/irregexp/RegExpAPI.cpp 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpAPI.cpp 2022-06-16 00:07:27.342875589 +0300 -@@ -0,0 +1,703 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+// Copyright 2020 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "irregexp/RegExpAPI.h" -+ -+#include "mozilla/ArrayUtils.h" -+#include "mozilla/Casting.h" -+ -+#include "irregexp/imported/regexp-ast.h" -+#include "irregexp/imported/regexp-bytecode-generator.h" -+#include "irregexp/imported/regexp-compiler.h" -+#include "irregexp/imported/regexp-interpreter.h" -+#include "irregexp/imported/regexp-macro-assembler-arch.h" -+#include "irregexp/imported/regexp-parser.h" -+#include "irregexp/imported/regexp-stack.h" -+#include "irregexp/imported/regexp.h" -+#include "irregexp/RegExpShim.h" -+#include "jit/JitCommon.h" -+ -+#include "util/Text.h" -+#include "vm/ErrorReporting.h" -+#include "vm/MatchPairs.h" -+#include "vm/RegExpShared.h" -+#include "vm/StringBuffer.h" -+ -+namespace js { -+namespace irregexp { -+ -+using namespace mozilla; -+ -+using frontend::DummyTokenStream; -+using frontend::TokenStreamAnyChars; -+ -+using v8::internal::DisallowGarbageCollection; -+using v8::internal::FlatStringReader; -+using v8::internal::HandleScope; -+using v8::internal::InputOutputData; -+using v8::internal::IrregexpInterpreter; -+using v8::internal::NativeRegExpMacroAssembler; -+using v8::internal::RegExpBytecodeGenerator; -+using v8::internal::RegExpCompileData; -+using v8::internal::RegExpCompiler; -+using v8::internal::RegExpError; -+using v8::internal::RegExpMacroAssembler; -+using v8::internal::RegExpNode; -+using v8::internal::RegExpParser; -+using v8::internal::SMRegExpMacroAssembler; -+using v8::internal::Zone; -+ -+using V8HandleString = v8::internal::Handle; -+using V8HandleRegExp = v8::internal::Handle; -+ -+using namespace v8::internal::regexp_compiler_constants; -+ -+static uint32_t ErrorNumber(RegExpError err) { -+ switch (err) { -+ case RegExpError::kNone: -+ return JSMSG_NOT_AN_ERROR; -+ case RegExpError::kStackOverflow: -+ return JSMSG_OVER_RECURSED; -+ case RegExpError::kAnalysisStackOverflow: -+ return JSMSG_OVER_RECURSED; -+ case RegExpError::kTooLarge: -+ return JSMSG_TOO_MANY_PARENS; -+ case RegExpError::kUnterminatedGroup: -+ return JSMSG_MISSING_PAREN; -+ case RegExpError::kUnmatchedParen: -+ return JSMSG_UNMATCHED_RIGHT_PAREN; -+ case RegExpError::kEscapeAtEndOfPattern: -+ return JSMSG_ESCAPE_AT_END_OF_REGEXP; -+ case RegExpError::kInvalidPropertyName: -+ return JSMSG_INVALID_PROPERTY_NAME; -+ case RegExpError::kInvalidEscape: -+ return JSMSG_INVALID_IDENTITY_ESCAPE; -+ case RegExpError::kInvalidDecimalEscape: -+ return JSMSG_INVALID_DECIMAL_ESCAPE; -+ case RegExpError::kInvalidUnicodeEscape: -+ return JSMSG_INVALID_UNICODE_ESCAPE; -+ case RegExpError::kNothingToRepeat: -+ return JSMSG_NOTHING_TO_REPEAT; -+ case RegExpError::kLoneQuantifierBrackets: -+ // Note: V8 reports the same error for both ']' and '}'. -+ return JSMSG_RAW_BRACKET_IN_REGEXP; -+ case RegExpError::kRangeOutOfOrder: -+ return JSMSG_NUMBERS_OUT_OF_ORDER; -+ case RegExpError::kIncompleteQuantifier: -+ return JSMSG_INCOMPLETE_QUANTIFIER; -+ case RegExpError::kInvalidQuantifier: -+ return JSMSG_INVALID_QUANTIFIER; -+ case RegExpError::kInvalidGroup: -+ return JSMSG_INVALID_GROUP; -+ case RegExpError::kMultipleFlagDashes: -+ case RegExpError::kRepeatedFlag: -+ case RegExpError::kInvalidFlagGroup: -+ // V8 contains experimental support for turning regexp flags on -+ // and off in the middle of a regular expression. Unless it -+ // becomes standardized, SM does not support this feature. -+ MOZ_CRASH("Mode modifiers not supported"); -+ case RegExpError::kNotLinear: -+ // V8 has an experimental non-backtracking engine. We do not -+ // support it yet. -+ MOZ_CRASH("Non-backtracking execution not supported"); -+ case RegExpError::kTooManyCaptures: -+ return JSMSG_TOO_MANY_PARENS; -+ case RegExpError::kInvalidCaptureGroupName: -+ return JSMSG_INVALID_CAPTURE_NAME; -+ case RegExpError::kDuplicateCaptureGroupName: -+ return JSMSG_DUPLICATE_CAPTURE_NAME; -+ case RegExpError::kInvalidNamedReference: -+ return JSMSG_INVALID_NAMED_REF; -+ case RegExpError::kInvalidNamedCaptureReference: -+ return JSMSG_INVALID_NAMED_CAPTURE_REF; -+ case RegExpError::kInvalidClassEscape: -+ return JSMSG_RANGE_WITH_CLASS_ESCAPE; -+ case RegExpError::kInvalidClassPropertyName: -+ return JSMSG_INVALID_CLASS_PROPERTY_NAME; -+ case RegExpError::kInvalidCharacterClass: -+ return JSMSG_RANGE_WITH_CLASS_ESCAPE; -+ case RegExpError::kUnterminatedCharacterClass: -+ return JSMSG_UNTERM_CLASS; -+ case RegExpError::kOutOfOrderCharacterClass: -+ return JSMSG_BAD_CLASS_RANGE; -+ case RegExpError::NumErrors: -+ MOZ_CRASH("Unreachable"); -+ } -+ MOZ_CRASH("Unreachable"); -+} -+ -+Isolate* CreateIsolate(JSContext* cx) { -+ auto isolate = MakeUnique(cx); -+ if (!isolate || !isolate->init()) { -+ return nullptr; -+ } -+ return isolate.release(); -+} -+ -+void DestroyIsolate(Isolate* isolate) { -+ MOZ_ASSERT(isolate->liveHandles() == 0); -+ MOZ_ASSERT(isolate->livePseudoHandles() == 0); -+ js_delete(isolate); -+} -+ -+size_t IsolateSizeOfIncludingThis(Isolate* isolate, -+ mozilla::MallocSizeOf mallocSizeOf) { -+ return isolate->sizeOfIncludingThis(mallocSizeOf); -+} -+ -+static size_t ComputeColumn(const Latin1Char* begin, const Latin1Char* end) { -+ return mozilla::PointerRangeSize(begin, end); -+} -+ -+static size_t ComputeColumn(const char16_t* begin, const char16_t* end) { -+ return unicode::CountCodePoints(begin, end); -+} -+ -+// This function is varargs purely so it can call ReportCompileErrorLatin1. -+// We never call it with additional arguments. -+template -+static void ReportSyntaxError(TokenStreamAnyChars& ts, RegExpCompileData& result, -+ CharT* start, size_t length, ...) { -+ gc::AutoSuppressGC suppressGC(ts.context()); -+ uint32_t errorNumber = ErrorNumber(result.error); -+ -+ if (errorNumber == JSMSG_OVER_RECURSED) { -+ ReportOverRecursed(ts.context()); -+ return; -+ } -+ -+ uint32_t offset = std::max(result.error_pos, 0); -+ MOZ_ASSERT(offset <= length); -+ -+ ErrorMetadata err; -+ -+ // Ordinarily this indicates whether line-of-context information can be -+ // added, but we entirely ignore that here because we create a -+ // a line of context based on the expression source. -+ uint32_t location = ts.currentToken().pos.begin; -+ if (ts.fillExcludingContext(&err, location)) { -+ // Line breaks are not significant in pattern text in the same way as -+ // in source text, so act as though pattern text is a single line, then -+ // compute a column based on "code point" count (treating a lone -+ // surrogate as a "code point" in UTF-16). Gak. -+ err.lineNumber = 1; -+ err.columnNumber = -+ AssertedCast(ComputeColumn(start, start + offset)); -+ } -+ -+ // For most error reporting, the line of context derives from the token -+ // stream. So when location information doesn't come from the token -+ // stream, we can't give a line of context. But here the "line of context" -+ // can be (and is) derived from the pattern text, so we can provide it no -+ // matter if the location is derived from the caller. -+ -+ const CharT* windowStart = -+ (offset > ErrorMetadata::lineOfContextRadius) -+ ? start + (offset - ErrorMetadata::lineOfContextRadius) -+ : start; -+ -+ const CharT* windowEnd = -+ (length - offset > ErrorMetadata::lineOfContextRadius) -+ ? start + offset + ErrorMetadata::lineOfContextRadius -+ : start + length; -+ -+ size_t windowLength = PointerRangeSize(windowStart, windowEnd); -+ MOZ_ASSERT(windowLength <= ErrorMetadata::lineOfContextRadius * 2); -+ -+ // Create the windowed string, not including the potential line -+ // terminator. -+ StringBuffer windowBuf(ts.context()); -+ if (!windowBuf.append(windowStart, windowEnd)) { -+ return; -+ } -+ -+ // The line of context must be null-terminated, and StringBuffer doesn't -+ // make that happen unless we force it to. -+ if (!windowBuf.append('\0')) { -+ return; -+ } -+ -+ err.lineOfContext.reset(windowBuf.stealChars()); -+ if (!err.lineOfContext) { -+ return; -+ } -+ -+ err.lineLength = windowLength; -+ err.tokenOffset = offset - (windowStart - start); -+ -+ va_list args; -+ va_start(args, length); -+ ReportCompileError(ts.context(), std::move(err), nullptr, /* notes/report */ -+ JSREPORT_ERROR, /*flags*/ -+ errorNumber, args); -+ va_end(args); -+} -+ -+static void ReportSyntaxError(TokenStreamAnyChars& ts, RegExpCompileData& result, -+ HandleAtom pattern) { -+ JS::AutoCheckCannotGC nogc_; -+ if (pattern->hasLatin1Chars()) { -+ ReportSyntaxError(ts, result, pattern->latin1Chars(nogc_), -+ pattern->length()); -+ } else { -+ ReportSyntaxError(ts, result, pattern->twoByteChars(nogc_), -+ pattern->length()); -+ } -+} -+ -+static bool CheckPatternSyntaxImpl(JSContext* cx, FlatStringReader* pattern, -+ JS::RegExpFlags flags, -+ RegExpCompileData* result) { -+ LifoAllocScope allocScope(&cx->tempLifoAlloc()); -+ Zone zone(allocScope.alloc()); -+ -+ HandleScope handleScope(cx->isolate); -+ DisallowGarbageCollection no_gc; -+ return RegExpParser::VerifyRegExpSyntax(cx->isolate, &zone, pattern, flags, -+ result, no_gc); -+} -+ -+bool CheckPatternSyntax(JSContext* cx, TokenStreamAnyChars& ts, -+ const mozilla::Range chars, -+ JS::RegExpFlags flags) { -+ FlatStringReader reader(chars); -+ RegExpCompileData result; -+ if (!CheckPatternSyntaxImpl(cx, &reader, flags, &result)) { -+ ReportSyntaxError(ts, result, chars.begin().get(), chars.length()); -+ return false; -+ } -+ return true; -+} -+ -+bool CheckPatternSyntax(JSContext* cx, TokenStreamAnyChars& ts, HandleAtom pattern, -+ JS::RegExpFlags flags) { -+ FlatStringReader reader(cx, pattern); -+ RegExpCompileData result; -+ if (!CheckPatternSyntaxImpl(cx, &reader, flags, &result)) { -+ ReportSyntaxError(ts, result, pattern); -+ return false; -+ } -+ return true; -+} -+ -+// A regexp is a good candidate for Boyer-Moore if it has at least 3 -+// times as many characters as it has unique characters. Note that -+// table lookups in irregexp are done modulo tableSize (128). -+template -+static bool HasFewDifferentCharacters(const CharT* chars, size_t length) { -+ const uint32_t tableSize = -+ v8::internal::NativeRegExpMacroAssembler::kTableSize; -+ bool character_found[tableSize]; -+ uint32_t different = 0; -+ memset(&character_found[0], 0, sizeof(character_found)); -+ for (uint32_t i = 0; i < length; i++) { -+ uint32_t ch = chars[i] % tableSize; -+ if (!character_found[ch]) { -+ character_found[ch] = true; -+ different++; -+ // We declare a regexp low-alphabet if it has at least 3 times as many -+ // characters as it has different characters. -+ if (different * 3 > length) { -+ return false; -+ } -+ } -+ } -+ return true; -+} -+ -+// Identifies the sort of pattern where Boyer-Moore is faster than string search -+static bool UseBoyerMoore(HandleAtom pattern, JS::AutoCheckCannotGC& nogc) { -+ size_t length = -+ std::min(size_t(kMaxLookaheadForBoyerMoore), pattern->length()); -+ if (length <= kPatternTooShortForBoyerMoore) { -+ return false; -+ } -+ -+ if (pattern->hasLatin1Chars()) { -+ return HasFewDifferentCharacters(pattern->latin1Chars(nogc), length); -+ } -+ MOZ_ASSERT(pattern->hasTwoByteChars()); -+ return HasFewDifferentCharacters(pattern->twoByteChars(nogc), length); -+} -+ -+// Sample character frequency information for use in Boyer-Moore. -+static void SampleCharacters(FlatStringReader* sample_subject, -+ RegExpCompiler& compiler) { -+ static const int kSampleSize = 128; -+ int chars_sampled = 0; -+ -+ int length = sample_subject->length(); -+ -+ int half_way = (length - kSampleSize) / 2; -+ for (int i = std::max(0, half_way); i < length && chars_sampled < kSampleSize; -+ i++, chars_sampled++) { -+ compiler.frequency_collator()->CountCharacter(sample_subject->Get(i)); -+ } -+} -+ -+// Recursively walking the AST for a deeply nested regexp (like -+// `/(a(a(a(a(a(a(a(...(a)...))))))))/`) may overflow the stack while -+// compiling. To avoid this, we use V8's implementation of the Visitor -+// pattern to walk the AST first with an overly large stack frame. -+class RegExpDepthCheck final : public v8::internal::RegExpVisitor { -+ public: -+ explicit RegExpDepthCheck(JSContext* cx) : cx_(cx) {} -+ -+ bool check(v8::internal::RegExpTree* root) { -+ return !!root->Accept(this, nullptr); -+ } -+ -+ // Leaf nodes with no children -+#define LEAF_DEPTH(Kind) \ -+ void* Visit##Kind(v8::internal::RegExp##Kind* node, void*) override { \ -+ uint8_t padding[FRAME_PADDING]; \ -+ dummy_ = padding; /* Prevent padding from being optimized away.*/ \ -+ return (void*)CheckRecursionLimitDontReport(cx_); \ -+ } -+ -+ LEAF_DEPTH(Assertion) -+ LEAF_DEPTH(Atom) -+ LEAF_DEPTH(BackReference) -+ LEAF_DEPTH(CharacterClass) -+ LEAF_DEPTH(Empty) -+ LEAF_DEPTH(Text) -+#undef LEAF_DEPTH -+ -+ // Wrapper nodes with one child -+#define WRAPPER_DEPTH(Kind) \ -+ void* Visit##Kind(v8::internal::RegExp##Kind* node, void*) override { \ -+ uint8_t padding[FRAME_PADDING]; \ -+ dummy_ = padding; /* Prevent padding from being optimized away.*/ \ -+ if (!CheckRecursionLimitDontReport(cx_)) { \ -+ return nullptr; \ -+ } \ -+ return node->body()->Accept(this, nullptr); \ -+ } -+ -+ WRAPPER_DEPTH(Capture) -+ WRAPPER_DEPTH(Group) -+ WRAPPER_DEPTH(Lookaround) -+ WRAPPER_DEPTH(Quantifier) -+#undef WRAPPER_DEPTH -+ -+ void* VisitAlternative(v8::internal::RegExpAlternative* node, -+ void*) override { -+ uint8_t padding[FRAME_PADDING]; -+ dummy_ = padding; /* Prevent padding from being optimized away.*/ -+ if (!CheckRecursionLimitDontReport(cx_)) { -+ return nullptr; -+ } -+ for (auto* child : *node->nodes()) { -+ if (!child->Accept(this, nullptr)) { -+ return nullptr; -+ } -+ } -+ return (void*)true; -+ } -+ void* VisitDisjunction(v8::internal::RegExpDisjunction* node, -+ void*) override { -+ uint8_t padding[FRAME_PADDING]; -+ dummy_ = padding; /* Prevent padding from being optimized away.*/ -+ if (!CheckRecursionLimitDontReport(cx_)) { -+ return nullptr; -+ } -+ for (auto* child : *node->alternatives()) { -+ if (!child->Accept(this, nullptr)) { -+ return nullptr; -+ } -+ } -+ return (void*)true; -+ } -+ -+ private: -+ JSContext* cx_; -+ void* dummy_ = nullptr; -+ -+ // This size is picked to be comfortably larger than any -+ // RegExp*::ToNode stack frame. -+ static const size_t FRAME_PADDING = 256; -+}; -+ -+enum class AssembleResult { -+ Success, -+ TooLarge, -+ OutOfMemory, -+}; -+ -+static MOZ_MUST_USE AssembleResult Assemble(JSContext* cx, -+ RegExpCompiler* compiler, -+ RegExpCompileData* data, -+ MutableHandleRegExpShared re, -+ HandleAtom pattern, Zone* zone, -+ bool useNativeCode, bool isLatin1) { -+ // Because we create a StackMacroAssembler, this function is not allowed -+ // to GC. If needed, we allocate and throw errors in the caller. -+ Maybe jctx; -+ Maybe stack_masm; -+ UniquePtr masm; -+ if (useNativeCode) { -+ NativeRegExpMacroAssembler::Mode mode = -+ isLatin1 ? NativeRegExpMacroAssembler::LATIN1 -+ : NativeRegExpMacroAssembler::UC16; -+ // If we are compiling native code, we need a macroassembler, -+ // which needs a jit context. -+ jctx.emplace(cx, nullptr); -+ stack_masm.emplace(); -+ uint32_t num_capture_registers = re->pairCount() * 2; -+ masm = MakeUnique(cx, stack_masm.ref(), zone, mode, -+ num_capture_registers); -+ } else { -+ masm = MakeUnique(cx->isolate, zone); -+ } -+ if (!masm) { -+ return AssembleResult::OutOfMemory; -+ } -+ -+ bool isLargePattern = -+ pattern->length() > v8::internal::RegExp::kRegExpTooLargeToOptimize; -+ masm->set_slow_safe(isLargePattern); -+ if (compiler->optimize()) { -+ compiler->set_optimize(!isLargePattern); -+ } -+ -+ // When matching a regexp with known maximum length that is anchored -+ // at the end, we may be able to skip the beginning of long input -+ // strings. This decision is made here because it depends on -+ // information in the AST that isn't replicated in the Node -+ // structure used inside the compiler. -+ bool is_start_anchored = data->tree->IsAnchoredAtStart(); -+ bool is_end_anchored = data->tree->IsAnchoredAtEnd(); -+ int max_length = data->tree->max_match(); -+ static const int kMaxBacksearchLimit = 1024; -+ if (is_end_anchored && !is_start_anchored && !re->sticky() && -+ max_length < kMaxBacksearchLimit) { -+ masm->SetCurrentPositionFromEnd(max_length); -+ } -+ -+ if (re->global()) { -+ RegExpMacroAssembler::GlobalMode mode = RegExpMacroAssembler::GLOBAL; -+ if (data->tree->min_match() > 0) { -+ mode = RegExpMacroAssembler::GLOBAL_NO_ZERO_LENGTH_CHECK; -+ } else if (re->unicode()) { -+ mode = RegExpMacroAssembler::GLOBAL_UNICODE; -+ } -+ masm->set_global_mode(mode); -+ } -+ -+ // Compile the regexp. -+ V8HandleString wrappedPattern(v8::internal::String(pattern), cx->isolate); -+ RegExpCompiler::CompilationResult result = compiler->Assemble( -+ cx->isolate, masm.get(), data->node, data->capture_count, wrappedPattern); -+ if (!result.Succeeded()) { -+ MOZ_ASSERT(result.error == RegExpError::kTooLarge); -+ return AssembleResult::TooLarge; -+ } -+ if (result.code->value().isUndefined()) { -+ // SMRegExpMacroAssembler::GetCode returns undefined on OOM. -+ MOZ_ASSERT(useNativeCode); -+ return AssembleResult::OutOfMemory; -+ } -+ -+ re->updateMaxRegisters(result.num_registers); -+ if (useNativeCode) { -+ // Transfer ownership of the tables from the macroassembler to the -+ // RegExpShared. -+ SMRegExpMacroAssembler::TableVector& tables = -+ static_cast(masm.get())->tables(); -+ for (uint32_t i = 0; i < tables.length(); i++) { -+ if (!re->addTable(std::move(tables[i]))) { -+ return AssembleResult::OutOfMemory; -+ } -+ } -+ re->setJitCode(v8::internal::Code::cast(*result.code).inner(), isLatin1); -+ } else { -+ // Transfer ownership of the bytecode from the HandleScope to the -+ // RegExpShared. -+ ByteArray bytecode = -+ v8::internal::ByteArray::cast(*result.code).takeOwnership(cx->isolate); -+ uint32_t length = bytecode->length; -+ re->setByteCode(bytecode.release(), isLatin1); -+ // js::AddCellMemory(re, length, MemoryUse::RegExpSharedBytecode); -+ } -+ -+ return AssembleResult::Success; -+} -+ -+bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re, -+ HandleLinearString input, RegExpShared::CodeKind codeKind) { -+ RootedAtom pattern(cx, re->getSource()); -+ JS::RegExpFlags flags = re->getFlags(); -+ LifoAllocScope allocScope(&cx->tempLifoAlloc()); -+ HandleScope handleScope(cx->isolate); -+ Zone zone(allocScope.alloc()); -+ -+ RegExpCompileData data; -+ { -+ FlatStringReader patternBytes(cx, pattern); -+ if (!RegExpParser::ParseRegExp(cx->isolate, &zone, &patternBytes, flags, -+ &data)) { -+ MOZ_ASSERT(data.error == RegExpError::kStackOverflow); -+ JS::CompileOptions options(cx); -+ DummyTokenStream dummyTokenStream(cx, options); -+ ReportSyntaxError(dummyTokenStream, data, pattern); -+ return false; -+ } -+ } -+ -+ // Avoid stack overflow while recursively walking the AST. -+ RegExpDepthCheck depthCheck(cx); -+ if (!depthCheck.check(data.tree)) { -+ JS_ReportErrorASCII(cx, "regexp too big"); -+ return false; -+ } -+ -+ if (re->kind() == RegExpShared::Kind::Unparsed) { -+ // This is the first time we have compiled this regexp. -+ // First, check to see if we should use simple string search -+ // with an atom. -+ if (!flags.ignoreCase() && !flags.sticky()) { -+ RootedAtom searchAtom(cx); -+ if (data.simple) { -+ // The parse-tree is a single atom that is equal to the pattern. -+ searchAtom = re->getSource(); -+ } else if (data.tree->IsAtom() && data.capture_count == 0) { -+ // The parse-tree is a single atom that is not equal to the pattern. -+ v8::internal::RegExpAtom* atom = data.tree->AsAtom(); -+ const char16_t* twoByteChars = atom->data().begin(); -+ searchAtom = AtomizeChars(cx, twoByteChars, atom->length()); -+ if (!searchAtom) { -+ return false; -+ } -+ } -+ JS::AutoCheckCannotGC nogc(cx); -+ if (searchAtom && !UseBoyerMoore(searchAtom, nogc)) { -+ re->useAtomMatch(searchAtom); -+ return true; -+ } -+ } -+ if (!data.capture_name_map.is_null()) { -+ RootedNativeObject namedCaptures(cx, data.capture_name_map->inner()); -+ if (!RegExpShared::initializeNamedCaptures(cx, re, namedCaptures)) { -+ return false; -+ } -+ } -+ // All fallible initialization has succeeded, so we can change state. -+ // Add one to capture_count to account for the whole-match capture. -+ uint32_t pairCount = data.capture_count + 1; -+ re->useRegExpMatch(pairCount); -+ } -+ -+ MOZ_ASSERT(re->kind() == RegExpShared::Kind::RegExp); -+ -+ RegExpCompiler compiler(cx->isolate, &zone, data.capture_count, -+ input->hasLatin1Chars()); -+ -+ bool isLatin1 = input->hasLatin1Chars(); -+ -+ FlatStringReader sample_subject(cx, input); -+ SampleCharacters(&sample_subject, compiler); -+ data.node = compiler.PreprocessRegExp(&data, flags, isLatin1); -+ data.error = AnalyzeRegExp(cx->isolate, isLatin1, data.node); -+ if (data.error != RegExpError::kNone) { -+ MOZ_ASSERT(data.error == RegExpError::kAnalysisStackOverflow); -+ ReportOverRecursed(cx); -+ return false; -+ } -+ -+ bool useNativeCode = codeKind == RegExpShared::CodeKind::Jitcode; -+ MOZ_ASSERT_IF(useNativeCode, IsNativeRegExpEnabled(cx)); -+ -+ switch (Assemble(cx, &compiler, &data, re, pattern, &zone, useNativeCode, -+ isLatin1)) { -+ case AssembleResult::TooLarge: -+ JS_ReportErrorASCII(cx, "regexp too big"); -+ return false; -+ case AssembleResult::OutOfMemory: -+ ReportOutOfMemory(cx); -+ return false; -+ case AssembleResult::Success: -+ break; -+ } -+ return true; -+} -+ -+template -+RegExpRunStatus ExecuteRaw(jit::JitCode* code, const CharT* chars, -+ size_t length, size_t startIndex, -+ MatchPairs* matches) { -+ InputOutputData data(chars, chars + length, startIndex, matches); -+ -+ static_assert(RegExpRunStatus_Error == -+ v8::internal::RegExp::kInternalRegExpException); -+ static_assert(RegExpRunStatus_Success == -+ v8::internal::RegExp::kInternalRegExpSuccess); -+ static_assert(RegExpRunStatus_Success_NotFound == -+ v8::internal::RegExp::kInternalRegExpFailure); -+ -+ typedef int (*RegExpCodeSignature)(InputOutputData*); -+ auto function = reinterpret_cast(code->raw()); -+ { -+ JS::AutoSuppressGCAnalysis nogc; -+ return (RegExpRunStatus)CALL_GENERATED_1(function, &data); -+ } -+} -+ -+RegExpRunStatus Interpret(JSContext* cx, MutableHandleRegExpShared re, -+ HandleLinearString input, size_t startIndex, -+ MatchPairs* matches) { -+ MOZ_ASSERT(re->getByteCode(input->hasLatin1Chars())); -+ -+ HandleScope handleScope(cx->isolate); -+ V8HandleRegExp wrappedRegExp(v8::internal::JSRegExp(re), cx->isolate); -+ V8HandleString wrappedInput(v8::internal::String(input), cx->isolate); -+ -+ static_assert(RegExpRunStatus_Error == -+ v8::internal::RegExp::kInternalRegExpException); -+ static_assert(RegExpRunStatus_Success == -+ v8::internal::RegExp::kInternalRegExpSuccess); -+ static_assert(RegExpRunStatus_Success_NotFound == -+ v8::internal::RegExp::kInternalRegExpFailure); -+ -+ RegExpRunStatus status = -+ (RegExpRunStatus)IrregexpInterpreter::MatchForCallFromRuntime( -+ cx->isolate, wrappedRegExp, wrappedInput, matches->pairsRaw(), -+ matches->pairCount() * 2, startIndex); -+ -+ MOZ_ASSERT(status == RegExpRunStatus_Error || -+ status == RegExpRunStatus_Success || -+ status == RegExpRunStatus_Success_NotFound); -+ -+ return status; -+} -+ -+RegExpRunStatus Execute(JSContext* cx, MutableHandleRegExpShared re, -+ HandleLinearString input, size_t startIndex, -+ MatchPairs* matches) { -+ bool latin1 = input->hasLatin1Chars(); -+ jit::JitCode* jitCode = re->getJitCode(latin1); -+ bool isCompiled = !!jitCode; -+ -+ // Reset the Irregexp backtrack stack if it grows during execution. -+ irregexp::RegExpStackScope stackScope(cx->isolate); -+ -+ if (isCompiled) { -+ JS::AutoCheckCannotGC nogc; -+ if (latin1) { -+ return ExecuteRaw(jitCode, input->latin1Chars(nogc), input->length(), -+ startIndex, matches); -+ } -+ return ExecuteRaw(jitCode, input->twoByteChars(nogc), input->length(), -+ startIndex, matches); -+ } -+ -+ return Interpret(cx, re, input, startIndex, matches); -+} -+ -+} // namespace irregexp -+} // namespace js -diff -Nrup mozilla/js/src/irregexp/RegExpAPI.h mozilla-OK/js/src/irregexp/RegExpAPI.h ---- mozilla/js/src/irregexp/RegExpAPI.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpAPI.h 2022-06-16 00:07:27.342875589 +0300 -@@ -0,0 +1,46 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * This Source Code Form is "Incompatible With Secondary Licenses", as -+ * defined by the Mozilla Public License, v. 2.0. -+ */ -+ -+/* This is the interface that the regexp engine exposes to SpiderMonkey. */ -+ -+#ifndef regexp_RegExpAPI_h -+#define regexp_RegExpAPI_h -+ -+#include "mozilla/MemoryReporting.h" -+ -+#include "frontend/TokenStream.h" -+#include "jscntxt.h" -+#include "jsgc.h" -+#include "vm/RegExpObject.h" -+ -+namespace js { -+namespace irregexp { -+ -+Isolate* CreateIsolate(JSContext* cx); -+void DestroyIsolate(Isolate* isolate); -+ -+size_t IsolateSizeOfIncludingThis(Isolate* isolate, -+ mozilla::MallocSizeOf mallocSizeOf); -+ -+bool CheckPatternSyntax(JSContext* cx, frontend::TokenStreamAnyChars& ts, -+ const mozilla::Range chars, -+ JS::RegExpFlags flags); -+bool CheckPatternSyntax(JSContext* cx, frontend::TokenStreamAnyChars& ts, -+ HandleAtom pattern, JS::RegExpFlags flags); -+bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re, -+ HandleLinearString input, RegExpShared::CodeKind codeKind); -+ -+RegExpRunStatus Execute(JSContext* cx, MutableHandleRegExpShared re, -+ HandleLinearString input, size_t start, -+ MatchPairs* matches); -+ -+} // namespace irregexp -+} // namespace js -+ -+#endif /* regexp_RegExpAPI_h */ -diff -Nrup mozilla/js/src/irregexp/RegExpNativeMacroAssembler.cpp mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.cpp ---- mozilla/js/src/irregexp/RegExpNativeMacroAssembler.cpp 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.cpp 2022-06-16 00:06:40.924190752 +0300 -@@ -0,0 +1,1250 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+// Copyright 2020 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "irregexp/imported/regexp-macro-assembler-arch.h" -+#include "irregexp/imported/regexp-stack.h" -+#include "irregexp/imported/special-case.h" -+#include "jit/Linker.h" -+#include "gc/Zone.h" -+#include "vm/MatchPairs.h" -+ -+#include "jit/MacroAssembler-inl.h" -+ -+using namespace js; -+using namespace js::irregexp; -+using namespace js::jit; -+ -+namespace v8 { -+namespace internal { -+ -+using js::MatchPairs; -+using js::jit::AbsoluteAddress; -+using js::jit::Address; -+using js::jit::AllocatableGeneralRegisterSet; -+using js::jit::Assembler; -+using js::jit::BaseIndex; -+using js::jit::CodeLocationLabel; -+using js::jit::GeneralRegisterBackwardIterator; -+using js::jit::GeneralRegisterForwardIterator; -+using js::jit::GeneralRegisterSet; -+using js::jit::Imm32; -+using js::jit::ImmPtr; -+using js::jit::ImmWord; -+using js::jit::JitCode; -+using js::jit::Linker; -+using js::jit::LiveGeneralRegisterSet; -+using js::jit::Register; -+using js::jit::Registers; -+using js::jit::StackMacroAssembler; -+ -+SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, -+ StackMacroAssembler& masm, -+ Zone* zone, Mode mode, -+ uint32_t num_capture_registers) -+ : NativeRegExpMacroAssembler(cx->isolate, zone), -+ cx_(cx), -+ masm_(masm), -+ mode_(mode), -+ num_registers_(num_capture_registers), -+ num_capture_registers_(num_capture_registers) { -+ // Each capture has a start and an end register -+ MOZ_ASSERT(num_capture_registers_ % 2 == 0); -+ -+ AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); -+ -+ temp0_ = regs.takeAny(); -+ temp1_ = regs.takeAny(); -+ temp2_ = regs.takeAny(); -+ input_end_pointer_ = regs.takeAny(); -+ current_character_ = regs.takeAny(); -+ current_position_ = regs.takeAny(); -+ backtrack_stack_pointer_ = regs.takeAny(); -+ savedRegisters_ = js::jit::SavedNonVolatileRegisters(regs); -+ -+ masm_.jump(&entry_label_); // We'll generate the entry code later -+ masm_.bind(&start_label_); // and continue from here. -+} -+ -+int SMRegExpMacroAssembler::stack_limit_slack() { -+ return RegExpStack::kStackLimitSlack; -+} -+ -+void SMRegExpMacroAssembler::AdvanceCurrentPosition(int by) { -+ if (by != 0) { -+ masm_.addPtr(Imm32(by * char_size()), current_position_); -+ } -+} -+ -+void SMRegExpMacroAssembler::AdvanceRegister(int reg, int by) { -+ MOZ_ASSERT(reg >= 0 && reg < num_registers_); -+ if (by != 0) { -+ masm_.addPtr(Imm32(by), register_location(reg)); -+ } -+} -+ -+void SMRegExpMacroAssembler::Backtrack() { -+ // Check for an interrupt. We have to restart from the beginning if we -+ // are interrupted, so we only check for urgent interrupts. -+ js::jit::Label noInterrupt; -+ masm_.branch32(Assembler::Equal, -+ AbsoluteAddress(cx_->addressOfInterruptRegExpJit()), Imm32(0), -+ &noInterrupt); -+ masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); -+ masm_.jump(&exit_label_); -+ masm_.bind(&noInterrupt); -+ -+ // Pop code location from backtrack stack and jump to location. -+ Pop(temp0_); -+ masm_.jump(temp0_); -+} -+ -+void SMRegExpMacroAssembler::Bind(Label* label) { -+ masm_.bind(label->inner()); -+ if (label->patchOffset_.bound()) { -+ AddLabelPatch(label->patchOffset_, label->pos()); -+ } -+} -+ -+// Check if current_position + cp_offset is the input start -+void SMRegExpMacroAssembler::CheckAtStartImpl(int cp_offset, Label* on_cond, -+ Assembler::Condition cond) { -+ Address addr(current_position_, cp_offset * char_size()); -+ masm_.computeEffectiveAddress(addr, temp0_); -+ -+ masm_.branchPtr(cond, inputStart(), temp0_, LabelOrBacktrack(on_cond)); -+} -+ -+void SMRegExpMacroAssembler::CheckAtStart(int cp_offset, Label* on_at_start) { -+ CheckAtStartImpl(cp_offset, on_at_start, Assembler::Equal); -+} -+ -+void SMRegExpMacroAssembler::CheckNotAtStart(int cp_offset, -+ Label* on_not_at_start) { -+ CheckAtStartImpl(cp_offset, on_not_at_start, Assembler::NotEqual); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterImpl(Imm32 c, Label* on_cond, -+ Assembler::Condition cond) { -+ masm_.branch32(cond, current_character_, c, LabelOrBacktrack(on_cond)); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacter(uint32_t c, Label* on_equal) { -+ CheckCharacterImpl(Imm32(c), on_equal, Assembler::Equal); -+} -+ -+void SMRegExpMacroAssembler::CheckNotCharacter(uint32_t c, -+ Label* on_not_equal) { -+ CheckCharacterImpl(Imm32(c), on_not_equal, Assembler::NotEqual); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterGT(uc16 c, Label* on_greater) { -+ CheckCharacterImpl(Imm32(c), on_greater, Assembler::GreaterThan); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterLT(uc16 c, Label* on_less) { -+ CheckCharacterImpl(Imm32(c), on_less, Assembler::LessThan); -+} -+ -+// Bitwise-and the current character with mask and then check for a -+// match with c. -+void SMRegExpMacroAssembler::CheckCharacterAfterAndImpl(uint32_t c, -+ uint32_t mask, -+ Label* on_cond, -+ bool is_not) { -+ if (c == 0) { -+ Assembler::Condition cond = is_not ? Assembler::NonZero : Assembler::Zero; -+ masm_.branchTest32(cond, current_character_, Imm32(mask), -+ LabelOrBacktrack(on_cond)); -+ } else { -+ Assembler::Condition cond = is_not ? Assembler::NotEqual : Assembler::Equal; -+ masm_.move32(Imm32(mask), temp0_); -+ masm_.and32(current_character_, temp0_); -+ masm_.branch32(cond, temp0_, Imm32(c), LabelOrBacktrack(on_cond)); -+ } -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, -+ Label* on_equal) { -+ CheckCharacterAfterAndImpl(c, mask, on_equal, /*is_not =*/false); -+} -+ -+void SMRegExpMacroAssembler::CheckNotCharacterAfterAnd(uint32_t c, -+ uint32_t mask, -+ Label* on_not_equal) { -+ CheckCharacterAfterAndImpl(c, mask, on_not_equal, /*is_not =*/true); -+} -+ -+// Subtract minus from the current character, then bitwise-and the -+// result with mask, then check for a match with c. -+void SMRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd( -+ uc16 c, uc16 minus, uc16 mask, Label* on_not_equal) { -+ masm_.computeEffectiveAddress(Address(current_character_, -minus), temp0_); -+ if (c == 0) { -+ masm_.branchTest32(Assembler::NonZero, temp0_, Imm32(mask), -+ LabelOrBacktrack(on_not_equal)); -+ } else { -+ masm_.and32(Imm32(mask), temp0_); -+ masm_.branch32(Assembler::NotEqual, temp0_, Imm32(c), -+ LabelOrBacktrack(on_not_equal)); -+ } -+} -+ -+// If the current position matches the position stored on top of the backtrack -+// stack, pops the backtrack stack and branches to the given label. -+void SMRegExpMacroAssembler::CheckGreedyLoop(Label* on_equal) { -+ js::jit::Label fallthrough; -+ masm_.branchPtr(Assembler::NotEqual, Address(backtrack_stack_pointer_, 0), -+ current_position_, &fallthrough); -+ masm_.addPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_); // Pop. -+ JumpOrBacktrack(on_equal); -+ masm_.bind(&fallthrough); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterInRangeImpl( -+ uc16 from, uc16 to, Label* on_cond, Assembler::Condition cond) { -+ // x is in [from,to] if unsigned(x - from) <= to - from -+ masm_.computeEffectiveAddress(Address(current_character_, -from), temp0_); -+ masm_.branch32(cond, temp0_, Imm32(to - from), LabelOrBacktrack(on_cond)); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterInRange(uc16 from, uc16 to, -+ Label* on_in_range) { -+ CheckCharacterInRangeImpl(from, to, on_in_range, Assembler::BelowOrEqual); -+} -+ -+void SMRegExpMacroAssembler::CheckCharacterNotInRange(uc16 from, uc16 to, -+ Label* on_not_in_range) { -+ CheckCharacterInRangeImpl(from, to, on_not_in_range, Assembler::Above); -+} -+ -+void SMRegExpMacroAssembler::CheckBitInTable(Handle table, -+ Label* on_bit_set) { -+ // Claim ownership of the ByteArray from the current HandleScope. -+ // ByteArrays are allocated on the C++ heap and are (eventually) -+ // owned by the RegExpShared. -+ PseudoHandle rawTable = table->takeOwnership(isolate()); -+ -+ masm_.movePtr(ImmPtr(rawTable->data()), temp0_); -+ -+ masm_.move32(Imm32(kTableMask), temp1_); -+ masm_.and32(current_character_, temp1_); -+ -+ masm_.load8ZeroExtend(BaseIndex(temp0_, temp1_, js::jit::TimesOne), temp0_); -+ masm_.branchTest32(Assembler::NonZero, temp0_, temp0_, -+ LabelOrBacktrack(on_bit_set)); -+ -+ // Transfer ownership of |rawTable| to the |tables_| vector. -+ AddTable(std::move(rawTable)); -+} -+ -+void SMRegExpMacroAssembler::CheckNotBackReferenceImpl(int start_reg, -+ bool read_backward, -+ bool unicode, -+ Label* on_no_match, -+ bool ignore_case) { -+ js::jit::Label fallthrough; -+ -+ // Captures are stored as a sequential pair of registers. -+ // Find the length of the back-referenced capture and load the -+ // capture's start index into current_character_. -+ masm_.loadPtr(register_location(start_reg), // index of start -+ current_character_); -+ masm_.loadPtr(register_location(start_reg + 1), temp0_); // index of end -+ masm_.subPtr(current_character_, temp0_); // length of capture -+ -+ // Capture registers are either both set or both cleared. -+ // If the capture length is zero, then the capture is either empty or cleared. -+ // Fall through in both cases. -+ masm_.branchPtr(Assembler::Equal, temp0_, ImmWord(0), &fallthrough); -+ -+ // Check that there are sufficient characters left in the input. -+ if (read_backward) { -+ // If start + len > current, there isn't enough room for a -+ // lookbehind backreference. -+ masm_.loadPtr(inputStart(), temp1_); -+ masm_.addPtr(temp0_, temp1_); -+ masm_.branchPtr(Assembler::GreaterThan, temp1_, current_position_, -+ LabelOrBacktrack(on_no_match)); -+ } else { -+ // current_position_ is the negative offset from the end. -+ // If current + len > 0, there isn't enough room for a backreference. -+ masm_.movePtr(current_position_, temp1_); -+ masm_.addPtr(temp0_, temp1_); -+ masm_.branchPtr(Assembler::GreaterThan, temp1_, ImmWord(0), -+ LabelOrBacktrack(on_no_match)); -+ } -+ -+ if (mode_ == UC16 && ignore_case) { -+ // We call a helper function for case-insensitive non-latin1 strings. -+ -+ // Save volatile regs. temp1_, temp2_, and current_character_ -+ // don't need to be saved. current_position_ needs to be saved -+ // even if it's non-volatile, because we modify it to use as an argument. -+ LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile()); -+ volatileRegs.addUnchecked(current_position_); -+ volatileRegs.takeUnchecked(temp1_); -+ volatileRegs.takeUnchecked(temp2_); -+ volatileRegs.takeUnchecked(current_character_); -+ masm_.PushRegsInMask(volatileRegs); -+ -+ // Parameters are -+ // Address captured - Address of captured substring's start. -+ // Address current - Address of current character position. -+ // size_t byte_length - length of capture (in bytes) -+ -+ // Compute |captured| -+ masm_.addPtr(input_end_pointer_, current_character_); -+ -+ // Compute |current| -+ masm_.addPtr(input_end_pointer_, current_position_); -+ if (read_backward) { -+ // Offset by length when matching backwards. -+ masm_.subPtr(temp0_, current_position_); -+ } -+ -+ masm_.setupUnalignedABICall(temp1_); -+ masm_.passABIArg(current_character_); -+ masm_.passABIArg(current_position_); -+ masm_.passABIArg(temp0_); -+ -+ if (unicode) { -+ uint32_t (*fun)(const char16_t*, const char16_t*, size_t) = -+ CaseInsensitiveCompareUnicode; -+ masm_.callWithABI(JS_FUNC_TO_DATA_PTR(void*, fun)); -+ } else { -+ uint32_t (*fun)(const char16_t*, const char16_t*, size_t) = -+ CaseInsensitiveCompareNonUnicode; -+ masm_.callWithABI(JS_FUNC_TO_DATA_PTR(void*, fun)); -+ } -+ masm_.storeCallInt32Result(temp1_); -+ masm_.PopRegsInMask(volatileRegs); -+ masm_.branchTest32(Assembler::Zero, temp1_, temp1_, -+ LabelOrBacktrack(on_no_match)); -+ -+ // On success, advance position by length of capture -+ if (read_backward) { -+ masm_.subPtr(temp0_, current_position_); -+ } else { -+ masm_.addPtr(temp0_, current_position_); -+ } -+ -+ masm_.bind(&fallthrough); -+ return; -+ } -+ -+ // We will be modifying current_position_. Save it in case the match fails. -+ masm_.push(current_position_); -+ -+ // Compute start of capture string -+ masm_.addPtr(input_end_pointer_, current_character_); -+ -+ // Compute start of match string -+ masm_.addPtr(input_end_pointer_, current_position_); -+ if (read_backward) { -+ // Offset by length when matching backwards. -+ masm_.subPtr(temp0_, current_position_); -+ } -+ -+ // Compute end of match string -+ masm_.addPtr(current_position_, temp0_); -+ -+ js::jit::Label success; -+ js::jit::Label fail; -+ js::jit::Label loop; -+ masm_.bind(&loop); -+ -+ // Load next character from each string. -+ if (mode_ == LATIN1) { -+ masm_.load8ZeroExtend(Address(current_character_, 0), temp1_); -+ masm_.load8ZeroExtend(Address(current_position_, 0), temp2_); -+ } else { -+ masm_.load16ZeroExtend(Address(current_character_, 0), temp1_); -+ masm_.load16ZeroExtend(Address(current_position_, 0), temp2_); -+ } -+ -+ if (ignore_case) { -+ MOZ_ASSERT(mode_ == LATIN1); -+ // Try exact match. -+ js::jit::Label loop_increment; -+ masm_.branch32(Assembler::Equal, temp1_, temp2_, &loop_increment); -+ -+ // Mismatch. Try case-insensitive match. -+ // Force the capture character to lower case (by setting bit 0x20) -+ // then check to see if it is a letter. -+ js::jit::Label convert_match; -+ masm_.or32(Imm32(0x20), temp1_); -+ -+ // Check if it is in [a,z]. -+ masm_.computeEffectiveAddress(Address(temp1_, -'a'), temp2_); -+ masm_.branch32(Assembler::BelowOrEqual, temp2_, Imm32('z' - 'a'), -+ &convert_match); -+ // Check for values in range [224,254]. -+ // Exclude 247 (U+00F7 DIVISION SIGN). -+ masm_.sub32(Imm32(224 - 'a'), temp2_); -+ masm_.branch32(Assembler::Above, temp2_, Imm32(254 - 224), &fail); -+ masm_.branch32(Assembler::Equal, temp2_, Imm32(247 - 224), &fail); -+ -+ // Capture character is lower case. Convert match character -+ // to lower case and compare. -+ masm_.bind(&convert_match); -+ masm_.load8ZeroExtend(Address(current_position_, 0), temp2_); -+ masm_.or32(Imm32(0x20), temp2_); -+ masm_.branch32(Assembler::NotEqual, temp1_, temp2_, &fail); -+ -+ masm_.bind(&loop_increment); -+ } else { -+ // Fail if characters do not match. -+ masm_.branch32(Assembler::NotEqual, temp1_, temp2_, &fail); -+ } -+ -+ // Increment pointers into match and capture strings. -+ masm_.addPtr(Imm32(char_size()), current_character_); -+ masm_.addPtr(Imm32(char_size()), current_position_); -+ -+ // Loop if we have not reached the end of the match string. -+ masm_.branchPtr(Assembler::Below, current_position_, temp0_, &loop); -+ masm_.jump(&success); -+ -+ // If we fail, restore current_position_ and branch. -+ masm_.bind(&fail); -+ masm_.pop(current_position_); -+ JumpOrBacktrack(on_no_match); -+ -+ masm_.bind(&success); -+ -+ // Drop saved value of current_position_ -+ masm_.addToStackPtr(Imm32(sizeof(uintptr_t))); -+ -+ // current_position_ is a pointer. Convert it back to an offset. -+ masm_.subPtr(input_end_pointer_, current_position_); -+ if (read_backward) { -+ // Subtract match length if we matched backward -+ masm_.addPtr(register_location(start_reg), current_position_); -+ masm_.subPtr(register_location(start_reg + 1), current_position_); -+ } -+ -+ masm_.bind(&fallthrough); -+} -+ -+// Branch if a back-reference does not match a previous capture. -+void SMRegExpMacroAssembler::CheckNotBackReference(int start_reg, -+ bool read_backward, -+ Label* on_no_match) { -+ CheckNotBackReferenceImpl(start_reg, read_backward, /*unicode = */ false, -+ on_no_match, /*ignore_case = */ false); -+} -+ -+void SMRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase( -+ int start_reg, bool read_backward, bool unicode, Label* on_no_match) { -+ CheckNotBackReferenceImpl(start_reg, read_backward, unicode, on_no_match, -+ /*ignore_case = */ true); -+} -+ -+// Checks whether the given offset from the current position is -+// inside the input string. -+void SMRegExpMacroAssembler::CheckPosition(int cp_offset, -+ Label* on_outside_input) { -+ // Note: current_position_ is a (negative) byte offset relative to -+ // the end of the input string. -+ if (cp_offset >= 0) { -+ // end + current + offset >= end -+ // <=> current + offset >= 0 -+ // <=> current >= -offset -+ masm_.branchPtr(Assembler::GreaterThanOrEqual, current_position_, -+ ImmWord(-cp_offset * char_size()), -+ LabelOrBacktrack(on_outside_input)); -+ } else { -+ // Compute offset position -+ masm_.computeEffectiveAddress( -+ Address(current_position_, cp_offset * char_size()), temp0_); -+ -+ // Compare to start of input. -+ masm_.branchPtr(Assembler::GreaterThan, inputStart(), temp0_, -+ LabelOrBacktrack(on_outside_input)); -+ } -+} -+ -+// This function attempts to generate special case code for character classes. -+// Returns true if a special case is generated. -+// Otherwise returns false and generates no code. -+bool SMRegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type, -+ Label* on_no_match) { -+ js::jit::Label* no_match = LabelOrBacktrack(on_no_match); -+ -+ // Note: throughout this function, range checks (c in [min, max]) -+ // are implemented by an unsigned (c - min) <= (max - min) check. -+ switch (type) { -+ case 's': { -+ // Match space-characters -+ if (mode_ != LATIN1) { -+ return false; -+ } -+ js::jit::Label success; -+ // One byte space characters are ' ', '\t'..'\r', and '\u00a0' (NBSP). -+ -+ // Check ' ' -+ masm_.branch32(Assembler::Equal, current_character_, Imm32(' '), -+ &success); -+ -+ // Check '\t'..'\r' -+ masm_.computeEffectiveAddress(Address(current_character_, -'\t'), temp0_); -+ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32('\r' - '\t'), -+ &success); -+ -+ // Check \u00a0. -+ masm_.branch32(Assembler::NotEqual, temp0_, Imm32(0x00a0 - '\t'), -+ no_match); -+ -+ masm_.bind(&success); -+ return true; -+ } -+ case 'S': -+ // The emitted code for generic character classes is good enough. -+ return false; -+ case 'd': -+ // Match latin1 digits ('0'-'9') -+ masm_.computeEffectiveAddress(Address(current_character_, -'0'), temp0_); -+ masm_.branch32(Assembler::Above, temp0_, Imm32('9' - '0'), no_match); -+ return true; -+ case 'D': -+ // Match anything except latin1 digits ('0'-'9') -+ masm_.computeEffectiveAddress(Address(current_character_, -'0'), temp0_); -+ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32('9' - '0'), -+ no_match); -+ return true; -+ case '.': -+ // Match non-newlines. This excludes '\n' (0x0a), '\r' (0x0d), -+ // U+2028 LINE SEPARATOR, and U+2029 PARAGRAPH SEPARATOR. -+ // See https://tc39.es/ecma262/#prod-LineTerminator -+ -+ // To test for 0x0a and 0x0d efficiently, we XOR the input with 1. -+ // This converts 0x0a to 0x0b, and 0x0d to 0x0c, allowing us to -+ // test for the contiguous range 0x0b..0x0c. -+ masm_.move32(current_character_, temp0_); -+ masm_.xor32(Imm32(0x01), temp0_); -+ masm_.sub32(Imm32(0x0b), temp0_); -+ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32(0x0c - 0x0b), -+ no_match); -+ -+ if (mode_ == UC16) { -+ // Compare original value to 0x2028 and 0x2029, using the already -+ // computed (current_char ^ 0x01 - 0x0b). I.e., check for -+ // 0x201d (0x2028 - 0x0b) or 0x201e. -+ masm_.sub32(Imm32(0x2028 - 0x0b), temp0_); -+ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32(0x2029 - 0x2028), -+ no_match); -+ } -+ return true; -+ case 'w': -+ // \w matches the set of 63 characters defined in Runtime Semantics: -+ // WordCharacters. We use a static lookup table, which is defined in -+ // regexp-macro-assembler.cc. -+ // Note: if both Unicode and IgnoreCase are true, \w matches a -+ // larger set of characters. That case is handled elsewhere. -+ if (mode_ != LATIN1) { -+ masm_.branch32(Assembler::Above, current_character_, Imm32('z'), -+ no_match); -+ } -+ static_assert( -+ arraysize(word_character_map) > unibrow::Latin1::kMaxChar, -+ "regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar"); -+ masm_.movePtr(ImmPtr(word_character_map), temp0_); -+ masm_.load8ZeroExtend( -+ BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); -+ masm_.branchTest32(Assembler::Zero, temp0_, temp0_, no_match); -+ return true; -+ case 'W': { -+ // See 'w' above. -+ js::jit::Label done; -+ if (mode_ != LATIN1) { -+ masm_.branch32(Assembler::Above, current_character_, Imm32('z'), &done); -+ } -+ static_assert( -+ arraysize(word_character_map) > unibrow::Latin1::kMaxChar, -+ "regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar"); -+ masm_.movePtr(ImmPtr(word_character_map), temp0_); -+ masm_.load8ZeroExtend( -+ BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); -+ masm_.branchTest32(Assembler::NonZero, temp0_, temp0_, no_match); -+ if (mode_ != LATIN1) { -+ masm_.bind(&done); -+ } -+ return true; -+ } -+ //////////////////////////////////////////////////////////////////////// -+ // Non-standard classes (with no syntactic shorthand) used internally // -+ //////////////////////////////////////////////////////////////////////// -+ case '*': -+ // Match any character -+ return true; -+ case 'n': -+ // Match newlines. The opposite of '.'. See '.' above. -+ masm_.move32(current_character_, temp0_); -+ masm_.xor32(Imm32(0x01), temp0_); -+ masm_.sub32(Imm32(0x0b), temp0_); -+ if (mode_ == LATIN1) { -+ masm_.branch32(Assembler::Above, temp0_, Imm32(0x0c - 0x0b), no_match); -+ } else { -+ MOZ_ASSERT(mode_ == UC16); -+ js::jit::Label done; -+ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32(0x0c - 0x0b), -+ &done); -+ -+ // Compare original value to 0x2028 and 0x2029, using the already -+ // computed (current_char ^ 0x01 - 0x0b). I.e., check for -+ // 0x201d (0x2028 - 0x0b) or 0x201e. -+ masm_.sub32(Imm32(0x2028 - 0x0b), temp0_); -+ masm_.branch32(Assembler::Above, temp0_, Imm32(0x2029 - 0x2028), -+ no_match); -+ masm_.bind(&done); -+ } -+ return true; -+ -+ // No custom implementation -+ default: -+ return false; -+ } -+} -+ -+void SMRegExpMacroAssembler::Fail() { -+ masm_.movePtr(ImmWord(js::RegExpRunStatus_Success_NotFound), temp0_); -+ masm_.jump(&exit_label_); -+} -+ -+void SMRegExpMacroAssembler::GoTo(Label* to) { -+ masm_.jump(LabelOrBacktrack(to)); -+} -+ -+void SMRegExpMacroAssembler::IfRegisterGE(int reg, int comparand, -+ Label* if_ge) { -+ masm_.branchPtr(Assembler::GreaterThanOrEqual, register_location(reg), -+ ImmWord(comparand), LabelOrBacktrack(if_ge)); -+} -+ -+void SMRegExpMacroAssembler::IfRegisterLT(int reg, int comparand, -+ Label* if_lt) { -+ masm_.branchPtr(Assembler::LessThan, register_location(reg), -+ ImmWord(comparand), LabelOrBacktrack(if_lt)); -+} -+ -+void SMRegExpMacroAssembler::IfRegisterEqPos(int reg, Label* if_eq) { -+ masm_.branchPtr(Assembler::Equal, register_location(reg), current_position_, -+ LabelOrBacktrack(if_eq)); -+} -+ -+// This is a word-for-word identical copy of the V8 code, which is -+// duplicated in at least nine different places in V8 (one per -+// supported architecture) with no differences outside of comments and -+// formatting. It should be hoisted into the superclass. Once that is -+// done upstream, this version can be deleted. -+void SMRegExpMacroAssembler::LoadCurrentCharacterImpl(int cp_offset, -+ Label* on_end_of_input, -+ bool check_bounds, -+ int characters, -+ int eats_at_least) { -+ // It's possible to preload a small number of characters when each success -+ // path requires a large number of characters, but not the reverse. -+ MOZ_ASSERT(eats_at_least >= characters); -+ MOZ_ASSERT(cp_offset < (1 << 30)); // Be sane! (And ensure negation works) -+ -+ if (check_bounds) { -+ if (cp_offset >= 0) { -+ CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input); -+ } else { -+ CheckPosition(cp_offset, on_end_of_input); -+ } -+ } -+ LoadCurrentCharacterUnchecked(cp_offset, characters); -+} -+ -+// Load the character (or characters) at the specified offset from the -+// current position. Zero-extend to 32 bits. -+void SMRegExpMacroAssembler::LoadCurrentCharacterUnchecked(int cp_offset, -+ int characters) { -+ BaseIndex address(input_end_pointer_, current_position_, js::jit::TimesOne, -+ cp_offset * char_size()); -+ if (mode_ == LATIN1) { -+ if (characters == 4) { -+ masm_.load32(address, current_character_); -+ } else if (characters == 2) { -+ masm_.load16ZeroExtend(address, current_character_); -+ } else { -+ MOZ_ASSERT(characters == 1); -+ masm_.load8ZeroExtend(address, current_character_); -+ } -+ } else { -+ MOZ_ASSERT(mode_ == UC16); -+ if (characters == 2) { -+ masm_.load32(address, current_character_); -+ } else { -+ MOZ_ASSERT(characters == 1); -+ masm_.load16ZeroExtend(address, current_character_); -+ } -+ } -+} -+ -+void SMRegExpMacroAssembler::PopCurrentPosition() { Pop(current_position_); } -+ -+void SMRegExpMacroAssembler::PopRegister(int register_index) { -+ Pop(temp0_); -+ masm_.storePtr(temp0_, register_location(register_index)); -+} -+ -+void SMRegExpMacroAssembler::PushBacktrack(Label* label) { -+ MOZ_ASSERT(!label->is_bound()); -+ MOZ_ASSERT(!label->patchOffset_.bound()); -+ label->patchOffset_ = masm_.movWithPatch(ImmPtr(nullptr), temp0_); -+ MOZ_ASSERT(label->patchOffset_.bound()); -+ -+ Push(temp0_); -+ -+ CheckBacktrackStackLimit(); -+} -+ -+void SMRegExpMacroAssembler::PushCurrentPosition() { Push(current_position_); } -+ -+void SMRegExpMacroAssembler::PushRegister(int register_index, -+ StackCheckFlag check_stack_limit) { -+ masm_.loadPtr(register_location(register_index), temp0_); -+ Push(temp0_); -+ if (check_stack_limit) { -+ CheckBacktrackStackLimit(); -+ } -+} -+ -+void SMRegExpMacroAssembler::ReadCurrentPositionFromRegister(int reg) { -+ masm_.loadPtr(register_location(reg), current_position_); -+} -+ -+void SMRegExpMacroAssembler::WriteCurrentPositionToRegister(int reg, -+ int cp_offset) { -+ if (cp_offset == 0) { -+ masm_.storePtr(current_position_, register_location(reg)); -+ } else { -+ Address addr(current_position_, cp_offset * char_size()); -+ masm_.computeEffectiveAddress(addr, temp0_); -+ masm_.storePtr(temp0_, register_location(reg)); -+ } -+} -+ -+// Note: The backtrack stack pointer is stored in a register as an -+// offset from the stack top, not as a bare pointer, so that it is not -+// corrupted if the backtrack stack grows (and therefore moves). -+void SMRegExpMacroAssembler::ReadStackPointerFromRegister(int reg) { -+ masm_.loadPtr(register_location(reg), backtrack_stack_pointer_); -+ masm_.addPtr(backtrackStackBase(), backtrack_stack_pointer_); -+} -+void SMRegExpMacroAssembler::WriteStackPointerToRegister(int reg) { -+ masm_.movePtr(backtrack_stack_pointer_, temp0_); -+ masm_.subPtr(backtrackStackBase(), temp0_); -+ masm_.storePtr(temp0_, register_location(reg)); -+} -+ -+// When matching a regexp that is anchored at the end, this operation -+// is used to try skipping the beginning of long strings. If the -+// maximum length of a match is less than the length of the string, we -+// can skip the initial len - max_len bytes. -+void SMRegExpMacroAssembler::SetCurrentPositionFromEnd(int by) { -+ js::jit::Label after_position; -+ masm_.branchPtr(Assembler::GreaterThanOrEqual, current_position_, -+ ImmWord(-by * char_size()), &after_position); -+ masm_.movePtr(ImmWord(-by * char_size()), current_position_); -+ -+ // On RegExp code entry (where this operation is used), the character before -+ // the current position is expected to be already loaded. -+ // We have advanced the position, so it's safe to read backwards. -+ LoadCurrentCharacterUnchecked(-1, 1); -+ masm_.bind(&after_position); -+} -+ -+void SMRegExpMacroAssembler::SetRegister(int register_index, int to) { -+ MOZ_ASSERT(register_index >= num_capture_registers_); -+ masm_.storePtr(ImmWord(to), register_location(register_index)); -+} -+ -+// Returns true if a regexp match can be restarted (aka the regexp is global). -+// The return value is not used anywhere, but we implement it to be safe. -+bool SMRegExpMacroAssembler::Succeed() { -+ masm_.jump(&success_label_); -+ return global(); -+} -+ -+// Capture registers are initialized to input[-1] -+void SMRegExpMacroAssembler::ClearRegisters(int reg_from, int reg_to) { -+ MOZ_ASSERT(reg_from <= reg_to); -+ masm_.loadPtr(inputStart(), temp0_); -+ masm_.subPtr(Imm32(char_size()), temp0_); -+ for (int reg = reg_from; reg <= reg_to; reg++) { -+ masm_.storePtr(temp0_, register_location(reg)); -+ } -+} -+ -+void SMRegExpMacroAssembler::Push(Register source) { -+ MOZ_ASSERT(source != backtrack_stack_pointer_); -+ -+ masm_.subPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_); -+ masm_.storePtr(source, Address(backtrack_stack_pointer_, 0)); -+} -+ -+void SMRegExpMacroAssembler::Pop(Register target) { -+ MOZ_ASSERT(target != backtrack_stack_pointer_); -+ -+ masm_.loadPtr(Address(backtrack_stack_pointer_, 0), target); -+ masm_.addPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_); -+} -+ -+void SMRegExpMacroAssembler::JumpOrBacktrack(Label* to) { -+ if (to) { -+ masm_.jump(to->inner()); -+ } else { -+ Backtrack(); -+ } -+} -+ -+// Generate a quick inline test for backtrack stack overflow. -+// If the test fails, call an OOL handler to try growing the stack. -+void SMRegExpMacroAssembler::CheckBacktrackStackLimit() { -+ js::jit::Label no_stack_overflow; -+ masm_.branchPtr( -+ Assembler::BelowOrEqual, -+ AbsoluteAddress(isolate()->regexp_stack()->limit_address_address()), -+ backtrack_stack_pointer_, &no_stack_overflow); -+ -+ masm_.call(&stack_overflow_label_); -+ -+ // Exit with an exception if the call failed -+ masm_.branchTest32(Assembler::Zero, temp0_, temp0_, -+ &exit_with_exception_label_); -+ -+ masm_.bind(&no_stack_overflow); -+} -+ -+// This is used to sneak an OOM through the V8 layer. -+static Handle DummyCode() { -+ return Handle::fromHandleValue(JS::UndefinedHandleValue); -+} -+ -+// Finalize code. This is called last, so that we know how many -+// registers we need. -+Handle SMRegExpMacroAssembler::GetCode(Handle source) { -+ if (!cx_->compartment()->ensureJitCompartmentExists(cx_)) { -+ return DummyCode(); -+ } -+ -+ masm_.bind(&entry_label_); -+ -+ createStackFrame(); -+ initFrameAndRegs(); -+ -+ masm_.jump(&start_label_); -+ -+ successHandler(); -+ exitHandler(); -+ backtrackHandler(); -+ stackOverflowHandler(); -+ -+ Linker linker(masm_); -+ JitCode* code = linker.newCode(cx_, REGEXP_CODE); -+ if (!code) { -+ ReportOutOfMemory(cx_); -+ return DummyCode(); -+ } -+ -+ for (LabelPatch& lp : labelPatches_) { -+ Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, lp.patchOffset_), -+ ImmPtr(code->raw() + lp.labelOffset_), -+ ImmPtr(nullptr)); -+ } -+ -+ return Handle(JS::PrivateGCThingValue(code), isolate()); -+} -+ -+/* -+ * The stack will have the following structure: -+ * sp-> - FrameData -+ * - inputStart -+ * - backtrack stack base -+ * - matches -+ * - numMatches -+ * - Registers -+ * - Capture positions -+ * - Scratch registers -+ * --- frame alignment --- -+ * - Saved register area -+ * - Return address -+ */ -+void SMRegExpMacroAssembler::createStackFrame() { -+#ifdef JS_CODEGEN_ARM64 -+ // ARM64 communicates stack address via SP, but uses a pseudo-sp (PSP) for -+ // addressing. The register we use for PSP may however also be used by -+ // calling code, and it is nonvolatile, so save it. Do this as a special -+ // case first because the generic save/restore code needs the PSP to be -+ // initialized already. -+ MOZ_ASSERT(js::jit::PseudoStackPointer64.Is(masm_.GetStackPointer64())); -+ masm_.Str(js::jit::PseudoStackPointer64, -+ vixl::MemOperand(js::jit::sp, -16, vixl::PreIndex)); -+ -+ // Initialize the PSP from the SP. -+ masm_.initPseudoStackPtr(); -+#endif -+ -+ // Push non-volatile registers which might be modified by jitcode. -+ size_t pushedNonVolatileRegisters = 0; -+ for (GeneralRegisterForwardIterator iter(savedRegisters_); iter.more(); -+ ++iter) { -+ masm_.Push(*iter); -+ pushedNonVolatileRegisters++; -+ } -+ -+ // The pointer to InputOutputData is passed as the first argument. -+ // On x86 we have to load it off the stack into temp0_. -+ // On other platforms it is already in a register. -+#ifdef JS_CODEGEN_X86 -+ Address ioDataAddr(masm_.getStackPointer(), -+ (pushedNonVolatileRegisters + 1) * sizeof(void*)); -+ masm_.loadPtr(ioDataAddr, temp0_); -+#else -+ if (js::jit::IntArgReg0 != temp0_) { -+ masm_.movePtr(js::jit::IntArgReg0, temp0_); -+ } -+#endif -+ -+ // Start a new stack frame. -+ size_t frameBytes = sizeof(FrameData) + num_registers_ * sizeof(void*); -+ frameSize_ = js::jit::StackDecrementForCall(js::jit::ABIStackAlignment, -+ masm_.framePushed(), frameBytes); -+ masm_.reserveStack(frameSize_); -+ masm_.checkStackAlignment(); -+ -+ // Check if we have space on the stack. Use the *NoInterrupt stack limit to -+ // avoid failing repeatedly when the regex code is called from Ion JIT code. -+ // (See bug 1208819) -+ js::jit::Label stack_ok; -+ AbsoluteAddress limit_addr(cx_->addressOfJitStackLimitNoInterrupt()); -+ masm_.branchStackPtrRhs(Assembler::Below, limit_addr, &stack_ok); -+ -+ // There is not enough space on the stack. Exit with an exception. -+ masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); -+ masm_.jump(&exit_label_); -+ -+ masm_.bind(&stack_ok); -+} -+ -+void SMRegExpMacroAssembler::initFrameAndRegs() { -+ // At this point, an uninitialized stack frame has been created, -+ // and the address of the InputOutputData is in temp0_. -+ Register ioDataReg = temp0_; -+ -+ Register matchesReg = temp1_; -+ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, matches)), -+ matchesReg); -+ -+ // Initialize output registers -+ masm_.loadPtr(Address(matchesReg, MatchPairs::offsetOfPairs()), temp2_); -+ masm_.storePtr(temp2_, matches()); -+ masm_.load32(Address(matchesReg, MatchPairs::offsetOfPairCount()), temp2_); -+ masm_.store32(temp2_, numMatches()); -+ -+#ifdef DEBUG -+ // Bounds-check numMatches. -+ js::jit::Label enoughRegisters; -+ masm_.branchPtr(Assembler::GreaterThanOrEqual, temp2_, -+ ImmWord(num_capture_registers_ / 2), &enoughRegisters); -+ masm_.assumeUnreachable("Not enough output pairs for RegExp"); -+ masm_.bind(&enoughRegisters); -+#endif -+ -+ // Load input start pointer. -+ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, inputStart)), -+ current_position_); -+ -+ // Load input end pointer -+ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, inputEnd)), -+ input_end_pointer_); -+ -+ // Set up input position to be negative offset from string end. -+ masm_.subPtr(input_end_pointer_, current_position_); -+ -+ // Store inputStart -+ masm_.storePtr(current_position_, inputStart()); -+ -+ // Load start index -+ Register startIndexReg = temp1_; -+ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, startIndex)), -+ startIndexReg); -+ masm_.computeEffectiveAddress( -+ BaseIndex(current_position_, startIndexReg, factor()), current_position_); -+ -+ // Initialize current_character_. -+ // Load newline if index is at start, or previous character otherwise. -+ js::jit::Label start_regexp; -+ js::jit::Label load_previous_character; -+ masm_.branchPtr(Assembler::NotEqual, startIndexReg, ImmWord(0), -+ &load_previous_character); -+ masm_.movePtr(ImmWord('\n'), current_character_); -+ masm_.jump(&start_regexp); -+ -+ masm_.bind(&load_previous_character); -+ LoadCurrentCharacterUnchecked(-1, 1); -+ masm_.bind(&start_regexp); -+ -+ // Initialize captured registers with inputStart - 1 -+ MOZ_ASSERT(num_capture_registers_ > 0); -+ Register inputStartMinusOneReg = temp2_; -+ masm_.loadPtr(inputStart(), inputStartMinusOneReg); -+ masm_.subPtr(Imm32(char_size()), inputStartMinusOneReg); -+ if (num_capture_registers_ > 8) { -+ masm_.movePtr(ImmWord(register_offset(0)), temp1_); -+ js::jit::Label init_loop; -+ masm_.bind(&init_loop); -+ masm_.storePtr(inputStartMinusOneReg, BaseIndex(masm_.getStackPointer(), -+ temp1_, js::jit::TimesOne)); -+ masm_.addPtr(ImmWord(sizeof(void*)), temp1_); -+ masm_.branchPtr(Assembler::LessThan, temp1_, -+ ImmWord(register_offset(num_capture_registers_)), -+ &init_loop); -+ } else { -+ // Unroll the loop -+ for (int i = 0; i < num_capture_registers_; i++) { -+ masm_.storePtr(inputStartMinusOneReg, register_location(i)); -+ } -+ } -+ -+ // Initialize backtrack stack pointer -+ masm_.loadPtr(AbsoluteAddress(isolate()->top_of_regexp_stack()), -+ backtrack_stack_pointer_); -+ masm_.storePtr(backtrack_stack_pointer_, backtrackStackBase()); -+} -+ -+// Called when we find a match. May not be generated if we can -+// determine ahead of time that a regexp cannot match: for example, -+// when compiling /\u1e9e/ for latin-1 inputs. -+void SMRegExpMacroAssembler::successHandler() { -+ if (!success_label_.used()) { -+ return; -+ } -+ masm_.bind(&success_label_); -+ -+ // Copy captures to the MatchPairs pointed to by the InputOutputData. -+ // Captures are stored as positions, which are negative byte offsets -+ // from the end of the string. We must convert them to actual -+ // indices. -+ // -+ // Index: [ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][END] -+ // Pos (1-byte): [-6 ][-5 ][-4 ][-3 ][-2 ][-1 ][ 0 ] // IS = -6 -+ // Pos (2-byte): [-12][-10][-8 ][-6 ][-4 ][-2 ][ 0 ] // IS = -12 -+ // -+ // To convert a position to an index, we subtract InputStart, and -+ // divide the result by char_size. -+ Register matchesReg = temp1_; -+ masm_.loadPtr(matches(), matchesReg); -+ -+ Register inputStartReg = temp2_; -+ masm_.loadPtr(inputStart(), inputStartReg); -+ -+ for (int i = 0; i < num_capture_registers_; i++) { -+ masm_.loadPtr(register_location(i), temp0_); -+ masm_.subPtr(inputStartReg, temp0_); -+ if (mode_ == UC16) { -+ masm_.rshiftPtrArithmetic(Imm32(1), temp0_); -+ } -+ masm_.store32(temp0_, Address(matchesReg, i * sizeof(int32_t))); -+ } -+ -+ masm_.movePtr(ImmWord(js::RegExpRunStatus_Success), temp0_); -+ // This falls through to the exit handler. -+} -+ -+void SMRegExpMacroAssembler::exitHandler() { -+ masm_.bind(&exit_label_); -+ -+ if (temp0_ != js::jit::ReturnReg) { -+ masm_.movePtr(temp0_, js::jit::ReturnReg); -+ } -+ -+ masm_.freeStack(frameSize_); -+ -+ // Restore registers which were saved on entry -+ for (GeneralRegisterBackwardIterator iter(savedRegisters_); iter.more(); -+ ++iter) { -+ masm_.Pop(*iter); -+ } -+ -+#ifdef JS_CODEGEN_ARM64 -+ // Now restore the value that was in the PSP register on entry, and return. -+ -+ // Obtain the correct SP from the PSP. -+ masm_.Mov(js::jit::sp, js::jit::PseudoStackPointer64); -+ -+ // Restore the saved value of the PSP register, this value is whatever the -+ // caller had saved in it, not any actual SP value, and it must not be -+ // overwritten subsequently. -+ masm_.Ldr(js::jit::PseudoStackPointer64, -+ vixl::MemOperand(js::jit::sp, 16, vixl::PostIndex)); -+ -+ // Perform a plain Ret(), as abiret() will move SP <- PSP and that is wrong. -+ masm_.Ret(vixl::lr); -+#else -+ masm_.abiret(); -+#endif -+ -+ if (exit_with_exception_label_.used()) { -+ masm_.bind(&exit_with_exception_label_); -+ -+ // Exit with an error result to signal thrown exception -+ masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); -+ masm_.jump(&exit_label_); -+ } -+} -+ -+void SMRegExpMacroAssembler::backtrackHandler() { -+ if (!backtrack_label_.used()) { -+ return; -+ } -+ masm_.bind(&backtrack_label_); -+ Backtrack(); -+} -+ -+void SMRegExpMacroAssembler::stackOverflowHandler() { -+ if (!stack_overflow_label_.used()) { -+ return; -+ } -+ -+ // Called if the backtrack-stack limit has been hit. -+ masm_.bind(&stack_overflow_label_); -+ -+ // Load argument -+ masm_.movePtr(ImmPtr(isolate()->regexp_stack()), temp1_); -+ -+ // Save registers before calling C function -+ LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile()); -+ -+#ifdef JS_USE_LINK_REGISTER -+ masm_.pushReturnAddress(); -+#endif -+ -+ // Adjust for the return address on the stack. -+ size_t frameOffset = sizeof(void*); -+ -+ volatileRegs.takeUnchecked(temp0_); -+ volatileRegs.takeUnchecked(temp1_); -+ masm_.PushRegsInMask(volatileRegs); -+ -+ masm_.setupUnalignedABICall(temp0_); -+ masm_.passABIArg(temp1_); -+ masm_.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GrowBacktrackStack)); -+ masm_.storeCallBoolResult(temp0_); -+ -+ masm_.PopRegsInMask(volatileRegs); -+ -+ // If GrowBacktrackStack returned false, we have failed to grow the -+ // stack, and must exit with a stack-overflow exception. Do this in -+ // the caller so that the stack is adjusted by our return instruction. -+ js::jit::Label overflow_return; -+ masm_.branchTest32(Assembler::Zero, temp0_, temp0_, &overflow_return); -+ -+ // Otherwise, store the new backtrack stack base and recompute the new -+ // top of the stack. -+ Address bsbAddress(masm_.getStackPointer(), -+ offsetof(FrameData, backtrackStackBase) + frameOffset); -+ masm_.subPtr(bsbAddress, backtrack_stack_pointer_); -+ -+ masm_.loadPtr(AbsoluteAddress(isolate()->top_of_regexp_stack()), temp1_); -+ masm_.storePtr(temp1_, bsbAddress); -+ masm_.addPtr(temp1_, backtrack_stack_pointer_); -+ -+ // Resume execution in calling code. -+ masm_.bind(&overflow_return); -+ masm_.ret(); -+} -+ -+// This is only used by tracing code. -+// The return value doesn't matter. -+RegExpMacroAssembler::IrregexpImplementation -+SMRegExpMacroAssembler::Implementation() { -+ return kBytecodeImplementation; -+} -+ -+// Compare two strings in `/i` mode (ignoreCase, but not unicode). -+/*static */ -+uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareNonUnicode( -+ const char16_t* substring1, const char16_t* substring2, size_t byteLength) { -+ JS::AutoCheckCannotGC nogc; -+ -+ MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); -+ size_t length = byteLength / sizeof(char16_t); -+ -+ for (size_t i = 0; i < length; i++) { -+ char16_t c1 = substring1[i]; -+ char16_t c2 = substring2[i]; -+ if (c1 != c2) { -+#ifdef JS_HAS_INTL_API -+ // Non-unicode regexps have weird case-folding rules. -+ c1 = RegExpCaseFolding::Canonicalize(c1); -+ c2 = RegExpCaseFolding::Canonicalize(c2); -+#else -+ // If we aren't building with ICU, fall back to `/iu` mode. The only -+ // differences are in corner cases. -+ c1 = js::unicode::FoldCase(c1); -+ c2 = js::unicode::FoldCase(c2); -+#endif -+ if (c1 != c2) { -+ return 0; -+ } -+ } -+ } -+ -+ return 1; -+} -+ -+// Compare two strings in `/iu` mode (ignoreCase and unicode). -+/*static */ -+uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUnicode( -+ const char16_t* substring1, const char16_t* substring2, size_t byteLength) { -+ JS::AutoCheckCannotGC nogc; -+ -+ MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); -+ size_t length = byteLength / sizeof(char16_t); -+ -+ for (size_t i = 0; i < length; i++) { -+ char16_t c1 = substring1[i]; -+ char16_t c2 = substring2[i]; -+ if (c1 != c2) { -+ // Unicode regexps use the common and simple case-folding -+ // mappings of the Unicode Character Database. -+ c1 = js::unicode::FoldCase(c1); -+ c2 = js::unicode::FoldCase(c2); -+ if (c1 != c2) { -+ return 0; -+ } -+ } -+ } -+ -+ return 1; -+} -+ -+/* static */ -+bool SMRegExpMacroAssembler::GrowBacktrackStack(RegExpStack* regexp_stack) { -+ JS::AutoCheckCannotGC nogc; -+ size_t size = regexp_stack->stack_capacity(); -+ return !!regexp_stack->EnsureCapacity(size * 2); -+} -+ -+bool SMRegExpMacroAssembler::CanReadUnaligned() { -+#if defined(JS_CODEGEN_ARM) -+ return !js::jit::HasAlignmentFault(); -+#elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) -+ return false; -+#else -+ return true; -+#endif -+} -+ -+} // namespace internal -+} // namespace v8 -diff -Nrup mozilla/js/src/irregexp/RegExpNativeMacroAssembler.h mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.h ---- mozilla/js/src/irregexp/RegExpNativeMacroAssembler.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.h 2022-06-16 00:06:40.925190745 +0300 -@@ -0,0 +1,297 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+// Copyright 2020 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+// This file implements the NativeRegExpMacroAssembler interface for -+// SpiderMonkey. It provides the same interface as each of V8's -+// architecture-specific implementations. -+ -+#ifndef RegexpMacroAssemblerArch_h -+#define RegexpMacroAssemblerArch_h -+ -+#include "irregexp/imported/regexp-macro-assembler.h" -+#include "jit/MacroAssembler.h" -+ -+namespace v8 { -+namespace internal { -+ -+struct FrameData { -+ // Character position at the start of the input, stored as a -+ // negative offset from the end of the string (input_end_pointer_). -+ size_t inputStart; -+ -+ // The backtrack_stack_pointer_ register points to the top of the stack. -+ // This points to the bottom of the backtrack stack. -+ void* backtrackStackBase; -+ -+ // Copy of the input MatchPairs. -+ int32_t* matches; // pointer to capture array -+ int32_t numMatches; // size of capture array -+}; -+ -+class SMRegExpMacroAssembler final : public NativeRegExpMacroAssembler { -+ public: -+ SMRegExpMacroAssembler(JSContext* cx, js::jit::StackMacroAssembler& masm, -+ Zone* zone, Mode mode, uint32_t num_capture_registers); -+ virtual ~SMRegExpMacroAssembler() {} // Nothing to do here -+ -+ virtual int stack_limit_slack(); -+ virtual IrregexpImplementation Implementation(); -+ -+ virtual bool Succeed(); -+ virtual void Fail(); -+ -+ virtual void AdvanceCurrentPosition(int by); -+ virtual void PopCurrentPosition(); -+ virtual void PushCurrentPosition(); -+ virtual void SetCurrentPositionFromEnd(int by); -+ -+ virtual void Backtrack(); -+ virtual void Bind(Label* label); -+ virtual void GoTo(Label* label); -+ virtual void PushBacktrack(Label* label); -+ -+ virtual void CheckCharacter(uint32_t c, Label* on_equal); -+ virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal); -+ virtual void CheckCharacterGT(uc16 limit, Label* on_greater); -+ virtual void CheckCharacterLT(uc16 limit, Label* on_less); -+ virtual void CheckCharacterAfterAnd(uint32_t c, uint32_t mask, -+ Label* on_equal); -+ virtual void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, -+ Label* on_not_equal); -+ virtual void CheckNotCharacterAfterMinusAnd(uc16 c, uc16 minus, uc16 mask, -+ Label* on_not_equal); -+ virtual void CheckGreedyLoop(Label* on_tos_equals_current_position); -+ virtual void CheckCharacterInRange(uc16 from, uc16 to, Label* on_in_range); -+ virtual void CheckCharacterNotInRange(uc16 from, uc16 to, -+ Label* on_not_in_range); -+ virtual void CheckAtStart(int cp_offset, Label* on_at_start); -+ virtual void CheckNotAtStart(int cp_offset, Label* on_not_at_start); -+ virtual void CheckPosition(int cp_offset, Label* on_outside_input); -+ virtual void CheckBitInTable(Handle table, Label* on_bit_set); -+ virtual bool CheckSpecialCharacterClass(uc16 type, Label* on_no_match); -+ virtual void CheckNotBackReference(int start_reg, bool read_backward, -+ Label* on_no_match); -+ virtual void CheckNotBackReferenceIgnoreCase(int start_reg, -+ bool read_backward, bool unicode, -+ Label* on_no_match); -+ -+ virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input, -+ bool check_bounds, int characters, -+ int eats_at_least); -+ -+ virtual void AdvanceRegister(int reg, int by); -+ virtual void IfRegisterGE(int reg, int comparand, Label* if_ge); -+ virtual void IfRegisterLT(int reg, int comparand, Label* if_lt); -+ virtual void IfRegisterEqPos(int reg, Label* if_eq); -+ virtual void PopRegister(int register_index); -+ virtual void PushRegister(int register_index, -+ StackCheckFlag check_stack_limit); -+ virtual void ReadCurrentPositionFromRegister(int reg); -+ virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); -+ virtual void ReadStackPointerFromRegister(int reg); -+ virtual void WriteStackPointerToRegister(int reg); -+ virtual void SetRegister(int register_index, int to); -+ virtual void ClearRegisters(int reg_from, int reg_to); -+ -+ virtual Handle GetCode(Handle source); -+ -+ virtual bool CanReadUnaligned(); -+ -+ private: -+ size_t frameSize_ = 0; -+ -+ void createStackFrame(); -+ void initFrameAndRegs(); -+ void successHandler(); -+ void exitHandler(); -+ void backtrackHandler(); -+ void stackOverflowHandler(); -+ -+ // Push a register on the backtrack stack. -+ void Push(js::jit::Register value); -+ -+ // Pop a value from the backtrack stack. -+ void Pop(js::jit::Register target); -+ -+ void CheckAtStartImpl(int cp_offset, Label* on_cond, -+ js::jit::Assembler::Condition cond); -+ void CheckCharacterImpl(js::jit::Imm32 c, Label* on_cond, -+ js::jit::Assembler::Condition cond); -+ void CheckCharacterAfterAndImpl(uint32_t c, uint32_t and_with, Label* on_cond, -+ bool negate); -+ void CheckCharacterInRangeImpl(uc16 from, uc16 to, Label* on_cond, -+ js::jit::Assembler::Condition cond); -+ void CheckNotBackReferenceImpl(int start_reg, bool read_backward, -+ bool unicode, Label* on_no_match, -+ bool ignore_case); -+ -+ void LoadCurrentCharacterUnchecked(int cp_offset, int characters); -+ -+ void JumpOrBacktrack(Label* to); -+ -+ // MacroAssembler methods that take a Label can be called with a -+ // null label, which means that we should backtrack if we would jump -+ // to that label. This is a helper to avoid writing out the same -+ // logic a dozen times. -+ inline js::jit::Label* LabelOrBacktrack(Label* to) { -+ return to ? to->inner() : &backtrack_label_; -+ } -+ -+ void CheckBacktrackStackLimit(); -+ -+ static bool GrowBacktrackStack(RegExpStack* regexp_stack); -+ -+ static uint32_t CaseInsensitiveCompareNonUnicode(const char16_t* substring1, -+ const char16_t* substring2, -+ size_t byteLength); -+ static uint32_t CaseInsensitiveCompareUnicode(const char16_t* substring1, -+ const char16_t* substring2, -+ size_t byteLength); -+ -+ inline int char_size() { return static_cast(mode_); } -+ inline js::jit::Scale factor() { -+ return mode_ == UC16 ? js::jit::TimesTwo : js::jit::TimesOne; -+ } -+ -+ js::jit::Address inputStart() { -+ return js::jit::Address(masm_.getStackPointer(), -+ offsetof(FrameData, inputStart)); -+ } -+ js::jit::Address backtrackStackBase() { -+ return js::jit::Address(masm_.getStackPointer(), -+ offsetof(FrameData, backtrackStackBase)); -+ } -+ js::jit::Address matches() { -+ return js::jit::Address(masm_.getStackPointer(), -+ offsetof(FrameData, matches)); -+ } -+ js::jit::Address numMatches() { -+ return js::jit::Address(masm_.getStackPointer(), -+ offsetof(FrameData, numMatches)); -+ } -+ -+ // The stack-pointer-relative location of a regexp register. -+ js::jit::Address register_location(int register_index) { -+ return js::jit::Address(masm_.getStackPointer(), -+ register_offset(register_index)); -+ } -+ -+ int32_t register_offset(int register_index) { -+ MOZ_ASSERT(register_index >= 0 && register_index <= kMaxRegister); -+ if (num_registers_ <= register_index) { -+ num_registers_ = register_index + 1; -+ } -+ static_assert(alignof(uintptr_t) <= alignof(FrameData), -+ "Regexp: Alignment of uintptr_t and FrameData mismatch"); -+ return sizeof(FrameData) + register_index * sizeof(uintptr_t*); -+ } -+ -+ JSContext* cx_; -+ js::jit::StackMacroAssembler& masm_; -+ -+ /* -+ * This assembler uses the following registers: -+ * -+ * - current_character_: -+ * Contains the character (or characters) currently being examined. -+ * Must be loaded using LoadCurrentCharacter before using any of the -+ * dispatch methods. After a matching pass for a global regexp, -+ * temporarily stores the index of capture start. -+ * - current_position_: -+ * Current position in input *as negative byte offset from end of string*. -+ * - input_end_pointer_: -+ * Points to byte after last character in the input. current_position_ is -+ * relative to this. -+ * - backtrack_stack_pointer_: -+ * Points to tip of the (heap-allocated) backtrack stack. The stack grows -+ * downward (like the native stack). -+ * - temp0_, temp1_, temp2_: -+ * Scratch registers. -+ * -+ * The native stack pointer is used to access arguments (InputOutputData), -+ * local variables (FrameData), and irregexp's internal virtual registers -+ * (see register_location). -+ */ -+ -+ js::jit::Register current_character_; -+ js::jit::Register current_position_; -+ js::jit::Register input_end_pointer_; -+ js::jit::Register backtrack_stack_pointer_; -+ js::jit::Register temp0_, temp1_, temp2_; -+ -+ // These labels are used in various API calls and bound (if used) in -+ // GetCode. If we abort in the middle of a compilation, as may -+ // happen if a regexp is too big, they may be used but not -+ // bound. -+ js::jit::NonAssertingLabel entry_label_; -+ js::jit::NonAssertingLabel start_label_; -+ js::jit::NonAssertingLabel backtrack_label_; -+ js::jit::NonAssertingLabel success_label_; -+ js::jit::NonAssertingLabel exit_label_; -+ js::jit::NonAssertingLabel stack_overflow_label_; -+ js::jit::NonAssertingLabel exit_with_exception_label_; -+ -+ // When we generate the code to push a backtrack label's address -+ // onto the backtrack stack, we don't know its final address. We -+ // have to patch it after linking. This is slightly delicate, as the -+ // Label itself (which is allocated on the stack) may not exist by -+ // the time we link. The approach is as follows: -+ // -+ // 1. When we push a label on the backtrack stack (PushBacktrack), -+ // we bind the label's patchOffset_ field to the offset within -+ // the code that should be overwritten. This works because each -+ // label is only pushed by a single instruction. -+ // -+ // 2. When we bind a label (Bind), we check to see if it has a -+ // bound patchOffset_. If it does, we create a LabelPatch mapping -+ // its patch offset to the offset of the label itself. -+ // -+ // 3. While linking the code, we walk the list of label patches -+ // and patch the code accordingly. -+ class LabelPatch { -+ public: -+ LabelPatch(js::jit::CodeOffset patchOffset, size_t labelOffset) -+ : patchOffset_(patchOffset), labelOffset_(labelOffset) {} -+ -+ js::jit::CodeOffset patchOffset_; -+ size_t labelOffset_ = 0; -+ }; -+ -+ js::Vector labelPatches_; -+ void AddLabelPatch(js::jit::CodeOffset patchOffset, size_t labelOffset) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ if (!labelPatches_.emplaceBack(patchOffset, labelOffset)) { -+ oomUnsafe.crash("Irregexp label patch"); -+ } -+ } -+ -+ Mode mode_; -+ int num_registers_; -+ int num_capture_registers_; -+ js::jit::LiveGeneralRegisterSet savedRegisters_; -+ -+ public: -+ using TableVector = -+ js::Vector, 4, js::SystemAllocPolicy>; -+ TableVector& tables() { return tables_; } -+ -+ private: -+ TableVector tables_; -+ void AddTable(PseudoHandle table) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ if (!tables_.append(std::move(table))) { -+ oomUnsafe.crash("Irregexp table append"); -+ } -+ } -+}; -+ -+} // namespace internal -+} // namespace v8 -+ -+#endif // RegexpMacroAssemblerArch_h -diff -Nrup mozilla/js/src/irregexp/RegExpShim.cpp mozilla-OK/js/src/irregexp/RegExpShim.cpp ---- mozilla/js/src/irregexp/RegExpShim.cpp 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpShim.cpp 2022-06-16 00:06:40.925190745 +0300 -@@ -0,0 +1,255 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+// Copyright 2019 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "irregexp/RegExpShim.h" -+ -+#include "mozilla/MemoryReporting.h" -+ -+#include -+ -+#include "irregexp/imported/regexp-macro-assembler.h" -+#include "irregexp/imported/regexp-stack.h" -+ -+#include "vm/NativeObject-inl.h" -+ -+#include "mozilla/Sprintf.h" // for SprintfLiteral -+ -+namespace v8 { -+namespace internal { -+ -+void PrintF(const char* format, ...) { -+ va_list arguments; -+ va_start(arguments, format); -+ vprintf(format, arguments); -+ va_end(arguments); -+} -+ -+void PrintF(FILE* out, const char* format, ...) { -+ va_list arguments; -+ va_start(arguments, format); -+ vfprintf(out, format, arguments); -+ va_end(arguments); -+} -+ -+StdoutStream::operator std::ostream&() const { return std::cerr; } -+ -+template -+std::ostream& StdoutStream::operator<<(T t) { -+ return std::cerr << t; -+} -+ -+template std::ostream& StdoutStream::operator<<(char const* c); -+ -+// Origin: -+// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/utils/ostreams.cc#L120-L169 -+// (This is a hand-simplified version.) -+// Writes the given character to the output escaping everything outside -+// of printable ASCII range. -+std::ostream& operator<<(std::ostream& os, const AsUC16& c) { -+ uc16 v = c.value; -+ bool isPrint = 0x20 < v && v <= 0x7e; -+ char buf[10]; -+ const char* format = isPrint ? "%c" : (v <= 0xFF) ? "\\x%02x" : "\\u%04x"; -+ SprintfLiteral(buf, format, v); -+ return os << buf; -+} -+std::ostream& operator<<(std::ostream& os, const AsUC32& c) { -+ int32_t v = c.value; -+ if (v <= String::kMaxUtf16CodeUnit) { -+ return os << AsUC16(v); -+ } -+ char buf[13]; -+ SprintfLiteral(buf, "\\u{%06x}", v); -+ return os << buf; -+} -+ -+HandleScope::HandleScope(Isolate* isolate) : isolate_(isolate) { -+ isolate->openHandleScope(*this); -+} -+ -+HandleScope::~HandleScope() { -+ isolate_->closeHandleScope(level_, non_gc_level_); -+} -+ -+template -+Handle::Handle(T object, Isolate* isolate) -+ : location_(isolate->getHandleLocation(object.value())) {} -+ -+template Handle::Handle(ByteArray b, Isolate* isolate); -+template Handle::Handle(const JS::Value& v, Isolate* isolate); -+template Handle::Handle(JSRegExp re, Isolate* isolate); -+template Handle::Handle(String s, Isolate* isolate); -+ -+template -+Handle::Handle(const JS::Value& value, Isolate* isolate) -+ : location_(isolate->getHandleLocation(value)) { -+ T::cast(Object(value)); // Assert that value has the correct type. -+} -+ -+JS::Value* Isolate::getHandleLocation(const JS::Value& value) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ if (!handleArena_.Append(value)) { -+ oomUnsafe.crash("Irregexp handle allocation"); -+ } -+ return &handleArena_.GetLast(); -+} -+ -+void* Isolate::allocatePseudoHandle(size_t bytes) { -+ PseudoHandle ptr; -+ ptr.reset(js_malloc(bytes)); -+ if (!ptr) { -+ return nullptr; -+ } -+ if (!uniquePtrArena_.Append(std::move(ptr))) { -+ return nullptr; -+ } -+ return uniquePtrArena_.GetLast().get(); -+} -+ -+template -+PseudoHandle Isolate::takeOwnership(void* ptr) { -+ for (auto iter = uniquePtrArena_.IterFromLast(); !iter.Done(); iter.Prev()) { -+ auto& entry = iter.Get(); -+ if (entry.get() == ptr) { -+ PseudoHandle result; -+ result.reset(static_cast(entry.release())); -+ return result; -+ } -+ } -+ MOZ_CRASH("Tried to take ownership of pseudohandle that is not in the arena"); -+} -+ -+PseudoHandle ByteArray::takeOwnership(Isolate* isolate) { -+ PseudoHandle result = -+ isolate->takeOwnership(value().toPrivate()); -+ setValue(JS::PrivateValue(nullptr)); -+ return result; -+} -+ -+void Isolate::trace(JSTracer* trc) { -+ for (auto iter = handleArena_.Iter(); !iter.Done(); iter.Next()) { -+ auto& elem = iter.Get(); -+ JS::GCPolicy::trace(trc, &elem, "Isolate handle arena"); -+ } -+} -+ -+size_t Isolate::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { -+ size_t size = mallocSizeOf(this); -+ -+ // The RegExpStack code is imported from V8, so we peek inside it to -+ // measure its memory from here. -+ size += mallocSizeOf(regexpStack_); -+ if (regexpStack_->thread_local_.owns_memory_) { -+ size += mallocSizeOf(regexpStack_->thread_local_.memory_); -+ } -+ -+ size += handleArena_.SizeOfExcludingThis(mallocSizeOf); -+ size += uniquePtrArena_.SizeOfExcludingThis(mallocSizeOf); -+ return size; -+} -+ -+/*static*/ Handle String::Flatten(Isolate* isolate, -+ Handle string) { -+ if (string->IsFlat()) { -+ return string; -+ } -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ JSLinearString* linear = string->str()->ensureLinear(isolate->cx()); -+ if (!linear) { -+ oomUnsafe.crash("Irregexp String::Flatten"); -+ } -+ return Handle(JS::StringValue(linear), isolate); -+} -+ -+// This is only used for trace messages printing the source pattern of -+// a regular expression. We have to return a unique_ptr, but we don't -+// care about the contents, so we return an empty null-terminated string. -+std::unique_ptr String::ToCString() { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ -+ std::unique_ptr ptr; -+ ptr.reset(static_cast(js_malloc(1))); -+ if (!ptr) { -+ oomUnsafe.crash("Irregexp String::ToCString"); -+ } -+ ptr[0] = '\0'; -+ -+ return ptr; -+} -+ -+bool Isolate::init() { -+ regexpStack_ = js_new(); -+ if (!regexpStack_) { -+ return false; -+ } -+ return true; -+} -+ -+Isolate::~Isolate() { -+ if (regexpStack_) { -+ js_delete(regexpStack_); -+ } -+} -+ -+byte* Isolate::top_of_regexp_stack() const { -+ return reinterpret_cast(regexpStack_->memory_top_address_address()); -+} -+ -+Handle Isolate::NewByteArray(int length, AllocationType alloc) { -+ MOZ_RELEASE_ASSERT(length >= 0); -+ -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ -+ size_t alloc_size = sizeof(uint32_t) + length; -+ ByteArrayData* data = -+ static_cast(allocatePseudoHandle(alloc_size)); -+ if (!data) { -+ oomUnsafe.crash("Irregexp NewByteArray"); -+ } -+ data->length = length; -+ -+ return Handle(JS::PrivateValue(data), this); -+} -+ -+Handle Isolate::NewFixedArray(int length) { -+ MOZ_RELEASE_ASSERT(length >= 0); -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ js::ArrayObject* array = js::NewDenseFullyAllocatedArray(cx(), length); -+ if (!array) { -+ oomUnsafe.crash("Irregexp NewFixedArray"); -+ } -+ array->ensureDenseInitializedLength(cx(), 0, length); -+ return Handle(JS::ObjectValue(*array), this); -+} -+ -+template -+Handle Isolate::InternalizeString(const Vector& str) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ JSAtom* atom = js::AtomizeChars(cx(), str.begin(), str.length()); -+ if (!atom) { -+ oomUnsafe.crash("Irregexp InternalizeString"); -+ } -+ return Handle(JS::StringValue(atom), this); -+} -+ -+template Handle Isolate::InternalizeString( -+ const Vector& str); -+template Handle Isolate::InternalizeString( -+ const Vector& str); -+ -+static_assert(JSRegExp::RegistersForCaptureCount(JSRegExp::kMaxCaptures) <= -+ RegExpMacroAssembler::kMaxRegisterCount); -+ -+bool FLAG_trace_regexp_assembler = false; -+bool FLAG_trace_regexp_bytecodes = false; -+bool FLAG_trace_regexp_parser = false; -+bool FLAG_trace_regexp_peephole_optimization = false; -+ -+} // namespace internal -+} // namespace v8 -diff -Nrup mozilla/js/src/irregexp/RegExpShim.h mozilla-OK/js/src/irregexp/RegExpShim.h ---- mozilla/js/src/irregexp/RegExpShim.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpShim.h 2022-06-16 00:07:27.343875583 +0300 -@@ -0,0 +1,1261 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+// Copyright 2019 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef RegexpShim_h -+#define RegexpShim_h -+ -+#include "mozilla/Assertions.h" -+#include "mozilla/Attributes.h" -+#include "mozilla/MathAlgorithms.h" -+#include "mozilla/Maybe.h" -+#include "mozilla/SegmentedVector.h" -+#include "mozilla/Sprintf.h" -+#include "mozilla/Types.h" -+ -+#include -+#include -+#include // needed for gcc 10 -+ -+#include "irregexp/RegExpTypes.h" -+#include "irregexp/util/FlagsShim.h" -+#include "irregexp/util/VectorShim.h" -+#include "irregexp/util/ZoneShim.h" -+#include "jit/Label.h" -+#include "jit/shared/Assembler-shared.h" -+#include "js/Value.h" -+#include "threading/ExclusiveData.h" -+#include "vm/MutexIDs.h" -+#include "vm/NativeObject.h" -+ -+// Forward declaration of classes -+namespace v8 { -+namespace internal { -+ -+class Heap; -+class Isolate; -+class RegExpMatchInfo; -+class RegExpStack; -+ -+} // namespace internal -+} // namespace v8 -+ -+#define V8_WARN_UNUSED_RESULT MOZ_MUST_USE -+#define V8_EXPORT_PRIVATE MOZ_EXPORT -+#define V8_FALLTHROUGH [[fallthrough]] -+#define V8_NODISCARD [[nodiscard]] -+ -+#define FATAL(x) MOZ_CRASH(x) -+#define UNREACHABLE() MOZ_CRASH("unreachable code") -+#define UNIMPLEMENTED() MOZ_CRASH("unimplemented code") -+#define STATIC_ASSERT(exp) static_assert(exp, #exp) -+ -+#define DCHECK MOZ_ASSERT -+#define DCHECK_EQ(lhs, rhs) MOZ_ASSERT((lhs) == (rhs)) -+#define DCHECK_NE(lhs, rhs) MOZ_ASSERT((lhs) != (rhs)) -+#define DCHECK_GT(lhs, rhs) MOZ_ASSERT((lhs) > (rhs)) -+#define DCHECK_GE(lhs, rhs) MOZ_ASSERT((lhs) >= (rhs)) -+#define DCHECK_LT(lhs, rhs) MOZ_ASSERT((lhs) < (rhs)) -+#define DCHECK_LE(lhs, rhs) MOZ_ASSERT((lhs) <= (rhs)) -+#define DCHECK_NULL(val) MOZ_ASSERT((val) == nullptr) -+#define DCHECK_NOT_NULL(val) MOZ_ASSERT((val) != nullptr) -+#define DCHECK_IMPLIES(lhs, rhs) MOZ_ASSERT_IF(lhs, rhs) -+#define CHECK MOZ_RELEASE_ASSERT -+#define CHECK_LE(lhs, rhs) MOZ_RELEASE_ASSERT((lhs) <= (rhs)) -+#define CHECK_GE(lhs, rhs) MOZ_RELEASE_ASSERT((lhs) >= (rhs)) -+#define CONSTEXPR_DCHECK MOZ_ASSERT -+ -+template -+static constexpr inline T Min(T t1, T t2) { -+ return t1 < t2 ? t1 : t2; -+} -+ -+template -+static constexpr inline T Max(T t1, T t2) { -+ return t1 > t2 ? t1 : t2; -+} -+#define MemCopy memcpy -+ -+// Origin: -+// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/macros.h#L310-L319 -+// ptrdiff_t is 't' according to the standard, but MSVC uses 'I'. -+#ifdef _MSC_VER -+# define V8PRIxPTRDIFF "Ix" -+# define V8PRIdPTRDIFF "Id" -+# define V8PRIuPTRDIFF "Iu" -+#else -+# define V8PRIxPTRDIFF "tx" -+# define V8PRIdPTRDIFF "td" -+# define V8PRIuPTRDIFF "tu" -+#endif -+ -+#define arraysize mozilla::ArrayLength -+ -+// Explicitly declare the assignment operator as deleted. -+#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete -+ -+// Explicitly declare the copy constructor and assignment operator as deleted. -+// This also deletes the implicit move constructor and implicit move assignment -+// operator, but still allows to manually define them. -+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ -+ TypeName(const TypeName&) = delete; \ -+ DISALLOW_ASSIGN(TypeName) -+ -+// Explicitly declare all implicit constructors as deleted, namely the -+// default constructor, copy constructor and operator= functions. -+// This is especially useful for classes containing only static methods. -+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ -+ TypeName() = delete; \ -+ DISALLOW_COPY_AND_ASSIGN(TypeName) -+ -+namespace v8 { -+ -+// Origin: -+// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/macros.h#L364-L367 -+template -+constexpr inline bool IsAligned(T value, U alignment) { -+ return (value & (alignment - 1)) == 0; -+} -+ -+using byte = uint8_t; -+using Address = uintptr_t; -+static const Address kNullAddress = 0; -+ -+// Latin1/UTF-16 constants -+// Code-point values in Unicode 4.0 are 21 bits wide. -+// Code units in UTF-16 are 16 bits wide. -+using uc16 = char16_t; -+using uc32 = uint32_t; -+ -+namespace base { -+ -+// Origin: -+// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/macros.h#L247-L258 -+// The USE(x, ...) template is used to silence C++ compiler warnings -+// issued for (yet) unused variables (typically parameters). -+// The arguments are guaranteed to be evaluated from left to right. -+struct Use { -+ template -+ Use(T&&) {} // NOLINT(runtime/explicit) -+}; -+#define USE(...) \ -+ do { \ -+ ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \ -+ (void)unused_tmp_array_for_use_macro; \ -+ } while (false) -+ -+// Origin: -+// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/safe_conversions.h#L35-L39 -+// saturated_cast<> is analogous to static_cast<> for numeric types, except -+// that the specified numeric conversion will saturate rather than overflow or -+// underflow. -+template -+inline Dst saturated_cast(Src value); -+ -+// This is the only specialization that is needed for regexp code. -+// Instead of pulling in dozens of lines of template goo -+// to derive it, I used the implementation from uint8_clamped in -+// ArrayBufferObject.h. -+template <> -+inline uint8_t saturated_cast(int x) { -+ return (x >= 0) ? ((x < 255) ? uint8_t(x) : 255) : 0; -+} -+ -+// Origin: -+// https://github.com/v8/v8/blob/fc088cdaccadede84886eee881e67af9db53669a/src/base/bounds.h#L14-L28 -+// Checks if value is in range [lower_limit, higher_limit] using a single -+// branch. -+template -+inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) { -+ using unsigned_T = typename std::make_unsigned::type; -+ // Use static_cast to support enum classes. -+ return static_cast(static_cast(value) - -+ static_cast(lower_limit)) <= -+ static_cast(static_cast(higher_limit) - -+ static_cast(lower_limit)); -+} -+ -+#define LAZY_INSTANCE_INITIALIZER \ -+ {} -+ -+template -+class LazyInstanceImpl { -+ public: -+ LazyInstanceImpl() : value_(js::mutexid::IrregexpLazyStatic) {} -+ -+ const T* Pointer() { -+ auto val = value_.lock(); -+ if (val->isNothing()) { -+ val->emplace(); -+ } -+ return val->ptr(); -+ } -+ -+ private: -+ js::ExclusiveData> value_; -+}; -+ -+template -+class LazyInstance { -+ public: -+ using type = LazyInstanceImpl; -+}; -+ -+namespace bits { -+ -+inline uint64_t CountTrailingZeros(uint64_t value) { -+ return mozilla::CountTrailingZeroes64(value); -+} -+ -+inline size_t RoundUpToPowerOfTwo32(size_t value) { -+ return mozilla::RoundUpPow2(value); -+} -+ -+template -+constexpr bool IsPowerOfTwo(T value) { -+ return value > 0 && (value & (value - 1)) == 0; -+} -+ -+} // namespace bits -+} // namespace base -+ -+namespace unibrow { -+ -+using uchar = unsigned int; -+ -+// Origin: -+// https://github.com/v8/v8/blob/1f1e4cdb04c75eab77adbecd5f5514ddc3eb56cf/src/strings/unicode.h#L133-L150 -+class Latin1 { -+ public: -+ static const uc16 kMaxChar = 0xff; -+ -+ // Convert the character to Latin-1 case equivalent if possible. -+ static inline uc16 TryConvertToLatin1(uc16 c) { -+ // "GREEK CAPITAL LETTER MU" case maps to "MICRO SIGN". -+ // "GREEK SMALL LETTER MU" case maps to "MICRO SIGN". -+ if (c == 0x039C || c == 0x03BC) { -+ return 0xB5; -+ } -+ // "LATIN CAPITAL LETTER Y WITH DIAERESIS" case maps to "LATIN SMALL LETTER -+ // Y WITH DIAERESIS". -+ if (c == 0x0178) { -+ return 0xFF; -+ } -+ return c; -+ } -+}; -+ -+// Origin: -+// https://github.com/v8/v8/blob/b4bfbce6f91fc2cc72178af42bb3172c5f5eaebb/src/strings/unicode.h#L99-L131 -+class Utf16 { -+ public: -+ static inline bool IsLeadSurrogate(int code) { -+ return js::unicode::IsLeadSurrogate(code); -+ } -+ static inline bool IsTrailSurrogate(int code) { -+ return js::unicode::IsTrailSurrogate(code); -+ } -+ static inline uc16 LeadSurrogate(uint32_t char_code) { -+ return js::unicode::LeadSurrogate(char_code); -+ } -+ static inline uc16 TrailSurrogate(uint32_t char_code) { -+ return js::unicode::TrailSurrogate(char_code); -+ } -+ static inline uint32_t CombineSurrogatePair(char16_t lead, char16_t trail) { -+ return js::unicode::UTF16Decode(lead, trail); -+ } -+ static const uchar kMaxNonSurrogateCharCode = 0xffff; -+}; -+ -+#ifndef V8_INTL_SUPPORT -+ -+// A cache used in case conversion. It caches the value for characters -+// that either have no mapping or map to a single character independent -+// of context. Characters that map to more than one character or that -+// map differently depending on context are always looked up. -+// Origin: -+// https://github.com/v8/v8/blob/b4bfbce6f91fc2cc72178af42bb3172c5f5eaebb/src/strings/unicode.h#L64-L88 -+template -+class Mapping { -+ public: -+ inline Mapping() = default; -+ inline int get(uchar c, uchar n, uchar* result) { -+ CacheEntry entry = entries_[c & kMask]; -+ if (entry.code_point_ == c) { -+ if (entry.offset_ == 0) { -+ return 0; -+ } else { -+ result[0] = c + entry.offset_; -+ return 1; -+ } -+ } else { -+ return CalculateValue(c, n, result); -+ } -+ } -+ -+ private: -+ int CalculateValue(uchar c, uchar n, uchar* result) { -+ bool allow_caching = true; -+ int length = T::Convert(c, n, result, &allow_caching); -+ if (allow_caching) { -+ if (length == 1) { -+ entries_[c & kMask] = CacheEntry(c, result[0] - c); -+ return 1; -+ } else { -+ entries_[c & kMask] = CacheEntry(c, 0); -+ return 0; -+ } -+ } else { -+ return length; -+ } -+ } -+ -+ struct CacheEntry { -+ inline CacheEntry() : code_point_(kNoChar), offset_(0) {} -+ inline CacheEntry(uchar code_point, signed offset) -+ : code_point_(code_point), offset_(offset) {} -+ uchar code_point_; -+ signed offset_; -+ static const int kNoChar = (1 << 21) - 1; -+ }; -+ static const int kSize = size; -+ static const int kMask = kSize - 1; -+ CacheEntry entries_[kSize]; -+}; -+ -+// Origin: -+// https://github.com/v8/v8/blob/b4bfbce6f91fc2cc72178af42bb3172c5f5eaebb/src/strings/unicode.h#L241-L252 -+struct Ecma262Canonicalize { -+ static const int kMaxWidth = 1; -+ static int Convert(uchar c, uchar n, uchar* result, bool* allow_caching_ptr); -+}; -+struct Ecma262UnCanonicalize { -+ static const int kMaxWidth = 4; -+ static int Convert(uchar c, uchar n, uchar* result, bool* allow_caching_ptr); -+}; -+struct CanonicalizationRange { -+ static const int kMaxWidth = 1; -+ static int Convert(uchar c, uchar n, uchar* result, bool* allow_caching_ptr); -+}; -+ -+#endif // !V8_INTL_SUPPORT -+ -+struct Letter { -+ static bool Is(uchar c); -+}; -+ -+} // namespace unibrow -+ -+namespace internal { -+ -+#define PRINTF_FORMAT(x, y) MOZ_FORMAT_PRINTF(x, y) -+void PRINTF_FORMAT(1, 2) PrintF(const char* format, ...); -+void PRINTF_FORMAT(2, 3) PrintF(FILE* out, const char* format, ...); -+ -+// Superclass for classes only using static method functions. -+// The subclass of AllStatic cannot be instantiated at all. -+class AllStatic { -+#ifdef DEBUG -+ public: -+ AllStatic() = delete; -+#endif -+}; -+ -+// Superclass for classes managed with new and delete. -+// In irregexp, this is only AlternativeGeneration (in regexp-compiler.cc) -+// Compare: -+// https://github.com/v8/v8/blob/7b3332844212d78ee87a9426f3a6f7f781a8fbfa/src/utils/allocation.cc#L88-L96 -+class Malloced { -+ public: -+ static void* operator new(size_t size) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ void* result = js_malloc(size); -+ if (!result) { -+ oomUnsafe.crash("Irregexp Malloced shim"); -+ } -+ return result; -+ } -+ static void operator delete(void* p) { js_free(p); } -+}; -+ -+constexpr int32_t KB = 1024; -+constexpr int32_t MB = 1024 * 1024; -+ -+#define kMaxInt JSVAL_INT_MAX -+#define kMinInt JSVAL_INT_MIN -+constexpr int kSystemPointerSize = sizeof(void*); -+ -+// The largest integer n such that n and n + 1 are both exactly -+// representable as a Number value. ES6 section 20.1.2.6 -+constexpr double kMaxSafeInteger = 9007199254740991.0; // 2^53-1 -+ -+constexpr int kBitsPerByte = 8; -+constexpr int kBitsPerByteLog2 = 3; -+constexpr int kUInt32Size = sizeof(uint32_t); -+constexpr int kInt64Size = sizeof(int64_t); -+constexpr int kUC16Size = sizeof(uc16); -+ -+inline constexpr bool IsDecimalDigit(uc32 c) { return c >= '0' && c <= '9'; } -+ -+inline bool is_uint24(int64_t val) { return (val >> 24) == 0; } -+inline bool is_int24(int64_t val) { -+ int64_t limit = int64_t(1) << 23; -+ return (-limit <= val) && (val < limit); -+} -+ -+inline bool IsIdentifierStart(uc32 c) { -+ return js::unicode::IsIdentifierStart(uint32_t(c)); -+} -+inline bool IsIdentifierPart(uc32 c) { -+ return js::unicode::IsIdentifierPart(uint32_t(c)); -+} -+ -+// Wrappers to disambiguate char16_t and uc16. -+struct AsUC16 { -+ explicit AsUC16(char16_t v) : value(v) {} -+ char16_t value; -+}; -+ -+struct AsUC32 { -+ explicit AsUC32(int32_t v) : value(v) {} -+ int32_t value; -+}; -+ -+std::ostream& operator<<(std::ostream& os, const AsUC16& c); -+std::ostream& operator<<(std::ostream& os, const AsUC32& c); -+ -+// This class is used for the output of trace-regexp-parser. V8 has -+// an elaborate implementation to ensure that the output gets to the -+// right place, even on Android. We just need something that will -+// print output (ideally to stderr, to match the rest of our tracing -+// code). This is an empty wrapper that will convert itself to -+// std::cerr when used. -+class StdoutStream { -+ public: -+ operator std::ostream&() const; -+ template -+ std::ostream& operator<<(T t); -+}; -+ -+// Reuse existing Maybe implementation -+using mozilla::Maybe; -+ -+template -+Maybe Just(const T& value) { -+ return mozilla::Some(value); -+} -+ -+template -+mozilla::Nothing Nothing() { -+ return mozilla::Nothing(); -+} -+ -+template -+using PseudoHandle = mozilla::UniquePtr; -+ -+// Compare 8bit/16bit chars to 8bit/16bit chars. -+// Used indirectly by regexp-interpreter.cc -+// Taken from: https://github.com/v8/v8/blob/master/src/utils/utils.h -+template -+inline int CompareCharsUnsigned(const lchar* lhs, const rchar* rhs, -+ size_t chars) { -+ const lchar* limit = lhs + chars; -+ if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) { -+ // memcmp compares byte-by-byte, yielding wrong results for two-byte -+ // strings on little-endian systems. -+ return memcmp(lhs, rhs, chars); -+ } -+ while (lhs < limit) { -+ int r = static_cast(*lhs) - static_cast(*rhs); -+ if (r != 0) return r; -+ ++lhs; -+ ++rhs; -+ } -+ return 0; -+} -+template -+inline int CompareChars(const lchar* lhs, const rchar* rhs, size_t chars) { -+ DCHECK_LE(sizeof(lchar), 2); -+ DCHECK_LE(sizeof(rchar), 2); -+ if (sizeof(lchar) == 1) { -+ if (sizeof(rchar) == 1) { -+ return CompareCharsUnsigned(reinterpret_cast(lhs), -+ reinterpret_cast(rhs), chars); -+ } else { -+ return CompareCharsUnsigned(reinterpret_cast(lhs), -+ reinterpret_cast(rhs), -+ chars); -+ } -+ } else { -+ if (sizeof(rchar) == 1) { -+ return CompareCharsUnsigned(reinterpret_cast(lhs), -+ reinterpret_cast(rhs), chars); -+ } else { -+ return CompareCharsUnsigned(reinterpret_cast(lhs), -+ reinterpret_cast(rhs), -+ chars); -+ } -+ } -+} -+ -+// Compare 8bit/16bit chars to 8bit/16bit chars. -+template -+inline bool CompareCharsEqualUnsigned(const lchar* lhs, const rchar* rhs, -+ size_t chars) { -+ STATIC_ASSERT(std::is_unsigned::value); -+ STATIC_ASSERT(std::is_unsigned::value); -+ if (sizeof(*lhs) == sizeof(*rhs)) { -+ // memcmp compares byte-by-byte, but for equality it doesn't matter whether -+ // two-byte char comparison is little- or big-endian. -+ return memcmp(lhs, rhs, chars * sizeof(*lhs)) == 0; -+ } -+ for (const lchar* limit = lhs + chars; lhs < limit; ++lhs, ++rhs) { -+ if (*lhs != *rhs) return false; -+ } -+ return true; -+} -+ -+template -+inline bool CompareCharsEqual(const lchar* lhs, const rchar* rhs, -+ size_t chars) { -+ using ulchar = typename std::make_unsigned::type; -+ using urchar = typename std::make_unsigned::type; -+ return CompareCharsEqualUnsigned(reinterpret_cast(lhs), -+ reinterpret_cast(rhs), chars); -+} -+ -+// Origin: -+// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/utils/utils.h#L40-L48 -+// Returns the value (0 .. 15) of a hexadecimal character c. -+// If c is not a legal hexadecimal character, returns a value < 0. -+// Used in regexp-parser.cc -+inline int HexValue(uc32 c) { -+ c -= '0'; -+ if (static_cast(c) <= 9) return c; -+ c = (c | 0x20) - ('a' - '0'); // detect 0x11..0x16 and 0x31..0x36. -+ if (static_cast(c) <= 5) return c + 10; -+ return -1; -+} -+ -+// V8::Object ~= JS::Value -+class Object { -+ public: -+ // The default object constructor in V8 stores a nullptr, -+ // which has its low bit clear and is interpreted as Smi(0). -+ constexpr Object() : asBits_(JS::Int32Value(0).asRawBits()) {} -+ -+ Object(const JS::Value& value) { setValue(value); } -+ -+ // Used in regexp-interpreter.cc to check the return value of -+ // isolate->stack_guard()->HandleInterrupts(). We want to handle -+ // interrupts in the caller, so we always return false from -+ // HandleInterrupts and true here. -+ inline bool IsException(Isolate*) const { -+ MOZ_ASSERT(!value().toBoolean()); -+ return true; -+ } -+ -+ JS::Value value() const { return JS::Value::fromRawBits(asBits_); } -+ -+ inline static Object cast(Object object) { return object; } -+ -+ protected: -+ void setValue(const JS::Value& val) { asBits_ = val.asRawBits(); } -+ uint64_t asBits_; -+} JS_HAZ_GC_POINTER; -+ -+class Smi : public Object { -+ public: -+ static Smi FromInt(int32_t value) { -+ Smi smi; -+ smi.setValue(JS::Int32Value(value)); -+ return smi; -+ } -+ static inline int32_t ToInt(const Object object) { -+ return object.value().toInt32(); -+ } -+}; -+ -+// V8::HeapObject ~= GC thing -+class HeapObject : public Object { -+ public: -+ inline static HeapObject cast(Object object) { -+ HeapObject h; -+ h.setValue(object.value()); -+ return h; -+ } -+}; -+ -+// A fixed-size array with Objects (aka Values) as element types. -+// Implemented using the dense elements of an ArrayObject. -+// Used for named captures. -+class FixedArray : public HeapObject { -+ public: -+ inline void set(uint32_t index, Object value) { -+ inner()->setDenseElement(index, value.value()); -+ } -+ inline static FixedArray cast(Object object) { -+ FixedArray f; -+ f.setValue(object.value()); -+ return f; -+ } -+ js::NativeObject* inner() { -+ return &value().toObject().as(); -+ } -+}; -+ -+/* -+ * Conceptually, ByteArrayData is a variable-size structure. To -+ * implement this in a C++-approved way, we allocate a struct -+ * containing the 32-bit length field, followed by additional memory -+ * for the data. To access the data, we get a pointer to the next byte -+ * after the length field and cast it to the correct type. -+ */ -+inline uint8_t* ByteArrayData::data() { -+ static_assert(alignof(uint8_t) <= alignof(ByteArrayData), -+ "The trailing data must be aligned to start immediately " -+ "after the header with no padding."); -+ ByteArrayData* immediatelyAfter = this + 1; -+ return reinterpret_cast(immediatelyAfter); -+} -+ -+// A fixed-size array of bytes. -+class ByteArray : public HeapObject { -+ ByteArrayData* inner() const { -+ return static_cast(value().toPrivate()); -+ } -+ -+ public: -+ PseudoHandle takeOwnership(Isolate* isolate); -+ byte get(uint32_t index) { -+ MOZ_ASSERT(index < length()); -+ return inner()->data()[index]; -+ } -+ void set(uint32_t index, byte val) { -+ MOZ_ASSERT(index < length()); -+ inner()->data()[index] = val; -+ } -+ uint32_t length() const { return inner()->length; } -+ byte* GetDataStartAddress() { return inner()->data(); } -+ -+ static ByteArray cast(Object object) { -+ ByteArray b; -+ b.setValue(object.value()); -+ return b; -+ } -+}; -+ -+// Like Handles in SM, V8 handles are references to marked pointers. -+// Unlike SM, where Rooted pointers are created individually on the -+// stack, the target of a V8 handle lives in an arena on the isolate -+// (~= JSContext). Whenever a Handle is created, a new "root" is -+// created at the end of the arena. -+// -+// HandleScopes are used to manage the lifetimes of these handles. A -+// HandleScope lives on the stack and stores the size of the arena at -+// the time of its creation. When the function returns and the -+// HandleScope is destroyed, the arena is truncated to its previous -+// size, clearing all roots that were created since the creation of -+// the HandleScope. -+// -+// In some cases, objects that are GC-allocated in V8 are not in SM. -+// In particular, irregexp allocates ByteArrays during code generation -+// to store lookup tables. This does not play nicely with the SM -+// macroassembler's requirement that no GC allocations take place -+// while it is on the stack. To work around this, this shim layer also -+// provides the ability to create pseudo-handles, which are not -+// managed by the GC but provide the same API to irregexp. The "root" -+// of a pseudohandle is a unique pointer living in a second arena. If -+// the allocated object should outlive the HandleScope, it must be -+// manually moved out of the arena using takeOwnership. -+ -+class MOZ_STACK_CLASS HandleScope { -+ public: -+ HandleScope(Isolate* isolate); -+ ~HandleScope(); -+ -+ private: -+ size_t level_; -+ size_t non_gc_level_; -+ Isolate* isolate_; -+ -+ friend class Isolate; -+}; -+ -+// Origin: -+// https://github.com/v8/v8/blob/5792f3587116503fc047d2f68c951c72dced08a5/src/handles/handles.h#L88-L171 -+template -+class MOZ_NONHEAP_CLASS Handle { -+ public: -+ Handle() : location_(nullptr) {} -+ Handle(T object, Isolate* isolate); -+ Handle(const JS::Value& value, Isolate* isolate); -+ -+ // Constructor for handling automatic up casting. -+ template ::value>::type> -+ inline Handle(Handle handle) : location_(handle.location_) {} -+ -+ inline bool is_null() const { return location_ == nullptr; } -+ -+ inline T operator*() const { return T::cast(Object(*location_)); }; -+ -+ // {ObjectRef} is returned by {Handle::operator->}. It should never be stored -+ // anywhere or used in any other code; no one should ever have to spell out -+ // {ObjectRef} in code. Its only purpose is to be dereferenced immediately by -+ // "operator-> chaining". Returning the address of the field is valid because -+ // this object's lifetime only ends at the end of the full statement. -+ // Origin: -+ // https://github.com/v8/v8/blob/03aaa4b3bf4cb01eee1f223b252e6869b04ab08c/src/handles/handles.h#L91-L105 -+ class ObjectRef { -+ public: -+ T* operator->() { return &object_; } -+ -+ private: -+ friend class Handle; -+ explicit ObjectRef(T object) : object_(object) {} -+ -+ T object_; -+ }; -+ inline ObjectRef operator->() const { return ObjectRef{**this}; } -+ -+ static Handle fromHandleValue(JS::HandleValue handle) { -+ return Handle(handle.address()); -+ } -+ -+ private: -+ Handle(const JS::Value* location) : location_(location) {} -+ -+ template -+ friend class Handle; -+ template -+ friend class MaybeHandle; -+ -+ const JS::Value* location_; -+}; -+ -+// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle -+// into a Handle requires checking that it does not point to nullptr. This -+// ensures nullptr checks before use. -+// -+// Also note that Handles do not provide default equality comparison or hashing -+// operators on purpose. Such operators would be misleading, because intended -+// semantics is ambiguous between Handle location and object identity. -+// Origin: -+// https://github.com/v8/v8/blob/5792f3587116503fc047d2f68c951c72dced08a5/src/handles/maybe-handles.h#L15-L78 -+template -+class MOZ_NONHEAP_CLASS MaybeHandle final { -+ public: -+ MaybeHandle() : location_(nullptr) {} -+ -+ // Constructor for handling automatic up casting from Handle. -+ // Ex. Handle can be passed when MaybeHandle is expected. -+ template ::value>::type> -+ MaybeHandle(Handle handle) : location_(handle.location_) {} -+ -+ inline Handle ToHandleChecked() const { -+ MOZ_RELEASE_ASSERT(location_); -+ return Handle(location_); -+ } -+ -+ // Convert to a Handle with a type that can be upcasted to. -+ template -+ inline bool ToHandle(Handle* out) const { -+ if (location_) { -+ *out = Handle(location_); -+ return true; -+ } else { -+ *out = Handle(); -+ return false; -+ } -+ } -+ -+ private: -+ JS::Value* location_; -+}; -+ -+// From v8/src/handles/handles-inl.h -+ -+template -+inline Handle handle(T object, Isolate* isolate) { -+ return Handle(object, isolate); -+} -+ -+// RAII Guard classes -+ -+using DisallowGarbageCollection = JS::AutoCheckCannotGC; -+ -+// V8 uses this inside DisallowGarbageCollection regions to turn -+// allocation back on before throwing a stack overflow exception or -+// handling interrupts. AutoSuppressGC is sufficient for the former -+// case, but not for the latter: handling interrupts can execute -+// arbitrary script code, and V8 jumps through some scary hoops to -+// "manually relocate unhandlified references" afterwards. To keep -+// things sane, we don't try to handle interrupts while regex code is -+// still on the stack. Instead, we return EXCEPTION and handle -+// interrupts in the caller. (See RegExpShared::execute.) -+ -+class AllowGarbageCollection { -+ public: -+ AllowGarbageCollection() {} -+}; -+ -+// Origin: -+// https://github.com/v8/v8/blob/84f3877c15bc7f8956d21614da4311337525a3c8/src/objects/string.h#L83-L474 -+class String : public HeapObject { -+ private: -+ JSString* str() const { return value().toString(); } -+ -+ public: -+ String() = default; -+ String(JSString* str) { setValue(JS::StringValue(str)); } -+ -+ operator JSString*() const { return str(); } -+ -+ // Max char codes. -+ static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar; -+ static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar; -+ static const int kMaxUtf16CodeUnit = 0xffff; -+ static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit; -+ static const uc32 kMaxCodePoint = 0x10ffff; -+ -+ MOZ_ALWAYS_INLINE int length() const { return str()->length(); } -+ bool IsFlat() { return str()->isLinear(); }; -+ -+ // Origin: -+ // https://github.com/v8/v8/blob/84f3877c15bc7f8956d21614da4311337525a3c8/src/objects/string.h#L95-L152 -+ class FlatContent { -+ public: -+ FlatContent(JSLinearString* string, const DisallowGarbageCollection& no_gc) -+ : string_(string), no_gc_(no_gc) {} -+ inline bool IsOneByte() const { return string_->hasLatin1Chars(); } -+ inline bool IsTwoByte() const { return !string_->hasLatin1Chars(); } -+ -+ Vector ToOneByteVector() const { -+ MOZ_ASSERT(IsOneByte()); -+ return Vector(string_->latin1Chars(no_gc_), -+ string_->length()); -+ } -+ Vector ToUC16Vector() const { -+ MOZ_ASSERT(IsTwoByte()); -+ return Vector(string_->twoByteChars(no_gc_), -+ string_->length()); -+ } -+ -+ private: -+ const JSLinearString* string_; -+ const JS::AutoCheckCannotGC& no_gc_; -+ }; -+ FlatContent GetFlatContent(const DisallowGarbageCollection& no_gc) { -+ MOZ_ASSERT(IsFlat()); -+ return FlatContent(&str()->asLinear(), no_gc); -+ } -+ -+ static Handle Flatten(Isolate* isolate, Handle string); -+ -+ inline static String cast(Object object) { -+ String s; -+ MOZ_ASSERT(object.value().isString()); -+ s.setValue(object.value()); -+ return s; -+ } -+ -+ inline static bool IsOneByteRepresentationUnderneath(String string) { -+ return string.str()->hasLatin1Chars(); -+ } -+ inline bool IsOneByteRepresentation() const { -+ return str()->hasLatin1Chars(); -+ } -+ -+ std::unique_ptr ToCString(); -+ -+ template -+ Vector GetCharVector(const DisallowGarbageCollection& no_gc); -+}; -+ -+template <> -+inline Vector String::GetCharVector( -+ const DisallowGarbageCollection& no_gc) { -+ String::FlatContent flat = GetFlatContent(no_gc); -+ MOZ_ASSERT(flat.IsOneByte()); -+ return flat.ToOneByteVector(); -+} -+ -+template <> -+inline Vector String::GetCharVector( -+ const DisallowGarbageCollection& no_gc) { -+ String::FlatContent flat = GetFlatContent(no_gc); -+ MOZ_ASSERT(flat.IsTwoByte()); -+ return flat.ToUC16Vector(); -+} -+ -+// A flat string reader provides random access to the contents of a -+// string independent of the character width of the string. -+class MOZ_STACK_CLASS FlatStringReader { -+ public: -+ FlatStringReader(JSContext* cx, js::HandleLinearString string) -+ : string_(string), length_(string->length()) {} -+ -+ FlatStringReader(const mozilla::Range range) -+ : string_(nullptr), range_(range), length_(range.length()) {} -+ -+ int length() { return length_; } -+ -+ inline char16_t Get(size_t index) { -+ MOZ_ASSERT(index < length_); -+ if (string_) { -+ return string_->latin1OrTwoByteChar(index); -+ } -+ return range_[index]; -+ } -+ -+ private: -+ js::HandleLinearString string_; -+ const mozilla::Range range_; -+ size_t length_; -+}; -+ -+class JSRegExp : public HeapObject { -+ public: -+ JSRegExp() : HeapObject() {} -+ JSRegExp(js::RegExpShared* re) { setValue(JS::PrivateGCThingValue(re)); } -+ -+ // ****************************************************** -+ // Methods that are called from inside the implementation -+ // ****************************************************** -+ void TierUpTick() { inner()->tierUpTick(); } -+ -+ Object Code(bool is_latin1) const { -+ return Object(JS::PrivateGCThingValue(inner()->getJitCode(is_latin1))); -+ } -+ Object Bytecode(bool is_latin1) const { -+ return Object(JS::PrivateValue(inner()->getByteCode(is_latin1))); -+ } -+ -+ // TODO: should we expose this? -+ uint32_t BacktrackLimit() const { return 0; } -+ -+ static JSRegExp cast(Object object) { -+ JSRegExp regexp; -+ js::gc::Cell* regexpShared = object.value().toGCThing(); -+ MOZ_ASSERT(regexpShared->is()); -+ regexp.setValue(JS::PrivateGCThingValue(regexpShared)); -+ return regexp; -+ } -+ -+ // Each capture (including the match itself) needs two registers. -+ static constexpr int RegistersForCaptureCount(int count) { -+ return (count + 1) * 2; -+ } -+ -+ inline int MaxRegisterCount() const { return inner()->getMaxRegisters(); } -+ -+ // ****************************** -+ // Static constants -+ // ****************************** -+ -+ // Maximum number of captures allowed. -+ static constexpr int kMaxCaptures = (1 << 15) - 1; -+ -+ // ************************************************** -+ // JSRegExp::Flags -+ // ************************************************** -+ -+ enum Flag : uint8_t { -+ kNone = JS::RegExpFlag::NoFlags, -+ kGlobal = JS::RegExpFlag::Global, -+ kIgnoreCase = JS::RegExpFlag::IgnoreCase, -+ kMultiline = JS::RegExpFlag::Multiline, -+ kSticky = JS::RegExpFlag::Sticky, -+ kUnicode = JS::RegExpFlag::Unicode, -+ kDotAll = JS::RegExpFlag::DotAll, -+ }; -+ using Flags = JS::RegExpFlags; -+ -+ static constexpr int kNoBacktrackLimit = 0; -+ -+ private: -+ js::RegExpShared* inner() const { -+ return static_cast(value().toGCThing()); -+ } -+}; -+ -+class Histogram { -+ public: -+ inline void AddSample(int sample) {} -+}; -+ -+class Counters { -+ public: -+ Histogram* regexp_backtracks() { return ®exp_backtracks_; } -+ -+ private: -+ Histogram regexp_backtracks_; -+}; -+ -+#define PROFILE(isolate, call) \ -+ do { \ -+ } while (false); -+ -+enum class AllocationType : uint8_t { -+ kYoung, // Allocate in the nursery -+ kOld, // Allocate in the tenured heap -+}; -+ -+using StackGuard = Isolate; -+using Factory = Isolate; -+ -+class Isolate { -+ public: -+ Isolate(JSContext* cx) : cx_(cx) {} -+ ~Isolate(); -+ bool init(); -+ -+ size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; -+ -+ //********** Isolate code **********// -+ RegExpStack* regexp_stack() const { return regexpStack_; } -+ byte* top_of_regexp_stack() const; -+ -+ // This is called from inside no-GC code. Instead of suppressing GC -+ // to allocate the error, we return false from Execute and call -+ // ReportOverRecursed in the caller. -+ void StackOverflow() {} -+ -+#ifndef V8_INTL_SUPPORT -+ unibrow::Mapping* jsregexp_uncanonicalize() { -+ return &jsregexp_uncanonicalize_; -+ } -+ unibrow::Mapping* -+ regexp_macro_assembler_canonicalize() { -+ return ®exp_macro_assembler_canonicalize_; -+ } -+ unibrow::Mapping* jsregexp_canonrange() { -+ return &jsregexp_canonrange_; -+ } -+ -+ private: -+ unibrow::Mapping jsregexp_uncanonicalize_; -+ unibrow::Mapping -+ regexp_macro_assembler_canonicalize_; -+ unibrow::Mapping jsregexp_canonrange_; -+#endif // !V8_INTL_SUPPORT -+ -+ public: -+ // An empty stub for telemetry we don't support -+ void IncreaseTotalRegexpCodeGenerated(Handle code) {} -+ -+ Counters* counters() { return &counters_; } -+ -+ //********** Factory code **********// -+ inline Factory* factory() { return this; } -+ -+ Handle NewByteArray( -+ int length, AllocationType allocation = AllocationType::kYoung); -+ -+ // Allocates a fixed array initialized with undefined values. -+ Handle NewFixedArray(int length); -+ -+ template -+ Handle InternalizeString(const Vector& str); -+ -+ //********** Stack guard code **********// -+ inline StackGuard* stack_guard() { return this; } -+ -+ // This is called from inside no-GC code. V8 runs the interrupt -+ // inside the no-GC code and then "manually relocates unhandlified -+ // references" afterwards. We just return false and let the caller -+ // handle interrupts. -+ Object HandleInterrupts() { return Object(JS::BooleanValue(false)); } -+ -+ JSContext* cx() const { return cx_; } -+ -+ void trace(JSTracer* trc); -+ -+ //********** Handle code **********// -+ -+ JS::Value* getHandleLocation(const JS::Value& value); -+ -+ private: -+ mozilla::SegmentedVector handleArena_; -+ mozilla::SegmentedVector, 256> uniquePtrArena_; -+ -+ void* allocatePseudoHandle(size_t bytes); -+ -+ public: -+ template -+ PseudoHandle takeOwnership(void* ptr); -+ -+ uint32_t liveHandles() const { return handleArena_.Length(); } -+ uint32_t livePseudoHandles() const { return uniquePtrArena_.Length(); } -+ -+ private: -+ void openHandleScope(HandleScope& scope) { -+ scope.level_ = handleArena_.Length(); -+ scope.non_gc_level_ = uniquePtrArena_.Length(); -+ } -+ void closeHandleScope(size_t prevLevel, size_t prevUniqueLevel) { -+ size_t currLevel = handleArena_.Length(); -+ handleArena_.PopLastN(currLevel - prevLevel); -+ -+ size_t currUniqueLevel = uniquePtrArena_.Length(); -+ uniquePtrArena_.PopLastN(currUniqueLevel - prevUniqueLevel); -+ } -+ friend class HandleScope; -+ -+ JSContext* cx_; -+ RegExpStack* regexpStack_; -+ Counters counters_; -+}; -+ -+// Origin: -+// https://github.com/v8/v8/blob/50dcf2af54ce27801a71c47c1be1d2c5e36b0dd6/src/execution/isolate.h#L1909-L1931 -+class StackLimitCheck { -+ public: -+ StackLimitCheck(Isolate* isolate) : cx_(isolate->cx()) {} -+ -+ // Use this to check for stack-overflows in C++ code. -+ bool HasOverflowed() { -+ bool overflowed = !CheckRecursionLimitDontReport(cx_); -+#ifdef JS_MORE_DETERMINISTIC -+ if (overflowed) { -+ // We don't report overrecursion here, but we throw an exception later -+ // and this still affects differential testing. Mimic ReportOverRecursed -+ // (the fuzzers check for this particular string). -+ fprintf(stderr, "ReportOverRecursed called\n"); -+ } -+#endif -+ return overflowed; -+ } -+ -+ // Use this to check for interrupt request in C++ code. -+ bool InterruptRequested() { return cx_->hasPendingInterrupt(); } -+ -+ // Use this to check for stack-overflow when entering runtime from JS code. -+ bool JsHasOverflowed() { -+ return !CheckRecursionLimitConservativeDontReport(cx_); -+ } -+ -+ private: -+ JSContext* cx_; -+}; -+ -+class Code : public HeapObject { -+ public: -+ uint8_t* raw_instruction_start() { return inner()->raw(); } -+ -+ static Code cast(Object object) { -+ Code c; -+ js::gc::Cell* jitCode = object.value().toGCThing(); -+ MOZ_ASSERT(jitCode->is()); -+ c.setValue(JS::PrivateGCThingValue(jitCode)); -+ return c; -+ } -+ js::jit::JitCode* inner() { -+ return static_cast(value().toGCThing()); -+ } -+}; -+ -+enum class MessageTemplate { kStackOverflow }; -+ -+class MessageFormatter { -+ public: -+ static const char* TemplateString(MessageTemplate index) { -+ switch (index) { -+ case MessageTemplate::kStackOverflow: -+ return "too much recursion"; -+ } -+ } -+}; -+ -+// Origin: https://github.com/v8/v8/blob/master/src/codegen/label.h -+class Label { -+ public: -+ Label() : inner_(js::jit::Label()) {} -+ -+ js::jit::Label* inner() { return &inner_; } -+ -+ void Unuse() { inner_.reset(); } -+ -+ bool is_linked() { return inner_.used(); } -+ bool is_bound() { return inner_.bound(); } -+ bool is_unused() { return !inner_.used() && !inner_.bound(); } -+ -+ int pos() { return inner_.offset(); } -+ void link_to(int pos) { inner_.use(pos); } -+ void bind_to(int pos) { inner_.bind(pos); } -+ -+ private: -+ js::jit::Label inner_; -+ js::jit::CodeOffset patchOffset_; -+ -+ friend class SMRegExpMacroAssembler; -+}; -+ -+//************************************************** -+// Constant Flags -+//************************************************** -+ -+// V8 uses this for differential fuzzing to handle stack overflows. -+// We address the same problem in StackLimitCheck::HasOverflowed. -+const bool FLAG_correctness_fuzzer_suppressions = false; -+ -+// Instead of using a flag for this, we provide an implementation of -+// CanReadUnaligned in SMRegExpMacroAssembler. -+const bool FLAG_enable_regexp_unaligned_accesses = false; -+ -+// This is used to guard a prototype implementation of sequence properties. -+// See: https://github.com/tc39/proposal-regexp-unicode-sequence-properties -+// TODO: Expose this behind a pref once it is past stage 2? -+const bool FLAG_harmony_regexp_sequence = false; -+ -+// This is only used in a helper function in regex.h that we never call. -+const bool FLAG_regexp_interpret_all = false; -+ -+// This is used to guard a prototype implementation of mode modifiers, -+// which can modify the regexp flags on the fly inside the pattern. -+// As far as I can tell, there isn't even a TC39 proposal for this. -+const bool FLAG_regexp_mode_modifiers = false; -+ -+// This is used to guard an old prototype implementation of possessive -+// quantifiers, which never got past the point of adding parser support. -+const bool FLAG_regexp_possessive_quantifier = false; -+ -+// These affect the default level of optimization. We can still turn -+// optimization off on a case-by-case basis in CompilePattern - for -+// example, if a regexp is too long - so we might as well turn these -+// flags on unconditionally. -+const bool FLAG_regexp_optimization = true; -+#if MOZ_BIG_ENDIAN -+// peephole optimization not supported on big endian -+const bool FLAG_regexp_peephole_optimization = false; -+#else -+const bool FLAG_regexp_peephole_optimization = true; -+#endif -+ -+// This is used to control whether regexps tier up from interpreted to -+// compiled. We control this with --no-native-regexp and -+// --regexp-warmup-threshold. -+const bool FLAG_regexp_tier_up = true; -+ -+//************************************************** -+// Debugging Flags -+//************************************************** -+ -+extern bool FLAG_trace_regexp_assembler; -+extern bool FLAG_trace_regexp_bytecodes; -+extern bool FLAG_trace_regexp_parser; -+extern bool FLAG_trace_regexp_peephole_optimization; -+ -+#define COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER -+ -+} // namespace internal -+} // namespace v8 -+ -+#endif // RegexpShim_h -diff -Nrup mozilla/js/src/irregexp/RegExpTypes.h mozilla-OK/js/src/irregexp/RegExpTypes.h ---- mozilla/js/src/irregexp/RegExpTypes.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/RegExpTypes.h 2022-06-16 00:06:40.927190732 +0300 -@@ -0,0 +1,64 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+// This file forward-defines Irregexp classes that need to be visible -+// to the rest of Spidermonkey and re-exports them into js::irregexp. -+ -+#ifndef regexp_RegExpTypes_h -+#define regexp_RegExpTypes_h -+ -+#include "js/UniquePtr.h" -+ -+namespace js { -+class MatchPairs; -+} -+ -+namespace v8 { -+namespace internal { -+ -+class ByteArrayData { -+ public: -+ uint32_t length; -+ uint8_t* data(); -+}; -+class Isolate; -+class RegExpStack; -+class RegExpStackScope; -+ -+struct InputOutputData { -+ const void* inputStart; -+ const void* inputEnd; -+ -+ // Index into inputStart (in chars) at which to begin matching. -+ size_t startIndex; -+ -+ js::MatchPairs* matches; -+ -+ template -+ InputOutputData(const CharT* inputStart, const CharT* inputEnd, -+ size_t startIndex, js::MatchPairs* matches) -+ : inputStart(inputStart), -+ inputEnd(inputEnd), -+ startIndex(startIndex), -+ matches(matches) {} -+}; -+ -+} // namespace internal -+} // namespace v8 -+ -+namespace js { -+namespace irregexp { -+ -+using Isolate = v8::internal::Isolate; -+using RegExpStack = v8::internal::RegExpStack; -+using RegExpStackScope = v8::internal::RegExpStackScope; -+using ByteArrayData = v8::internal::ByteArrayData; -+using ByteArray = js::UniquePtr; -+using InputOutputData = v8::internal::InputOutputData; -+ -+} // namespace irregexp -+} // namespace js -+ -+#endif // regexp_RegExpTypes_h -diff -Nrup mozilla/js/src/irregexp/import-irregexp.py mozilla-OK/js/src/irregexp/import-irregexp.py ---- mozilla/js/src/irregexp/import-irregexp.py 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/import-irregexp.py 2022-06-16 00:06:40.927190732 +0300 -@@ -0,0 +1,148 @@ -+#!/usr/bin/env python3 -+ -+# This Source Code Form is subject to the terms of the Mozilla Public -+# License, v. 2.0. If a copy of the MPL was not distributed with this file, -+# You can obtain one at http://mozilla.org/MPL/2.0/. -+ -+# This script handles all the mechanical steps of importing irregexp from v8: -+# -+# 1. Acquire the source: either from github, or optionally from a local copy of v8. -+# 2. Copy the contents of v8/src/regexp into js/src/irregexp/imported -+# - Exclude files that we have chosen not to import. -+# 3. While doing so, update #includes: -+# - Change "src/regexp/*" to "irregexp/imported/*". -+# - Remove other v8-specific headers completely. -+# 4. Add '#include "irregexp/RegExpShim.h" in the necessary places. -+# 5. Update the IRREGEXP_VERSION file to include the correct git hash. -+# -+# Usage: -+# cd path/to/js/src/irregexp -+# ./import-irregexp.py --path path/to/v8/src/regexp -+# -+# Alternatively, without the --path argument, import-irregexp.py will -+# clone v8 from github into a temporary directory. -+# -+# After running this script, changes to the shim code may be necessary -+# to account for changes in upstream irregexp. -+ -+import os -+import re -+import subprocess -+import sys -+from pathlib import Path -+ -+ -+def get_hash(path): -+ # Get the hash for the current git revision -+ cwd = os.getcwd() -+ os.chdir(path) -+ command = ["git", "rev-parse", "HEAD"] -+ result = subprocess.check_output(command, encoding="utf-8") -+ os.chdir(cwd) -+ return result.rstrip() -+ -+ -+def copy_and_update_includes(src_path, dst_path): -+ # List of header files that need to include the shim header -+ need_shim = [ -+ "property-sequences.h", -+ "regexp-ast.h", -+ "regexp-bytecode-peephole.h", -+ "regexp-bytecodes.h", -+ "regexp-dotprinter.h", -+ "regexp-error.h", -+ "regexp.h", -+ "regexp-macro-assembler.h", -+ "regexp-stack.h", -+ "special-case.h", -+ ] -+ -+ src = open(str(src_path), "r") -+ dst = open(str(dst_path), "w") -+ -+ # 1. Rewrite includes of V8 regexp headers: -+ regexp_include = re.compile('#include "src/regexp') -+ regexp_include_new = '#include "irregexp/imported' -+ -+ # 2. Remove includes of other V8 headers -+ other_include = re.compile('#include "src/') -+ -+ # 3. If needed, add '#include "irregexp/RegExpShim.h"'. -+ # Note: We get a little fancy to ensure that header files are -+ # in alphabetic order. `need_to_add_shim` is true if we still -+ # have to add the shim header in this file. `adding_shim_now` -+ # is true if we have found a '#include "src/*' and we are just -+ # waiting to find an empty line so that we can insert the shim -+ # header in the right place. -+ need_to_add_shim = src_path.name in need_shim -+ adding_shim_now = False -+ -+ for line in src: -+ if adding_shim_now: -+ if line == "\n": -+ dst.write('#include "irregexp/RegExpShim.h"\n') -+ need_to_add_shim = False -+ adding_shim_now = False -+ -+ if regexp_include.search(line): -+ dst.write(re.sub(regexp_include, regexp_include_new, line)) -+ elif other_include.search(line): -+ if need_to_add_shim: -+ adding_shim_now = True -+ else: -+ dst.write(line) -+ -+ -+def import_from(srcdir, dstdir): -+ excluded = [ -+ "DIR_METADATA", -+ "OWNERS", -+ "regexp.cc", -+ "regexp-utils.cc", -+ "regexp-utils.h", -+ "regexp-macro-assembler-arch.h", -+ ] -+ -+ for file in srcdir.iterdir(): -+ if file.is_dir(): -+ continue -+ if str(file.name) in excluded: -+ continue -+ copy_and_update_includes(file, dstdir / "imported" / file.name) -+ -+ # Update IRREGEXP_VERSION file -+ hash = get_hash(srcdir) -+ version_file = open(str(dstdir / "IRREGEXP_VERSION"), "w") -+ version_file.write("Imported using import-irregexp.py from:\n") -+ version_file.write("https://github.com/v8/v8/tree/%s/src/regexp\n" % hash) -+ -+ -+if __name__ == "__main__": -+ import argparse -+ import tempfile -+ -+ # This script should be run from js/src/irregexp to work correctly. -+ current_path = Path(os.getcwd()) -+ expected_path = "js/src/irregexp" -+ if not current_path.match(expected_path): -+ raise RuntimeError("%s must be run from %s" % (sys.argv[0], expected_path)) -+ -+ parser = argparse.ArgumentParser(description="Import irregexp from v8") -+ parser.add_argument("-p", "--path", help="path to v8/src/regexp") -+ args = parser.parse_args() -+ -+ if args.path: -+ src_path = Path(args.path) -+ -+ if not (src_path / "regexp.h").exists(): -+ print("Usage:\n import-irregexp.py --path ") -+ sys.exit(1) -+ import_from(src_path, current_path) -+ sys.exit(0) -+ -+ with tempfile.TemporaryDirectory() as tempdir: -+ v8_git = "https://github.com/v8/v8.git" -+ clone = "git clone --depth 1 %s %s" % (v8_git, tempdir) -+ os.system(clone) -+ src_path = Path(tempdir) / "src/regexp" -+ import_from(src_path, current_path) -diff -Nrup mozilla/js/src/irregexp/moz.build mozilla-OK/js/src/irregexp/moz.build ---- mozilla/js/src/irregexp/moz.build 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/moz.build 2022-06-16 00:06:40.944190616 +0300 -@@ -0,0 +1,45 @@ -+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -+# This Source Code Form is subject to the terms of the Mozilla Public -+# License, v. 2.0. If a copy of the MPL was not distributed with this -+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ -+include('../js-config.mozbuild') -+include('../js-cxxflags.mozbuild') -+ -+FINAL_LIBRARY = "js" -+ -+# Includes should be relative to parent path -+LOCAL_INCLUDES += ["!..", ".."] -+ -+CXXFLAGS += ["-Wno-error=type-limits"] -+ -+SOURCES += [ -+ 'imported/regexp-ast.cc', -+ 'imported/regexp-bytecode-generator.cc', -+ 'imported/regexp-bytecode-peephole.cc', -+ 'imported/regexp-bytecodes.cc', -+ 'imported/regexp-compiler-tonode.cc', -+ 'imported/regexp-compiler.cc', -+ 'imported/regexp-dotprinter.cc', -+ 'imported/regexp-interpreter.cc', -+ 'imported/regexp-macro-assembler-tracer.cc', -+ 'imported/regexp-macro-assembler.cc', -+ 'imported/regexp-parser.cc', -+ 'imported/regexp-stack.cc', -+ 'RegExpAPI.cpp', -+ 'RegExpNativeMacroAssembler.cpp', -+ 'RegExpShim.cpp', -+ 'util/UnicodeShim.cpp' -+] -+ -+if CONFIG['ENABLE_INTL_API']: -+ CXXFLAGS += ['-DV8_INTL_SUPPORT'] -+ SOURCES += [ -+ 'imported/property-sequences.cc', -+ 'imported/special-case.cc' -+ ] -+ -+if CONFIG['_MSC_VER']: -+ # This is intended as a temporary workaround to unblock compilation -+ # on VS2015 in warnings as errors mode. -+ CXXFLAGS += ['-wd4275'] -\ No newline at end of file -diff -Nrup mozilla/js/src/irregexp/util/FlagsShim.h mozilla-OK/js/src/irregexp/util/FlagsShim.h ---- mozilla/js/src/irregexp/util/FlagsShim.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/util/FlagsShim.h 2022-06-16 00:06:40.944190616 +0300 -@@ -0,0 +1,87 @@ -+// Copyright 2014 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef V8_UTIL_FLAGS_H_ -+#define V8_UTIL_FLAGS_H_ -+ -+// Origin: -+// https://github.com/v8/v8/blob/1bafcc6b999b23ea1d394f5d267a08183e3c4e19/src/base/flags.h#L15-L90 -+ -+namespace v8 { -+namespace base { -+ -+// The Flags class provides a type-safe way of storing OR-combinations of enum -+// values. The Flags class is a template class, where T is an enum type, -+// and S is the underlying storage type (usually int). -+// -+// The traditional C++ approach for storing OR-combinations of enum values is to -+// use an int or unsigned int variable. The inconvenience with this approach is -+// that there's no type checking at all; any enum value can be OR'd with any -+// other enum value and passed on to a function that takes an int or unsigned -+// int. -+template -+class Flags final { -+ public: -+ using flag_type = T; -+ using mask_type = S; -+ -+ Flags() : mask_(0) {} -+ Flags(flag_type flag) : mask_(static_cast(flag)) {} -+ Flags(mask_type mask) : mask_(static_cast(mask)) {} -+ -+ bool operator==(flag_type flag) const { -+ return mask_ == static_cast(flag); -+ } -+ bool operator!=(flag_type flag) const { -+ return mask_ != static_cast(flag); -+ } -+ -+ Flags& operator&=(const Flags& flags) { -+ mask_ &= flags.mask_; -+ return *this; -+ } -+ Flags& operator|=(const Flags& flags) { -+ mask_ |= flags.mask_; -+ return *this; -+ } -+ Flags& operator^=(const Flags& flags) { -+ mask_ ^= flags.mask_; -+ return *this; -+ } -+ -+ Flags operator&(const Flags& flags) const { -+ return Flags(mask_ & flags.mask_); -+ } -+ Flags operator|(const Flags& flags) const { -+ return Flags(mask_ | flags.mask_); -+ } -+ Flags operator^(const Flags& flags) const { -+ return Flags(mask_ ^ flags.mask_); -+ } -+ -+ Flags& operator&=(flag_type flag) { return operator&=(Flags(flag)); } -+ Flags& operator|=(flag_type flag) { return operator|=(Flags(flag)); } -+ Flags& operator^=(flag_type flag) { return operator^=(Flags(flag)); } -+ -+ Flags operator&(flag_type flag) const { return operator&(Flags(flag)); } -+ Flags operator|(flag_type flag) const { return operator|(Flags(flag)); } -+ Flags operator^(flag_type flag) const { return operator^(Flags(flag)); } -+ -+ Flags operator~() const { return Flags(~mask_); } -+ -+ operator mask_type() const { return mask_; } -+ bool operator!() const { return !mask_; } -+ -+ Flags without(flag_type flag) { return *this & (~Flags(flag)); } -+ -+ friend size_t hash_value(const Flags& flags) { return flags.mask_; } -+ -+ private: -+ mask_type mask_; -+}; -+ -+} // namespace base -+} // namespace v8 -+ -+#endif // V8_UTIL_FLAG_H_ -diff -Nrup mozilla/js/src/irregexp/util/UnicodeShim.cpp mozilla-OK/js/src/irregexp/util/UnicodeShim.cpp ---- mozilla/js/src/irregexp/util/UnicodeShim.cpp 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/util/UnicodeShim.cpp 2022-06-16 00:06:40.946190602 +0300 -@@ -0,0 +1,1866 @@ -+// Copyright 2012 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+// -+// This file is a subset of: -+// https://github.com/v8/v8/blob/master/src/strings/unicode.cc -+ -+#include "irregexp/RegExpShim.h" -+ -+#ifdef V8_INTL_SUPPORT -+# include "unicode/uchar.h" -+#endif -+ -+namespace v8 { -+namespace unibrow { -+ -+#ifndef V8_INTL_SUPPORT -+static const int kStartBit = (1 << 30); -+static const int kChunkBits = (1 << 13); -+#endif // !V8_INTL_SUPPORT -+ -+static const uchar kSentinel = static_cast(-1); -+ -+/** -+ * \file -+ * Implementations of functions for working with Unicode. -+ */ -+ -+using int16_t = signed short; // NOLINT -+using uint16_t = unsigned short; // NOLINT -+using int32_t = int; // NOLINT -+ -+#ifndef V8_INTL_SUPPORT -+// All access to the character table should go through this function. -+template -+static inline uchar TableGet(const int32_t* table, int index) { -+ return table[D * index]; -+} -+ -+static inline uchar GetEntry(int32_t entry) { return entry & (kStartBit - 1); } -+ -+static inline bool IsStart(int32_t entry) { return (entry & kStartBit) != 0; } -+ -+/** -+ * Look up a character in the Unicode table using a mix of binary and -+ * interpolation search. For a uniformly distributed array -+ * interpolation search beats binary search by a wide margin. However, -+ * in this case interpolation search degenerates because of some very -+ * high values in the lower end of the table so this function uses a -+ * combination. The average number of steps to look up the information -+ * about a character is around 10, slightly higher if there is no -+ * information available about the character. -+ */ -+static bool LookupPredicate(const int32_t* table, uint16_t size, uchar chr) { -+ static const int kEntryDist = 1; -+ uint16_t value = chr & (kChunkBits - 1); -+ unsigned int low = 0; -+ unsigned int high = size - 1; -+ while (high != low) { -+ unsigned int mid = low + ((high - low) >> 1); -+ uchar current_value = GetEntry(TableGet(table, mid)); -+ // If we've found an entry less than or equal to this one, and the -+ // next one is not also less than this one, we've arrived. -+ if ((current_value <= value) && -+ (mid + 1 == size || -+ GetEntry(TableGet(table, mid + 1)) > value)) { -+ low = mid; -+ break; -+ } else if (current_value < value) { -+ low = mid + 1; -+ } else if (current_value > value) { -+ // If we've just checked the bottom-most value and it's not -+ // the one we're looking for, we're done. -+ if (mid == 0) break; -+ high = mid - 1; -+ } -+ } -+ int32_t field = TableGet(table, low); -+ uchar entry = GetEntry(field); -+ bool is_start = IsStart(field); -+ return (entry == value) || (entry < value && is_start); -+} -+#endif // !V8_INTL_SUPPORT -+ -+template -+struct MultiCharacterSpecialCase { -+ static const uchar kEndOfEncoding = kSentinel; -+ uchar chars[kW]; -+}; -+ -+#ifndef V8_INTL_SUPPORT -+// Look up the mapping for the given character in the specified table, -+// which is of the specified length and uses the specified special case -+// mapping for multi-char mappings. The next parameter is the character -+// following the one to map. The result will be written in to the result -+// buffer and the number of characters written will be returned. Finally, -+// if the allow_caching_ptr is non-null then false will be stored in -+// it if the result contains multiple characters or depends on the -+// context. -+// If ranges are linear, a match between a start and end point is -+// offset by the distance between the match and the start. Otherwise -+// the result is the same as for the start point on the entire range. -+template -+static int LookupMapping(const int32_t* table, uint16_t size, -+ const MultiCharacterSpecialCase* multi_chars, -+ uchar chr, uchar next, uchar* result, -+ bool* allow_caching_ptr) { -+ static const int kEntryDist = 2; -+ uint16_t key = chr & (kChunkBits - 1); -+ uint16_t chunk_start = chr - key; -+ unsigned int low = 0; -+ unsigned int high = size - 1; -+ while (high != low) { -+ unsigned int mid = low + ((high - low) >> 1); -+ uchar current_value = GetEntry(TableGet(table, mid)); -+ // If we've found an entry less than or equal to this one, and the next one -+ // is not also less than this one, we've arrived. -+ if ((current_value <= key) && -+ (mid + 1 == size || -+ GetEntry(TableGet(table, mid + 1)) > key)) { -+ low = mid; -+ break; -+ } else if (current_value < key) { -+ low = mid + 1; -+ } else if (current_value > key) { -+ // If we've just checked the bottom-most value and it's not -+ // the one we're looking for, we're done. -+ if (mid == 0) break; -+ high = mid - 1; -+ } -+ } -+ int32_t field = TableGet(table, low); -+ uchar entry = GetEntry(field); -+ bool is_start = IsStart(field); -+ bool found = (entry == key) || (entry < key && is_start); -+ if (found) { -+ int32_t value = table[2 * low + 1]; -+ if (value == 0) { -+ // 0 means not present -+ return 0; -+ } else if ((value & 3) == 0) { -+ // Low bits 0 means a constant offset from the given character. -+ if (ranges_are_linear) { -+ result[0] = chr + (value >> 2); -+ } else { -+ result[0] = entry + chunk_start + (value >> 2); -+ } -+ return 1; -+ } else if ((value & 3) == 1) { -+ // Low bits 1 means a special case mapping -+ if (allow_caching_ptr) *allow_caching_ptr = false; -+ const MultiCharacterSpecialCase& mapping = multi_chars[value >> 2]; -+ int length = 0; -+ for (length = 0; length < kW; length++) { -+ uchar mapped = mapping.chars[length]; -+ if (mapped == MultiCharacterSpecialCase::kEndOfEncoding) break; -+ if (ranges_are_linear) { -+ result[length] = mapped + (key - entry); -+ } else { -+ result[length] = mapped; -+ } -+ } -+ return length; -+ } else { -+ // Low bits 2 means a really really special case -+ if (allow_caching_ptr) *allow_caching_ptr = false; -+ // The cases of this switch are defined in unicode.py in the -+ // really_special_cases mapping. -+ switch (value >> 2) { -+ case 1: -+ // Really special case 1: upper case sigma. This letter -+ // converts to two different lower case sigmas depending on -+ // whether or not it occurs at the end of a word. -+ if (next != 0 && Letter::Is(next)) { -+ result[0] = 0x03C3; -+ } else { -+ result[0] = 0x03C2; -+ } -+ return 1; -+ default: -+ return 0; -+ } -+ return -1; -+ } -+ } else { -+ return 0; -+ } -+} -+#endif // !V8_INTL_SUPPORT -+ -+// Letter: point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl'] -+#ifdef V8_INTL_SUPPORT -+bool Letter::Is(uchar c) { return static_cast(u_isalpha(c)); } -+#else -+static const uint16_t kLetterTable0Size = 431; -+static const int32_t kLetterTable0[431] = { -+ 1073741889, 90, 1073741921, 122, -+ 170, 181, 186, 1073742016, // NOLINT -+ 214, 1073742040, 246, 1073742072, -+ 705, 1073742534, 721, 1073742560, // NOLINT -+ 740, 748, 750, 1073742704, -+ 884, 1073742710, 887, 1073742714, // NOLINT -+ 893, 895, 902, 1073742728, -+ 906, 908, 1073742734, 929, // NOLINT -+ 1073742755, 1013, 1073742839, 1153, -+ 1073742986, 1327, 1073743153, 1366, // NOLINT -+ 1369, 1073743201, 1415, 1073743312, -+ 1514, 1073743344, 1522, 1073743392, // NOLINT -+ 1610, 1073743470, 1647, 1073743473, -+ 1747, 1749, 1073743589, 1766, // NOLINT -+ 1073743598, 1775, 1073743610, 1788, -+ 1791, 1808, 1073743634, 1839, // NOLINT -+ 1073743693, 1957, 1969, 1073743818, -+ 2026, 1073743860, 2037, 2042, // NOLINT -+ 1073743872, 2069, 2074, 2084, -+ 2088, 1073743936, 2136, 1073744032, // NOLINT -+ 2226, 1073744132, 2361, 2365, -+ 2384, 1073744216, 2401, 1073744241, // NOLINT -+ 2432, 1073744261, 2444, 1073744271, -+ 2448, 1073744275, 2472, 1073744298, // NOLINT -+ 2480, 2482, 1073744310, 2489, -+ 2493, 2510, 1073744348, 2525, // NOLINT -+ 1073744351, 2529, 1073744368, 2545, -+ 1073744389, 2570, 1073744399, 2576, // NOLINT -+ 1073744403, 2600, 1073744426, 2608, -+ 1073744434, 2611, 1073744437, 2614, // NOLINT -+ 1073744440, 2617, 1073744473, 2652, -+ 2654, 1073744498, 2676, 1073744517, // NOLINT -+ 2701, 1073744527, 2705, 1073744531, -+ 2728, 1073744554, 2736, 1073744562, // NOLINT -+ 2739, 1073744565, 2745, 2749, -+ 2768, 1073744608, 2785, 1073744645, // NOLINT -+ 2828, 1073744655, 2832, 1073744659, -+ 2856, 1073744682, 2864, 1073744690, // NOLINT -+ 2867, 1073744693, 2873, 2877, -+ 1073744732, 2909, 1073744735, 2913, // NOLINT -+ 2929, 2947, 1073744773, 2954, -+ 1073744782, 2960, 1073744786, 2965, // NOLINT -+ 1073744793, 2970, 2972, 1073744798, -+ 2975, 1073744803, 2980, 1073744808, // NOLINT -+ 2986, 1073744814, 3001, 3024, -+ 1073744901, 3084, 1073744910, 3088, // NOLINT -+ 1073744914, 3112, 1073744938, 3129, -+ 3133, 1073744984, 3161, 1073744992, // NOLINT -+ 3169, 1073745029, 3212, 1073745038, -+ 3216, 1073745042, 3240, 1073745066, // NOLINT -+ 3251, 1073745077, 3257, 3261, -+ 3294, 1073745120, 3297, 1073745137, // NOLINT -+ 3314, 1073745157, 3340, 1073745166, -+ 3344, 1073745170, 3386, 3389, // NOLINT -+ 3406, 1073745248, 3425, 1073745274, -+ 3455, 1073745285, 3478, 1073745306, // NOLINT -+ 3505, 1073745331, 3515, 3517, -+ 1073745344, 3526, 1073745409, 3632, // NOLINT -+ 1073745458, 3635, 1073745472, 3654, -+ 1073745537, 3714, 3716, 1073745543, // NOLINT -+ 3720, 3722, 3725, 1073745556, -+ 3735, 1073745561, 3743, 1073745569, // NOLINT -+ 3747, 3749, 3751, 1073745578, -+ 3755, 1073745581, 3760, 1073745586, // NOLINT -+ 3763, 3773, 1073745600, 3780, -+ 3782, 1073745628, 3807, 3840, // NOLINT -+ 1073745728, 3911, 1073745737, 3948, -+ 1073745800, 3980, 1073745920, 4138, // NOLINT -+ 4159, 1073746000, 4181, 1073746010, -+ 4189, 4193, 1073746021, 4198, // NOLINT -+ 1073746030, 4208, 1073746037, 4225, -+ 4238, 1073746080, 4293, 4295, // NOLINT -+ 4301, 1073746128, 4346, 1073746172, -+ 4680, 1073746506, 4685, 1073746512, // NOLINT -+ 4694, 4696, 1073746522, 4701, -+ 1073746528, 4744, 1073746570, 4749, // NOLINT -+ 1073746576, 4784, 1073746610, 4789, -+ 1073746616, 4798, 4800, 1073746626, // NOLINT -+ 4805, 1073746632, 4822, 1073746648, -+ 4880, 1073746706, 4885, 1073746712, // NOLINT -+ 4954, 1073746816, 5007, 1073746848, -+ 5108, 1073746945, 5740, 1073747567, // NOLINT -+ 5759, 1073747585, 5786, 1073747616, -+ 5866, 1073747694, 5880, 1073747712, // NOLINT -+ 5900, 1073747726, 5905, 1073747744, -+ 5937, 1073747776, 5969, 1073747808, // NOLINT -+ 5996, 1073747822, 6000, 1073747840, -+ 6067, 6103, 6108, 1073748000, // NOLINT -+ 6263, 1073748096, 6312, 6314, -+ 1073748144, 6389, 1073748224, 6430, // NOLINT -+ 1073748304, 6509, 1073748336, 6516, -+ 1073748352, 6571, 1073748417, 6599, // NOLINT -+ 1073748480, 6678, 1073748512, 6740, -+ 6823, 1073748741, 6963, 1073748805, // NOLINT -+ 6987, 1073748867, 7072, 1073748910, -+ 7087, 1073748922, 7141, 1073748992, // NOLINT -+ 7203, 1073749069, 7247, 1073749082, -+ 7293, 1073749225, 7404, 1073749230, // NOLINT -+ 7409, 1073749237, 7414, 1073749248, -+ 7615, 1073749504, 7957, 1073749784, // NOLINT -+ 7965, 1073749792, 8005, 1073749832, -+ 8013, 1073749840, 8023, 8025, // NOLINT -+ 8027, 8029, 1073749855, 8061, -+ 1073749888, 8116, 1073749942, 8124, // NOLINT -+ 8126, 1073749954, 8132, 1073749958, -+ 8140, 1073749968, 8147, 1073749974, // NOLINT -+ 8155, 1073749984, 8172, 1073750002, -+ 8180, 1073750006, 8188}; // NOLINT -+static const uint16_t kLetterTable1Size = 87; -+static const int32_t kLetterTable1[87] = { -+ 113, 127, 1073741968, 156, -+ 258, 263, 1073742090, 275, // NOLINT -+ 277, 1073742105, 285, 292, -+ 294, 296, 1073742122, 301, // NOLINT -+ 1073742127, 313, 1073742140, 319, -+ 1073742149, 329, 334, 1073742176, // NOLINT -+ 392, 1073744896, 3118, 1073744944, -+ 3166, 1073744992, 3300, 1073745131, // NOLINT -+ 3310, 1073745138, 3315, 1073745152, -+ 3365, 3367, 3373, 1073745200, // NOLINT -+ 3431, 3439, 1073745280, 3478, -+ 1073745312, 3494, 1073745320, 3502, // NOLINT -+ 1073745328, 3510, 1073745336, 3518, -+ 1073745344, 3526, 1073745352, 3534, // NOLINT -+ 1073745360, 3542, 1073745368, 3550, -+ 3631, 1073745925, 4103, 1073745953, // NOLINT -+ 4137, 1073745969, 4149, 1073745976, -+ 4156, 1073745985, 4246, 1073746077, // NOLINT -+ 4255, 1073746081, 4346, 1073746172, -+ 4351, 1073746181, 4397, 1073746225, // NOLINT -+ 4494, 1073746336, 4538, 1073746416, -+ 4607, 1073746944, 8191}; // NOLINT -+static const uint16_t kLetterTable2Size = 4; -+static const int32_t kLetterTable2[4] = {1073741824, 3509, 1073745408, -+ 8191}; // NOLINT -+static const uint16_t kLetterTable3Size = 2; -+static const int32_t kLetterTable3[2] = {1073741824, 8191}; // NOLINT -+static const uint16_t kLetterTable4Size = 2; -+static const int32_t kLetterTable4[2] = {1073741824, 8140}; // NOLINT -+static const uint16_t kLetterTable5Size = 100; -+static const int32_t kLetterTable5[100] = { -+ 1073741824, 1164, 1073743056, 1277, -+ 1073743104, 1548, 1073743376, 1567, // NOLINT -+ 1073743402, 1579, 1073743424, 1646, -+ 1073743487, 1693, 1073743520, 1775, // NOLINT -+ 1073743639, 1823, 1073743650, 1928, -+ 1073743755, 1934, 1073743760, 1965, // NOLINT -+ 1073743792, 1969, 1073743863, 2049, -+ 1073743875, 2053, 1073743879, 2058, // NOLINT -+ 1073743884, 2082, 1073743936, 2163, -+ 1073744002, 2227, 1073744114, 2295, // NOLINT -+ 2299, 1073744138, 2341, 1073744176, -+ 2374, 1073744224, 2428, 1073744260, // NOLINT -+ 2482, 2511, 1073744352, 2532, -+ 1073744358, 2543, 1073744378, 2558, // NOLINT -+ 1073744384, 2600, 1073744448, 2626, -+ 1073744452, 2635, 1073744480, 2678, // NOLINT -+ 2682, 1073744510, 2735, 2737, -+ 1073744565, 2742, 1073744569, 2749, // NOLINT -+ 2752, 2754, 1073744603, 2781, -+ 1073744608, 2794, 1073744626, 2804, // NOLINT -+ 1073744641, 2822, 1073744649, 2830, -+ 1073744657, 2838, 1073744672, 2854, // NOLINT -+ 1073744680, 2862, 1073744688, 2906, -+ 1073744732, 2911, 1073744740, 2917, // NOLINT -+ 1073744832, 3042, 1073744896, 8191}; // NOLINT -+static const uint16_t kLetterTable6Size = 6; -+static const int32_t kLetterTable6[6] = {1073741824, 6051, 1073747888, 6086, -+ 1073747915, 6139}; // NOLINT -+static const uint16_t kLetterTable7Size = 48; -+static const int32_t kLetterTable7[48] = { -+ 1073748224, 6765, 1073748592, 6873, -+ 1073748736, 6918, 1073748755, 6935, // NOLINT -+ 6941, 1073748767, 6952, 1073748778, -+ 6966, 1073748792, 6972, 6974, // NOLINT -+ 1073748800, 6977, 1073748803, 6980, -+ 1073748806, 7089, 1073748947, 7485, // NOLINT -+ 1073749328, 7567, 1073749394, 7623, -+ 1073749488, 7675, 1073749616, 7796, // NOLINT -+ 1073749622, 7932, 1073749793, 7994, -+ 1073749825, 8026, 1073749862, 8126, // NOLINT -+ 1073749954, 8135, 1073749962, 8143, -+ 1073749970, 8151, 1073749978, 8156}; // NOLINT -+bool Letter::Is(uchar c) { -+ int chunk_index = c >> 13; -+ switch (chunk_index) { -+ case 0: -+ return LookupPredicate(kLetterTable0, kLetterTable0Size, c); -+ case 1: -+ return LookupPredicate(kLetterTable1, kLetterTable1Size, c); -+ case 2: -+ return LookupPredicate(kLetterTable2, kLetterTable2Size, c); -+ case 3: -+ return LookupPredicate(kLetterTable3, kLetterTable3Size, c); -+ case 4: -+ return LookupPredicate(kLetterTable4, kLetterTable4Size, c); -+ case 5: -+ return LookupPredicate(kLetterTable5, kLetterTable5Size, c); -+ case 6: -+ return LookupPredicate(kLetterTable6, kLetterTable6Size, c); -+ case 7: -+ return LookupPredicate(kLetterTable7, kLetterTable7Size, c); -+ default: -+ return false; -+ } -+} -+#endif -+ -+#ifndef V8_INTL_SUPPORT -+ -+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings0[1] = -+ { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262CanonicalizeTable0Size = 498; // NOLINT -+static const int32_t kEcma262CanonicalizeTable0[996] = { -+ 1073741921, -128, 122, -128, 181, 2972, -+ 1073742048, -128, 246, -128, 1073742072, -128, -+ 254, -128, 255, 484, // NOLINT -+ 257, -4, 259, -4, 261, -4, -+ 263, -4, 265, -4, 267, -4, -+ 269, -4, 271, -4, // NOLINT -+ 273, -4, 275, -4, 277, -4, -+ 279, -4, 281, -4, 283, -4, -+ 285, -4, 287, -4, // NOLINT -+ 289, -4, 291, -4, 293, -4, -+ 295, -4, 297, -4, 299, -4, -+ 301, -4, 303, -4, // NOLINT -+ 307, -4, 309, -4, 311, -4, -+ 314, -4, 316, -4, 318, -4, -+ 320, -4, 322, -4, // NOLINT -+ 324, -4, 326, -4, 328, -4, -+ 331, -4, 333, -4, 335, -4, -+ 337, -4, 339, -4, // NOLINT -+ 341, -4, 343, -4, 345, -4, -+ 347, -4, 349, -4, 351, -4, -+ 353, -4, 355, -4, // NOLINT -+ 357, -4, 359, -4, 361, -4, -+ 363, -4, 365, -4, 367, -4, -+ 369, -4, 371, -4, // NOLINT -+ 373, -4, 375, -4, 378, -4, -+ 380, -4, 382, -4, 384, 780, -+ 387, -4, 389, -4, // NOLINT -+ 392, -4, 396, -4, 402, -4, -+ 405, 388, 409, -4, 410, 652, -+ 414, 520, 417, -4, // NOLINT -+ 419, -4, 421, -4, 424, -4, -+ 429, -4, 432, -4, 436, -4, -+ 438, -4, 441, -4, // NOLINT -+ 445, -4, 447, 224, 453, -4, -+ 454, -8, 456, -4, 457, -8, -+ 459, -4, 460, -8, // NOLINT -+ 462, -4, 464, -4, 466, -4, -+ 468, -4, 470, -4, 472, -4, -+ 474, -4, 476, -4, // NOLINT -+ 477, -316, 479, -4, 481, -4, -+ 483, -4, 485, -4, 487, -4, -+ 489, -4, 491, -4, // NOLINT -+ 493, -4, 495, -4, 498, -4, -+ 499, -8, 501, -4, 505, -4, -+ 507, -4, 509, -4, // NOLINT -+ 511, -4, 513, -4, 515, -4, -+ 517, -4, 519, -4, 521, -4, -+ 523, -4, 525, -4, // NOLINT -+ 527, -4, 529, -4, 531, -4, -+ 533, -4, 535, -4, 537, -4, -+ 539, -4, 541, -4, // NOLINT -+ 543, -4, 547, -4, 549, -4, -+ 551, -4, 553, -4, 555, -4, -+ 557, -4, 559, -4, // NOLINT -+ 561, -4, 563, -4, 572, -4, -+ 1073742399, 43260, 576, 43260, 578, -4, -+ 583, -4, 585, -4, // NOLINT -+ 587, -4, 589, -4, 591, -4, -+ 592, 43132, 593, 43120, 594, 43128, -+ 595, -840, 596, -824, // NOLINT -+ 1073742422, -820, 599, -820, 601, -808, -+ 603, -812, 604, 169276, 608, -820, -+ 609, 169260, 611, -828, // NOLINT -+ 613, 169120, 614, 169232, 616, -836, -+ 617, -844, 619, 42972, 620, 169220, -+ 623, -844, 625, 42996, // NOLINT -+ 626, -852, 629, -856, 637, 42908, -+ 640, -872, 643, -872, 647, 169128, -+ 648, -872, 649, -276, // NOLINT -+ 1073742474, -868, 651, -868, 652, -284, -+ 658, -876, 670, 169032, 837, 336, -+ 881, -4, 883, -4, // NOLINT -+ 887, -4, 1073742715, 520, 893, 520, -+ 940, -152, 1073742765, -148, 943, -148, -+ 1073742769, -128, 961, -128, // NOLINT -+ 962, -124, 1073742787, -128, 971, -128, -+ 972, -256, 1073742797, -252, 974, -252, -+ 976, -248, 977, -228, // NOLINT -+ 981, -188, 982, -216, 983, -32, -+ 985, -4, 987, -4, 989, -4, -+ 991, -4, 993, -4, // NOLINT -+ 995, -4, 997, -4, 999, -4, -+ 1001, -4, 1003, -4, 1005, -4, -+ 1007, -4, 1008, -344, // NOLINT -+ 1009, -320, 1010, 28, 1011, -464, -+ 1013, -384, 1016, -4, 1019, -4, -+ 1073742896, -128, 1103, -128, // NOLINT -+ 1073742928, -320, 1119, -320, 1121, -4, -+ 1123, -4, 1125, -4, 1127, -4, -+ 1129, -4, 1131, -4, // NOLINT -+ 1133, -4, 1135, -4, 1137, -4, -+ 1139, -4, 1141, -4, 1143, -4, -+ 1145, -4, 1147, -4, // NOLINT -+ 1149, -4, 1151, -4, 1153, -4, -+ 1163, -4, 1165, -4, 1167, -4, -+ 1169, -4, 1171, -4, // NOLINT -+ 1173, -4, 1175, -4, 1177, -4, -+ 1179, -4, 1181, -4, 1183, -4, -+ 1185, -4, 1187, -4, // NOLINT -+ 1189, -4, 1191, -4, 1193, -4, -+ 1195, -4, 1197, -4, 1199, -4, -+ 1201, -4, 1203, -4, // NOLINT -+ 1205, -4, 1207, -4, 1209, -4, -+ 1211, -4, 1213, -4, 1215, -4, -+ 1218, -4, 1220, -4, // NOLINT -+ 1222, -4, 1224, -4, 1226, -4, -+ 1228, -4, 1230, -4, 1231, -60, -+ 1233, -4, 1235, -4, // NOLINT -+ 1237, -4, 1239, -4, 1241, -4, -+ 1243, -4, 1245, -4, 1247, -4, -+ 1249, -4, 1251, -4, // NOLINT -+ 1253, -4, 1255, -4, 1257, -4, -+ 1259, -4, 1261, -4, 1263, -4, -+ 1265, -4, 1267, -4, // NOLINT -+ 1269, -4, 1271, -4, 1273, -4, -+ 1275, -4, 1277, -4, 1279, -4, -+ 1281, -4, 1283, -4, // NOLINT -+ 1285, -4, 1287, -4, 1289, -4, -+ 1291, -4, 1293, -4, 1295, -4, -+ 1297, -4, 1299, -4, // NOLINT -+ 1301, -4, 1303, -4, 1305, -4, -+ 1307, -4, 1309, -4, 1311, -4, -+ 1313, -4, 1315, -4, // NOLINT -+ 1317, -4, 1319, -4, 1321, -4, -+ 1323, -4, 1325, -4, 1327, -4, -+ 1073743201, -192, 1414, -192, // NOLINT -+ 7545, 141328, 7549, 15256, 7681, -4, -+ 7683, -4, 7685, -4, 7687, -4, -+ 7689, -4, 7691, -4, // NOLINT -+ 7693, -4, 7695, -4, 7697, -4, -+ 7699, -4, 7701, -4, 7703, -4, -+ 7705, -4, 7707, -4, // NOLINT -+ 7709, -4, 7711, -4, 7713, -4, -+ 7715, -4, 7717, -4, 7719, -4, -+ 7721, -4, 7723, -4, // NOLINT -+ 7725, -4, 7727, -4, 7729, -4, -+ 7731, -4, 7733, -4, 7735, -4, -+ 7737, -4, 7739, -4, // NOLINT -+ 7741, -4, 7743, -4, 7745, -4, -+ 7747, -4, 7749, -4, 7751, -4, -+ 7753, -4, 7755, -4, // NOLINT -+ 7757, -4, 7759, -4, 7761, -4, -+ 7763, -4, 7765, -4, 7767, -4, -+ 7769, -4, 7771, -4, // NOLINT -+ 7773, -4, 7775, -4, 7777, -4, -+ 7779, -4, 7781, -4, 7783, -4, -+ 7785, -4, 7787, -4, // NOLINT -+ 7789, -4, 7791, -4, 7793, -4, -+ 7795, -4, 7797, -4, 7799, -4, -+ 7801, -4, 7803, -4, // NOLINT -+ 7805, -4, 7807, -4, 7809, -4, -+ 7811, -4, 7813, -4, 7815, -4, -+ 7817, -4, 7819, -4, // NOLINT -+ 7821, -4, 7823, -4, 7825, -4, -+ 7827, -4, 7829, -4, 7835, -236, -+ 7841, -4, 7843, -4, // NOLINT -+ 7845, -4, 7847, -4, 7849, -4, -+ 7851, -4, 7853, -4, 7855, -4, -+ 7857, -4, 7859, -4, // NOLINT -+ 7861, -4, 7863, -4, 7865, -4, -+ 7867, -4, 7869, -4, 7871, -4, -+ 7873, -4, 7875, -4, // NOLINT -+ 7877, -4, 7879, -4, 7881, -4, -+ 7883, -4, 7885, -4, 7887, -4, -+ 7889, -4, 7891, -4, // NOLINT -+ 7893, -4, 7895, -4, 7897, -4, -+ 7899, -4, 7901, -4, 7903, -4, -+ 7905, -4, 7907, -4, // NOLINT -+ 7909, -4, 7911, -4, 7913, -4, -+ 7915, -4, 7917, -4, 7919, -4, -+ 7921, -4, 7923, -4, // NOLINT -+ 7925, -4, 7927, -4, 7929, -4, -+ 7931, -4, 7933, -4, 7935, -4, -+ 1073749760, 32, 7943, 32, // NOLINT -+ 1073749776, 32, 7957, 32, 1073749792, 32, -+ 7975, 32, 1073749808, 32, 7991, 32, -+ 1073749824, 32, 8005, 32, // NOLINT -+ 8017, 32, 8019, 32, 8021, 32, -+ 8023, 32, 1073749856, 32, 8039, 32, -+ 1073749872, 296, 8049, 296, // NOLINT -+ 1073749874, 344, 8053, 344, 1073749878, 400, -+ 8055, 400, 1073749880, 512, 8057, 512, -+ 1073749882, 448, 8059, 448, // NOLINT -+ 1073749884, 504, 8061, 504, 1073749936, 32, -+ 8113, 32, 8126, -28820, 1073749968, 32, -+ 8145, 32, 1073749984, 32, // NOLINT -+ 8161, 32, 8165, 28}; // NOLINT -+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings1[1] = -+ { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262CanonicalizeTable1Size = 73; // NOLINT -+static const int32_t kEcma262CanonicalizeTable1[146] = { -+ 334, -112, 1073742192, -64, 383, -64, -+ 388, -4, 1073743056, -104, 1257, -104, -+ 1073744944, -192, 3166, -192, // NOLINT -+ 3169, -4, 3173, -43180, 3174, -43168, -+ 3176, -4, 3178, -4, 3180, -4, -+ 3187, -4, 3190, -4, // NOLINT -+ 3201, -4, 3203, -4, 3205, -4, -+ 3207, -4, 3209, -4, 3211, -4, -+ 3213, -4, 3215, -4, // NOLINT -+ 3217, -4, 3219, -4, 3221, -4, -+ 3223, -4, 3225, -4, 3227, -4, -+ 3229, -4, 3231, -4, // NOLINT -+ 3233, -4, 3235, -4, 3237, -4, -+ 3239, -4, 3241, -4, 3243, -4, -+ 3245, -4, 3247, -4, // NOLINT -+ 3249, -4, 3251, -4, 3253, -4, -+ 3255, -4, 3257, -4, 3259, -4, -+ 3261, -4, 3263, -4, // NOLINT -+ 3265, -4, 3267, -4, 3269, -4, -+ 3271, -4, 3273, -4, 3275, -4, -+ 3277, -4, 3279, -4, // NOLINT -+ 3281, -4, 3283, -4, 3285, -4, -+ 3287, -4, 3289, -4, 3291, -4, -+ 3293, -4, 3295, -4, // NOLINT -+ 3297, -4, 3299, -4, 3308, -4, -+ 3310, -4, 3315, -4, 1073745152, -29056, -+ 3365, -29056, 3367, -29056, // NOLINT -+ 3373, -29056}; // NOLINT -+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings5[1] = -+ { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262CanonicalizeTable5Size = 95; // NOLINT -+static const int32_t kEcma262CanonicalizeTable5[190] = -+ { -+ 1601, -4, 1603, -4, 1605, -4, 1607, -4, -+ 1609, -4, 1611, -4, 1613, -4, 1615, -4, // NOLINT -+ 1617, -4, 1619, -4, 1621, -4, 1623, -4, -+ 1625, -4, 1627, -4, 1629, -4, 1631, -4, // NOLINT -+ 1633, -4, 1635, -4, 1637, -4, 1639, -4, -+ 1641, -4, 1643, -4, 1645, -4, 1665, -4, // NOLINT -+ 1667, -4, 1669, -4, 1671, -4, 1673, -4, -+ 1675, -4, 1677, -4, 1679, -4, 1681, -4, // NOLINT -+ 1683, -4, 1685, -4, 1687, -4, 1689, -4, -+ 1691, -4, 1827, -4, 1829, -4, 1831, -4, // NOLINT -+ 1833, -4, 1835, -4, 1837, -4, 1839, -4, -+ 1843, -4, 1845, -4, 1847, -4, 1849, -4, // NOLINT -+ 1851, -4, 1853, -4, 1855, -4, 1857, -4, -+ 1859, -4, 1861, -4, 1863, -4, 1865, -4, // NOLINT -+ 1867, -4, 1869, -4, 1871, -4, 1873, -4, -+ 1875, -4, 1877, -4, 1879, -4, 1881, -4, // NOLINT -+ 1883, -4, 1885, -4, 1887, -4, 1889, -4, -+ 1891, -4, 1893, -4, 1895, -4, 1897, -4, // NOLINT -+ 1899, -4, 1901, -4, 1903, -4, 1914, -4, -+ 1916, -4, 1919, -4, 1921, -4, 1923, -4, // NOLINT -+ 1925, -4, 1927, -4, 1932, -4, 1937, -4, -+ 1939, -4, 1943, -4, 1945, -4, 1947, -4, // NOLINT -+ 1949, -4, 1951, -4, 1953, -4, 1955, -4, -+ 1957, -4, 1959, -4, 1961, -4}; // NOLINT -+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings7[1] = -+ { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262CanonicalizeTable7Size = 2; // NOLINT -+static const int32_t kEcma262CanonicalizeTable7[4] = {1073749825, -128, 8026, -+ -128}; // NOLINT -+int Ecma262Canonicalize::Convert(uchar c, uchar n, uchar* result, -+ bool* allow_caching_ptr) { -+ int chunk_index = c >> 13; -+ switch (chunk_index) { -+ case 0: -+ return LookupMapping( -+ kEcma262CanonicalizeTable0, kEcma262CanonicalizeTable0Size, -+ kEcma262CanonicalizeMultiStrings0, c, n, result, allow_caching_ptr); -+ case 1: -+ return LookupMapping( -+ kEcma262CanonicalizeTable1, kEcma262CanonicalizeTable1Size, -+ kEcma262CanonicalizeMultiStrings1, c, n, result, allow_caching_ptr); -+ case 5: -+ return LookupMapping( -+ kEcma262CanonicalizeTable5, kEcma262CanonicalizeTable5Size, -+ kEcma262CanonicalizeMultiStrings5, c, n, result, allow_caching_ptr); -+ case 7: -+ return LookupMapping( -+ kEcma262CanonicalizeTable7, kEcma262CanonicalizeTable7Size, -+ kEcma262CanonicalizeMultiStrings7, c, n, result, allow_caching_ptr); -+ default: -+ return 0; -+ } -+} -+ -+static const MultiCharacterSpecialCase<4> -+ kEcma262UnCanonicalizeMultiStrings0[507] = { // NOLINT -+ {{65, 97, kSentinel}}, -+ {{90, 122, kSentinel}}, -+ {{181, 924, 956, kSentinel}}, -+ {{192, 224, kSentinel}}, // NOLINT -+ {{214, 246, kSentinel}}, -+ {{216, 248, kSentinel}}, -+ {{222, 254, kSentinel}}, -+ {{255, 376, kSentinel}}, // NOLINT -+ {{256, 257, kSentinel}}, -+ {{258, 259, kSentinel}}, -+ {{260, 261, kSentinel}}, -+ {{262, 263, kSentinel}}, // NOLINT -+ {{264, 265, kSentinel}}, -+ {{266, 267, kSentinel}}, -+ {{268, 269, kSentinel}}, -+ {{270, 271, kSentinel}}, // NOLINT -+ {{272, 273, kSentinel}}, -+ {{274, 275, kSentinel}}, -+ {{276, 277, kSentinel}}, -+ {{278, 279, kSentinel}}, // NOLINT -+ {{280, 281, kSentinel}}, -+ {{282, 283, kSentinel}}, -+ {{284, 285, kSentinel}}, -+ {{286, 287, kSentinel}}, // NOLINT -+ {{288, 289, kSentinel}}, -+ {{290, 291, kSentinel}}, -+ {{292, 293, kSentinel}}, -+ {{294, 295, kSentinel}}, // NOLINT -+ {{296, 297, kSentinel}}, -+ {{298, 299, kSentinel}}, -+ {{300, 301, kSentinel}}, -+ {{302, 303, kSentinel}}, // NOLINT -+ {{306, 307, kSentinel}}, -+ {{308, 309, kSentinel}}, -+ {{310, 311, kSentinel}}, -+ {{313, 314, kSentinel}}, // NOLINT -+ {{315, 316, kSentinel}}, -+ {{317, 318, kSentinel}}, -+ {{319, 320, kSentinel}}, -+ {{321, 322, kSentinel}}, // NOLINT -+ {{323, 324, kSentinel}}, -+ {{325, 326, kSentinel}}, -+ {{327, 328, kSentinel}}, -+ {{330, 331, kSentinel}}, // NOLINT -+ {{332, 333, kSentinel}}, -+ {{334, 335, kSentinel}}, -+ {{336, 337, kSentinel}}, -+ {{338, 339, kSentinel}}, // NOLINT -+ {{340, 341, kSentinel}}, -+ {{342, 343, kSentinel}}, -+ {{344, 345, kSentinel}}, -+ {{346, 347, kSentinel}}, // NOLINT -+ {{348, 349, kSentinel}}, -+ {{350, 351, kSentinel}}, -+ {{352, 353, kSentinel}}, -+ {{354, 355, kSentinel}}, // NOLINT -+ {{356, 357, kSentinel}}, -+ {{358, 359, kSentinel}}, -+ {{360, 361, kSentinel}}, -+ {{362, 363, kSentinel}}, // NOLINT -+ {{364, 365, kSentinel}}, -+ {{366, 367, kSentinel}}, -+ {{368, 369, kSentinel}}, -+ {{370, 371, kSentinel}}, // NOLINT -+ {{372, 373, kSentinel}}, -+ {{374, 375, kSentinel}}, -+ {{377, 378, kSentinel}}, -+ {{379, 380, kSentinel}}, // NOLINT -+ {{381, 382, kSentinel}}, -+ {{384, 579, kSentinel}}, -+ {{385, 595, kSentinel}}, -+ {{386, 387, kSentinel}}, // NOLINT -+ {{388, 389, kSentinel}}, -+ {{390, 596, kSentinel}}, -+ {{391, 392, kSentinel}}, -+ {{393, 598, kSentinel}}, // NOLINT -+ {{394, 599, kSentinel}}, -+ {{395, 396, kSentinel}}, -+ {{398, 477, kSentinel}}, -+ {{399, 601, kSentinel}}, // NOLINT -+ {{400, 603, kSentinel}}, -+ {{401, 402, kSentinel}}, -+ {{403, 608, kSentinel}}, -+ {{404, 611, kSentinel}}, // NOLINT -+ {{405, 502, kSentinel}}, -+ {{406, 617, kSentinel}}, -+ {{407, 616, kSentinel}}, -+ {{408, 409, kSentinel}}, // NOLINT -+ {{410, 573, kSentinel}}, -+ {{412, 623, kSentinel}}, -+ {{413, 626, kSentinel}}, -+ {{414, 544, kSentinel}}, // NOLINT -+ {{415, 629, kSentinel}}, -+ {{416, 417, kSentinel}}, -+ {{418, 419, kSentinel}}, -+ {{420, 421, kSentinel}}, // NOLINT -+ {{422, 640, kSentinel}}, -+ {{423, 424, kSentinel}}, -+ {{425, 643, kSentinel}}, -+ {{428, 429, kSentinel}}, // NOLINT -+ {{430, 648, kSentinel}}, -+ {{431, 432, kSentinel}}, -+ {{433, 650, kSentinel}}, -+ {{434, 651, kSentinel}}, // NOLINT -+ {{435, 436, kSentinel}}, -+ {{437, 438, kSentinel}}, -+ {{439, 658, kSentinel}}, -+ {{440, 441, kSentinel}}, // NOLINT -+ {{444, 445, kSentinel}}, -+ {{447, 503, kSentinel}}, -+ {{452, 453, 454, kSentinel}}, -+ {{455, 456, 457, kSentinel}}, // NOLINT -+ {{458, 459, 460, kSentinel}}, -+ {{461, 462, kSentinel}}, -+ {{463, 464, kSentinel}}, -+ {{465, 466, kSentinel}}, // NOLINT -+ {{467, 468, kSentinel}}, -+ {{469, 470, kSentinel}}, -+ {{471, 472, kSentinel}}, -+ {{473, 474, kSentinel}}, // NOLINT -+ {{475, 476, kSentinel}}, -+ {{478, 479, kSentinel}}, -+ {{480, 481, kSentinel}}, -+ {{482, 483, kSentinel}}, // NOLINT -+ {{484, 485, kSentinel}}, -+ {{486, 487, kSentinel}}, -+ {{488, 489, kSentinel}}, -+ {{490, 491, kSentinel}}, // NOLINT -+ {{492, 493, kSentinel}}, -+ {{494, 495, kSentinel}}, -+ {{497, 498, 499, kSentinel}}, -+ {{500, 501, kSentinel}}, // NOLINT -+ {{504, 505, kSentinel}}, -+ {{506, 507, kSentinel}}, -+ {{508, 509, kSentinel}}, -+ {{510, 511, kSentinel}}, // NOLINT -+ {{512, 513, kSentinel}}, -+ {{514, 515, kSentinel}}, -+ {{516, 517, kSentinel}}, -+ {{518, 519, kSentinel}}, // NOLINT -+ {{520, 521, kSentinel}}, -+ {{522, 523, kSentinel}}, -+ {{524, 525, kSentinel}}, -+ {{526, 527, kSentinel}}, // NOLINT -+ {{528, 529, kSentinel}}, -+ {{530, 531, kSentinel}}, -+ {{532, 533, kSentinel}}, -+ {{534, 535, kSentinel}}, // NOLINT -+ {{536, 537, kSentinel}}, -+ {{538, 539, kSentinel}}, -+ {{540, 541, kSentinel}}, -+ {{542, 543, kSentinel}}, // NOLINT -+ {{546, 547, kSentinel}}, -+ {{548, 549, kSentinel}}, -+ {{550, 551, kSentinel}}, -+ {{552, 553, kSentinel}}, // NOLINT -+ {{554, 555, kSentinel}}, -+ {{556, 557, kSentinel}}, -+ {{558, 559, kSentinel}}, -+ {{560, 561, kSentinel}}, // NOLINT -+ {{562, 563, kSentinel}}, -+ {{570, 11365, kSentinel}}, -+ {{571, 572, kSentinel}}, -+ {{574, 11366, kSentinel}}, // NOLINT -+ {{575, 11390, kSentinel}}, -+ {{576, 11391, kSentinel}}, -+ {{577, 578, kSentinel}}, -+ {{580, 649, kSentinel}}, // NOLINT -+ {{581, 652, kSentinel}}, -+ {{582, 583, kSentinel}}, -+ {{584, 585, kSentinel}}, -+ {{586, 587, kSentinel}}, // NOLINT -+ {{588, 589, kSentinel}}, -+ {{590, 591, kSentinel}}, -+ {{592, 11375, kSentinel}}, -+ {{593, 11373, kSentinel}}, // NOLINT -+ {{594, 11376, kSentinel}}, -+ {{604, 42923, kSentinel}}, -+ {{609, 42924, kSentinel}}, -+ {{613, 42893, kSentinel}}, // NOLINT -+ {{614, 42922, kSentinel}}, -+ {{619, 11362, kSentinel}}, -+ {{620, 42925, kSentinel}}, -+ {{625, 11374, kSentinel}}, // NOLINT -+ {{637, 11364, kSentinel}}, -+ {{647, 42929, kSentinel}}, -+ {{670, 42928, kSentinel}}, -+ {{837, 921, 953, 8126}}, // NOLINT -+ {{880, 881, kSentinel}}, -+ {{882, 883, kSentinel}}, -+ {{886, 887, kSentinel}}, -+ {{891, 1021, kSentinel}}, // NOLINT -+ {{893, 1023, kSentinel}}, -+ {{895, 1011, kSentinel}}, -+ {{902, 940, kSentinel}}, -+ {{904, 941, kSentinel}}, // NOLINT -+ {{906, 943, kSentinel}}, -+ {{908, 972, kSentinel}}, -+ {{910, 973, kSentinel}}, -+ {{911, 974, kSentinel}}, // NOLINT -+ {{913, 945, kSentinel}}, -+ {{914, 946, 976, kSentinel}}, -+ {{915, 947, kSentinel}}, -+ {{916, 948, kSentinel}}, // NOLINT -+ {{917, 949, 1013, kSentinel}}, -+ {{918, 950, kSentinel}}, -+ {{919, 951, kSentinel}}, -+ {{920, 952, 977, kSentinel}}, // NOLINT -+ {{922, 954, 1008, kSentinel}}, -+ {{923, 955, kSentinel}}, -+ {{925, 957, kSentinel}}, -+ {{927, 959, kSentinel}}, // NOLINT -+ {{928, 960, 982, kSentinel}}, -+ {{929, 961, 1009, kSentinel}}, -+ {{931, 962, 963, kSentinel}}, -+ {{932, 964, kSentinel}}, // NOLINT -+ {{933, 965, kSentinel}}, -+ {{934, 966, 981, kSentinel}}, -+ {{935, 967, kSentinel}}, -+ {{939, 971, kSentinel}}, // NOLINT -+ {{975, 983, kSentinel}}, -+ {{984, 985, kSentinel}}, -+ {{986, 987, kSentinel}}, -+ {{988, 989, kSentinel}}, // NOLINT -+ {{990, 991, kSentinel}}, -+ {{992, 993, kSentinel}}, -+ {{994, 995, kSentinel}}, -+ {{996, 997, kSentinel}}, // NOLINT -+ {{998, 999, kSentinel}}, -+ {{1000, 1001, kSentinel}}, -+ {{1002, 1003, kSentinel}}, -+ {{1004, 1005, kSentinel}}, // NOLINT -+ {{1006, 1007, kSentinel}}, -+ {{1010, 1017, kSentinel}}, -+ {{1015, 1016, kSentinel}}, -+ {{1018, 1019, kSentinel}}, // NOLINT -+ {{1024, 1104, kSentinel}}, -+ {{1039, 1119, kSentinel}}, -+ {{1040, 1072, kSentinel}}, -+ {{1071, 1103, kSentinel}}, // NOLINT -+ {{1120, 1121, kSentinel}}, -+ {{1122, 1123, kSentinel}}, -+ {{1124, 1125, kSentinel}}, -+ {{1126, 1127, kSentinel}}, // NOLINT -+ {{1128, 1129, kSentinel}}, -+ {{1130, 1131, kSentinel}}, -+ {{1132, 1133, kSentinel}}, -+ {{1134, 1135, kSentinel}}, // NOLINT -+ {{1136, 1137, kSentinel}}, -+ {{1138, 1139, kSentinel}}, -+ {{1140, 1141, kSentinel}}, -+ {{1142, 1143, kSentinel}}, // NOLINT -+ {{1144, 1145, kSentinel}}, -+ {{1146, 1147, kSentinel}}, -+ {{1148, 1149, kSentinel}}, -+ {{1150, 1151, kSentinel}}, // NOLINT -+ {{1152, 1153, kSentinel}}, -+ {{1162, 1163, kSentinel}}, -+ {{1164, 1165, kSentinel}}, -+ {{1166, 1167, kSentinel}}, // NOLINT -+ {{1168, 1169, kSentinel}}, -+ {{1170, 1171, kSentinel}}, -+ {{1172, 1173, kSentinel}}, -+ {{1174, 1175, kSentinel}}, // NOLINT -+ {{1176, 1177, kSentinel}}, -+ {{1178, 1179, kSentinel}}, -+ {{1180, 1181, kSentinel}}, -+ {{1182, 1183, kSentinel}}, // NOLINT -+ {{1184, 1185, kSentinel}}, -+ {{1186, 1187, kSentinel}}, -+ {{1188, 1189, kSentinel}}, -+ {{1190, 1191, kSentinel}}, // NOLINT -+ {{1192, 1193, kSentinel}}, -+ {{1194, 1195, kSentinel}}, -+ {{1196, 1197, kSentinel}}, -+ {{1198, 1199, kSentinel}}, // NOLINT -+ {{1200, 1201, kSentinel}}, -+ {{1202, 1203, kSentinel}}, -+ {{1204, 1205, kSentinel}}, -+ {{1206, 1207, kSentinel}}, // NOLINT -+ {{1208, 1209, kSentinel}}, -+ {{1210, 1211, kSentinel}}, -+ {{1212, 1213, kSentinel}}, -+ {{1214, 1215, kSentinel}}, // NOLINT -+ {{1216, 1231, kSentinel}}, -+ {{1217, 1218, kSentinel}}, -+ {{1219, 1220, kSentinel}}, -+ {{1221, 1222, kSentinel}}, // NOLINT -+ {{1223, 1224, kSentinel}}, -+ {{1225, 1226, kSentinel}}, -+ {{1227, 1228, kSentinel}}, -+ {{1229, 1230, kSentinel}}, // NOLINT -+ {{1232, 1233, kSentinel}}, -+ {{1234, 1235, kSentinel}}, -+ {{1236, 1237, kSentinel}}, -+ {{1238, 1239, kSentinel}}, // NOLINT -+ {{1240, 1241, kSentinel}}, -+ {{1242, 1243, kSentinel}}, -+ {{1244, 1245, kSentinel}}, -+ {{1246, 1247, kSentinel}}, // NOLINT -+ {{1248, 1249, kSentinel}}, -+ {{1250, 1251, kSentinel}}, -+ {{1252, 1253, kSentinel}}, -+ {{1254, 1255, kSentinel}}, // NOLINT -+ {{1256, 1257, kSentinel}}, -+ {{1258, 1259, kSentinel}}, -+ {{1260, 1261, kSentinel}}, -+ {{1262, 1263, kSentinel}}, // NOLINT -+ {{1264, 1265, kSentinel}}, -+ {{1266, 1267, kSentinel}}, -+ {{1268, 1269, kSentinel}}, -+ {{1270, 1271, kSentinel}}, // NOLINT -+ {{1272, 1273, kSentinel}}, -+ {{1274, 1275, kSentinel}}, -+ {{1276, 1277, kSentinel}}, -+ {{1278, 1279, kSentinel}}, // NOLINT -+ {{1280, 1281, kSentinel}}, -+ {{1282, 1283, kSentinel}}, -+ {{1284, 1285, kSentinel}}, -+ {{1286, 1287, kSentinel}}, // NOLINT -+ {{1288, 1289, kSentinel}}, -+ {{1290, 1291, kSentinel}}, -+ {{1292, 1293, kSentinel}}, -+ {{1294, 1295, kSentinel}}, // NOLINT -+ {{1296, 1297, kSentinel}}, -+ {{1298, 1299, kSentinel}}, -+ {{1300, 1301, kSentinel}}, -+ {{1302, 1303, kSentinel}}, // NOLINT -+ {{1304, 1305, kSentinel}}, -+ {{1306, 1307, kSentinel}}, -+ {{1308, 1309, kSentinel}}, -+ {{1310, 1311, kSentinel}}, // NOLINT -+ {{1312, 1313, kSentinel}}, -+ {{1314, 1315, kSentinel}}, -+ {{1316, 1317, kSentinel}}, -+ {{1318, 1319, kSentinel}}, // NOLINT -+ {{1320, 1321, kSentinel}}, -+ {{1322, 1323, kSentinel}}, -+ {{1324, 1325, kSentinel}}, -+ {{1326, 1327, kSentinel}}, // NOLINT -+ {{1329, 1377, kSentinel}}, -+ {{1366, 1414, kSentinel}}, -+ {{4256, 11520, kSentinel}}, -+ {{4293, 11557, kSentinel}}, // NOLINT -+ {{4295, 11559, kSentinel}}, -+ {{4301, 11565, kSentinel}}, -+ {{7545, 42877, kSentinel}}, -+ {{7549, 11363, kSentinel}}, // NOLINT -+ {{7680, 7681, kSentinel}}, -+ {{7682, 7683, kSentinel}}, -+ {{7684, 7685, kSentinel}}, -+ {{7686, 7687, kSentinel}}, // NOLINT -+ {{7688, 7689, kSentinel}}, -+ {{7690, 7691, kSentinel}}, -+ {{7692, 7693, kSentinel}}, -+ {{7694, 7695, kSentinel}}, // NOLINT -+ {{7696, 7697, kSentinel}}, -+ {{7698, 7699, kSentinel}}, -+ {{7700, 7701, kSentinel}}, -+ {{7702, 7703, kSentinel}}, // NOLINT -+ {{7704, 7705, kSentinel}}, -+ {{7706, 7707, kSentinel}}, -+ {{7708, 7709, kSentinel}}, -+ {{7710, 7711, kSentinel}}, // NOLINT -+ {{7712, 7713, kSentinel}}, -+ {{7714, 7715, kSentinel}}, -+ {{7716, 7717, kSentinel}}, -+ {{7718, 7719, kSentinel}}, // NOLINT -+ {{7720, 7721, kSentinel}}, -+ {{7722, 7723, kSentinel}}, -+ {{7724, 7725, kSentinel}}, -+ {{7726, 7727, kSentinel}}, // NOLINT -+ {{7728, 7729, kSentinel}}, -+ {{7730, 7731, kSentinel}}, -+ {{7732, 7733, kSentinel}}, -+ {{7734, 7735, kSentinel}}, // NOLINT -+ {{7736, 7737, kSentinel}}, -+ {{7738, 7739, kSentinel}}, -+ {{7740, 7741, kSentinel}}, -+ {{7742, 7743, kSentinel}}, // NOLINT -+ {{7744, 7745, kSentinel}}, -+ {{7746, 7747, kSentinel}}, -+ {{7748, 7749, kSentinel}}, -+ {{7750, 7751, kSentinel}}, // NOLINT -+ {{7752, 7753, kSentinel}}, -+ {{7754, 7755, kSentinel}}, -+ {{7756, 7757, kSentinel}}, -+ {{7758, 7759, kSentinel}}, // NOLINT -+ {{7760, 7761, kSentinel}}, -+ {{7762, 7763, kSentinel}}, -+ {{7764, 7765, kSentinel}}, -+ {{7766, 7767, kSentinel}}, // NOLINT -+ {{7768, 7769, kSentinel}}, -+ {{7770, 7771, kSentinel}}, -+ {{7772, 7773, kSentinel}}, -+ {{7774, 7775, kSentinel}}, // NOLINT -+ {{7776, 7777, 7835, kSentinel}}, -+ {{7778, 7779, kSentinel}}, -+ {{7780, 7781, kSentinel}}, -+ {{7782, 7783, kSentinel}}, // NOLINT -+ {{7784, 7785, kSentinel}}, -+ {{7786, 7787, kSentinel}}, -+ {{7788, 7789, kSentinel}}, -+ {{7790, 7791, kSentinel}}, // NOLINT -+ {{7792, 7793, kSentinel}}, -+ {{7794, 7795, kSentinel}}, -+ {{7796, 7797, kSentinel}}, -+ {{7798, 7799, kSentinel}}, // NOLINT -+ {{7800, 7801, kSentinel}}, -+ {{7802, 7803, kSentinel}}, -+ {{7804, 7805, kSentinel}}, -+ {{7806, 7807, kSentinel}}, // NOLINT -+ {{7808, 7809, kSentinel}}, -+ {{7810, 7811, kSentinel}}, -+ {{7812, 7813, kSentinel}}, -+ {{7814, 7815, kSentinel}}, // NOLINT -+ {{7816, 7817, kSentinel}}, -+ {{7818, 7819, kSentinel}}, -+ {{7820, 7821, kSentinel}}, -+ {{7822, 7823, kSentinel}}, // NOLINT -+ {{7824, 7825, kSentinel}}, -+ {{7826, 7827, kSentinel}}, -+ {{7828, 7829, kSentinel}}, -+ {{7840, 7841, kSentinel}}, // NOLINT -+ {{7842, 7843, kSentinel}}, -+ {{7844, 7845, kSentinel}}, -+ {{7846, 7847, kSentinel}}, -+ {{7848, 7849, kSentinel}}, // NOLINT -+ {{7850, 7851, kSentinel}}, -+ {{7852, 7853, kSentinel}}, -+ {{7854, 7855, kSentinel}}, -+ {{7856, 7857, kSentinel}}, // NOLINT -+ {{7858, 7859, kSentinel}}, -+ {{7860, 7861, kSentinel}}, -+ {{7862, 7863, kSentinel}}, -+ {{7864, 7865, kSentinel}}, // NOLINT -+ {{7866, 7867, kSentinel}}, -+ {{7868, 7869, kSentinel}}, -+ {{7870, 7871, kSentinel}}, -+ {{7872, 7873, kSentinel}}, // NOLINT -+ {{7874, 7875, kSentinel}}, -+ {{7876, 7877, kSentinel}}, -+ {{7878, 7879, kSentinel}}, -+ {{7880, 7881, kSentinel}}, // NOLINT -+ {{7882, 7883, kSentinel}}, -+ {{7884, 7885, kSentinel}}, -+ {{7886, 7887, kSentinel}}, -+ {{7888, 7889, kSentinel}}, // NOLINT -+ {{7890, 7891, kSentinel}}, -+ {{7892, 7893, kSentinel}}, -+ {{7894, 7895, kSentinel}}, -+ {{7896, 7897, kSentinel}}, // NOLINT -+ {{7898, 7899, kSentinel}}, -+ {{7900, 7901, kSentinel}}, -+ {{7902, 7903, kSentinel}}, -+ {{7904, 7905, kSentinel}}, // NOLINT -+ {{7906, 7907, kSentinel}}, -+ {{7908, 7909, kSentinel}}, -+ {{7910, 7911, kSentinel}}, -+ {{7912, 7913, kSentinel}}, // NOLINT -+ {{7914, 7915, kSentinel}}, -+ {{7916, 7917, kSentinel}}, -+ {{7918, 7919, kSentinel}}, -+ {{7920, 7921, kSentinel}}, // NOLINT -+ {{7922, 7923, kSentinel}}, -+ {{7924, 7925, kSentinel}}, -+ {{7926, 7927, kSentinel}}, -+ {{7928, 7929, kSentinel}}, // NOLINT -+ {{7930, 7931, kSentinel}}, -+ {{7932, 7933, kSentinel}}, -+ {{7934, 7935, kSentinel}}, -+ {{7936, 7944, kSentinel}}, // NOLINT -+ {{7943, 7951, kSentinel}}, -+ {{7952, 7960, kSentinel}}, -+ {{7957, 7965, kSentinel}}, -+ {{7968, 7976, kSentinel}}, // NOLINT -+ {{7975, 7983, kSentinel}}, -+ {{7984, 7992, kSentinel}}, -+ {{7991, 7999, kSentinel}}, -+ {{8000, 8008, kSentinel}}, // NOLINT -+ {{8005, 8013, kSentinel}}, -+ {{8017, 8025, kSentinel}}, -+ {{8019, 8027, kSentinel}}, -+ {{8021, 8029, kSentinel}}, // NOLINT -+ {{8023, 8031, kSentinel}}, -+ {{8032, 8040, kSentinel}}, -+ {{8039, 8047, kSentinel}}, -+ {{8048, 8122, kSentinel}}, // NOLINT -+ {{8049, 8123, kSentinel}}, -+ {{8050, 8136, kSentinel}}, -+ {{8053, 8139, kSentinel}}, -+ {{8054, 8154, kSentinel}}, // NOLINT -+ {{8055, 8155, kSentinel}}, -+ {{8056, 8184, kSentinel}}, -+ {{8057, 8185, kSentinel}}, -+ {{8058, 8170, kSentinel}}, // NOLINT -+ {{8059, 8171, kSentinel}}, -+ {{8060, 8186, kSentinel}}, -+ {{8061, 8187, kSentinel}}, -+ {{8112, 8120, kSentinel}}, // NOLINT -+ {{8113, 8121, kSentinel}}, -+ {{8144, 8152, kSentinel}}, -+ {{8145, 8153, kSentinel}}, -+ {{8160, 8168, kSentinel}}, // NOLINT -+ {{8161, 8169, kSentinel}}, -+ {{8165, 8172, kSentinel}}, -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262UnCanonicalizeTable0Size = 1005; // NOLINT -+static const int32_t kEcma262UnCanonicalizeTable0[2010] = { -+ 1073741889, 1, 90, 5, 1073741921, 1, -+ 122, 5, 181, 9, 1073742016, 13, -+ 214, 17, 1073742040, 21, // NOLINT -+ 222, 25, 1073742048, 13, 246, 17, -+ 1073742072, 21, 254, 25, 255, 29, -+ 256, 33, 257, 33, // NOLINT -+ 258, 37, 259, 37, 260, 41, -+ 261, 41, 262, 45, 263, 45, -+ 264, 49, 265, 49, // NOLINT -+ 266, 53, 267, 53, 268, 57, -+ 269, 57, 270, 61, 271, 61, -+ 272, 65, 273, 65, // NOLINT -+ 274, 69, 275, 69, 276, 73, -+ 277, 73, 278, 77, 279, 77, -+ 280, 81, 281, 81, // NOLINT -+ 282, 85, 283, 85, 284, 89, -+ 285, 89, 286, 93, 287, 93, -+ 288, 97, 289, 97, // NOLINT -+ 290, 101, 291, 101, 292, 105, -+ 293, 105, 294, 109, 295, 109, -+ 296, 113, 297, 113, // NOLINT -+ 298, 117, 299, 117, 300, 121, -+ 301, 121, 302, 125, 303, 125, -+ 306, 129, 307, 129, // NOLINT -+ 308, 133, 309, 133, 310, 137, -+ 311, 137, 313, 141, 314, 141, -+ 315, 145, 316, 145, // NOLINT -+ 317, 149, 318, 149, 319, 153, -+ 320, 153, 321, 157, 322, 157, -+ 323, 161, 324, 161, // NOLINT -+ 325, 165, 326, 165, 327, 169, -+ 328, 169, 330, 173, 331, 173, -+ 332, 177, 333, 177, // NOLINT -+ 334, 181, 335, 181, 336, 185, -+ 337, 185, 338, 189, 339, 189, -+ 340, 193, 341, 193, // NOLINT -+ 342, 197, 343, 197, 344, 201, -+ 345, 201, 346, 205, 347, 205, -+ 348, 209, 349, 209, // NOLINT -+ 350, 213, 351, 213, 352, 217, -+ 353, 217, 354, 221, 355, 221, -+ 356, 225, 357, 225, // NOLINT -+ 358, 229, 359, 229, 360, 233, -+ 361, 233, 362, 237, 363, 237, -+ 364, 241, 365, 241, // NOLINT -+ 366, 245, 367, 245, 368, 249, -+ 369, 249, 370, 253, 371, 253, -+ 372, 257, 373, 257, // NOLINT -+ 374, 261, 375, 261, 376, 29, -+ 377, 265, 378, 265, 379, 269, -+ 380, 269, 381, 273, // NOLINT -+ 382, 273, 384, 277, 385, 281, -+ 386, 285, 387, 285, 388, 289, -+ 389, 289, 390, 293, // NOLINT -+ 391, 297, 392, 297, 1073742217, 301, -+ 394, 305, 395, 309, 396, 309, -+ 398, 313, 399, 317, // NOLINT -+ 400, 321, 401, 325, 402, 325, -+ 403, 329, 404, 333, 405, 337, -+ 406, 341, 407, 345, // NOLINT -+ 408, 349, 409, 349, 410, 353, -+ 412, 357, 413, 361, 414, 365, -+ 415, 369, 416, 373, // NOLINT -+ 417, 373, 418, 377, 419, 377, -+ 420, 381, 421, 381, 422, 385, -+ 423, 389, 424, 389, // NOLINT -+ 425, 393, 428, 397, 429, 397, -+ 430, 401, 431, 405, 432, 405, -+ 1073742257, 409, 434, 413, // NOLINT -+ 435, 417, 436, 417, 437, 421, -+ 438, 421, 439, 425, 440, 429, -+ 441, 429, 444, 433, // NOLINT -+ 445, 433, 447, 437, 452, 441, -+ 453, 441, 454, 441, 455, 445, -+ 456, 445, 457, 445, // NOLINT -+ 458, 449, 459, 449, 460, 449, -+ 461, 453, 462, 453, 463, 457, -+ 464, 457, 465, 461, // NOLINT -+ 466, 461, 467, 465, 468, 465, -+ 469, 469, 470, 469, 471, 473, -+ 472, 473, 473, 477, // NOLINT -+ 474, 477, 475, 481, 476, 481, -+ 477, 313, 478, 485, 479, 485, -+ 480, 489, 481, 489, // NOLINT -+ 482, 493, 483, 493, 484, 497, -+ 485, 497, 486, 501, 487, 501, -+ 488, 505, 489, 505, // NOLINT -+ 490, 509, 491, 509, 492, 513, -+ 493, 513, 494, 517, 495, 517, -+ 497, 521, 498, 521, // NOLINT -+ 499, 521, 500, 525, 501, 525, -+ 502, 337, 503, 437, 504, 529, -+ 505, 529, 506, 533, // NOLINT -+ 507, 533, 508, 537, 509, 537, -+ 510, 541, 511, 541, 512, 545, -+ 513, 545, 514, 549, // NOLINT -+ 515, 549, 516, 553, 517, 553, -+ 518, 557, 519, 557, 520, 561, -+ 521, 561, 522, 565, // NOLINT -+ 523, 565, 524, 569, 525, 569, -+ 526, 573, 527, 573, 528, 577, -+ 529, 577, 530, 581, // NOLINT -+ 531, 581, 532, 585, 533, 585, -+ 534, 589, 535, 589, 536, 593, -+ 537, 593, 538, 597, // NOLINT -+ 539, 597, 540, 601, 541, 601, -+ 542, 605, 543, 605, 544, 365, -+ 546, 609, 547, 609, // NOLINT -+ 548, 613, 549, 613, 550, 617, -+ 551, 617, 552, 621, 553, 621, -+ 554, 625, 555, 625, // NOLINT -+ 556, 629, 557, 629, 558, 633, -+ 559, 633, 560, 637, 561, 637, -+ 562, 641, 563, 641, // NOLINT -+ 570, 645, 571, 649, 572, 649, -+ 573, 353, 574, 653, 1073742399, 657, -+ 576, 661, 577, 665, // NOLINT -+ 578, 665, 579, 277, 580, 669, -+ 581, 673, 582, 677, 583, 677, -+ 584, 681, 585, 681, // NOLINT -+ 586, 685, 587, 685, 588, 689, -+ 589, 689, 590, 693, 591, 693, -+ 592, 697, 593, 701, // NOLINT -+ 594, 705, 595, 281, 596, 293, -+ 1073742422, 301, 599, 305, 601, 317, -+ 603, 321, 604, 709, // NOLINT -+ 608, 329, 609, 713, 611, 333, -+ 613, 717, 614, 721, 616, 345, -+ 617, 341, 619, 725, // NOLINT -+ 620, 729, 623, 357, 625, 733, -+ 626, 361, 629, 369, 637, 737, -+ 640, 385, 643, 393, // NOLINT -+ 647, 741, 648, 401, 649, 669, -+ 1073742474, 409, 651, 413, 652, 673, -+ 658, 425, 670, 745, // NOLINT -+ 837, 749, 880, 753, 881, 753, -+ 882, 757, 883, 757, 886, 761, -+ 887, 761, 1073742715, 765, // NOLINT -+ 893, 769, 895, 773, 902, 777, -+ 1073742728, 781, 906, 785, 908, 789, -+ 1073742734, 793, 911, 797, // NOLINT -+ 913, 801, 914, 805, 1073742739, 809, -+ 916, 813, 917, 817, 1073742742, 821, -+ 919, 825, 920, 829, // NOLINT -+ 921, 749, 922, 833, 923, 837, -+ 924, 9, 1073742749, 841, 927, 845, -+ 928, 849, 929, 853, // NOLINT -+ 931, 857, 1073742756, 861, 933, 865, -+ 934, 869, 1073742759, 873, 939, 877, -+ 940, 777, 1073742765, 781, // NOLINT -+ 943, 785, 945, 801, 946, 805, -+ 1073742771, 809, 948, 813, 949, 817, -+ 1073742774, 821, 951, 825, // NOLINT -+ 952, 829, 953, 749, 954, 833, -+ 955, 837, 956, 9, 1073742781, 841, -+ 959, 845, 960, 849, // NOLINT -+ 961, 853, 962, 857, 963, 857, -+ 1073742788, 861, 965, 865, 966, 869, -+ 1073742791, 873, 971, 877, // NOLINT -+ 972, 789, 1073742797, 793, 974, 797, -+ 975, 881, 976, 805, 977, 829, -+ 981, 869, 982, 849, // NOLINT -+ 983, 881, 984, 885, 985, 885, -+ 986, 889, 987, 889, 988, 893, -+ 989, 893, 990, 897, // NOLINT -+ 991, 897, 992, 901, 993, 901, -+ 994, 905, 995, 905, 996, 909, -+ 997, 909, 998, 913, // NOLINT -+ 999, 913, 1000, 917, 1001, 917, -+ 1002, 921, 1003, 921, 1004, 925, -+ 1005, 925, 1006, 929, // NOLINT -+ 1007, 929, 1008, 833, 1009, 853, -+ 1010, 933, 1011, 773, 1013, 817, -+ 1015, 937, 1016, 937, // NOLINT -+ 1017, 933, 1018, 941, 1019, 941, -+ 1073742845, 765, 1023, 769, 1073742848, 945, -+ 1039, 949, 1073742864, 953, // NOLINT -+ 1071, 957, 1073742896, 953, 1103, 957, -+ 1073742928, 945, 1119, 949, 1120, 961, -+ 1121, 961, 1122, 965, // NOLINT -+ 1123, 965, 1124, 969, 1125, 969, -+ 1126, 973, 1127, 973, 1128, 977, -+ 1129, 977, 1130, 981, // NOLINT -+ 1131, 981, 1132, 985, 1133, 985, -+ 1134, 989, 1135, 989, 1136, 993, -+ 1137, 993, 1138, 997, // NOLINT -+ 1139, 997, 1140, 1001, 1141, 1001, -+ 1142, 1005, 1143, 1005, 1144, 1009, -+ 1145, 1009, 1146, 1013, // NOLINT -+ 1147, 1013, 1148, 1017, 1149, 1017, -+ 1150, 1021, 1151, 1021, 1152, 1025, -+ 1153, 1025, 1162, 1029, // NOLINT -+ 1163, 1029, 1164, 1033, 1165, 1033, -+ 1166, 1037, 1167, 1037, 1168, 1041, -+ 1169, 1041, 1170, 1045, // NOLINT -+ 1171, 1045, 1172, 1049, 1173, 1049, -+ 1174, 1053, 1175, 1053, 1176, 1057, -+ 1177, 1057, 1178, 1061, // NOLINT -+ 1179, 1061, 1180, 1065, 1181, 1065, -+ 1182, 1069, 1183, 1069, 1184, 1073, -+ 1185, 1073, 1186, 1077, // NOLINT -+ 1187, 1077, 1188, 1081, 1189, 1081, -+ 1190, 1085, 1191, 1085, 1192, 1089, -+ 1193, 1089, 1194, 1093, // NOLINT -+ 1195, 1093, 1196, 1097, 1197, 1097, -+ 1198, 1101, 1199, 1101, 1200, 1105, -+ 1201, 1105, 1202, 1109, // NOLINT -+ 1203, 1109, 1204, 1113, 1205, 1113, -+ 1206, 1117, 1207, 1117, 1208, 1121, -+ 1209, 1121, 1210, 1125, // NOLINT -+ 1211, 1125, 1212, 1129, 1213, 1129, -+ 1214, 1133, 1215, 1133, 1216, 1137, -+ 1217, 1141, 1218, 1141, // NOLINT -+ 1219, 1145, 1220, 1145, 1221, 1149, -+ 1222, 1149, 1223, 1153, 1224, 1153, -+ 1225, 1157, 1226, 1157, // NOLINT -+ 1227, 1161, 1228, 1161, 1229, 1165, -+ 1230, 1165, 1231, 1137, 1232, 1169, -+ 1233, 1169, 1234, 1173, // NOLINT -+ 1235, 1173, 1236, 1177, 1237, 1177, -+ 1238, 1181, 1239, 1181, 1240, 1185, -+ 1241, 1185, 1242, 1189, // NOLINT -+ 1243, 1189, 1244, 1193, 1245, 1193, -+ 1246, 1197, 1247, 1197, 1248, 1201, -+ 1249, 1201, 1250, 1205, // NOLINT -+ 1251, 1205, 1252, 1209, 1253, 1209, -+ 1254, 1213, 1255, 1213, 1256, 1217, -+ 1257, 1217, 1258, 1221, // NOLINT -+ 1259, 1221, 1260, 1225, 1261, 1225, -+ 1262, 1229, 1263, 1229, 1264, 1233, -+ 1265, 1233, 1266, 1237, // NOLINT -+ 1267, 1237, 1268, 1241, 1269, 1241, -+ 1270, 1245, 1271, 1245, 1272, 1249, -+ 1273, 1249, 1274, 1253, // NOLINT -+ 1275, 1253, 1276, 1257, 1277, 1257, -+ 1278, 1261, 1279, 1261, 1280, 1265, -+ 1281, 1265, 1282, 1269, // NOLINT -+ 1283, 1269, 1284, 1273, 1285, 1273, -+ 1286, 1277, 1287, 1277, 1288, 1281, -+ 1289, 1281, 1290, 1285, // NOLINT -+ 1291, 1285, 1292, 1289, 1293, 1289, -+ 1294, 1293, 1295, 1293, 1296, 1297, -+ 1297, 1297, 1298, 1301, // NOLINT -+ 1299, 1301, 1300, 1305, 1301, 1305, -+ 1302, 1309, 1303, 1309, 1304, 1313, -+ 1305, 1313, 1306, 1317, // NOLINT -+ 1307, 1317, 1308, 1321, 1309, 1321, -+ 1310, 1325, 1311, 1325, 1312, 1329, -+ 1313, 1329, 1314, 1333, // NOLINT -+ 1315, 1333, 1316, 1337, 1317, 1337, -+ 1318, 1341, 1319, 1341, 1320, 1345, -+ 1321, 1345, 1322, 1349, // NOLINT -+ 1323, 1349, 1324, 1353, 1325, 1353, -+ 1326, 1357, 1327, 1357, 1073743153, 1361, -+ 1366, 1365, 1073743201, 1361, // NOLINT -+ 1414, 1365, 1073746080, 1369, 4293, 1373, -+ 4295, 1377, 4301, 1381, 7545, 1385, -+ 7549, 1389, 7680, 1393, // NOLINT -+ 7681, 1393, 7682, 1397, 7683, 1397, -+ 7684, 1401, 7685, 1401, 7686, 1405, -+ 7687, 1405, 7688, 1409, // NOLINT -+ 7689, 1409, 7690, 1413, 7691, 1413, -+ 7692, 1417, 7693, 1417, 7694, 1421, -+ 7695, 1421, 7696, 1425, // NOLINT -+ 7697, 1425, 7698, 1429, 7699, 1429, -+ 7700, 1433, 7701, 1433, 7702, 1437, -+ 7703, 1437, 7704, 1441, // NOLINT -+ 7705, 1441, 7706, 1445, 7707, 1445, -+ 7708, 1449, 7709, 1449, 7710, 1453, -+ 7711, 1453, 7712, 1457, // NOLINT -+ 7713, 1457, 7714, 1461, 7715, 1461, -+ 7716, 1465, 7717, 1465, 7718, 1469, -+ 7719, 1469, 7720, 1473, // NOLINT -+ 7721, 1473, 7722, 1477, 7723, 1477, -+ 7724, 1481, 7725, 1481, 7726, 1485, -+ 7727, 1485, 7728, 1489, // NOLINT -+ 7729, 1489, 7730, 1493, 7731, 1493, -+ 7732, 1497, 7733, 1497, 7734, 1501, -+ 7735, 1501, 7736, 1505, // NOLINT -+ 7737, 1505, 7738, 1509, 7739, 1509, -+ 7740, 1513, 7741, 1513, 7742, 1517, -+ 7743, 1517, 7744, 1521, // NOLINT -+ 7745, 1521, 7746, 1525, 7747, 1525, -+ 7748, 1529, 7749, 1529, 7750, 1533, -+ 7751, 1533, 7752, 1537, // NOLINT -+ 7753, 1537, 7754, 1541, 7755, 1541, -+ 7756, 1545, 7757, 1545, 7758, 1549, -+ 7759, 1549, 7760, 1553, // NOLINT -+ 7761, 1553, 7762, 1557, 7763, 1557, -+ 7764, 1561, 7765, 1561, 7766, 1565, -+ 7767, 1565, 7768, 1569, // NOLINT -+ 7769, 1569, 7770, 1573, 7771, 1573, -+ 7772, 1577, 7773, 1577, 7774, 1581, -+ 7775, 1581, 7776, 1585, // NOLINT -+ 7777, 1585, 7778, 1589, 7779, 1589, -+ 7780, 1593, 7781, 1593, 7782, 1597, -+ 7783, 1597, 7784, 1601, // NOLINT -+ 7785, 1601, 7786, 1605, 7787, 1605, -+ 7788, 1609, 7789, 1609, 7790, 1613, -+ 7791, 1613, 7792, 1617, // NOLINT -+ 7793, 1617, 7794, 1621, 7795, 1621, -+ 7796, 1625, 7797, 1625, 7798, 1629, -+ 7799, 1629, 7800, 1633, // NOLINT -+ 7801, 1633, 7802, 1637, 7803, 1637, -+ 7804, 1641, 7805, 1641, 7806, 1645, -+ 7807, 1645, 7808, 1649, // NOLINT -+ 7809, 1649, 7810, 1653, 7811, 1653, -+ 7812, 1657, 7813, 1657, 7814, 1661, -+ 7815, 1661, 7816, 1665, // NOLINT -+ 7817, 1665, 7818, 1669, 7819, 1669, -+ 7820, 1673, 7821, 1673, 7822, 1677, -+ 7823, 1677, 7824, 1681, // NOLINT -+ 7825, 1681, 7826, 1685, 7827, 1685, -+ 7828, 1689, 7829, 1689, 7835, 1585, -+ 7840, 1693, 7841, 1693, // NOLINT -+ 7842, 1697, 7843, 1697, 7844, 1701, -+ 7845, 1701, 7846, 1705, 7847, 1705, -+ 7848, 1709, 7849, 1709, // NOLINT -+ 7850, 1713, 7851, 1713, 7852, 1717, -+ 7853, 1717, 7854, 1721, 7855, 1721, -+ 7856, 1725, 7857, 1725, // NOLINT -+ 7858, 1729, 7859, 1729, 7860, 1733, -+ 7861, 1733, 7862, 1737, 7863, 1737, -+ 7864, 1741, 7865, 1741, // NOLINT -+ 7866, 1745, 7867, 1745, 7868, 1749, -+ 7869, 1749, 7870, 1753, 7871, 1753, -+ 7872, 1757, 7873, 1757, // NOLINT -+ 7874, 1761, 7875, 1761, 7876, 1765, -+ 7877, 1765, 7878, 1769, 7879, 1769, -+ 7880, 1773, 7881, 1773, // NOLINT -+ 7882, 1777, 7883, 1777, 7884, 1781, -+ 7885, 1781, 7886, 1785, 7887, 1785, -+ 7888, 1789, 7889, 1789, // NOLINT -+ 7890, 1793, 7891, 1793, 7892, 1797, -+ 7893, 1797, 7894, 1801, 7895, 1801, -+ 7896, 1805, 7897, 1805, // NOLINT -+ 7898, 1809, 7899, 1809, 7900, 1813, -+ 7901, 1813, 7902, 1817, 7903, 1817, -+ 7904, 1821, 7905, 1821, // NOLINT -+ 7906, 1825, 7907, 1825, 7908, 1829, -+ 7909, 1829, 7910, 1833, 7911, 1833, -+ 7912, 1837, 7913, 1837, // NOLINT -+ 7914, 1841, 7915, 1841, 7916, 1845, -+ 7917, 1845, 7918, 1849, 7919, 1849, -+ 7920, 1853, 7921, 1853, // NOLINT -+ 7922, 1857, 7923, 1857, 7924, 1861, -+ 7925, 1861, 7926, 1865, 7927, 1865, -+ 7928, 1869, 7929, 1869, // NOLINT -+ 7930, 1873, 7931, 1873, 7932, 1877, -+ 7933, 1877, 7934, 1881, 7935, 1881, -+ 1073749760, 1885, 7943, 1889, // NOLINT -+ 1073749768, 1885, 7951, 1889, 1073749776, 1893, -+ 7957, 1897, 1073749784, 1893, 7965, 1897, -+ 1073749792, 1901, 7975, 1905, // NOLINT -+ 1073749800, 1901, 7983, 1905, 1073749808, 1909, -+ 7991, 1913, 1073749816, 1909, 7999, 1913, -+ 1073749824, 1917, 8005, 1921, // NOLINT -+ 1073749832, 1917, 8013, 1921, 8017, 1925, -+ 8019, 1929, 8021, 1933, 8023, 1937, -+ 8025, 1925, 8027, 1929, // NOLINT -+ 8029, 1933, 8031, 1937, 1073749856, 1941, -+ 8039, 1945, 1073749864, 1941, 8047, 1945, -+ 1073749872, 1949, 8049, 1953, // NOLINT -+ 1073749874, 1957, 8053, 1961, 1073749878, 1965, -+ 8055, 1969, 1073749880, 1973, 8057, 1977, -+ 1073749882, 1981, 8059, 1985, // NOLINT -+ 1073749884, 1989, 8061, 1993, 1073749936, 1997, -+ 8113, 2001, 1073749944, 1997, 8121, 2001, -+ 1073749946, 1949, 8123, 1953, // NOLINT -+ 8126, 749, 1073749960, 1957, 8139, 1961, -+ 1073749968, 2005, 8145, 2009, 1073749976, 2005, -+ 8153, 2009, 1073749978, 1965, // NOLINT -+ 8155, 1969, 1073749984, 2013, 8161, 2017, -+ 8165, 2021, 1073749992, 2013, 8169, 2017, -+ 1073749994, 1981, 8171, 1985, // NOLINT -+ 8172, 2021, 1073750008, 1973, 8185, 1977, -+ 1073750010, 1989, 8187, 1993}; // NOLINT -+static const MultiCharacterSpecialCase<2> -+ kEcma262UnCanonicalizeMultiStrings1[83] = { // NOLINT -+ {{8498, 8526}}, {{8544, 8560}}, {{8559, 8575}}, -+ {{8579, 8580}}, // NOLINT -+ {{9398, 9424}}, {{9423, 9449}}, {{11264, 11312}}, -+ {{11310, 11358}}, // NOLINT -+ {{11360, 11361}}, {{619, 11362}}, {{7549, 11363}}, -+ {{637, 11364}}, // NOLINT -+ {{570, 11365}}, {{574, 11366}}, {{11367, 11368}}, -+ {{11369, 11370}}, // NOLINT -+ {{11371, 11372}}, {{593, 11373}}, {{625, 11374}}, -+ {{592, 11375}}, // NOLINT -+ {{594, 11376}}, {{11378, 11379}}, {{11381, 11382}}, -+ {{575, 11390}}, // NOLINT -+ {{576, 11391}}, {{11392, 11393}}, {{11394, 11395}}, -+ {{11396, 11397}}, // NOLINT -+ {{11398, 11399}}, {{11400, 11401}}, {{11402, 11403}}, -+ {{11404, 11405}}, // NOLINT -+ {{11406, 11407}}, {{11408, 11409}}, {{11410, 11411}}, -+ {{11412, 11413}}, // NOLINT -+ {{11414, 11415}}, {{11416, 11417}}, {{11418, 11419}}, -+ {{11420, 11421}}, // NOLINT -+ {{11422, 11423}}, {{11424, 11425}}, {{11426, 11427}}, -+ {{11428, 11429}}, // NOLINT -+ {{11430, 11431}}, {{11432, 11433}}, {{11434, 11435}}, -+ {{11436, 11437}}, // NOLINT -+ {{11438, 11439}}, {{11440, 11441}}, {{11442, 11443}}, -+ {{11444, 11445}}, // NOLINT -+ {{11446, 11447}}, {{11448, 11449}}, {{11450, 11451}}, -+ {{11452, 11453}}, // NOLINT -+ {{11454, 11455}}, {{11456, 11457}}, {{11458, 11459}}, -+ {{11460, 11461}}, // NOLINT -+ {{11462, 11463}}, {{11464, 11465}}, {{11466, 11467}}, -+ {{11468, 11469}}, // NOLINT -+ {{11470, 11471}}, {{11472, 11473}}, {{11474, 11475}}, -+ {{11476, 11477}}, // NOLINT -+ {{11478, 11479}}, {{11480, 11481}}, {{11482, 11483}}, -+ {{11484, 11485}}, // NOLINT -+ {{11486, 11487}}, {{11488, 11489}}, {{11490, 11491}}, -+ {{11499, 11500}}, // NOLINT -+ {{11501, 11502}}, {{11506, 11507}}, {{4256, 11520}}, -+ {{4293, 11557}}, // NOLINT -+ {{4295, 11559}}, {{4301, 11565}}, {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262UnCanonicalizeTable1Size = 149; // NOLINT -+static const int32_t kEcma262UnCanonicalizeTable1[298] = { -+ 306, 1, 334, 1, 1073742176, 5, 367, 9, -+ 1073742192, 5, 383, 9, 387, 13, 388, 13, // NOLINT -+ 1073743030, 17, 1231, 21, 1073743056, 17, 1257, 21, -+ 1073744896, 25, 3118, 29, 1073744944, 25, 3166, 29, // NOLINT -+ 3168, 33, 3169, 33, 3170, 37, 3171, 41, -+ 3172, 45, 3173, 49, 3174, 53, 3175, 57, // NOLINT -+ 3176, 57, 3177, 61, 3178, 61, 3179, 65, -+ 3180, 65, 3181, 69, 3182, 73, 3183, 77, // NOLINT -+ 3184, 81, 3186, 85, 3187, 85, 3189, 89, -+ 3190, 89, 1073745022, 93, 3199, 97, 3200, 101, // NOLINT -+ 3201, 101, 3202, 105, 3203, 105, 3204, 109, -+ 3205, 109, 3206, 113, 3207, 113, 3208, 117, // NOLINT -+ 3209, 117, 3210, 121, 3211, 121, 3212, 125, -+ 3213, 125, 3214, 129, 3215, 129, 3216, 133, // NOLINT -+ 3217, 133, 3218, 137, 3219, 137, 3220, 141, -+ 3221, 141, 3222, 145, 3223, 145, 3224, 149, // NOLINT -+ 3225, 149, 3226, 153, 3227, 153, 3228, 157, -+ 3229, 157, 3230, 161, 3231, 161, 3232, 165, // NOLINT -+ 3233, 165, 3234, 169, 3235, 169, 3236, 173, -+ 3237, 173, 3238, 177, 3239, 177, 3240, 181, // NOLINT -+ 3241, 181, 3242, 185, 3243, 185, 3244, 189, -+ 3245, 189, 3246, 193, 3247, 193, 3248, 197, // NOLINT -+ 3249, 197, 3250, 201, 3251, 201, 3252, 205, -+ 3253, 205, 3254, 209, 3255, 209, 3256, 213, // NOLINT -+ 3257, 213, 3258, 217, 3259, 217, 3260, 221, -+ 3261, 221, 3262, 225, 3263, 225, 3264, 229, // NOLINT -+ 3265, 229, 3266, 233, 3267, 233, 3268, 237, -+ 3269, 237, 3270, 241, 3271, 241, 3272, 245, // NOLINT -+ 3273, 245, 3274, 249, 3275, 249, 3276, 253, -+ 3277, 253, 3278, 257, 3279, 257, 3280, 261, // NOLINT -+ 3281, 261, 3282, 265, 3283, 265, 3284, 269, -+ 3285, 269, 3286, 273, 3287, 273, 3288, 277, // NOLINT -+ 3289, 277, 3290, 281, 3291, 281, 3292, 285, -+ 3293, 285, 3294, 289, 3295, 289, 3296, 293, // NOLINT -+ 3297, 293, 3298, 297, 3299, 297, 3307, 301, -+ 3308, 301, 3309, 305, 3310, 305, 3314, 309, // NOLINT -+ 3315, 309, 1073745152, 313, 3365, 317, 3367, 321, -+ 3373, 325}; // NOLINT -+static const MultiCharacterSpecialCase<2> -+ kEcma262UnCanonicalizeMultiStrings5[104] = { // NOLINT -+ {{42560, 42561}}, {{42562, 42563}}, -+ {{42564, 42565}}, {{42566, 42567}}, // NOLINT -+ {{42568, 42569}}, {{42570, 42571}}, -+ {{42572, 42573}}, {{42574, 42575}}, // NOLINT -+ {{42576, 42577}}, {{42578, 42579}}, -+ {{42580, 42581}}, {{42582, 42583}}, // NOLINT -+ {{42584, 42585}}, {{42586, 42587}}, -+ {{42588, 42589}}, {{42590, 42591}}, // NOLINT -+ {{42592, 42593}}, {{42594, 42595}}, -+ {{42596, 42597}}, {{42598, 42599}}, // NOLINT -+ {{42600, 42601}}, {{42602, 42603}}, -+ {{42604, 42605}}, {{42624, 42625}}, // NOLINT -+ {{42626, 42627}}, {{42628, 42629}}, -+ {{42630, 42631}}, {{42632, 42633}}, // NOLINT -+ {{42634, 42635}}, {{42636, 42637}}, -+ {{42638, 42639}}, {{42640, 42641}}, // NOLINT -+ {{42642, 42643}}, {{42644, 42645}}, -+ {{42646, 42647}}, {{42648, 42649}}, // NOLINT -+ {{42650, 42651}}, {{42786, 42787}}, -+ {{42788, 42789}}, {{42790, 42791}}, // NOLINT -+ {{42792, 42793}}, {{42794, 42795}}, -+ {{42796, 42797}}, {{42798, 42799}}, // NOLINT -+ {{42802, 42803}}, {{42804, 42805}}, -+ {{42806, 42807}}, {{42808, 42809}}, // NOLINT -+ {{42810, 42811}}, {{42812, 42813}}, -+ {{42814, 42815}}, {{42816, 42817}}, // NOLINT -+ {{42818, 42819}}, {{42820, 42821}}, -+ {{42822, 42823}}, {{42824, 42825}}, // NOLINT -+ {{42826, 42827}}, {{42828, 42829}}, -+ {{42830, 42831}}, {{42832, 42833}}, // NOLINT -+ {{42834, 42835}}, {{42836, 42837}}, -+ {{42838, 42839}}, {{42840, 42841}}, // NOLINT -+ {{42842, 42843}}, {{42844, 42845}}, -+ {{42846, 42847}}, {{42848, 42849}}, // NOLINT -+ {{42850, 42851}}, {{42852, 42853}}, -+ {{42854, 42855}}, {{42856, 42857}}, // NOLINT -+ {{42858, 42859}}, {{42860, 42861}}, -+ {{42862, 42863}}, {{42873, 42874}}, // NOLINT -+ {{42875, 42876}}, {{7545, 42877}}, -+ {{42878, 42879}}, {{42880, 42881}}, // NOLINT -+ {{42882, 42883}}, {{42884, 42885}}, -+ {{42886, 42887}}, {{42891, 42892}}, // NOLINT -+ {{613, 42893}}, {{42896, 42897}}, -+ {{42898, 42899}}, {{42902, 42903}}, // NOLINT -+ {{42904, 42905}}, {{42906, 42907}}, -+ {{42908, 42909}}, {{42910, 42911}}, // NOLINT -+ {{42912, 42913}}, {{42914, 42915}}, -+ {{42916, 42917}}, {{42918, 42919}}, // NOLINT -+ {{42920, 42921}}, {{614, 42922}}, -+ {{604, 42923}}, {{609, 42924}}, // NOLINT -+ {{620, 42925}}, {{670, 42928}}, -+ {{647, 42929}}, {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262UnCanonicalizeTable5Size = 198; // NOLINT -+static const int32_t -+ kEcma262UnCanonicalizeTable5[396] = -+ {1600, 1, 1601, 1, 1602, 5, 1603, 5, -+ 1604, 9, 1605, 9, 1606, 13, 1607, 13, // NOLINT -+ 1608, 17, 1609, 17, 1610, 21, 1611, 21, -+ 1612, 25, 1613, 25, 1614, 29, 1615, 29, // NOLINT -+ 1616, 33, 1617, 33, 1618, 37, 1619, 37, -+ 1620, 41, 1621, 41, 1622, 45, 1623, 45, // NOLINT -+ 1624, 49, 1625, 49, 1626, 53, 1627, 53, -+ 1628, 57, 1629, 57, 1630, 61, 1631, 61, // NOLINT -+ 1632, 65, 1633, 65, 1634, 69, 1635, 69, -+ 1636, 73, 1637, 73, 1638, 77, 1639, 77, // NOLINT -+ 1640, 81, 1641, 81, 1642, 85, 1643, 85, -+ 1644, 89, 1645, 89, 1664, 93, 1665, 93, // NOLINT -+ 1666, 97, 1667, 97, 1668, 101, 1669, 101, -+ 1670, 105, 1671, 105, 1672, 109, 1673, 109, // NOLINT -+ 1674, 113, 1675, 113, 1676, 117, 1677, 117, -+ 1678, 121, 1679, 121, 1680, 125, 1681, 125, // NOLINT -+ 1682, 129, 1683, 129, 1684, 133, 1685, 133, -+ 1686, 137, 1687, 137, 1688, 141, 1689, 141, // NOLINT -+ 1690, 145, 1691, 145, 1826, 149, 1827, 149, -+ 1828, 153, 1829, 153, 1830, 157, 1831, 157, // NOLINT -+ 1832, 161, 1833, 161, 1834, 165, 1835, 165, -+ 1836, 169, 1837, 169, 1838, 173, 1839, 173, // NOLINT -+ 1842, 177, 1843, 177, 1844, 181, 1845, 181, -+ 1846, 185, 1847, 185, 1848, 189, 1849, 189, // NOLINT -+ 1850, 193, 1851, 193, 1852, 197, 1853, 197, -+ 1854, 201, 1855, 201, 1856, 205, 1857, 205, // NOLINT -+ 1858, 209, 1859, 209, 1860, 213, 1861, 213, -+ 1862, 217, 1863, 217, 1864, 221, 1865, 221, // NOLINT -+ 1866, 225, 1867, 225, 1868, 229, 1869, 229, -+ 1870, 233, 1871, 233, 1872, 237, 1873, 237, // NOLINT -+ 1874, 241, 1875, 241, 1876, 245, 1877, 245, -+ 1878, 249, 1879, 249, 1880, 253, 1881, 253, // NOLINT -+ 1882, 257, 1883, 257, 1884, 261, 1885, 261, -+ 1886, 265, 1887, 265, 1888, 269, 1889, 269, // NOLINT -+ 1890, 273, 1891, 273, 1892, 277, 1893, 277, -+ 1894, 281, 1895, 281, 1896, 285, 1897, 285, // NOLINT -+ 1898, 289, 1899, 289, 1900, 293, 1901, 293, -+ 1902, 297, 1903, 297, 1913, 301, 1914, 301, // NOLINT -+ 1915, 305, 1916, 305, 1917, 309, 1918, 313, -+ 1919, 313, 1920, 317, 1921, 317, 1922, 321, // NOLINT -+ 1923, 321, 1924, 325, 1925, 325, 1926, 329, -+ 1927, 329, 1931, 333, 1932, 333, 1933, 337, // NOLINT -+ 1936, 341, 1937, 341, 1938, 345, 1939, 345, -+ 1942, 349, 1943, 349, 1944, 353, 1945, 353, // NOLINT -+ 1946, 357, 1947, 357, 1948, 361, 1949, 361, -+ 1950, 365, 1951, 365, 1952, 369, 1953, 369, // NOLINT -+ 1954, 373, 1955, 373, 1956, 377, 1957, 377, -+ 1958, 381, 1959, 381, 1960, 385, 1961, 385, // NOLINT -+ 1962, 389, 1963, 393, 1964, 397, 1965, 401, -+ 1968, 405, 1969, 409}; // NOLINT -+static const MultiCharacterSpecialCase<2> -+ kEcma262UnCanonicalizeMultiStrings7[3] = { // NOLINT -+ {{65313, 65345}}, -+ {{65338, 65370}}, -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kEcma262UnCanonicalizeTable7Size = 4; // NOLINT -+static const int32_t kEcma262UnCanonicalizeTable7[8] = { -+ 1073749793, 1, 7994, 5, 1073749825, 1, 8026, 5}; // NOLINT -+int Ecma262UnCanonicalize::Convert(uchar c, uchar n, uchar* result, -+ bool* allow_caching_ptr) { -+ int chunk_index = c >> 13; -+ switch (chunk_index) { -+ case 0: -+ return LookupMapping( -+ kEcma262UnCanonicalizeTable0, kEcma262UnCanonicalizeTable0Size, -+ kEcma262UnCanonicalizeMultiStrings0, c, n, result, allow_caching_ptr); -+ case 1: -+ return LookupMapping( -+ kEcma262UnCanonicalizeTable1, kEcma262UnCanonicalizeTable1Size, -+ kEcma262UnCanonicalizeMultiStrings1, c, n, result, allow_caching_ptr); -+ case 5: -+ return LookupMapping( -+ kEcma262UnCanonicalizeTable5, kEcma262UnCanonicalizeTable5Size, -+ kEcma262UnCanonicalizeMultiStrings5, c, n, result, allow_caching_ptr); -+ case 7: -+ return LookupMapping( -+ kEcma262UnCanonicalizeTable7, kEcma262UnCanonicalizeTable7Size, -+ kEcma262UnCanonicalizeMultiStrings7, c, n, result, allow_caching_ptr); -+ default: -+ return 0; -+ } -+} -+ -+static const MultiCharacterSpecialCase<1> -+ kCanonicalizationRangeMultiStrings0[1] = { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kCanonicalizationRangeTable0Size = 70; // NOLINT -+static const int32_t kCanonicalizationRangeTable0[140] = { -+ 1073741889, 100, 90, 0, 1073741921, 100, 122, 0, -+ 1073742016, 88, 214, 0, 1073742040, 24, 222, 0, // NOLINT -+ 1073742048, 88, 246, 0, 1073742072, 24, 254, 0, -+ 1073742715, 8, 893, 0, 1073742728, 8, 906, 0, // NOLINT -+ 1073742749, 8, 927, 0, 1073742759, 16, 939, 0, -+ 1073742765, 8, 943, 0, 1073742781, 8, 959, 0, // NOLINT -+ 1073742791, 16, 971, 0, 1073742845, 8, 1023, 0, -+ 1073742848, 60, 1039, 0, 1073742864, 124, 1071, 0, // NOLINT -+ 1073742896, 124, 1103, 0, 1073742928, 60, 1119, 0, -+ 1073743153, 148, 1366, 0, 1073743201, 148, 1414, 0, // NOLINT -+ 1073746080, 148, 4293, 0, 1073749760, 28, 7943, 0, -+ 1073749768, 28, 7951, 0, 1073749776, 20, 7957, 0, // NOLINT -+ 1073749784, 20, 7965, 0, 1073749792, 28, 7975, 0, -+ 1073749800, 28, 7983, 0, 1073749808, 28, 7991, 0, // NOLINT -+ 1073749816, 28, 7999, 0, 1073749824, 20, 8005, 0, -+ 1073749832, 20, 8013, 0, 1073749856, 28, 8039, 0, // NOLINT -+ 1073749864, 28, 8047, 0, 1073749874, 12, 8053, 0, -+ 1073749960, 12, 8139, 0}; // NOLINT -+static const MultiCharacterSpecialCase<1> -+ kCanonicalizationRangeMultiStrings1[1] = { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kCanonicalizationRangeTable1Size = 14; // NOLINT -+static const int32_t kCanonicalizationRangeTable1[28] = { -+ 1073742176, 60, 367, 0, 1073742192, 60, 383, 0, -+ 1073743030, 100, 1231, 0, 1073743056, 100, 1257, 0, // NOLINT -+ 1073744896, 184, 3118, 0, 1073744944, 184, 3166, 0, -+ 1073745152, 148, 3365, 0}; // NOLINT -+static const MultiCharacterSpecialCase<1> -+ kCanonicalizationRangeMultiStrings7[1] = { // NOLINT -+ {{kSentinel}}}; // NOLINT -+static const uint16_t kCanonicalizationRangeTable7Size = 4; // NOLINT -+static const int32_t kCanonicalizationRangeTable7[8] = { -+ 1073749793, 100, 7994, 0, 1073749825, 100, 8026, 0}; // NOLINT -+int CanonicalizationRange::Convert(uchar c, uchar n, uchar* result, -+ bool* allow_caching_ptr) { -+ int chunk_index = c >> 13; -+ switch (chunk_index) { -+ case 0: -+ return LookupMapping( -+ kCanonicalizationRangeTable0, kCanonicalizationRangeTable0Size, -+ kCanonicalizationRangeMultiStrings0, c, n, result, allow_caching_ptr); -+ case 1: -+ return LookupMapping( -+ kCanonicalizationRangeTable1, kCanonicalizationRangeTable1Size, -+ kCanonicalizationRangeMultiStrings1, c, n, result, allow_caching_ptr); -+ case 7: -+ return LookupMapping( -+ kCanonicalizationRangeTable7, kCanonicalizationRangeTable7Size, -+ kCanonicalizationRangeMultiStrings7, c, n, result, allow_caching_ptr); -+ default: -+ return 0; -+ } -+} -+ -+#endif // !V8_INTL_SUPPORT -+ -+} // namespace unibrow -+} // namespace v8 -diff -Nrup mozilla/js/src/irregexp/util/VectorShim.h mozilla-OK/js/src/irregexp/util/VectorShim.h ---- mozilla/js/src/irregexp/util/VectorShim.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/util/VectorShim.h 2022-06-16 00:07:27.343875583 +0300 -@@ -0,0 +1,215 @@ -+// Copyright 2014 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef V8_UTIL_VECTOR_H_ -+#define V8_UTIL_VECTOR_H_ -+ -+#include -+#include -+#include -+#include -+ -+#include "jsalloc.h" -+#include "js/Utility.h" -+#include "js/Vector.h" -+ -+namespace v8 { -+namespace internal { -+ -+////////////////////////////////////////////////// -+ -+// Adapted from: -+// https://github.com/v8/v8/blob/5f69bbc233c2d1baf149faf869a7901603929914/src/utils/allocation.h#L36-L58 -+ -+template -+T* NewArray(size_t size) { -+ static_assert(std::is_pod::value, ""); -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ T* result = static_cast(js_malloc(size * sizeof(T))); -+ if (!result) { -+ oomUnsafe.crash("Irregexp NewArray"); -+ } -+ return result; -+} -+ -+template -+void DeleteArray(T* array) { -+ js_free(array); -+} -+ -+////////////////////////////////////////////////// -+ -+// A non-resizable vector containing a pointer and a length. -+// The Vector may or may not own the pointer, depending on context. -+// Origin: -+// https://github.com/v8/v8/blob/5f69bbc233c2d1baf149faf869a7901603929914/src/utils/vector.h#L20-L134 -+ -+template -+class Vector { -+ public: -+ Vector() : start_(nullptr), length_(0) {} -+ -+ Vector(T* data, size_t length) : start_(data), length_(length) { -+ MOZ_ASSERT_IF(length != 0, data != nullptr); -+ } -+ -+ static Vector New(size_t length) { -+ return Vector(NewArray(length), length); -+ } -+ -+ // Returns a vector using the same backing storage as this one, -+ // spanning from and including 'from', to but not including 'to'. -+ Vector SubVector(size_t from, size_t to) const { -+ MOZ_ASSERT(from <= to); -+ MOZ_ASSERT(to <= length_); -+ return Vector(begin() + from, to - from); -+ } -+ -+ // Returns the length of the vector. Only use this if you really need an -+ // integer return value. Use {size()} otherwise. -+ int length() const { -+ MOZ_ASSERT(length_ <= static_cast(std::numeric_limits::max())); -+ return static_cast(length_); -+ } -+ -+ // Returns the length of the vector as a size_t. -+ constexpr size_t size() const { return length_; } -+ -+ // Returns whether or not the vector is empty. -+ constexpr bool empty() const { return length_ == 0; } -+ -+ // Access individual vector elements - checks bounds in debug mode. -+ T& operator[](size_t index) const { -+ MOZ_ASSERT(index < length_); -+ return start_[index]; -+ } -+ -+ const T& at(size_t index) const { return operator[](index); } -+ -+ T& first() { return start_[0]; } -+ -+ T& last() { -+ MOZ_ASSERT(length_ > 0); -+ return start_[length_ - 1]; -+ } -+ -+ // Returns a pointer to the start of the data in the vector. -+ constexpr T* begin() const { return start_; } -+ -+ // Returns a pointer past the end of the data in the vector. -+ constexpr T* end() const { return start_ + length_; } -+ -+ // Returns a clone of this vector with a new backing store. -+ Vector Clone() const { -+ T* result = NewArray(length_); -+ for (size_t i = 0; i < length_; i++) result[i] = start_[i]; -+ return Vector(result, length_); -+ } -+ -+ void Truncate(size_t length) { -+ MOZ_ASSERT(length <= length_); -+ length_ = length; -+ } -+ -+ // Releases the array underlying this vector. Once disposed the -+ // vector is empty. -+ void Dispose() { -+ DeleteArray(start_); -+ start_ = nullptr; -+ length_ = 0; -+ } -+ -+ Vector operator+(size_t offset) { -+ MOZ_ASSERT(offset <= length_); -+ return Vector(start_ + offset, length_ - offset); -+ } -+ -+ Vector operator+=(size_t offset) { -+ MOZ_ASSERT(offset <= length_); -+ start_ += offset; -+ length_ -= offset; -+ return *this; -+ } -+ -+ // Implicit conversion from Vector to Vector. -+ inline operator Vector() const { -+ return Vector::cast(*this); -+ } -+ -+ template -+ static constexpr Vector cast(Vector input) { -+ return Vector(reinterpret_cast(input.begin()), -+ input.length() * sizeof(S) / sizeof(T)); -+ } -+ -+ bool operator==(const Vector other) const { -+ if (length_ != other.length_) return false; -+ if (start_ == other.start_) return true; -+ for (size_t i = 0; i < length_; ++i) { -+ if (start_[i] != other.start_[i]) { -+ return false; -+ } -+ } -+ return true; -+ } -+ -+ private: -+ T* start_; -+ size_t length_; -+}; -+ -+// The resulting vector does not contain a null-termination byte. If you want -+// the null byte, use ArrayVector("foo"). -+inline Vector CStrVector(const char* data) { -+ return Vector(data, strlen(data)); -+} -+ -+} // namespace internal -+ -+namespace base { -+ -+// SmallVector uses inline storage first, and reallocates when full. -+// It is basically equivalent to js::Vector, and is implemented -+// as a thin wrapper. -+// V8's implementation: -+// https://github.com/v8/v8/blob/master/src/base/small-vector.h -+template -+class SmallVector { -+ public: -+ SmallVector() = default; -+ SmallVector(size_t size) { resize_no_init(size); } -+ -+ inline bool empty() const { return inner_.empty(); } -+ inline const T& back() const { return inner_.back(); } -+ inline void pop_back() { inner_.popBack(); }; -+ template -+ inline void emplace_back(Args&&... args) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ if (!inner_.emplaceBack(args...)) { -+ oomUnsafe.crash("Irregexp SmallVector emplace_back"); -+ } -+ }; -+ inline size_t size() const { return inner_.length(); } -+ inline const T& at(size_t index) const { return inner_[index]; } -+ T* data() { return inner_.begin(); } -+ -+ T& operator[](size_t index) { return inner_[index]; } -+ const T& operator[](size_t index) const { return inner_[index]; } -+ -+ void resize_no_init(size_t new_size) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ if (!inner_.resizeUninitialized(new_size)) { -+ oomUnsafe.crash("Irregexp SmallVector resize"); -+ } -+ } -+ -+ private: -+ js::Vector inner_; -+}; -+ -+} // namespace base -+ -+} // namespace v8 -+ -+#endif // V8_UTIL_VECTOR_H_ -diff -Nrup mozilla/js/src/irregexp/util/ZoneShim.h mozilla-OK/js/src/irregexp/util/ZoneShim.h ---- mozilla/js/src/irregexp/util/ZoneShim.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/irregexp/util/ZoneShim.h 2022-06-16 00:06:40.947190595 +0300 -@@ -0,0 +1,376 @@ -+// Copyright 2019 the V8 project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef V8_UTIL_ZONE_H_ -+#define V8_UTIL_ZONE_H_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "ds/LifoAlloc.h" -+#include "ds/Sort.h" -+#include "irregexp/util/VectorShim.h" -+ -+namespace v8 { -+namespace internal { -+ -+// V8::Zone ~= LifoAlloc -+class Zone { -+ public: -+ Zone(js::LifoAlloc& alloc) : lifoAlloc_(alloc) {} -+ -+ template -+ T* New(Args&&... args) { -+ js::LifoAlloc::AutoFallibleScope fallible(&lifoAlloc_); -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ void* memory = lifoAlloc_.alloc(sizeof(T)); -+ if (!memory) { -+ oomUnsafe.crash("Irregexp Zone::New"); -+ } -+ return new (memory) T(std::forward(args)...); -+ } -+ -+ // Allocates uninitialized memory for 'length' number of T instances. -+ template -+ T* NewArray(size_t length) { -+ js::LifoAlloc::AutoFallibleScope fallible(&lifoAlloc_); -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ void* memory = lifoAlloc_.alloc(length * sizeof(T)); -+ if (!memory) { -+ oomUnsafe.crash("Irregexp Zone::New"); -+ } -+ return static_cast(memory); -+ } -+ -+ void DeleteAll() { lifoAlloc_.freeAll(); } -+ -+ // Returns true if the total memory allocated exceeds a threshold. -+ static const size_t kExcessLimit = 256 * 1024 * 1024; -+ bool excess_allocation() const { -+ return lifoAlloc_.computedSizeOfExcludingThis() > kExcessLimit; -+ } -+ -+ private: -+ js::LifoAlloc& lifoAlloc_; -+}; -+ -+// Superclass for classes allocated in a Zone. -+// Based on: https://github.com/v8/v8/blob/master/src/zone/zone.h -+class ZoneObject { -+ public: -+ // new (zone) SomeObject(...) was the old pattern. -+ // Delete the constructor to avoid using it accidentally. -+ void* operator new(size_t size, Zone* zone) = delete; -+ -+ // Allow non-allocating placement new -+ void* operator new(size_t size, void* ptr) { return ptr; } -+ -+ // Ideally, the delete operator should be private instead of -+ // public, but unfortunately the compiler sometimes synthesizes -+ // (unused) destructors for classes derived from ZoneObject, which -+ // require the operator to be visible. MSVC requires the delete -+ // operator to be public. -+ -+ // ZoneObjects should never be deleted individually; use -+ // Zone::DeleteAll() to delete all zone objects in one go. -+ void operator delete(void*, size_t) { MOZ_CRASH("unreachable"); } -+ void operator delete(void* pointer, Zone* zone) { MOZ_CRASH("unreachable"); } -+}; -+ -+// ZoneLists are growable lists with constant-time access to the -+// elements. The list itself and all its elements are allocated in the -+// Zone. ZoneLists cannot be deleted individually; you can delete all -+// objects in the Zone by calling Zone::DeleteAll(). -+// Used throughout irregexp. -+// Based on: https://github.com/v8/v8/blob/master/src/zone/zone-list.h -+template -+class ZoneList final : public ZoneObject { -+ public: -+ // Construct a new ZoneList with the given capacity; the length is -+ // always zero. The capacity must be non-negative. -+ ZoneList(int capacity, Zone* zone) : capacity_(capacity) { -+ data_ = (capacity_ > 0) ? zone->NewArray(capacity_) : nullptr; -+ } -+ // Construct a new ZoneList by copying the elements of the given ZoneList. -+ ZoneList(const ZoneList& other, Zone* zone) -+ : ZoneList(other.length(), zone) { -+ AddAll(other, zone); -+ } -+ -+ // Returns a reference to the element at index i. This reference is not safe -+ // to use after operations that can change the list's backing store -+ // (e.g. Add). -+ inline T& operator[](int i) const { -+ MOZ_ASSERT(i >= 0); -+ MOZ_ASSERT(static_cast(i) < static_cast(length_)); -+ return data_[i]; -+ } -+ inline T& at(int i) const { return operator[](i); } -+ inline T& last() const { return at(length_ - 1); } -+ inline T& first() const { return at(0); } -+ -+ using iterator = T*; -+ inline iterator begin() const { return &data_[0]; } -+ inline iterator end() const { return &data_[length_]; } -+ -+ inline bool is_empty() const { return length_ == 0; } -+ inline int length() const { return length_; } -+ inline int capacity() const { return capacity_; } -+ -+ Vector ToVector() const { return Vector(data_, length_); } -+ Vector ToVector(int start, int length) const { -+ return Vector(data_ + start, std::min(length_ - start, length)); -+ } -+ -+ Vector ToConstVector() const { -+ return Vector(data_, length_); -+ } -+ -+ // Adds a copy of the given 'element' to the end of the list, -+ // expanding the list if necessary. -+ void Add(const T& element, Zone* zone) { -+ if (length_ < capacity_) { -+ data_[length_++] = element; -+ } else { -+ ZoneList::ResizeAdd(element, zone); -+ } -+ } -+ // Add all the elements from the argument list to this list. -+ void AddAll(const ZoneList& other, Zone* zone) { -+ AddAll(other.ToVector(), zone); -+ } -+ // Add all the elements from the vector to this list. -+ void AddAll(const Vector& other, Zone* zone) { -+ int result_length = length_ + other.length(); -+ if (capacity_ < result_length) { -+ Resize(result_length, zone); -+ } -+ if (std::is_fundamental()) { -+ memcpy(data_ + length_, other.begin(), sizeof(*data_) * other.length()); -+ } else { -+ for (int i = 0; i < other.length(); i++) { -+ data_[length_ + i] = other.at(i); -+ } -+ } -+ length_ = result_length; -+ } -+ -+ // Overwrites the element at the specific index. -+ void Set(int index, const T& element) { -+ MOZ_ASSERT(index >= 0 && index <= length_); -+ data_[index] = element; -+ } -+ -+ // Removes the i'th element without deleting it even if T is a -+ // pointer type; moves all elements above i "down". Returns the -+ // removed element. This function's complexity is linear in the -+ // size of the list. -+ T Remove(int i) { -+ T element = at(i); -+ length_--; -+ while (i < length_) { -+ data_[i] = data_[i + 1]; -+ i++; -+ } -+ return element; -+ } -+ -+ // Removes the last element without deleting it even if T is a -+ // pointer type. Returns the removed element. -+ inline T RemoveLast() { return Remove(length_ - 1); } -+ -+ // Clears the list by freeing the storage memory. If you want to keep the -+ // memory, use Rewind(0) instead. Be aware, that even if T is a -+ // pointer type, clearing the list doesn't delete the entries. -+ inline void Clear() { -+ data_ = nullptr; -+ capacity_ = 0; -+ length_ = 0; -+ } -+ -+ // Drops all but the first 'pos' elements from the list. -+ inline void Rewind(int pos) { -+ MOZ_ASSERT(0 <= pos && pos <= length_); -+ length_ = pos; -+ } -+ -+ inline bool Contains(const T& elm) const { -+ for (int i = 0; i < length_; i++) { -+ if (data_[i] == elm) return true; -+ } -+ return false; -+ } -+ -+ template -+ void StableSort(CompareFunction cmp, size_t start, size_t length) { -+ js::AutoEnterOOMUnsafeRegion oomUnsafe; -+ T* scratch = static_cast(js_malloc(length * sizeof(T))); -+ if (!scratch) { -+ oomUnsafe.crash("Irregexp stable sort scratch space"); -+ } -+ auto comparator = [cmp](const T& a, const T& b, bool* lessOrEqual) { -+ *lessOrEqual = cmp(&a, &b) <= 0; -+ return true; -+ }; -+ MOZ_ALWAYS_TRUE( -+ js::MergeSort(begin() + start, length, scratch, comparator)); -+ js_free(scratch); -+ } -+ -+ void operator delete(void* pointer) { MOZ_CRASH("unreachable"); } -+ void operator delete(void* pointer, Zone* zone) { MOZ_CRASH("unreachable"); } -+ -+ private: -+ T* data_ = nullptr; -+ int capacity_ = 0; -+ int length_ = 0; -+ -+ // Increase the capacity of a full list, and add an element. -+ // List must be full already. -+ void ResizeAdd(const T& element, Zone* zone) { -+ MOZ_ASSERT(length_ >= capacity_); -+ // Grow the list capacity by 100%, but make sure to let it grow -+ // even when the capacity is zero (possible initial case). -+ int new_capacity = 1 + 2 * capacity_; -+ // Since the element reference could be an element of the list, copy -+ // it out of the old backing storage before resizing. -+ T temp = element; -+ Resize(new_capacity, zone); -+ data_[length_++] = temp; -+ } -+ -+ // Resize the list. -+ void Resize(int new_capacity, Zone* zone) { -+ MOZ_ASSERT(length_ <= new_capacity); -+ static_assert(std::is_trivially_copyable::value); -+ T* new_data = zone->NewArray(new_capacity); -+ if (length_ > 0) { -+ memcpy(new_data, data_, length_ * sizeof(T)); -+ } -+ data_ = new_data; -+ capacity_ = new_capacity; -+ } -+ -+ ZoneList& operator=(const ZoneList&) = delete; -+ ZoneList() = delete; -+ ZoneList(const ZoneList&) = delete; -+}; -+ -+// Based on: https://github.com/v8/v8/blob/master/src/zone/zone-allocator.h -+template -+class ZoneAllocator { -+ public: -+ using pointer = T*; -+ using const_pointer = const T*; -+ using reference = T&; -+ using const_reference = const T&; -+ using value_type = T; -+ using size_type = size_t; -+ using difference_type = ptrdiff_t; -+ template -+ struct rebind { -+ using other = ZoneAllocator; -+ }; -+ -+ explicit ZoneAllocator(Zone* zone) : zone_(zone) {} -+ template -+ ZoneAllocator(const ZoneAllocator& other) -+ : ZoneAllocator(other.zone_) {} -+ template -+ friend class ZoneAllocator; -+ -+ T* allocate(size_t n) { return zone_->NewArray(n); } -+ void deallocate(T* p, size_t) {} // noop for zones -+ -+ bool operator==(ZoneAllocator const& other) const { -+ return zone_ == other.zone_; -+ } -+ bool operator!=(ZoneAllocator const& other) const { -+ return zone_ != other.zone_; -+ } -+ -+ private: -+ Zone* zone_; -+}; -+ -+// Zone wrappers for std containers: -+// Origin: -+// https://github.com/v8/v8/blob/5e514a969376dc63517d575b062758efd36cd757/src/zone/zone-containers.h#L25-L169 -+ -+// A wrapper subclass for std::vector to make it easy to construct one -+// that uses a zone allocator. -+// Used throughout irregexp -+template -+class ZoneVector : public std::vector> { -+ public: -+ ZoneVector(Zone* zone) -+ : std::vector>(ZoneAllocator(zone)) {} -+ -+ // Constructs a new vector and fills it with the contents of the range -+ // [first, last). -+ template -+ ZoneVector(Iter first, Iter last, Zone* zone) -+ : std::vector>(first, last, ZoneAllocator(zone)) {} -+}; -+ -+// A wrapper subclass for std::list to make it easy to construct one -+// that uses a zone allocator. -+// Used in regexp-bytecode-peephole.cc -+template -+class ZoneLinkedList : public std::list> { -+ public: -+ // Constructs an empty list. -+ explicit ZoneLinkedList(Zone* zone) -+ : std::list>(ZoneAllocator(zone)) {} -+}; -+ -+// A wrapper subclass for std::set to make it easy to construct one that uses -+// a zone allocator. -+// Used in regexp-parser.cc -+template > -+class ZoneSet : public std::set> { -+ public: -+ // Constructs an empty set. -+ explicit ZoneSet(Zone* zone) -+ : std::set>(Compare(), -+ ZoneAllocator(zone)) {} -+}; -+ -+// A wrapper subclass for std::map to make it easy to construct one that uses -+// a zone allocator. -+// Used in regexp-bytecode-peephole.cc -+template > -+class ZoneMap -+ : public std::map>> { -+ public: -+ // Constructs an empty map. -+ explicit ZoneMap(Zone* zone) -+ : std::map>>( -+ Compare(), ZoneAllocator>(zone)) {} -+}; -+ -+// A wrapper subclass for std::unordered_map to make it easy to construct one -+// that uses a zone allocator. -+// Used in regexp-bytecode-peephole.cc -+template , -+ typename KeyEqual = std::equal_to> -+class ZoneUnorderedMap -+ : public std::unordered_map>> { -+ public: -+ // Constructs an empty map. -+ explicit ZoneUnorderedMap(Zone* zone, size_t bucket_count = 100) -+ : std::unordered_map>>( -+ bucket_count, Hash(), KeyEqual(), -+ ZoneAllocator>(zone)) {} -+}; -+ -+} // namespace internal -+} // namespace v8 -+ -+#endif // V8_UTIL_FLAG_H_ -diff -Nrup mozilla/js/src/jit/BaselineIC.cpp mozilla-OK/js/src/jit/BaselineIC.cpp ---- mozilla/js/src/jit/BaselineIC.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/BaselineIC.cpp 2022-06-15 23:27:12.203259941 +0300 -@@ -2112,6 +2112,11 @@ GetTemplateObjectForNative(JSContext* cx - return !!res; - } - -+ if (native == js::intrinsic_NewRegExpStringIterator) { -+ res.set(NewRegExpStringIteratorObject(cx, TenuredObject)); -+ return !!res; -+ } -+ - if (JitSupportsSimd() && GetTemplateObjectForSimd(cx, target, res)) - return !!res; - -diff -Nrup mozilla/js/src/jit/CodeGenerator.cpp mozilla-OK/js/src/jit/CodeGenerator.cpp ---- mozilla/js/src/jit/CodeGenerator.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/CodeGenerator.cpp 2022-06-16 00:04:45.970971259 +0300 -@@ -26,7 +26,7 @@ - #include "builtin/SelfHostingDefines.h" - #include "builtin/TypedObject.h" - #include "gc/Nursery.h" --#include "irregexp/NativeRegExpMacroAssembler.h" -+#include "irregexp/RegExpTypes.h" - #include "jit/AtomicOperations.h" - #include "jit/BaselineCompiler.h" - #include "jit/IonBuilder.h" -@@ -41,6 +41,7 @@ - #include "jit/RangeAnalysis.h" - #include "jit/SharedICHelpers.h" - #include "jit/StackSlotAllocator.h" -+#include "js/RegExpFlags.h" - #include "vm/AsyncFunction.h" - #include "vm/AsyncIteration.h" - #include "vm/MatchPairs.h" -@@ -1183,243 +1184,314 @@ CodeGenerator::visitRegExp(LRegExp* lir) - masm.bind(ool->rejoin()); - } - -+static const size_t InputOutputDataSize = sizeof(irregexp::InputOutputData); -+ - // Amount of space to reserve on the stack when executing RegExps inline. --static const size_t RegExpReservedStack = sizeof(irregexp::InputOutputData) -+static const size_t RegExpReservedStack = InputOutputDataSize - + sizeof(MatchPairs) - + RegExpObject::MaxPairCount * sizeof(MatchPair); - - static size_t - RegExpPairsVectorStartOffset(size_t inputOutputDataStartOffset) - { -- return inputOutputDataStartOffset + sizeof(irregexp::InputOutputData) + sizeof(MatchPairs); -+ return inputOutputDataStartOffset + InputOutputDataSize + sizeof(MatchPairs); - } - - static Address - RegExpPairCountAddress(MacroAssembler& masm, size_t inputOutputDataStartOffset) - { - return Address(masm.getStackPointer(), inputOutputDataStartOffset -- + sizeof(irregexp::InputOutputData) -+ + InputOutputDataSize - + MatchPairs::offsetOfPairCount()); - } - -+// When the unicode flag is set, if lastIndex points to a trail -+// surrogate, we should step back to the corresponding lead surrogate. -+// See ExecuteRegExp in builtin/RegExp.cpp for more detail. -+static void -+StepBackToLeadSurrogate(MacroAssembler& masm, -+ Register regexpShared, -+ Register input, -+ Register lastIndex, -+ Register temp1, -+ Register temp2) -+{ -+ Label done; -+ -+ // If the unicode flag is not set, there is nothing to do. -+ masm.branchTest32(Assembler::Zero, -+ Address(regexpShared, RegExpShared::offsetOfFlags()), -+ Imm32(int32_t(JS::RegExpFlag::Unicode)), -+ &done); -+ -+ // If the input is latin1, there can't be any surrogates. -+ masm.branchLatin1String(input, &done); -+ -+ // Check if |lastIndex > 0 && lastIndex < input->length()|. -+ // lastIndex should already have no sign here. -+ masm.branchTest32(Assembler::Zero, lastIndex, lastIndex, &done); -+ masm.loadStringLength(input, temp1); -+ masm.branch32(Assembler::AboveOrEqual, lastIndex, temp1, &done); -+ -+ Register charsReg = temp1; -+ masm.loadStringChars(input, charsReg); -+ -+ // Check if input[lastIndex] is trail surrogate. -+ masm.computeEffectiveAddress(BaseIndex(charsReg, lastIndex, TimesTwo), temp2); -+ masm.load16ZeroExtend(Address(temp2, 0), temp2); -+ -+ masm.branch32(Assembler::Below, temp2, Imm32(unicode::TrailSurrogateMin), &done); -+ masm.branch32(Assembler::Above, temp2, Imm32(unicode::TrailSurrogateMax), &done); -+ -+ // Check if input[lastIndex-1] is lead surrogate. -+ masm.move32(lastIndex, temp2); -+ masm.sub32(Imm32(1), temp2); -+ masm.computeEffectiveAddress(BaseIndex(charsReg, temp2, TimesTwo), temp2); -+ masm.load16ZeroExtend(Address(temp2, 0), temp2); -+ -+ masm.branch32(Assembler::Below, temp2, Imm32(unicode::LeadSurrogateMin), &done); -+ masm.branch32(Assembler::Above, temp2, Imm32(unicode::LeadSurrogateMax), &done); -+ -+ // Move lastIndex back to lead surrogate. -+ masm.subPtr(Imm32(1), lastIndex); -+ -+ masm.bind(&done); -+} -+ -+static void -+UpdateRegExpStatics(MacroAssembler& masm, -+ Register regexp, -+ Register input, -+ Register lastIndex, -+ Register staticsReg, -+ Register temp1, -+ Register temp2, -+ // bool stringsCanBeInNursery, -+ LiveGeneralRegisterSet& volatileRegs) -+{ -+ Address pendingInputAddress(staticsReg, RegExpStatics::offsetOfPendingInput()); -+ Address matchesInputAddress(staticsReg, RegExpStatics::offsetOfMatchesInput()); -+ Address lazySourceAddress(staticsReg, RegExpStatics::offsetOfLazySource()); -+ Address lazyIndexAddress(staticsReg, RegExpStatics::offsetOfLazyIndex()); -+ -+ masm.guardedCallPreBarrier(pendingInputAddress, MIRType::String); -+ masm.guardedCallPreBarrier(matchesInputAddress, MIRType::String); -+ masm.guardedCallPreBarrier(lazySourceAddress, MIRType::String); -+ -+ masm.storePtr(input, pendingInputAddress); -+ masm.storePtr(input, matchesInputAddress); -+ masm.storePtr(lastIndex, Address(staticsReg, RegExpStatics::offsetOfLazyIndex())); -+ masm.store32(Imm32(1), Address(staticsReg, RegExpStatics::offsetOfPendingLazyEvaluation())); -+ -+ masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), -+ temp1); -+ masm.loadPtr(Address(temp1, RegExpShared::offsetOfSource()), temp2); -+ masm.storePtr(temp2, lazySourceAddress); -+ masm.load32(Address(temp1, RegExpShared::offsetOfFlags()), temp2); -+ masm.store32(temp2, Address(staticsReg, RegExpStatics::offsetOfLazyFlags())); -+} -+ - // Prepare an InputOutputData and optional MatchPairs which space has been - // allocated for on the stack, and try to execute a RegExp on a string input. --// If the RegExp was successfully executed and matched the input, fallthrough, --// otherwise jump to notFound or failure. -+// If the RegExp was successfully executed and matched the input, fallthrough. -+// Otherwise, jump to notFound or failure. - static bool --PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Register input, -+PrepareAndExecuteRegExp(JSContext* cx, -+ MacroAssembler& masm, -+ Register regexp, -+ Register input, - Register lastIndex, -- Register temp1, Register temp2, Register temp3, -+ Register temp1, -+ Register temp2, -+ Register temp3, - size_t inputOutputDataStartOffset, -- RegExpShared::CompilationMode mode, -- Label* notFound, Label* failure) --{ -- size_t matchPairsStartOffset = inputOutputDataStartOffset + sizeof(irregexp::InputOutputData); -- size_t pairsVectorStartOffset = RegExpPairsVectorStartOffset(inputOutputDataStartOffset); -+ // bool stringsCanBeInNursery, -+ Label* notFound, -+ Label* failure) -+{ -+ using irregexp::InputOutputData; -+ -+ size_t ioOffset = inputOutputDataStartOffset; -+ size_t matchPairsOffset = ioOffset + sizeof(InputOutputData); -+ size_t pairsArrayOffset = matchPairsOffset + sizeof(MatchPairs); - - Address inputStartAddress(masm.getStackPointer(), -- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, inputStart)); -+ ioOffset + offsetof(InputOutputData, inputStart)); - Address inputEndAddress(masm.getStackPointer(), -- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, inputEnd)); -- Address matchesPointerAddress(masm.getStackPointer(), -- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, matches)); -+ ioOffset + offsetof(InputOutputData, inputEnd)); - Address startIndexAddress(masm.getStackPointer(), -- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, startIndex)); -- Address endIndexAddress(masm.getStackPointer(), -- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, endIndex)); -- Address matchResultAddress(masm.getStackPointer(), -- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, result)); -+ ioOffset + offsetof(InputOutputData, startIndex)); -+ Address matchesAddress(masm.getStackPointer(), ioOffset + offsetof(InputOutputData, matches)); - -- Address pairCountAddress = RegExpPairCountAddress(masm, inputOutputDataStartOffset); -+ Address matchPairsAddress(masm.getStackPointer(), matchPairsOffset); -+ Address pairCountAddress(masm.getStackPointer(), -+ matchPairsOffset + MatchPairs::offsetOfPairCount()); - Address pairsPointerAddress(masm.getStackPointer(), -- matchPairsStartOffset + MatchPairs::offsetOfPairs()); -+ matchPairsOffset + MatchPairs::offsetOfPairs()); - -- Address pairsVectorAddress(masm.getStackPointer(), pairsVectorStartOffset); -+ Address pairsArrayAddress(masm.getStackPointer(), pairsArrayOffset); - -- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); -- if (!res) -- return false; --#ifdef JS_USE_LINK_REGISTER -- if (mode != RegExpShared::MatchOnly) -- masm.pushReturnAddress(); --#endif -- if (mode == RegExpShared::Normal) { -- // First, fill in a skeletal MatchPairs instance on the stack. This will be -- // passed to the OOL stub in the caller if we aren't able to execute the -- // RegExp inline, and that stub needs to be able to determine whether the -- // execution finished successfully. -- masm.store32(Imm32(1), pairCountAddress); -- masm.store32(Imm32(-1), pairsVectorAddress); -- masm.computeEffectiveAddress(pairsVectorAddress, temp1); -- masm.storePtr(temp1, pairsPointerAddress); -- } -+ // First, fill in a skeletal MatchPairs instance on the stack. This will be -+ // passed to the OOL stub in the caller if we aren't able to execute the -+ // RegExp inline, and that stub needs to be able to determine whether the -+ // execution finished successfully. -+ -+ // Initialize MatchPairs::pairCount to 1. The correct value can only -+ // be determined after loading the RegExpShared. If the RegExpShared -+ // has Kind::Atom, this is the correct pairCount. -+ masm.store32(Imm32(1), pairCountAddress); -+ -+ // Initialize MatchPairs::pairs pointer -+ masm.store32(Imm32(-1), pairsArrayAddress); -+ masm.computeEffectiveAddress(pairsArrayAddress, temp1); -+ masm.storePtr(temp1, pairsPointerAddress); - - // Check for a linear input string. - masm.branchIfRopeOrExternal(input, temp1, failure); - -- // Get the RegExpShared for the RegExp. -- masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), temp1); -- masm.branchPtr(Assembler::Equal, temp1, ImmWord(0), failure); -+ // Load the RegExpShared. -+ Register regexpReg = temp1; - -- // ES6 21.2.2.2 step 2. -- // See RegExp.cpp ExecuteRegExp for more detail. -+ // Get the RegExpShared for the RegExp. -+ masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), -+ regexpReg); -+ masm.branchPtr(Assembler::Equal, regexpReg, ImmWord(0), failure); -+ -+ // Handle Atom matches -+ Label notAtom, checkSuccess; -+ masm.branchPtr(Assembler::Equal, -+ Address(regexpReg, RegExpShared::offsetOfPatternAtom()), -+ ImmWord(0), ¬Atom); - { -- Label done; -- -- masm.branchTest32(Assembler::Zero, Address(temp1, RegExpShared::offsetOfFlags()), -- Imm32(UnicodeFlag), &done); -- -- // If input is latin1, there should not be surrogate pair. -- masm.branchLatin1String(input, &done); -- -- // Check if |lastIndex > 0 && lastIndex < input->length()|. -- // lastIndex should already have no sign here. -- masm.branchTest32(Assembler::Zero, lastIndex, lastIndex, &done); -- masm.loadStringLength(input, temp2); -- masm.branch32(Assembler::AboveOrEqual, lastIndex, temp2, &done); -- -- // Check if input[lastIndex] is trail surrogate. -- masm.loadStringChars(input, temp2); -- masm.computeEffectiveAddress(BaseIndex(temp2, lastIndex, TimesTwo), temp3); -- masm.load16ZeroExtend(Address(temp3, 0), temp3); -- -- masm.branch32(Assembler::Below, temp3, Imm32(unicode::TrailSurrogateMin), &done); -- masm.branch32(Assembler::Above, temp3, Imm32(unicode::TrailSurrogateMax), &done); -- -- // Check if input[lastIndex-1] is lead surrogate. -- masm.move32(lastIndex, temp3); -- masm.sub32(Imm32(1), temp3); -- masm.computeEffectiveAddress(BaseIndex(temp2, temp3, TimesTwo), temp3); -- masm.load16ZeroExtend(Address(temp3, 0), temp3); -- -- masm.branch32(Assembler::Below, temp3, Imm32(unicode::LeadSurrogateMin), &done); -- masm.branch32(Assembler::Above, temp3, Imm32(unicode::LeadSurrogateMax), &done); -- -- // Move lastIndex to lead surrogate. -- masm.subPtr(Imm32(1), lastIndex); -- -- masm.bind(&done); -- } -- -- if (mode == RegExpShared::Normal) { -- // Don't handle RegExps with excessive parens. -- masm.load32(Address(temp1, RegExpShared::offsetOfParenCount()), temp2); -- masm.branch32(Assembler::AboveOrEqual, temp2, Imm32(RegExpObject::MaxPairCount), failure); -- -- // Fill in the paren count in the MatchPairs on the stack. -- masm.add32(Imm32(1), temp2); -- masm.store32(temp2, pairCountAddress); -- } -- -- // Load the code pointer for the type of input string we have, and compute -- // the input start/end pointers in the InputOutputData. -- Register codePointer = temp1; -+ LiveGeneralRegisterSet regsToSave(GeneralRegisterSet::Volatile()); -+ regsToSave.takeUnchecked(temp1); -+ regsToSave.takeUnchecked(temp2); -+ regsToSave.takeUnchecked(temp3); -+ -+ masm.computeEffectiveAddress(matchPairsAddress, temp3); -+ -+ masm.PushRegsInMask(regsToSave); -+ masm.setupUnalignedABICall(temp2); -+ masm.passABIArg(regexpReg); -+ masm.passABIArg(input); -+ masm.passABIArg(lastIndex); -+ masm.passABIArg(temp3); -+ masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ExecuteRegExpAtomRaw)); -+ masm.storeCallInt32Result(temp1); -+ masm.PopRegsInMask(regsToSave); -+ -+ masm.jump(&checkSuccess); -+ } -+ masm.bind(¬Atom); -+ -+ // Don't handle regexps with too many capture pairs. -+ masm.load32(Address(regexpReg, RegExpShared::offsetOfPairCount()), temp2); -+ masm.branch32(Assembler::Above, temp2, Imm32(RegExpObject::MaxPairCount), failure); -+ -+ // Fill in the pair count in the MatchPairs on the stack. -+ masm.store32(temp2, pairCountAddress); -+ -+ // Update lastIndex if necessary. -+ StepBackToLeadSurrogate(masm, regexpReg, input, lastIndex, temp2, temp3); -+ -+ // Load code pointer and length of input (in bytes). -+ // Store the input start in the InputOutputData. -+ Register codePointer = temp1; // Note: temp1 was previously regexpReg. -+ Register byteLength = temp3; - { -+ Label isLatin1, done; - masm.loadStringChars(input, temp2); - masm.storePtr(temp2, inputStartAddress); -- masm.loadStringLength(input, temp3); -+ masm.loadStringLength(input, byteLength); - -- Label isLatin1, done; - masm.branchLatin1String(input, &isLatin1); -- { -- masm.lshiftPtr(Imm32(1), temp3); -- masm.loadPtr(Address(temp1, RegExpShared::offsetOfTwoByteJitCode(mode)), -- codePointer); -- } -+ -+ // Two-byte input -+ masm.loadPtr(Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 =*/false)), -+ codePointer); -+ masm.lshiftPtr(Imm32(1), byteLength); - masm.jump(&done); -- { -- masm.bind(&isLatin1); -- masm.loadPtr(Address(temp1, RegExpShared::offsetOfLatin1JitCode(mode)), -- codePointer); -- } -+ -+ // Latin1 input -+ masm.bind(&isLatin1); -+ masm.loadPtr(Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 = */ true)), -+ codePointer); -+ - masm.bind(&done); - -- masm.addPtr(temp3, temp2); -+ // Store end pointer -+ masm.addPtr(byteLength, temp2); - masm.storePtr(temp2, inputEndAddress); - } - -- // Check the RegExpShared has been compiled for this type of input. -+ // Guard that the RegExpShared has been compiled for this type of input. -+ // If it has not been compiled, we fall back to the OOL case, which will -+ // do a VM call into the interpreter. -+ // TODO: add an interpreter trampoline? - masm.branchPtr(Assembler::Equal, codePointer, ImmWord(0), failure); - masm.loadPtr(Address(codePointer, JitCode::offsetOfCode()), codePointer); - -- // Finish filling in the InputOutputData instance on the stack. -- if (mode == RegExpShared::Normal) { -- masm.computeEffectiveAddress(Address(masm.getStackPointer(), matchPairsStartOffset), temp2); -- masm.storePtr(temp2, matchesPointerAddress); -- } else { -- // Use InputOutputData.endIndex itself for output. -- masm.computeEffectiveAddress(endIndexAddress, temp2); -- masm.storePtr(temp2, endIndexAddress); -- } -+ // Finish filling in the InputOutputData instance on the stack -+ masm.computeEffectiveAddress(matchPairsAddress, temp2); -+ masm.storePtr(temp2, matchesAddress); - masm.storePtr(lastIndex, startIndexAddress); -- masm.store32(Imm32(0), matchResultAddress); - - // Save any volatile inputs. - LiveGeneralRegisterSet volatileRegs; -- if (lastIndex.volatile_()) -+ if (lastIndex.volatile_()) { - volatileRegs.add(lastIndex); -- if (input.volatile_()) -+ } -+ if (input.volatile_()) { - volatileRegs.add(input); -- if (regexp.volatile_()) -+ } -+ if (regexp.volatile_()) { - volatileRegs.add(regexp); -+ } - - #ifdef JS_TRACE_LOGGING - if (TraceLogTextIdEnabled(TraceLogger_IrregexpExecute)) { -- masm.push(temp1); -- masm.loadTraceLogger(temp1); -- masm.tracelogStartId(temp1, TraceLogger_IrregexpExecute); -- masm.pop(temp1); -+ masm.loadTraceLogger(temp2); -+ masm.tracelogStartId(temp2, TraceLogger_IrregexpExecute); - } - #endif - - // Execute the RegExp. -- masm.computeEffectiveAddress(Address(masm.getStackPointer(), inputOutputDataStartOffset), temp2); -+ masm.computeEffectiveAddress(Address(masm.getStackPointer(), inputOutputDataStartOffset), -+ temp2); - masm.PushRegsInMask(volatileRegs); - masm.setupUnalignedABICall(temp3); - masm.passABIArg(temp2); - masm.callWithABI(codePointer); -+ masm.storeCallInt32Result(temp1); - masm.PopRegsInMask(volatileRegs); - - #ifdef JS_TRACE_LOGGING - if (TraceLogTextIdEnabled(TraceLogger_IrregexpExecute)) { -- masm.loadTraceLogger(temp1); -- masm.tracelogStopId(temp1, TraceLogger_IrregexpExecute); -+ masm.loadTraceLogger(temp2); -+ masm.tracelogStopId(temp2, TraceLogger_IrregexpExecute); - } - #endif - - Label success; -- masm.branch32(Assembler::Equal, matchResultAddress, -- Imm32(RegExpRunStatus_Success_NotFound), notFound); -- masm.branch32(Assembler::Equal, matchResultAddress, -- Imm32(RegExpRunStatus_Error), failure); -+ masm.bind(&checkSuccess); -+ masm.branch32(Assembler::Equal, temp1, Imm32(RegExpRunStatus_Success_NotFound), notFound); -+ masm.branch32(Assembler::Equal, temp1, Imm32(RegExpRunStatus_Error), failure); - - // Lazily update the RegExpStatics. -- masm.movePtr(ImmPtr(res), temp1); -- -- Address pendingInputAddress(temp1, RegExpStatics::offsetOfPendingInput()); -- Address matchesInputAddress(temp1, RegExpStatics::offsetOfMatchesInput()); -- Address lazySourceAddress(temp1, RegExpStatics::offsetOfLazySource()); -- Address lazyIndexAddress(temp1, RegExpStatics::offsetOfLazyIndex()); -- -- masm.guardedCallPreBarrier(pendingInputAddress, MIRType::String); -- masm.guardedCallPreBarrier(matchesInputAddress, MIRType::String); -- masm.guardedCallPreBarrier(lazySourceAddress, MIRType::String); -- -- masm.storePtr(input, pendingInputAddress); -- masm.storePtr(input, matchesInputAddress); -- masm.storePtr(lastIndex, Address(temp1, RegExpStatics::offsetOfLazyIndex())); -- masm.store32(Imm32(1), Address(temp1, RegExpStatics::offsetOfPendingLazyEvaluation())); -- -- masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), temp2); -- masm.loadPtr(Address(temp2, RegExpShared::offsetOfSource()), temp3); -- masm.storePtr(temp3, lazySourceAddress); -- masm.load32(Address(temp2, RegExpShared::offsetOfFlags()), temp3); -- masm.store32(temp3, Address(temp1, RegExpStatics::offsetOfLazyFlags())); -- -- if (mode == RegExpShared::MatchOnly) { -- // endIndex is passed via temp3. -- masm.load32(endIndexAddress, temp3); -+ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); -+ if (!res) { -+ return false; - } -+ masm.movePtr(ImmPtr(res), temp1); -+ UpdateRegExpStatics(masm, -+ regexp, -+ input, -+ lastIndex, -+ temp1, -+ temp2, -+ temp3, -+ // stringsCanBeInNursery, -+ volatileRegs); - - return true; - } -@@ -1705,17 +1777,31 @@ JitCompartment::generateRegExpMatcherStu - - MacroAssembler masm(cx); - -+#ifdef JS_USE_LINK_REGISTER -+ masm.pushReturnAddress(); -+#endif -+ - // The InputOutputData is placed above the return address on the stack. - size_t inputOutputDataStartOffset = sizeof(void*); - - Label notFound, oolEntry; - if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, - temp1, temp2, temp5, inputOutputDataStartOffset, -- RegExpShared::Normal, ¬Found, &oolEntry)) -+ ¬Found, &oolEntry)) - { - return nullptr; - } - -+ // If a regexp has named captures, fall back to the OOL stub, which -+ // will end up calling CreateRegExpMatchResults. -+ Register shared = temp2; -+ masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), -+ shared); -+ masm.branchPtr(Assembler::NotEqual, -+ Address(shared, RegExpShared::offsetOfGroupsTemplate()), -+ ImmWord(0), -+ &oolEntry); -+ - // Construct the result. - Register object = temp1; - Label matchResultFallback, matchResultJoin; -@@ -1726,6 +1812,7 @@ JitCompartment::generateRegExpMatcherStu - masm.loadPtr(Address(object, NativeObject::offsetOfSlots()), temp2); - masm.storeValue(templateObject->getSlot(0), Address(temp2, 0)); - masm.storeValue(templateObject->getSlot(1), Address(temp2, sizeof(Value))); -+ masm.storeValue(templateObject->getSlot(2), Address(temp2, 2 * sizeof(Value))); - - size_t elementsOffset = NativeObject::offsetOfFixedElements(); - -@@ -1935,7 +2022,7 @@ CodeGenerator::visitOutOfLineRegExpMatch - Register temp = regs.takeAny(); - - masm.computeEffectiveAddress(Address(masm.getStackPointer(), -- sizeof(irregexp::InputOutputData)), temp); -+ InputOutputDataSize), temp); - - pushArg(temp); - pushArg(lastIndex); -@@ -2006,13 +2093,17 @@ JitCompartment::generateRegExpSearcherSt - - MacroAssembler masm(cx); - -+#ifdef JS_USE_LINK_REGISTER -+ masm.pushReturnAddress(); -+#endif -+ - // The InputOutputData is placed above the return address on the stack. - size_t inputOutputDataStartOffset = sizeof(void*); - - Label notFound, oolEntry; - if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, - temp1, temp2, temp3, inputOutputDataStartOffset, -- RegExpShared::Normal, ¬Found, &oolEntry)) -+ ¬Found, &oolEntry)) - { - return nullptr; - } -@@ -2092,7 +2183,7 @@ CodeGenerator::visitOutOfLineRegExpSearc - Register temp = regs.takeAny(); - - masm.computeEffectiveAddress(Address(masm.getStackPointer(), -- sizeof(irregexp::InputOutputData)), temp); -+ InputOutputDataSize), temp); - - pushArg(temp); - pushArg(lastIndex); -@@ -2158,20 +2249,29 @@ JitCompartment::generateRegExpTesterStub - Register temp2 = regs.takeAny(); - Register temp3 = regs.takeAny(); - -- masm.reserveStack(sizeof(irregexp::InputOutputData)); -+ masm.reserveStack(RegExpReservedStack); - - Label notFound, oolEntry; - if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, - temp1, temp2, temp3, 0, -- RegExpShared::MatchOnly, ¬Found, &oolEntry)) -+ ¬Found, &oolEntry)) - { - return nullptr; - } - - Label done; - -- // temp3 contains endIndex. -- masm.move32(temp3, result); -+ // In visitRegExpMatcher and visitRegExpSearcher, we reserve stack space -+ // before calling the stub. For RegExpTester we call the stub before reserving -+ // stack space, so the offset of the InputOutputData is 0. -+ size_t inputOutputDataStartOffset = 0; -+ -+ size_t pairsVectorStartOffset = RegExpPairsVectorStartOffset(inputOutputDataStartOffset); -+ Address matchPairLimit(masm.getStackPointer(), -+ pairsVectorStartOffset + offsetof(MatchPair, limit)); -+ -+ // RegExpTester returns the end index of the match to update lastIndex. -+ masm.load32(matchPairLimit, result); - masm.jump(&done); - - masm.bind(¬Found); -@@ -2182,7 +2282,7 @@ JitCompartment::generateRegExpTesterStub - masm.move32(Imm32(RegExpTesterResultFailed), result); - - masm.bind(&done); -- masm.freeStack(sizeof(irregexp::InputOutputData)); -+ masm.freeStack(RegExpReservedStack); - masm.ret(); - - Linker linker(masm); -@@ -5715,6 +5815,12 @@ typedef StringIteratorObject* (*NewStrin - static const VMFunction NewStringIteratorObjectInfo = - FunctionInfo(NewStringIteratorObject, "NewStringIteratorObject"); - -+typedef RegExpStringIteratorObject* (*NewRegExpStringIteratorObjectFn)(JSContext*, NewObjectKind); -+ -+static const VMFunction NewRegExpStringIteratorObjectInfo = -+ FunctionInfo(NewRegExpStringIteratorObject, -+ "NewRegExpStringIteratorObject"); -+ - void - CodeGenerator::visitNewIterator(LNewIterator* lir) - { -@@ -5734,6 +5840,12 @@ CodeGenerator::visitNewIterator(LNewIter - ArgList(Imm32(GenericObject)), - StoreRegisterTo(objReg)); - break; -+ case MNewIterator::RegExpStringIterator: -+ ool = oolCallVM(NewRegExpStringIteratorObjectInfo, -+ lir, -+ ArgList(Imm32(GenericObject)), -+ StoreRegisterTo(objReg)); -+ break; - default: - MOZ_CRASH("unexpected iterator type"); - } -diff -Nrup mozilla/js/src/jit/InlinableNatives.h mozilla-OK/js/src/jit/InlinableNatives.h ---- mozilla/js/src/jit/InlinableNatives.h 2021-08-08 16:01:59.000000000 +0300 -+++ mozilla-OK/js/src/jit/InlinableNatives.h 2022-06-15 23:27:12.207259914 +0300 -@@ -136,6 +136,7 @@ - _(IntrinsicIsMapIterator) \ - _(IntrinsicIsSetIterator) \ - _(IntrinsicIsStringIterator) \ -+ _(IntrinsicGuardToRegExpStringIterator) \ - \ - _(IntrinsicIsMapObject) \ - _(IntrinsicGetNextMapEntryForIterator) \ -@@ -145,6 +146,7 @@ - \ - _(IntrinsicNewArrayIterator) \ - _(IntrinsicNewStringIterator) \ -+ _(IntrinsicNewRegExpStringIterator) \ - \ - _(IntrinsicArrayBufferByteLength) \ - _(IntrinsicPossiblyWrappedArrayBufferByteLength) \ -diff -Nrup mozilla/js/src/jit/JitOptions.cpp mozilla-OK/js/src/jit/JitOptions.cpp ---- mozilla/js/src/jit/JitOptions.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/JitOptions.cpp 2022-06-15 23:53:00.817758191 +0300 -@@ -159,6 +159,10 @@ DefaultJitOptions::DefaultJitOptions() - // are compiled with the baseline compiler. - SET_DEFAULT(baselineWarmUpThreshold, 10); - -+ // How many invocations are needed before regexps are compiled to -+ // native code. -+ SET_DEFAULT(regexpWarmUpThreshold, 10); -+ - // Number of exception bailouts (resuming into catch/finally block) before - // we invalidate and forbid Ion compilation. - SET_DEFAULT(exceptionBailoutThreshold, 10); -@@ -275,6 +279,7 @@ DefaultJitOptions::setEagerCompilation() - { - eagerCompilation = true; - baselineWarmUpThreshold = 0; -+ regexpWarmUpThreshold = 0; - forcedDefaultIonWarmUpThreshold.reset(); - forcedDefaultIonWarmUpThreshold.emplace(0); - forcedDefaultIonSmallFunctionWarmUpThreshold.reset(); -diff -Nrup mozilla/js/src/jit/JitOptions.h mozilla-OK/js/src/jit/JitOptions.h ---- mozilla/js/src/jit/JitOptions.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/JitOptions.h 2022-06-15 23:53:00.818758185 +0300 -@@ -78,6 +78,7 @@ struct DefaultJitOptions - bool ionInterruptWithoutSignals; - bool simulatorAlwaysInterrupt; - uint32_t baselineWarmUpThreshold; -+ uint32_t regexpWarmUpThreshold; - uint32_t exceptionBailoutThreshold; - uint32_t frequentBailoutThreshold; - uint32_t maxStackArgs; -diff -Nrup mozilla/js/src/jit/MCallOptimize.cpp mozilla-OK/js/src/jit/MCallOptimize.cpp ---- mozilla/js/src/jit/MCallOptimize.cpp 2022-01-25 01:04:29.000000000 +0300 -+++ mozilla-OK/js/src/jit/MCallOptimize.cpp 2022-06-15 23:27:12.208259907 +0300 -@@ -26,6 +26,7 @@ - #include "jit/Lowering.h" - #include "jit/MIR.h" - #include "jit/MIRGraph.h" -+#include "js/RegExpFlags.h" - #include "vm/ArgumentsObject.h" - #include "vm/ProxyObject.h" - #include "vm/SelfHosting.h" -@@ -42,6 +43,8 @@ using mozilla::ArrayLength; - using mozilla::AssertedCast; - - using JS::DoubleNaNValue; -+using JS::RegExpFlag; -+using JS::RegExpFlags; - using JS::TrackedOutcome; - using JS::TrackedStrategy; - using JS::TrackedTypeSite; -@@ -224,6 +227,8 @@ IonBuilder::inlineNativeCall(CallInfo& c - return inlineRegExpInstanceOptimizable(callInfo); - case InlinableNative::GetFirstDollarIndex: - return inlineGetFirstDollarIndex(callInfo); -+ case InlinableNative::IntrinsicNewRegExpStringIterator: -+ return inlineNewIterator(callInfo, MNewIterator::RegExpStringIterator); - - // String natives. - case InlinableNative::String: -@@ -328,6 +333,8 @@ IonBuilder::inlineNativeCall(CallInfo& c - return inlineHasClass(callInfo, &SetIteratorObject::class_); - case InlinableNative::IntrinsicIsStringIterator: - return inlineHasClass(callInfo, &StringIteratorObject::class_); -+ case InlinableNative::IntrinsicGuardToRegExpStringIterator: -+ return inlineHasClass(callInfo, &RegExpStringIteratorObject::class_); - case InlinableNative::IntrinsicObjectHasPrototype: - return inlineObjectHasPrototype(callInfo); - case InlinableNative::IntrinsicFinishBoundFunctionInit: -@@ -426,7 +433,7 @@ IonBuilder::inlineNativeGetter(CallInfo& - } - - // Try to optimize RegExp getters. -- RegExpFlag mask = NoFlags; -+ RegExpFlags mask = RegExpFlag::NoFlags; - if (RegExpObject::isOriginalFlagGetter(native, &mask)) { - const Class* clasp = thisTypes->getKnownClass(constraints()); - if (clasp != &RegExpObject::class_) -@@ -435,7 +442,7 @@ IonBuilder::inlineNativeGetter(CallInfo& - MLoadFixedSlot* flags = MLoadFixedSlot::New(alloc(), thisArg, RegExpObject::flagsSlot()); - current->add(flags); - flags->setResultType(MIRType::Int32); -- MConstant* maskConst = MConstant::New(alloc(), Int32Value(mask)); -+ MConstant* maskConst = MConstant::New(alloc(), Int32Value(mask.value())); - current->add(maskConst); - MBitAnd* maskedFlag = MBitAnd::New(alloc(), flags, maskConst); - maskedFlag->setInt32Specialization(); -@@ -1026,6 +1033,10 @@ IonBuilder::inlineNewIterator(CallInfo& - templateObject = inspector->getTemplateObjectForNative(pc, js::intrinsic_NewStringIterator); - MOZ_ASSERT_IF(templateObject, templateObject->is()); - break; -+ case MNewIterator::RegExpStringIterator: -+ templateObject = inspector->getTemplateObjectForNative(pc, js::intrinsic_NewRegExpStringIterator); -+ MOZ_ASSERT_IF(templateObject, templateObject->is()); -+ break; - } - - if (!templateObject) -diff -Nrup mozilla/js/src/jit/MIR.h mozilla-OK/js/src/jit/MIR.h ---- mozilla/js/src/jit/MIR.h 2022-04-13 21:14:22.000000000 +0300 -+++ mozilla-OK/js/src/jit/MIR.h 2022-06-15 23:27:12.211259887 +0300 -@@ -3608,6 +3608,7 @@ class MNewIterator - enum Type { - ArrayIterator, - StringIterator, -+ RegExpStringIterator, - }; - - private: -diff -Nrup mozilla/js/src/jit/MacroAssembler.h mozilla-OK/js/src/jit/MacroAssembler.h ---- mozilla/js/src/jit/MacroAssembler.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/MacroAssembler.h 2022-06-16 00:07:27.344875576 +0300 -@@ -2241,6 +2241,20 @@ class MacroAssembler : public MacroAssem - inline void assertStackAlignment(uint32_t alignment, int32_t offset = 0); - }; - -+// StackMacroAssembler checks no GC will happen while it's on the stack. -+class MOZ_RAII StackMacroAssembler : public MacroAssembler -+{ -+ JS::AutoCheckCannotGC nogc; -+ -+ public: -+ StackMacroAssembler() -+ : MacroAssembler() -+ {} -+ explicit StackMacroAssembler(JSContext* cx) -+ : MacroAssembler(cx) -+ {} -+}; -+ - //{{{ check_macroassembler_style - inline uint32_t - MacroAssembler::framePushed() const -diff -Nrup mozilla/js/src/jit/Recover.cpp mozilla-OK/js/src/jit/Recover.cpp ---- mozilla/js/src/jit/Recover.cpp 2021-03-01 21:17:56.000000000 +0300 -+++ mozilla-OK/js/src/jit/Recover.cpp 2022-06-15 23:27:12.212259880 +0300 -@@ -1396,6 +1396,9 @@ RNewIterator::recover(JSContext* cx, Sna - case MNewIterator::StringIterator: - resultObject = NewStringIteratorObject(cx); - break; -+ case MNewIterator::RegExpStringIterator: -+ resultObject = NewRegExpStringIteratorObject(cx); -+ break; - } - - if (!resultObject) -diff -Nrup mozilla/js/src/jit/VMFunctions.h mozilla-OK/js/src/jit/VMFunctions.h ---- mozilla/js/src/jit/VMFunctions.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/VMFunctions.h 2022-06-15 23:27:12.213259873 +0300 -@@ -290,6 +290,7 @@ template <> struct TypeToDataType struct TypeToDataType { static const DataType result = Type_Object; }; - template <> struct TypeToDataType { static const DataType result = Type_Object; }; - template <> struct TypeToDataType { static const DataType result = Type_Object; }; -+template <> struct TypeToDataType{ static const DataType result = Type_Object; }; - template <> struct TypeToDataType { static const DataType result = Type_Object; }; - template <> struct TypeToDataType { static const DataType result = Type_Object; }; - template <> struct TypeToDataType { static const DataType result = Type_Handle; }; -diff -Nrup mozilla/js/src/jit/arm64/Assembler-arm64.h mozilla-OK/js/src/jit/arm64/Assembler-arm64.h ---- mozilla/js/src/jit/arm64/Assembler-arm64.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jit/arm64/Assembler-arm64.h 2022-06-15 23:53:00.818758185 +0300 -@@ -71,9 +71,6 @@ static constexpr Register PseudoStackPoi - static constexpr ARMRegister PseudoStackPointer64 = { Registers::x28, 64 }; - static constexpr ARMRegister PseudoStackPointer32 = { Registers::x28, 32 }; - --// StackPointer for use by irregexp. --static constexpr Register RegExpStackPointer = PseudoStackPointer; -- - static constexpr Register IntArgReg0 { Registers::x0 }; - static constexpr Register IntArgReg1 { Registers::x1 }; - static constexpr Register IntArgReg2 { Registers::x2 }; -diff -Nrup mozilla/js/src/jit-test/lib/regexp_parse.js mozilla-OK/js/src/jit-test/lib/regexp_parse.js ---- mozilla/js/src/jit-test/lib/regexp_parse.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/lib/regexp_parse.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,205 +0,0 @@ --load(libdir + "asserts.js"); -- --// helper functions -- --function Disjunction(alternatives) { -- return{ -- type: "Disjunction", -- alternatives: alternatives -- }; --} -- --function Alternative(nodes) { -- return { -- type: "Alternative", -- nodes: nodes -- }; --} -- --function Empty() { -- return { -- type: "Empty" -- }; --} -- --function Text(elements) { -- return { -- type: "Text", -- elements: elements -- }; --} -- --function Assertion(type) { -- return { -- type: "Assertion", -- assertion_type: type -- }; --} -- --function Atom(data) { -- return { -- type: "Atom", -- data: data -- }; --} -- --const kInfinity = 0x7FFFFFFF; --function Quantifier(min, max, type, body) { -- return { -- type: "Quantifier", -- min: min, -- max: max, -- quantifier_type: type, -- body: body -- }; --} -- --function Lookahead(body) { -- return { -- type: "Lookahead", -- is_positive: true, -- body: body -- }; --} -- --function NegativeLookahead(body) { -- return { -- type: "Lookahead", -- is_positive: false, -- body: body -- }; --} -- --function BackReference(index) { -- return { -- type: "BackReference", -- index: index -- }; --} -- --function CharacterClass(ranges) { -- return { -- type: "CharacterClass", -- is_negated: false, -- ranges: ranges.map(([from, to]) => ({ from ,to })) -- }; --} -- --function NegativeCharacterClass(ranges) { -- return { -- type: "CharacterClass", -- is_negated: true, -- ranges: ranges.map(([from, to]) => ({ from ,to })) -- }; --} -- --function Capture(index, body) { -- return { -- type: "Capture", -- index: index, -- body: body -- }; --} -- --function AllSurrogateAndCharacterClass(ranges) { -- return Disjunction([ -- CharacterClass(ranges), -- Alternative([ -- CharacterClass([["\uD800", "\uDBFF"]]), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- CharacterClass([["\uDC00", "\uDFFF"]]) -- ]), -- Text([ -- CharacterClass([["\uD800", "\uDBFF"]]), -- CharacterClass([["\uDC00", "\uDFFF"]]) -- ]) -- ]); --} -- --// testing functions -- --var all_flags = [ -- "", -- "i", -- "m", -- "u", -- "im", -- "iu", -- "mu", -- "imu", --]; -- --var no_unicode_flags = [ -- "", -- "i", -- "m", -- "im", --]; -- --var unicode_flags = [ -- "u", -- "iu", -- "mu", -- "imu", --]; -- --var no_multiline_flags = [ -- "", -- "i", -- "u", -- "iu", --]; -- --var multiline_flags = [ -- "m", -- "im", -- "mu", -- "imu", --]; -- --function test_flags(pattern, flags, match_only, expected) { -- for (var flag of flags) { -- assertDeepEq(parseRegExp(pattern, flag, match_only), expected); -- } --} -- --function make_mix(tree) { -- if (tree.type == "Atom") { -- return Atom("X" + tree.data + "Y"); -- } -- if (tree.type == "CharacterClass") { -- return Text([ -- Atom("X"), -- tree, -- Atom("Y") -- ]); -- } -- if (tree.type == "Alternative") { -- return Alternative([ -- Atom("X"), -- ...tree.nodes, -- Atom("Y") -- ]); -- } -- return Alternative([ -- Atom("X"), -- tree, -- Atom("Y") -- ]); --} -- --function test_mix(pattern, flags, expected) { -- test_flags(pattern, flags, false, expected); -- test_flags("X" + pattern + "Y", flags, false, make_mix(expected)); --} -- --function test(pattern, flags, expected) { -- test_flags(pattern, flags, false, expected); --} -- --function test_match_only(pattern, flags, expected) { -- test_flags(pattern, flags, true, expected); --} -diff -Nrup mozilla/js/src/jit-test/tests/regexp/bug1640479.js mozilla-OK/js/src/jit-test/tests/regexp/bug1640479.js ---- mozilla/js/src/jit-test/tests/regexp/bug1640479.js 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp/bug1640479.js 2022-06-15 23:12:21.057293201 +0300 -@@ -0,0 +1,15 @@ -+// |jit-test| skip-if: !('oomTest' in this) -+ -+var failures = 0; -+var i = 0; -+ -+function foo() { -+ var e; -+ var r = RegExp("(?<_" + (i++) + "a>)"); -+ try { e = r.exec("a"); } catch {} -+ e = r.exec("a"); -+ if (e.groups === undefined) failures++; -+} -+ -+oomTest(foo); -+assertEq(failures, 0); -diff -Nrup mozilla/js/src/jit-test/tests/regexp/huge-02.js mozilla-OK/js/src/jit-test/tests/regexp/huge-02.js ---- mozilla/js/src/jit-test/tests/regexp/huge-02.js 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp/huge-02.js 2022-06-15 23:01:05.392864572 +0300 -@@ -0,0 +1,13 @@ -+var interestingCaptureNums = [(1 << 14), -+ (1 << 15) - 1, -+ (1 << 15), -+ (1 << 15) + 1, -+ (1 << 16)] -+ -+for (let i of interestingCaptureNums) { -+ print(i); -+ try { -+ var source = Array(i).join("(") + "a" + Array(i).join(")"); -+ RegExp(source).exec("a"); -+ } catch {} -+} -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Assertion.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Assertion.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Assertion.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Assertion.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,20 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("^", no_multiline_flags, -- Assertion("START_OF_INPUT")); --test_mix("^", multiline_flags, -- Assertion("START_OF_LINE")); -- --test_mix("$", no_multiline_flags, -- Assertion("END_OF_INPUT")); --test_mix("$", multiline_flags, -- Assertion("END_OF_LINE")); -- --test_mix("\\b", all_flags, -- Assertion("BOUNDARY")); -- --test_mix("\\B", all_flags, -- Assertion("NON_BOUNDARY")); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,54 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("a", all_flags, -- Atom("a")); --test_mix("abc\u3042\u3044\u3046", all_flags, -- Atom("abc\u3042\u3044\u3046")); -- --// raw brace -- --test("{", no_unicode_flags, -- Atom("{")); --test("{a", no_unicode_flags, -- Atom("{a")); --test("a{b", no_unicode_flags, -- Atom("a{b")); -- --test("}", no_unicode_flags, -- Atom("}")); --test("}a", no_unicode_flags, -- Atom("}a")); --test("a}b", no_unicode_flags, -- Atom("a}b")); -- --// raw surrogate pair -- --test("X\uD83D\uDC38Y", unicode_flags, -- Text([ -- Atom("X"), -- Atom("\uD83D\uDC38"), -- Atom("Y") -- ])); -- --test("X\uD83DY", unicode_flags, -- Alternative([ -- Atom("X"), -- Alternative([ -- Atom("\uD83D"), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]), -- Atom("Y") -- ])); -- --test("X\uDC38Y", unicode_flags, -- Alternative([ -- Atom("X"), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- Atom("\uDC38"), -- ]), -- Atom("Y") -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,115 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("\\d", all_flags, -- CharacterClass([["0", "9"]])); -- --test_mix("\\D", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "/"], -- [":", "\uFFFF"] -- ])); --test_mix("\\D", unicode_flags, -- AllSurrogateAndCharacterClass([ -- ["\u0000", "/"], -- [":", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); -- --test_mix("\\s", all_flags, -- CharacterClass([ -- ["\t", "\r"], -- [" ", " "], -- ["\u00A0", "\u00A0"], -- ["\u1680", "\u1680"], -- ["\u2000", "\u200A"], -- ["\u2028", "\u2029"], -- ["\u202F", "\u202F"], -- ["\u205F", "\u205F"], -- ["\u3000", "\u3000"], -- ["\uFEFF", "\uFEFF"] -- ])); --test_mix("\\S", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "\u0008"], -- ["\u000E", "\u001F"], -- ["!", "\u009F"], -- ["\u00A1", "\u167F"], -- ["\u1681", "\u1FFF"], -- ["\u200B", "\u2027"], -- ["\u202A", "\u202E"], -- ["\u2030", "\u205E"], -- ["\u2060", "\u2FFF"], -- ["\u3001", "\uFEFE"], -- ["\uFF00", "\uFFFF"] -- ])); --test_mix("\\S", unicode_flags, -- AllSurrogateAndCharacterClass([ -- ["\u0000", "\u0008"], -- ["\u000E", "\u001F"], -- ["!", "\u009F"], -- ["\u00A1", "\u167F"], -- ["\u1681", "\u1FFF"], -- ["\u200B", "\u2027"], -- ["\u202A", "\u202E"], -- ["\u2030", "\u205E"], -- ["\u2060", "\u2FFF"], -- ["\u3001", "\uD7FF"], -- ["\uE000", "\uFEFE"], -- ["\uFF00", "\uFFFF"] -- ])); -- --test_mix("\\w", no_unicode_flags, -- CharacterClass([ -- ["0", "9"], -- ["A", "Z"], -- ["_", "_"], -- ["a", "z"] -- ])); --test_mix("\\w", ["u", "mu"], -- CharacterClass([ -- ["0", "9"], -- ["A", "Z"], -- ["_", "_"], -- ["a", "z"] -- ])); --test_mix("\\w", ["iu", "imu"], -- CharacterClass([ -- ["0", "9"], -- ["A", "Z"], -- ["_", "_"], -- ["a", "z"], -- ["\u017F", "\u017F"], -- ["\u212A", "\u212A"] -- ])); -- --test_mix("\\W", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "/"], -- [":", "@"], -- ["[", "^"], -- ["`", "`"], -- ["{", "\uFFFF"] -- ])); --test_mix("\\W", ["u", "mu"], -- AllSurrogateAndCharacterClass([ -- ["\u0000", "/"], -- [":", "@"], -- ["[", "^"], -- ["`", "`"], -- ["{", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); --test_mix("\\W", ["iu", "imu"], -- AllSurrogateAndCharacterClass([ -- ["\u0000", "/"], -- [":", "@"], -- ["[", "^"], -- ["`", "`"], -- ["{", "\u017E"], -- ["\u0180", "\u2129"], -- ["\u212B", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,19 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("\\f", all_flags, -- Atom("\u000c")); -- --test_mix("\\n", all_flags, -- Atom("\u000a")); -- --test_mix("\\r", all_flags, -- Atom("\u000d")); -- --test_mix("\\t", all_flags, -- Atom("\u0009")); -- --test_mix("\\v", all_flags, -- Atom("\u000b")); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,13 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("\\ca", all_flags, -- Atom("\u0001")); --test_mix("\\cz", all_flags, -- Atom("\u001a")); --test_mix("\\cA", all_flags, -- Atom("\u0001")); --test_mix("\\cZ", all_flags, -- Atom("\u001a")); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,87 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --// LegacyOctalEscapeSequence -- --test_mix("\\1", no_unicode_flags, -- Atom("\u0001")); --test_mix("\\2", no_unicode_flags, -- Atom("\u0002")); --test_mix("\\3", no_unicode_flags, -- Atom("\u0003")); --test_mix("\\4", no_unicode_flags, -- Atom("\u0004")); --test_mix("\\5", no_unicode_flags, -- Atom("\u0005")); --test_mix("\\6", no_unicode_flags, -- Atom("\u0006")); --test_mix("\\7", no_unicode_flags, -- Atom("\u0007")); --test_mix("\\8", no_unicode_flags, -- Atom("8")); --test_mix("\\9", no_unicode_flags, -- Atom("9")); -- --test_mix("\\10", no_unicode_flags, -- Atom("\u0008")); --test_mix("\\11", no_unicode_flags, -- Atom("\u0009")); -- --test_mix("\\189", no_unicode_flags, -- Atom("\u{0001}89")); --test_mix("\\1089", no_unicode_flags, -- Atom("\u{0008}89")); --test_mix("\\10189", no_unicode_flags, -- Atom("A89")); --test_mix("\\101189", no_unicode_flags, -- Atom("A189")); -- --// BackReference -- --test_mix("()\\1", no_unicode_flags, -- Alternative([ -- Capture(1, Empty()), -- BackReference(1) -- ])); --test_mix("()\\1", unicode_flags, -- Alternative([ -- Capture(1, Empty()), -- Alternative([ -- BackReference(1), -- Assertion("NOT_IN_SURROGATE_PAIR") -- ]) -- ])); -- --test_mix("()()()()()()()()()()\\10", no_unicode_flags, -- Alternative([ -- Capture(1, Empty()), -- Capture(2, Empty()), -- Capture(3, Empty()), -- Capture(4, Empty()), -- Capture(5, Empty()), -- Capture(6, Empty()), -- Capture(7, Empty()), -- Capture(8, Empty()), -- Capture(9, Empty()), -- Capture(10, Empty()), -- BackReference(10) -- ])); --test_mix("()()()()()()()()()()\\10", unicode_flags, -- Alternative([ -- Capture(1, Empty()), -- Capture(2, Empty()), -- Capture(3, Empty()), -- Capture(4, Empty()), -- Capture(5, Empty()), -- Capture(6, Empty()), -- Capture(7, Empty()), -- Capture(8, Empty()), -- Capture(9, Empty()), -- Capture(10, Empty()), -- Alternative([ -- BackReference(10), -- Assertion("NOT_IN_SURROGATE_PAIR") -- ]) -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,19 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("\\x00", all_flags, -- Atom("\u0000")); --test_mix("\\xFF", all_flags, -- Atom("\u00FF")); -- --test_mix("\\x0", no_unicode_flags, -- Atom("x0")); --test_mix("\\x000", all_flags, -- Atom("\u{0000}0")); -- --test_mix("\\xG", no_unicode_flags, -- Atom("xG")); --test_mix("\\x0G", no_unicode_flags, -- Atom("x0G")); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,55 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --// SyntaxCharacter -- --test("\\^", all_flags, -- Atom("^")); --test("\\$", all_flags, -- Atom("$")); --test("\\\\", all_flags, -- Atom("\\")); --test("\\.", all_flags, -- Atom(".")); --test("\\*", all_flags, -- Atom("*")); --test("\\+", all_flags, -- Atom("+")); --test("\\?", all_flags, -- Atom("?")); --test("\\(", all_flags, -- Atom("(")); --test("\\)", all_flags, -- Atom(")")); --test("\\[", all_flags, -- Atom("[")); --test("\\]", all_flags, -- Atom("]")); --test("\\{", all_flags, -- Atom("{")); --test("\\}", all_flags, -- Atom("}")); --test("\\|", all_flags, -- Atom("|")); -- --// Slash -- --test("\\/", all_flags, -- Atom("/")); -- --// SourceCharacter -- --test("\\P", no_unicode_flags, -- Atom("P")); -- --test("\\uX", no_unicode_flags, -- Atom("uX")); -- --test("\\u{0000}", no_unicode_flags, -- Quantifier(0, 0, "GREEDY", Atom("u"))); -- --test("\\c_", no_unicode_flags, -- Atom("\\c_")); -- -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_Null.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_Null.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_Null.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_Null.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,7 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("\\0", all_flags, -- Atom("\u0000")); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,108 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --// LeadSurrogate TrailSurrogate -- --test("\\uD83D\\uDC38", all_flags, -- Atom("\uD83D\uDC38")); --test("X\\uD83D\\uDC38Y", no_unicode_flags, -- Atom("X\uD83D\uDC38Y")); --test("X\\uD83D\\uDC38Y", unicode_flags, -- Text([ -- Atom("X"), -- Atom("\uD83D\uDC38"), -- Atom("Y") -- ])); -- --// LeadSurrogate -- --test_mix("\\uD83D", no_unicode_flags, -- Atom("\uD83D")); --test("\\uD83D", unicode_flags, -- Alternative([ -- Atom("\uD83D"), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ])); --test("X\\uD83DY", unicode_flags, -- Alternative([ -- Atom("X"), -- Alternative([ -- Atom("\uD83D"), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]), -- Atom("Y") -- ])); -- --// TrailSurrogate -- --test_mix("\\uDC38", no_unicode_flags, -- Atom("\uDC38")); --test("\\uDC38", unicode_flags, -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- Atom("\uDC38"), -- ])); --test("X\\uDC38Y", unicode_flags, -- Alternative([ -- Atom("X"), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- Atom("\uDC38"), -- ]), -- Atom("Y") -- ])); -- --// NonSurrogate / Hex4Digits -- --test_mix("\\u0000", all_flags, -- Atom("\u0000")); --test_mix("\\uFFFF", all_flags, -- Atom("\uFFFF")); -- --// braced HexDigits -- --test_mix("\\u{0000}", unicode_flags, -- Atom("\u0000")); --test_mix("\\u{FFFF}", unicode_flags, -- Atom("\uFFFF")); -- --test("\\u{1F438}", unicode_flags, -- Atom("\uD83D\uDC38")); --test("X\\u{1F438}Y", unicode_flags, -- Text([ -- Atom("X"), -- Atom("\uD83D\uDC38"), -- Atom("Y") -- ])); -- --test("\\u{D83D}", unicode_flags, -- Alternative([ -- Atom("\uD83D"), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ])); --test("X\\u{D83D}Y", unicode_flags, -- Alternative([ -- Atom("X"), -- Alternative([ -- Atom("\uD83D"), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]), -- Atom("Y") -- ])); -- --test("\\u{DC38}", unicode_flags, -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- Atom("\uDC38"), -- ])); --test("X\\u{DC38}Y", unicode_flags, -- Alternative([ -- Atom("X"), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- Atom("\uDC38"), -- ]), -- Atom("Y") -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Capture.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Capture.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Capture.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Capture.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,21 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("()", all_flags, -- Capture(1, Empty())); -- --test("(a)", all_flags, -- Capture(1, Atom("a"))); -- --test("((a()b))c(d)", all_flags, -- Alternative([ -- Capture(1, Capture(2, Alternative([ -- Atom("a"), -- Capture(3, Empty()), -- Atom("b") -- ]))), -- Atom("c"), -- Capture(4, Atom("d")) -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,74 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("[]", all_flags, -- NegativeCharacterClass([ -- ["\u0000", "\uFFFF"] -- ])); -- --test("[a]", all_flags, -- CharacterClass([ -- ["a", "a"] -- ])); -- --test("[abc\u3042\u3044\u3046]", all_flags, -- CharacterClass([ -- ["a", "a"], -- ["b", "b"], -- ["c", "c"], -- ["\u3042", "\u3042"], -- ["\u3044", "\u3044"], -- ["\u3046", "\u3046"], -- ])); -- --test("[a-c\u3042-\u3046]", all_flags, -- CharacterClass([ -- ["a", "c"], -- ["\u3042", "\u3046"] -- ])); -- --test("[-]", all_flags, -- CharacterClass([ -- ["-", "-"] -- ])); -- --// raw surrogate pair -- --test("[X\uD83D\uDC38Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"], -- ]), -- Atom("\uD83D\uDC38") -- ])); -- --test("[X\uD83DY]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"] -- ]), -- Alternative([ -- CharacterClass([ -- ["\uD83D", "\uD83D"] -- ]), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]) -- ])); -- --test("[X\uDC38Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"] -- ]), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- CharacterClass([ -- ["\uDC38", "\uDC38"] -- ]) -- ]) -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,115 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("[\\d]", all_flags, -- CharacterClass([["0", "9"]])); -- --test("[\\D]", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "/"], -- [":", "\uFFFF"] -- ])); --test("[\\D]", unicode_flags, -- AllSurrogateAndCharacterClass([ -- ["\u0000", "/"], -- [":", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); -- --test("[\\s]", all_flags, -- CharacterClass([ -- ["\t", "\r"], -- [" ", " "], -- ["\u00A0", "\u00A0"], -- ["\u1680", "\u1680"], -- ["\u2000", "\u200A"], -- ["\u2028", "\u2029"], -- ["\u202F", "\u202F"], -- ["\u205F", "\u205F"], -- ["\u3000", "\u3000"], -- ["\uFEFF", "\uFEFF"] -- ])); --test("[\\S]", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "\u0008"], -- ["\u000E", "\u001F"], -- ["!", "\u009F"], -- ["\u00A1", "\u167F"], -- ["\u1681", "\u1FFF"], -- ["\u200B", "\u2027"], -- ["\u202A", "\u202E"], -- ["\u2030", "\u205E"], -- ["\u2060", "\u2FFF"], -- ["\u3001", "\uFEFE"], -- ["\uFF00", "\uFFFF"] -- ])); --test("[\\S]", unicode_flags, -- AllSurrogateAndCharacterClass([ -- ["\u0000", "\u0008"], -- ["\u000E", "\u001F"], -- ["!", "\u009F"], -- ["\u00A1", "\u167F"], -- ["\u1681", "\u1FFF"], -- ["\u200B", "\u2027"], -- ["\u202A", "\u202E"], -- ["\u2030", "\u205E"], -- ["\u2060", "\u2FFF"], -- ["\u3001", "\uD7FF"], -- ["\uE000", "\uFEFE"], -- ["\uFF00", "\uFFFF"] -- ])); -- --test("[\\w]", no_unicode_flags, -- CharacterClass([ -- ["0", "9"], -- ["A", "Z"], -- ["_", "_"], -- ["a", "z"] -- ])); --test("[\\w]", ["u", "mu"], -- CharacterClass([ -- ["0", "9"], -- ["A", "Z"], -- ["_", "_"], -- ["a", "z"] -- ])); --test("[\\w]", ["iu", "imu"], -- CharacterClass([ -- ["0", "9"], -- ["A", "Z"], -- ["_", "_"], -- ["a", "z"], -- ["\u017F", "\u017F"], -- ["\u212A", "\u212A"] -- ])); -- --test("[\\W]", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "/"], -- [":", "@"], -- ["[", "^"], -- ["`", "`"], -- ["{", "\uFFFF"] -- ])); --test("[\\W]", ["u", "mu"], -- AllSurrogateAndCharacterClass([ -- ["\u0000", "/"], -- [":", "@"], -- ["[", "^"], -- ["`", "`"], -- ["{", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); --test("[\\W]", ["iu", "imu"], -- AllSurrogateAndCharacterClass([ -- ["\u0000", "/"], -- [":", "@"], -- ["[", "^"], -- ["`", "`"], -- ["{", "\u017E"], -- ["\u0180", "\u2129"], -- ["\u212B", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,13 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("[\b]", all_flags, -- CharacterClass([ -- ["\u0008", "\u0008"] -- ])); --test("[\-]", all_flags, -- CharacterClass([ -- ["-", "-"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,29 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("[\\f]", all_flags, -- CharacterClass([ -- ["\u000c", "\u000c"] -- ])); -- --test("[\\n]", all_flags, -- CharacterClass([ -- ["\u000a", "\u000a"] -- ])); -- --test("[\\r]", all_flags, -- CharacterClass([ -- ["\u000d", "\u000d"] -- ])); -- --test("[\\t]", all_flags, -- CharacterClass([ -- ["\u0009", "\u0009"] -- ])); -- --test("[\\v]", all_flags, -- CharacterClass([ -- ["\u000b", "\u000b"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,35 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("[\\ca]", all_flags, -- CharacterClass([ -- ["\u0001", "\u0001"] -- ])); --test("[\\cz]", all_flags, -- CharacterClass([ -- ["\u001a", "\u001a"] -- ])); --test("[\\cA]", all_flags, -- CharacterClass([ -- ["\u0001", "\u0001"] -- ])); --test("[\\cZ]", all_flags, -- CharacterClass([ -- ["\u001a", "\u001a"] -- ])); -- --// Invalid -- --test("[\\c]", no_unicode_flags, -- CharacterClass([ -- ["\\", "\\"], -- ["c", "c"] -- ])); --test("[\\c=]", no_unicode_flags, -- CharacterClass([ -- ["\\", "\\"], -- ["c", "c"], -- ["=", "="] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,39 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("[\\x00]", all_flags, -- CharacterClass([ -- ["\u0000", "\u0000"] -- ])); --test("[\\xff]", all_flags, -- CharacterClass([ -- ["\u00FF", "\u00FF"] -- ])); -- --// Invalid -- --test("[\\x]", no_unicode_flags, -- CharacterClass([ -- ["x", "x"] -- ])); -- --test("[\\xG]", no_unicode_flags, -- CharacterClass([ -- ["x", "x"], -- ["G", "G"] -- ])); -- --test("[\\x0]", no_unicode_flags, -- CharacterClass([ -- ["x", "x"], -- ["0", "0"] -- ])); -- --test("[\\x0G]", no_unicode_flags, -- CharacterClass([ -- ["x", "x"], -- ["0", "0"], -- ["G", "G"], -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,9 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("[\\0]", all_flags, -- CharacterClass([ -- ["\u0000", "\u0000"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js ---- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,162 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --// LeadSurrogate TrailSurrogate -- --test("[X\\uD83D\\uDC38Y]", no_unicode_flags, -- CharacterClass([ -- ["X", "X"], -- ["\uD83D", "\uD83D"], -- ["\uDC38", "\uDC38"], -- ["Y", "Y"] -- ])); --test("[X\\uD83D\\uDC38Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"], -- ]), -- Atom("\uD83D\uDC38") -- ])); -- --// LeadSurrogate -- --test("[X\\uD83DY]", no_unicode_flags, -- CharacterClass([ -- ["X", "X"], -- ["\uD83D", "\uD83D"], -- ["Y", "Y"] -- ])); --test("[X\\uD83DY]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"] -- ]), -- Alternative([ -- CharacterClass([ -- ["\uD83D", "\uD83D"] -- ]), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]) -- ])); -- --// TrailSurrogate -- --test("[X\\uDC38Y]", no_unicode_flags, -- CharacterClass([ -- ["X", "X"], -- ["\uDC38", "\uDC38"], -- ["Y", "Y"] -- ])); --test("[X\\uDC38Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"] -- ]), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- CharacterClass([ -- ["\uDC38", "\uDC38"] -- ]) -- ]) -- ])); -- --// NonSurrogate / Hex4Digits -- --test("[X\\u0000Y]", all_flags, -- CharacterClass([ -- ["X", "X"], -- ["\u0000", "\u0000"], -- ["Y", "Y"] -- ])); --test("[X\\uFFFFY]", all_flags, -- CharacterClass([ -- ["X", "X"], -- ["\uFFFF", "\uFFFF"], -- ["Y", "Y"] -- ])); -- --// braced HexDigits -- --test("[X\\u{0000}Y]", unicode_flags, -- CharacterClass([ -- ["X", "X"], -- ["\u0000", "\u0000"], -- ["Y", "Y"] -- ])); --test("[X\\uFFFFY]", unicode_flags, -- CharacterClass([ -- ["X", "X"], -- ["\uFFFF", "\uFFFF"], -- ["Y", "Y"] -- ])); -- --test("[X\\u{1F438}Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"], -- ]), -- Atom("\uD83D\uDC38") -- ])); -- --test("[X\\u{D83D}Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"] -- ]), -- Alternative([ -- CharacterClass([ -- ["\uD83D", "\uD83D"] -- ]), -- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) -- ]) -- ])); --test("[X\\u{DC38}Y]", unicode_flags, -- Disjunction([ -- CharacterClass([ -- ["X", "X"], -- ["Y", "Y"] -- ]), -- Alternative([ -- Assertion("NOT_AFTER_LEAD_SURROGATE"), -- CharacterClass([ -- ["\uDC38", "\uDC38"] -- ]) -- ]) -- ])); -- --// Invalid -- --test("[\\u]", no_unicode_flags, -- CharacterClass([ -- ["u", "u"] -- ])); -- --test("[\\uG]", no_unicode_flags, -- CharacterClass([ -- ["u", "u"], -- ["G", "G"] -- ])); -- --test("[\\uD83]", no_unicode_flags, -- CharacterClass([ -- ["u", "u"], -- ["D", "D"], -- ["8", "8"], -- ["3", "3"] -- ])); -- --test("[\\uD83G]", no_unicode_flags, -- CharacterClass([ -- ["u", "u"], -- ["D", "D"], -- ["8", "8"], -- ["3", "3"], -- ["G", "G"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Disjunction.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Disjunction.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Disjunction.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Disjunction.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,42 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("a|\u3042", all_flags, -- Disjunction([ -- Atom("a"), -- Atom("\u3042") -- ])); -- --test("a|\u3042|abc", all_flags, -- Disjunction([ -- Atom("a"), -- Atom("\u3042"), -- Atom("abc") -- ])); -- --test("|", all_flags, -- Disjunction([ -- Empty(), -- Empty() -- ])); -- --test("||", all_flags, -- Disjunction([ -- Empty(), -- Empty(), -- Empty() -- ])); -- --test("abc|", all_flags, -- Disjunction([ -- Atom("abc"), -- Empty() -- ])); -- --test("|abc", all_flags, -- Disjunction([ -- Empty(), -- Atom("abc") -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Empty.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Empty.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Empty.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Empty.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,7 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("", all_flags, -- Empty()); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Everything.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Everything.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Everything.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Everything.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,21 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix(".", no_unicode_flags, -- CharacterClass([ -- ["\u0000", "\u0009"], -- ["\u000b", "\u000c"], -- ["\u000e", "\u2027"], -- ["\u202A", "\uFFFF"] -- ])); -- --test_mix(".", unicode_flags, -- AllSurrogateAndCharacterClass([ -- ["\u0000", "\u0009"], -- ["\u000b", "\u000c"], -- ["\u000e", "\u2027"], -- ["\u202A", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Group.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Group.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Group.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Group.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,15 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test("(?:)", all_flags, -- Empty()); --test("(?:a)", all_flags, -- Atom("a")); --test("X(?:a)Y", all_flags, -- Text([ -- Atom("X"), -- Atom("a"), -- Atom("Y") -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Lookahead.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Lookahead.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Lookahead.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Lookahead.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,31 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("(?=abc)", all_flags, -- Lookahead(Atom("abc"))); -- --test_mix("(?!abc)", all_flags, -- NegativeLookahead(Atom("abc"))); -- --test_mix("(?=abc)+", no_unicode_flags, -- Lookahead(Atom("abc"))); -- --// Lookahead becomes Empty because max_match of Lookahead is 0 and the min vaue --// of Quantifier is also 0. --test("(?=abc)*", no_unicode_flags, -- Empty()); --test("X(?=abc)*Y", no_unicode_flags, -- Alternative([ -- Atom("X"), -- Atom("Y"), -- ])); -- --test("(?=abc)?", no_unicode_flags, -- Empty()); --test("X(?=abc)?Y", no_unicode_flags, -- Alternative([ -- Atom("X"), -- Atom("Y"), -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/MatchOnly.js mozilla-OK/js/src/jit-test/tests/regexp_parse/MatchOnly.js ---- mozilla/js/src/jit-test/tests/regexp_parse/MatchOnly.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/MatchOnly.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,35 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --// Leading and trailing .* are ignored if match_only==true. -- --test_match_only(".*abc", all_flags, -- Atom("abc")); --test_match_only("abc.*", all_flags, -- Atom("abc")); -- --test_match_only(".*?abc", no_unicode_flags, -- Alternative([ -- Quantifier(0, kInfinity, "NON_GREEDY", -- CharacterClass([ -- ["\u0000", "\u0009"], -- ["\u000b", "\u000c"], -- ["\u000e", "\u2027"], -- ["\u202A", "\uFFFF"] -- ])), -- Atom("abc") -- ])); --test_match_only(".*?abc", unicode_flags, -- Alternative([ -- Quantifier(0, kInfinity, "NON_GREEDY", -- AllSurrogateAndCharacterClass([ -- ["\u0000", "\u0009"], -- ["\u000b", "\u000c"], -- ["\u000e", "\u2027"], -- ["\u202A", "\uD7FF"], -- ["\uE000", "\uFFFF"] -- ])), -- Atom("abc") -- ])); -diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Quantifier.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Quantifier.js ---- mozilla/js/src/jit-test/tests/regexp_parse/Quantifier.js 2020-02-18 02:37:52.000000000 +0300 -+++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Quantifier.js 1970-01-01 03:00:00.000000000 +0300 -@@ -1,58 +0,0 @@ --if (typeof parseRegExp === 'undefined') -- quit(); -- --load(libdir + "regexp_parse.js"); -- --test_mix("a*", all_flags, -- Quantifier(0, kInfinity, "GREEDY", Atom("a"))); --test_mix("a*?", all_flags, -- Quantifier(0, kInfinity, "NON_GREEDY", Atom("a"))); -- --test_mix("a+", all_flags, -- Quantifier(1, kInfinity, "GREEDY", Atom("a"))); --test_mix("a+?", all_flags, -- Quantifier(1, kInfinity, "NON_GREEDY", Atom("a"))); -- --test_mix("a?", all_flags, -- Quantifier(0, 1, "GREEDY", Atom("a"))); --test_mix("a??", all_flags, -- Quantifier(0, 1, "NON_GREEDY", Atom("a"))); -- --test_mix("a{3}", all_flags, -- Quantifier(3, 3, "GREEDY", Atom("a"))); --test_mix("a{3}?", all_flags, -- Quantifier(3, 3, "NON_GREEDY", Atom("a"))); -- --test_mix("a{3,}", all_flags, -- Quantifier(3, kInfinity, "GREEDY", Atom("a"))); --test_mix("a{3,}?", all_flags, -- Quantifier(3, kInfinity, "NON_GREEDY", Atom("a"))); -- --test_mix("a{3,5}", all_flags, -- Quantifier(3, 5, "GREEDY", Atom("a"))); --test_mix("a{3,5}?", all_flags, -- Quantifier(3, 5, "NON_GREEDY", Atom("a"))); -- --// Surrogate Pair and Quantifier -- --test("\\uD83D\\uDC38+", no_unicode_flags, -- Alternative([ -- Atom("\uD83D"), -- Quantifier(1, kInfinity, "GREEDY", Atom("\uDC38")) -- ])); --test("\\uD83D\\uDC38+", unicode_flags, -- Quantifier(1, kInfinity, "GREEDY", Atom("\uD83D\uDC38"))); -- --// Invalid -- --test_mix("a{", no_unicode_flags, -- Atom("a{")); --test_mix("a{1", no_unicode_flags, -- Atom("a{1")); --test_mix("a{1,", no_unicode_flags, -- Atom("a{1,")); --test_mix("a{1,2", no_unicode_flags, -- Atom("a{1,2")); -- --test_mix("a{,", no_unicode_flags, -- Atom("a{,")); -diff -Nrup mozilla/js/src/js.msg mozilla-OK/js/src/js.msg ---- mozilla/js/src/js.msg 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/js.msg 2022-06-15 23:53:00.823758151 +0300 -@@ -490,7 +490,6 @@ MSG_DEF(JSMSG_INVALID_TIME_ZONE, 1 - MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") - - // RegExp --MSG_DEF(JSMSG_BACK_REF_OUT_OF_RANGE, 0, JSEXN_SYNTAXERR, "back reference out of range in regular expression") - MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") - MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") - MSG_DEF(JSMSG_EXEC_NOT_OBJORNULL, 0, JSEXN_TYPEERR, "RegExp exec method should return object or null") -@@ -503,12 +502,19 @@ MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 0 - MSG_DEF(JSMSG_NOTHING_TO_REPEAT, 0, JSEXN_SYNTAXERR, "nothing to repeat") - MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER, 0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.") - MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class escape cannot be used in class range in regular expression") --MSG_DEF(JSMSG_RAW_BRACE_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") --MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") -+MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEXP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") - MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") - MSG_DEF(JSMSG_UNICODE_OVERFLOW, 1, JSEXN_SYNTAXERR, "Unicode codepoint must not be greater than 0x10FFFF in {0}") - MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") - MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") -+MSG_DEF(JSMSG_INVALID_PROPERTY_NAME, 0, JSEXN_SYNTAXERR, "invalid property name in regular expression") -+MSG_DEF(JSMSG_INVALID_CLASS_PROPERTY_NAME, 0, JSEXN_SYNTAXERR, "invalid class property name in regular expression") -+MSG_DEF(JSMSG_INCOMPLETE_QUANTIFIER, 0, JSEXN_SYNTAXERR, "incomplete quantifier in regular expression") -+MSG_DEF(JSMSG_INVALID_QUANTIFIER, 0, JSEXN_SYNTAXERR, "invalid quantifier in regular expression") -+MSG_DEF(JSMSG_INVALID_CAPTURE_NAME, 0, JSEXN_SYNTAXERR, "invalid capture group name in regular expression") -+MSG_DEF(JSMSG_DUPLICATE_CAPTURE_NAME, 0, JSEXN_SYNTAXERR, "duplicate capture group name in regular expression") -+MSG_DEF(JSMSG_INVALID_NAMED_REF, 0, JSEXN_SYNTAXERR, "invalid named reference in regular expression") -+MSG_DEF(JSMSG_INVALID_NAMED_CAPTURE_REF, 0, JSEXN_SYNTAXERR, "invalid named capture reference in regular expression") - - // Self-hosting - MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 0, JSEXN_ERR, "internal error getting the default locale") -diff -Nrup mozilla/js/src/jsapi-tests/testRegExp.cpp mozilla-OK/js/src/jsapi-tests/testRegExp.cpp ---- mozilla/js/src/jsapi-tests/testRegExp.cpp 2020-02-18 02:37:53.000000000 +0300 -+++ mozilla-OK/js/src/jsapi-tests/testRegExp.cpp 2022-06-15 21:39:37.377986050 +0300 -@@ -2,6 +2,8 @@ - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -+#include "js/RegExp.h" -+#include "js/RegExpFlags.h" - #include "jsapi-tests/tests.h" - - BEGIN_TEST(testObjectIsRegExp) -@@ -12,12 +14,12 @@ BEGIN_TEST(testObjectIsRegExp) - - EVAL("new Object", &val); - JS::RootedObject obj(cx, val.toObjectOrNull()); -- CHECK(JS_ObjectIsRegExp(cx, obj, &isRegExp)); -+ CHECK(JS::ObjectIsRegExp(cx, obj, &isRegExp)); - CHECK(!isRegExp); - - EVAL("/foopy/", &val); - obj = val.toObjectOrNull(); -- CHECK(JS_ObjectIsRegExp(cx, obj, &isRegExp)); -+ CHECK(JS::ObjectIsRegExp(cx, obj, &isRegExp)); - CHECK(isRegExp); - - return true; -@@ -31,15 +33,16 @@ BEGIN_TEST(testGetRegExpFlags) - - EVAL("/foopy/", &val); - obj = val.toObjectOrNull(); -- CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), 0u); -+ CHECK_EQUAL(JS::GetRegExpFlags(cx, obj), JS::RegExpFlags(JS::RegExpFlag::NoFlags)); - - EVAL("/foopy/g", &val); - obj = val.toObjectOrNull(); -- CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), JSREG_GLOB); -+ CHECK_EQUAL(JS::GetRegExpFlags(cx, obj), JS::RegExpFlags(JS::RegExpFlag::Global)); - - EVAL("/foopy/gi", &val); - obj = val.toObjectOrNull(); -- CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), (JSREG_FOLD | JSREG_GLOB)); -+ CHECK_EQUAL(JS::GetRegExpFlags(cx, obj), -+ JS::RegExpFlags(JS::RegExpFlag::Global | JS::RegExpFlag::IgnoreCase)); - - return true; - } -@@ -52,7 +55,8 @@ BEGIN_TEST(testGetRegExpSource) - - EVAL("/foopy/", &val); - obj = val.toObjectOrNull(); -- JSString* source = JS_GetRegExpSource(cx, obj); -+ JSString* source = JS::GetRegExpSource(cx, obj); -+ CHECK(source); - CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(source), "foopy")); - - return true; -diff -Nrup mozilla/js/src/jsapi-tests/tests.h mozilla-OK/js/src/jsapi-tests/tests.h ---- mozilla/js/src/jsapi-tests/tests.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsapi-tests/tests.h 2022-06-15 23:25:52.450800549 +0300 -@@ -19,6 +19,7 @@ - #include "jscntxt.h" - #include "jsgc.h" - -+#include "js/RegExpFlags.h" - #include "js/Vector.h" - - /* Note: Aborts on OOM. */ -@@ -150,6 +151,30 @@ class JSAPITest - return JSAPITestString(v ? "true" : "false"); - } - -+ JSAPITestString toSource(JS::RegExpFlags flags) -+ { -+ JSAPITestString str; -+ if (flags.global()) { -+ str += "g"; -+ } -+ if (flags.ignoreCase()) { -+ str += "i"; -+ } -+ if (flags.multiline()) { -+ str += "m"; -+ } -+ if (flags.dotAll()) { -+ str += "s"; -+ } -+ if (flags.unicode()) { -+ str += "u"; -+ } -+ if (flags.sticky()) { -+ str += "y"; -+ } -+ return str; -+ } -+ - JSAPITestString toSource(JSAtom* v) { - JS::RootedValue val(cx, JS::StringValue((JSString*)v)); - return jsvalToSource(val); -diff -Nrup mozilla/js/src/jsapi.cpp mozilla-OK/js/src/jsapi.cpp ---- mozilla/js/src/jsapi.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsapi.cpp 2022-06-15 21:38:08.876586393 +0300 -@@ -44,7 +44,6 @@ - #include "builtin/Eval.h" - #include "builtin/MapObject.h" - #include "builtin/Promise.h" --#include "builtin/RegExp.h" - #include "builtin/Stream.h" - #include "builtin/SymbolObject.h" - #ifdef ENABLE_SIMD -@@ -76,7 +75,6 @@ - #include "vm/ErrorObject.h" - #include "vm/HelperThreads.h" - #include "vm/Interpreter.h" --#include "vm/RegExpStatics.h" - #include "vm/Runtime.h" - #include "vm/SavedStacks.h" - #include "vm/SelfHosting.h" -@@ -6543,138 +6541,6 @@ JS_ObjectIsDate(JSContext* cx, HandleObj - } - - /************************************************************************/ -- --/* -- * Regular Expressions. -- */ --JS_PUBLIC_API(JSObject*) --JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- -- ScopedJSFreePtr chars(InflateString(cx, bytes, length)); -- if (!chars) -- return nullptr; -- -- return RegExpObject::create(cx, chars.get(), length, RegExpFlag(flags), cx->tempLifoAlloc(), -- GenericObject); --} -- --JS_PUBLIC_API(JSObject*) --JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- -- return RegExpObject::create(cx, chars, length, RegExpFlag(flags), cx->tempLifoAlloc(), -- GenericObject); --} -- --JS_PUBLIC_API(bool) --JS_SetRegExpInput(JSContext* cx, HandleObject obj, HandleString input) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- assertSameCompartment(cx, input); -- -- Handle global = obj.as(); -- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); -- if (!res) -- return false; -- -- res->reset(input); -- return true; --} -- --JS_PUBLIC_API(bool) --JS_ClearRegExpStatics(JSContext* cx, HandleObject obj) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- MOZ_ASSERT(obj); -- -- Handle global = obj.as(); -- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); -- if (!res) -- return false; -- -- res->clear(); -- return true; --} -- --JS_PUBLIC_API(bool) --JS_ExecuteRegExp(JSContext* cx, HandleObject obj, HandleObject reobj, char16_t* chars, -- size_t length, size_t* indexp, bool test, MutableHandleValue rval) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- -- Handle global = obj.as(); -- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); -- if (!res) -- return false; -- -- RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); -- if (!input) -- return false; -- -- return ExecuteRegExpLegacy(cx, res, reobj.as(), input, indexp, test, rval); --} -- --JS_PUBLIC_API(bool) --JS_ExecuteRegExpNoStatics(JSContext* cx, HandleObject obj, char16_t* chars, size_t length, -- size_t* indexp, bool test, MutableHandleValue rval) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- -- RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); -- if (!input) -- return false; -- -- return ExecuteRegExpLegacy(cx, nullptr, obj.as(), input, indexp, test, -- rval); --} -- --JS_PUBLIC_API(bool) --JS_ObjectIsRegExp(JSContext* cx, HandleObject obj, bool* isRegExp) --{ -- assertSameCompartment(cx, obj); -- -- ESClass cls; -- if (!GetBuiltinClass(cx, obj, &cls)) -- return false; -- -- *isRegExp = cls == ESClass::RegExp; -- return true; --} -- --JS_PUBLIC_API(unsigned) --JS_GetRegExpFlags(JSContext* cx, HandleObject obj) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- -- RegExpShared* shared = RegExpToShared(cx, obj); -- if (!shared) -- return false; -- return shared->getFlags(); --} -- --JS_PUBLIC_API(JSString*) --JS_GetRegExpSource(JSContext* cx, HandleObject obj) --{ -- AssertHeapIsIdle(); -- CHECK_REQUEST(cx); -- -- RegExpShared* shared = RegExpToShared(cx, obj); -- if (!shared) -- return nullptr; -- return shared->getSource(); --} -- --/************************************************************************/ - - JS_PUBLIC_API(bool) - JS_SetDefaultLocale(JSRuntime* rt, const char* locale) -diff -Nrup mozilla/js/src/jsapi.h mozilla-OK/js/src/jsapi.h ---- mozilla/js/src/jsapi.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsapi.h 2022-06-15 23:27:12.214259866 +0300 -@@ -4998,7 +4998,8 @@ GetSymbolDescription(HandleSymbol symbol - macro(toPrimitive) \ - macro(toStringTag) \ - macro(unscopables) \ -- macro(asyncIterator) -+ macro(asyncIterator) \ -+ macro(matchAll) - - enum class SymbolCode : uint32_t { - // There is one SymbolCode for each well-known symbol. -@@ -5608,56 +5609,6 @@ JS_ObjectIsDate(JSContext* cx, JS::Handl - - /************************************************************************/ - --/* -- * Regular Expressions. -- */ --#define JSREG_FOLD 0x01u /* fold uppercase to lowercase */ --#define JSREG_GLOB 0x02u /* global exec, creates array of matches */ --#define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */ --#define JSREG_STICKY 0x08u /* only match starting at lastIndex */ --#define JSREG_UNICODE 0x10u /* unicode */ -- --extern JS_PUBLIC_API(JSObject*) --JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags); -- --extern JS_PUBLIC_API(JSObject*) --JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags); -- --extern JS_PUBLIC_API(bool) --JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input); -- --extern JS_PUBLIC_API(bool) --JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj); -- --extern JS_PUBLIC_API(bool) --JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj, -- char16_t* chars, size_t length, size_t* indexp, bool test, -- JS::MutableHandleValue rval); -- --/* RegExp interface for clients without a global object. */ -- --extern JS_PUBLIC_API(bool) --JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length, -- size_t* indexp, bool test, JS::MutableHandleValue rval); -- --/** -- * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp -- * object or a wrapper around one, otherwise returns false on failure. -- * -- * This method returns true with |*isRegExp == false| when passed a proxy whose -- * target is a RegExp, or when passed a revoked proxy. -- */ --extern JS_PUBLIC_API(bool) --JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp); -- --extern JS_PUBLIC_API(unsigned) --JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj); -- --extern JS_PUBLIC_API(JSString*) --JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj); -- --/************************************************************************/ -- - extern JS_PUBLIC_API(bool) - JS_IsExceptionPending(JSContext* cx); - -diff -Nrup mozilla/js/src/jscntxt.cpp mozilla-OK/js/src/jscntxt.cpp ---- mozilla/js/src/jscntxt.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jscntxt.cpp 2022-06-16 00:04:57.749891256 +0300 -@@ -44,6 +44,7 @@ - - #include "gc/FreeOp.h" - #include "gc/Marking.h" -+#include "irregexp/RegExpAPI.h" - #include "jit/Ion.h" - #include "jit/PcScriptCache.h" - #include "js/CharacterEncoding.h" -@@ -116,9 +117,6 @@ JSContext::init(ContextKind kind) - threadNative_ = (size_t)pthread_self(); - #endif - -- if (!regexpStack.ref().init()) -- return false; -- - if (!fx.initInstance()) - return false; - -@@ -132,6 +130,11 @@ JSContext::init(ContextKind kind) - return false; - } - -+ isolate = irregexp::CreateIsolate(this); -+ if (!isolate) { -+ return false; -+ } -+ - // Set the ContextKind last, so that ProtectedData checks will allow us to - // initialize this context before it becomes the runtime's active context. - kind_ = kind; -@@ -1361,6 +1364,10 @@ JSContext::~JSContext() - DestroyTraceLogger(traceLogger); - #endif - -+ if (isolate) { -+ irregexp::DestroyIsolate(isolate.ref()); -+ } -+ - MOZ_ASSERT(TlsContext.get() == this); - TlsContext.set(nullptr); - } -@@ -1492,15 +1499,15 @@ JSContext::updateJITEnabled() - jitIsBroken = IsJITBrokenHere(); - } - --size_t --JSContext::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const --{ -- /* -- * There are other JSContext members that could be measured; the following -- * ones have been found by DMD to be worth measuring. More stuff may be -- * added later. -- */ -- return cycleDetectorVector().sizeOfExcludingThis(mallocSizeOf); -+size_t JSContext::sizeOfExcludingThis( -+ mozilla::MallocSizeOf mallocSizeOf) const { -+ /* -+ * There are other JSContext members that could be measured; the following -+ * ones have been found by DMD to be worth measuring. More stuff may be -+ * added later. -+ */ -+ return cycleDetectorVector().sizeOfExcludingThis(mallocSizeOf) + -+ irregexp::IsolateSizeOfIncludingThis(isolate, mallocSizeOf); - } - - void -diff -Nrup mozilla/js/src/jscntxt.h mozilla-OK/js/src/jscntxt.h ---- mozilla/js/src/jscntxt.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jscntxt.h 2022-06-15 23:53:00.825758137 +0300 -@@ -11,6 +11,7 @@ - - #include "mozilla/MemoryReporting.h" - -+#include "irregexp/RegExpTypes.h" - #include "js/CharacterEncoding.h" - #include "js/GCVector.h" - #include "js/Result.h" -@@ -343,8 +344,8 @@ struct JSContext : public JS::RootingCon - */ - js::ThreadLocalData jitActivation; - -- // Information about the heap allocated backtrack stack used by RegExp JIT code. -- js::ThreadLocalData regexpStack; -+ // Shim for V8 interfaces used by irregexp code -+ js::ThreadLocalData isolate; - - /* - * Points to the most recent activation running on the thread. -diff -Nrup mozilla/js/src/jsgc.cpp mozilla-OK/js/src/jsgc.cpp ---- mozilla/js/src/jsgc.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsgc.cpp 2022-06-15 23:12:02.918415878 +0300 -@@ -2768,7 +2768,8 @@ static const AllocKinds UpdatePhaseMisc - AllocKind::OBJECT_GROUP, - AllocKind::STRING, - AllocKind::JITCODE, -- AllocKind::SCOPE -+ AllocKind::SCOPE, -+ AllocKind::REGEXP_SHARED - }; - - static const AllocKinds UpdatePhaseObjects { -diff -Nrup mozilla/js/src/jsiter.cpp mozilla-OK/js/src/jsiter.cpp ---- mozilla/js/src/jsiter.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsiter.cpp 2022-06-15 23:45:41.105740896 +0300 -@@ -23,6 +23,7 @@ - #include "jstypes.h" - #include "jsutil.h" - -+#include "builtin/SelfHostingDefines.h" - #include "ds/Sort.h" - #include "gc/FreeOp.h" - #include "gc/Marking.h" -@@ -1175,6 +1176,78 @@ js::NewStringIteratorObject(JSContext* c - return NewObjectWithGivenProto(cx, proto, newKind); - } - -+static const Class RegExpStringIteratorPrototypeClass = { -+ "RegExp String Iterator", 0 -+}; -+ -+enum { -+ // The regular expression used for iteration. May hold the original RegExp -+ // object when it is reused instead of a new RegExp object. -+ RegExpStringIteratorSlotRegExp, -+ -+ // The String value being iterated upon. -+ RegExpStringIteratorSlotString, -+ -+ // The source string of the original RegExp object. Used to validate we can -+ // reuse the original RegExp object for matching. -+ RegExpStringIteratorSlotSource, -+ -+ // The flags of the original RegExp object. -+ RegExpStringIteratorSlotFlags, -+ -+ // When non-negative, this slot holds the current lastIndex position when -+ // reusing the original RegExp object for matching. When set to |-1|, the -+ // iterator has finished. When set to any other negative value, the -+ // iterator is not yet exhausted and we're not on the fast path and we're -+ // not reusing the input RegExp object. -+ RegExpStringIteratorSlotLastIndex, -+ -+ RegExpStringIteratorSlotCount -+}; -+ -+static_assert(RegExpStringIteratorSlotRegExp == -+ REGEXP_STRING_ITERATOR_REGEXP_SLOT, -+ "RegExpStringIteratorSlotRegExp must match self-hosting define " -+ "for regexp slot."); -+static_assert(RegExpStringIteratorSlotString == -+ REGEXP_STRING_ITERATOR_STRING_SLOT, -+ "RegExpStringIteratorSlotString must match self-hosting define " -+ "for string slot."); -+static_assert(RegExpStringIteratorSlotSource == -+ REGEXP_STRING_ITERATOR_SOURCE_SLOT, -+ "RegExpStringIteratorSlotString must match self-hosting define " -+ "for source slot."); -+static_assert(RegExpStringIteratorSlotFlags == -+ REGEXP_STRING_ITERATOR_FLAGS_SLOT, -+ "RegExpStringIteratorSlotFlags must match self-hosting define " -+ "for flags slot."); -+static_assert(RegExpStringIteratorSlotLastIndex == -+ REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, -+ "RegExpStringIteratorSlotLastIndex must match self-hosting " -+ "define for lastIndex slot."); -+ -+const Class RegExpStringIteratorObject::class_ = { -+ "RegExp String Iterator", -+ JSCLASS_HAS_RESERVED_SLOTS(RegExpStringIteratorSlotCount) -+}; -+ -+static const JSFunctionSpec regexp_string_iterator_methods[] = { -+ JS_SELF_HOSTED_FN("next", "RegExpStringIteratorNext", 0, 0), -+ JS_FS_END -+}; -+ -+RegExpStringIteratorObject* js::NewRegExpStringIteratorObject( -+ JSContext* cx, NewObjectKind newKind) { -+ RootedObject proto(cx, GlobalObject::getOrCreateRegExpStringIteratorPrototype( -+ cx, cx->global())); -+ if (!proto) { -+ return nullptr; -+ } -+ -+ return NewObjectWithGivenProto(cx, proto, -+ newKind); -+} -+ - JSObject* - js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp) - { -@@ -1516,3 +1589,29 @@ GlobalObject::initStringIteratorProto(JS - global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto)); - return true; - } -+ -+/* static */ bool -+GlobalObject::initRegExpStringIteratorProto(JSContext* cx, Handle global) -+{ -+ if (global->getReservedSlot(REGEXP_STRING_ITERATOR_PROTO).isObject()) { -+ return true; -+ } -+ -+ RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global)); -+ if (!iteratorProto) { -+ return false; -+ } -+ -+ const Class* cls = &RegExpStringIteratorPrototypeClass; -+ RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls, -+ iteratorProto)); -+ if (!proto || -+ !DefinePropertiesAndFunctions(cx, proto, nullptr, regexp_string_iterator_methods) || -+ !DefineToStringTag(cx, proto, cx->names().RegExpStringIterator)) -+ { -+ return false; -+ } -+ -+ global->setReservedSlot(REGEXP_STRING_ITERATOR_PROTO, ObjectValue(*proto)); -+ return true; -+} -diff -Nrup mozilla/js/src/jsiter.h mozilla-OK/js/src/jsiter.h ---- mozilla/js/src/jsiter.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsiter.h 2022-06-15 23:27:12.216259852 +0300 -@@ -157,6 +157,15 @@ class StringIteratorObject : public JSOb - StringIteratorObject* - NewStringIteratorObject(JSContext* cx, NewObjectKind newKind = GenericObject); - -+class RegExpStringIteratorObject : public NativeObject -+{ -+ public: -+ static const Class class_; -+}; -+ -+RegExpStringIteratorObject* -+NewRegExpStringIteratorObject(JSContext* cx, NewObjectKind newKind = GenericObject); -+ - JSObject* - GetIterator(JSContext* cx, HandleObject obj, unsigned flags); - -diff -Nrup mozilla/js/src/jsstr.cpp mozilla-OK/js/src/jsstr.cpp ---- mozilla/js/src/jsstr.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/jsstr.cpp 2022-06-15 23:27:12.217259846 +0300 -@@ -3599,6 +3599,7 @@ static const JSFunctionSpec string_metho - - /* Perl-ish methods (search is actually Python-esque). */ - JS_SELF_HOSTED_FN("match", "String_match", 1,0), -+ JS_SELF_HOSTED_FN("matchAll", "String_matchAll", 1,0), - JS_SELF_HOSTED_FN("search", "String_search", 1,0), - JS_SELF_HOSTED_FN("replace", "String_replace", 2,0), - JS_SELF_HOSTED_FN("replaceAll", "String_replaceAll", 2, 0), -diff -Nrup mozilla/js/src/moz.build mozilla-OK/js/src/moz.build ---- mozilla/js/src/moz.build 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/moz.build 2022-06-16 00:13:48.971283246 +0300 -@@ -146,6 +146,8 @@ EXPORTS.js += [ - '../public/Proxy.h', - '../public/Realm.h', - '../public/RefCounted.h', -+ '../public/RegExp.h', -+ '../public/RegExpFlags.h', - '../public/RequiredDefines.h', - '../public/Result.h', - '../public/RootingAPI.h', -@@ -170,6 +172,10 @@ EXPORTS.js += [ - '../public/WeakMapPtr.h', - ] - -+SOURCES += [ -+ 'util/Text.cpp', -+] -+ - UNIFIED_SOURCES += [ - 'builtin/AtomicsObject.cpp', - 'builtin/DataViewObject.cpp', -@@ -200,14 +206,6 @@ UNIFIED_SOURCES += [ - 'ds/Bitmap.cpp', - 'ds/LifoAlloc.cpp', - 'ds/MemoryProtectionExceptionHandler.cpp', -- 'irregexp/NativeRegExpMacroAssembler.cpp', -- 'irregexp/RegExpAST.cpp', -- 'irregexp/RegExpCharacters.cpp', -- 'irregexp/RegExpEngine.cpp', -- 'irregexp/RegExpInterpreter.cpp', -- 'irregexp/RegExpMacroAssembler.cpp', -- 'irregexp/RegExpParser.cpp', -- 'irregexp/RegExpStack.cpp', - 'jsalloc.cpp', - 'jsapi.cpp', - 'jsarray.cpp', -@@ -384,13 +382,39 @@ else: - 'perf/pm_stub.cpp' - ] - -+SOURCES += [ -+ 'irregexp/imported/regexp-ast.cc', -+ 'irregexp/imported/regexp-bytecode-generator.cc', -+ 'irregexp/imported/regexp-bytecode-peephole.cc', -+ 'irregexp/imported/regexp-bytecodes.cc', -+ 'irregexp/imported/regexp-compiler-tonode.cc', -+ 'irregexp/imported/regexp-compiler.cc', -+ 'irregexp/imported/regexp-dotprinter.cc', -+ 'irregexp/imported/regexp-interpreter.cc', -+ 'irregexp/imported/regexp-macro-assembler-tracer.cc', -+ 'irregexp/imported/regexp-macro-assembler.cc', -+ 'irregexp/imported/regexp-parser.cc', -+ 'irregexp/imported/regexp-stack.cc', -+ 'irregexp/RegExpAPI.cpp', -+ 'irregexp/RegExpNativeMacroAssembler.cpp', -+ 'irregexp/RegExpShim.cpp', -+ 'irregexp/util/UnicodeShim.cpp' -+] -+ -+if CONFIG['ENABLE_INTL_API']: -+ CXXFLAGS += ['-DV8_INTL_SUPPORT'] -+ SOURCES += [ -+ 'irregexp/imported/property-sequences.cc', -+ 'irregexp/imported/special-case.cc' -+ ] -+ - DIRS += [ - 'build', - 'frontend', - 'gc', - 'jit', - 'wasm', --] + (['new-regexp'] if CONFIG['ENABLE_NEW_REGEXP'] else []) -+] - - FINAL_LIBRARY = 'js' - -diff -Nrup mozilla/js/src/moz.build.later mozilla-OK/js/src/moz.build.later ---- mozilla/js/src/moz.build.later 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/moz.build.later 2022-06-15 23:53:00.825758137 +0300 -@@ -0,0 +1,10 @@ -+--- js/src/moz.build -++++ js/src/moz.build -+@@ -114,6 +114,7 @@ -+ 'frontend', -+ 'gc', -+ 'jit', -++ 'irregexp', -+ 'perf', -+ 'proxy', -+ 'threading', -diff -Nrup mozilla/js/src/shell/js.cpp mozilla-OK/js/src/shell/js.cpp ---- mozilla/js/src/shell/js.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/shell/js.cpp 2022-06-15 23:53:18.843635900 +0300 -@@ -8154,6 +8154,11 @@ SetContextOptions(JSContext* cx, const O - if (warmUpThreshold >= 0) - jit::JitOptions.baselineWarmUpThreshold = warmUpThreshold; - -+ warmUpThreshold = op.getIntOption("regexp-warmup-threshold"); -+ if (warmUpThreshold >= 0) { -+ jit::JitOptions.regexpWarmUpThreshold = warmUpThreshold; -+ } -+ - if (op.getBoolOption("baseline-eager")) - jit::JitOptions.baselineWarmUpThreshold = 0; - -@@ -8477,6 +8482,11 @@ main(int argc, char** argv, char** envp) - || !op.addBoolOption('\0', "test-wasm-await-tier2", "Forcibly activate tiering and block " - "instantiation on completion of tier2") - || !op.addBoolOption('\0', "no-native-regexp", "Disable native regexp compilation") -+ || !op.addIntOption( -+ '\0', "regexp-warmup-threshold", "COUNT", -+ "Wait for COUNT invocations before compiling regexps to native code " -+ "(default 10)", -+ -1) - || !op.addBoolOption('\0', "no-unboxed-objects", "Disable creating unboxed plain objects") - || !op.addBoolOption('\0', "wasm-test-mode", "Enable wasm testing mode, creating synthetic " - "objects for non-canonical NaNs and i64 returned from wasm.") -diff -Nrup mozilla/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js mozilla-OK/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js ---- mozilla/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js 2022-06-16 00:04:51.609932951 +0300 -@@ -0,0 +1,12 @@ -+// Bug 1667094. -+ -+var obj = { -+ exec() { -+ return function(){}; -+ } -+}; -+ -+assertEq(RegExp.prototype.test.call(obj, ""), true); -+ -+if (typeof reportCompare === "function") -+ reportCompare(true, true); -diff -Nrup mozilla/js/src/tests/non262/extensions/bad-regexp-data-clone.js mozilla-OK/js/src/tests/non262/extensions/bad-regexp-data-clone.js ---- mozilla/js/src/tests/non262/extensions/bad-regexp-data-clone.js 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/tests/non262/extensions/bad-regexp-data-clone.js 2022-06-15 22:16:24.018030987 +0300 -@@ -0,0 +1,20 @@ -+// |reftest| skip-if(!xulRuntime.shell) -+// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- -+// Any copyright is dedicated to the Public Domain. -+// http://creativecommons.org/licenses/publicdomain/ -+ -+let data = new Uint8Array([ -+ 104,97,108,101,6,0,255,255,95,98, -+ 0,0,0,0,0,104,97,108,101,9,0,255, -+ 255,95,98,115,0,0,0,0,0,0,65,0,0, -+ 0,0,0,0,0,0,0,0,0,0,0,0,0 -+]); -+let cloneBuffer = serialize(null); -+cloneBuffer.clonebuffer = data.buffer; -+ -+// One of the bytes above encodes a JS::RegExpFlags, but that byte contains bits -+// outside of JS::RegExpFlag::AllFlags and so will trigger an error. -+assertThrowsInstanceOf(() => deserialize(cloneBuffer), InternalError); -+ -+if (typeof reportCompare === "function") -+ reportCompare(0, 0, 'ok'); -diff -Nrup mozilla/js/src/util/Text.cpp mozilla-OK/js/src/util/Text.cpp ---- mozilla/js/src/util/Text.cpp 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/util/Text.cpp 2022-06-15 22:16:34.699958658 +0300 -@@ -0,0 +1,37 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * vim: set ts=8 sts=2 et sw=2 tw=80: -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#include "util/Text.h" -+ -+#include "mozilla/Assertions.h" -+#include "vm/Unicode.h" -+ -+using namespace JS; -+using namespace js; -+ -+size_t -+js::unicode::CountCodePoints(const char16_t* begin, const char16_t* end) -+{ -+ MOZ_ASSERT(begin <= end); -+ -+ size_t count = 0; -+ -+ const char16_t* ptr = begin; -+ while (ptr < end) { -+ count++; -+ -+ if (!IsLeadSurrogate(*ptr++)) { -+ continue; -+ } -+ -+ if (ptr < end && IsTrailSurrogate(*ptr)) { -+ ptr++; -+ } -+ } -+ MOZ_ASSERT(ptr == end, "should have consumed the full range"); -+ -+ return count; -+} -diff -Nrup mozilla/js/src/util/Text.h mozilla-OK/js/src/util/Text.h ---- mozilla/js/src/util/Text.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/js/src/util/Text.h 2022-06-15 22:16:34.699958658 +0300 -@@ -0,0 +1,27 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * vim: set ts=8 sts=2 et sw=2 tw=80: -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#ifndef util_Text_h -+#define util_Text_h -+ -+#include -+ -+namespace js { -+ -+namespace unicode { -+/** -+ * Count the number of code points in [begin, end]. -+ * -+ * Every sequence of 16-bit units is considered valid. Lone surrogates are -+ * treated as if they represented a code point of the same value. -+ */ -+extern size_t -+CountCodePoints(const char16_t* begin, const char16_t* end); -+} // namespace unicode -+ -+} // namespace js -+ -+#endif // util_Text_h -diff -Nrup mozilla/js/src/vm/CommonPropertyNames.h mozilla-OK/js/src/vm/CommonPropertyNames.h ---- mozilla/js/src/vm/CommonPropertyNames.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/CommonPropertyNames.h 2022-06-15 23:27:12.217259846 +0300 -@@ -104,6 +104,7 @@ - macro(displayURL, displayURL, "displayURL") \ - macro(do, do_, "do") \ - macro(done, done, "done") \ -+ macro(dotAll, dotAll, "dotAll") \ - macro(dotGenerator, dotGenerator, ".generator") \ - macro(dotThis, dotThis, ".this") \ - macro(each, each, "each") \ -@@ -170,6 +171,7 @@ - macro(global, global, "global") \ - macro(globalThis, globalThis, "globalThis") \ - macro(group, group, "group") \ -+ macro(groups, groups, "groups") \ - macro(Handle, Handle, "Handle") \ - macro(has, has, "has") \ - macro(hasOwn, hasOwn, "hasOwn") \ -@@ -348,6 +350,7 @@ - macro(ReadableStreamTee, ReadableStreamTee, "ReadableStreamTee") \ - macro(reason, reason, "reason") \ - macro(RegExpFlagsGetter, RegExpFlagsGetter, "RegExpFlagsGetter") \ -+ macro(RegExpStringIterator, RegExpStringIterator, "RegExp String Iterator") \ - macro(Reify, Reify, "Reify") \ - macro(reject, reject, "reject") \ - macro(rejected, rejected, "rejected") \ -diff -Nrup mozilla/js/src/vm/GlobalObject.cpp mozilla-OK/js/src/vm/GlobalObject.cpp ---- mozilla/js/src/vm/GlobalObject.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/GlobalObject.cpp 2022-06-15 23:27:12.218259839 +0300 -@@ -488,63 +488,30 @@ GlobalObject::initSelfHostingBuiltins(JS - return false; - } - -- RootedValue std_isConcatSpreadable(cx); -- std_isConcatSpreadable.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::isConcatSpreadable)); -- if (!JS_DefineProperty(cx, global, "std_isConcatSpreadable", std_isConcatSpreadable, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -- return false; -- } -- -- // Define a top-level property 'std_iterator' with the name of the method -- // used by for-of loops to create an iterator. -- RootedValue std_iterator(cx); -- std_iterator.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::iterator)); -- if (!JS_DefineProperty(cx, global, "std_iterator", std_iterator, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -- return false; -- } -- -- RootedValue std_match(cx); -- std_match.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::match)); -- if (!JS_DefineProperty(cx, global, "std_match", std_match, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -- return false; -- } -- -- RootedValue std_replace(cx); -- std_replace.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::replace)); -- if (!JS_DefineProperty(cx, global, "std_replace", std_replace, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -- return false; -- } -- -- RootedValue std_search(cx); -- std_search.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::search)); -- if (!JS_DefineProperty(cx, global, "std_search", std_search, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -- return false; -- } -- -- RootedValue std_species(cx); -- std_species.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::species)); -- if (!JS_DefineProperty(cx, global, "std_species", std_species, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -- return false; -- } -- -- RootedValue std_split(cx); -- std_split.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::split)); -- if (!JS_DefineProperty(cx, global, "std_split", std_split, -- JSPROP_PERMANENT | JSPROP_READONLY)) -- { -+ struct SymbolAndName { -+ JS::SymbolCode code; -+ const char* name; -+ }; -+ -+ SymbolAndName wellKnownSymbols[] = { -+ {JS::SymbolCode::isConcatSpreadable, "std_isConcatSpreadable"}, -+ {JS::SymbolCode::iterator, "std_iterator"}, -+ {JS::SymbolCode::match, "std_match"}, -+ {JS::SymbolCode::matchAll, "std_matchAll"}, -+ {JS::SymbolCode::replace, "std_replace"}, -+ {JS::SymbolCode::search, "std_search"}, -+ {JS::SymbolCode::species, "std_species"}, -+ {JS::SymbolCode::split, "std_split"}, -+ }; -+ -+ RootedValue symVal(cx); -+ for (const auto& sym : wellKnownSymbols) { -+ symVal.setSymbol(cx->wellKnownSymbols().get(sym.code)); -+ if (!JS_DefineProperty(cx, global, sym.name, symVal, -+ JSPROP_PERMANENT | JSPROP_READONLY)) { - return false; - } -+ } - - return InitBareBuiltinCtor(cx, global, JSProto_Array) && - InitBareBuiltinCtor(cx, global, JSProto_TypedArray) && -diff -Nrup mozilla/js/src/vm/GlobalObject.h mozilla-OK/js/src/vm/GlobalObject.h ---- mozilla/js/src/vm/GlobalObject.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/GlobalObject.h 2022-06-15 23:41:55.675270064 +0300 -@@ -77,6 +77,7 @@ class GlobalObject : public NativeObject - ITERATOR_PROTO, - ARRAY_ITERATOR_PROTO, - STRING_ITERATOR_PROTO, -+ REGEXP_STRING_ITERATOR_PROTO, - GENERATOR_OBJECT_PROTO, - GENERATOR_FUNCTION_PROTO, - GENERATOR_FUNCTION, -@@ -580,6 +581,12 @@ class GlobalObject : public NativeObject - } - - static NativeObject* -+ getOrCreateRegExpStringIteratorPrototype(JSContext* cx, Handle global) { -+ return MaybeNativeObject(getOrCreateObject(cx, global, REGEXP_STRING_ITERATOR_PROTO, -+ initRegExpStringIteratorProto)); -+ } -+ -+ static NativeObject* - getOrCreateGeneratorObjectPrototype(JSContext* cx, Handle global) - { - return MaybeNativeObject(getOrCreateObject(cx, global, GENERATOR_OBJECT_PROTO, -@@ -765,6 +772,7 @@ class GlobalObject : public NativeObject - static bool initIteratorProto(JSContext* cx, Handle global); - static bool initArrayIteratorProto(JSContext* cx, Handle global); - static bool initStringIteratorProto(JSContext* cx, Handle global); -+ static bool initRegExpStringIteratorProto(JSContext* cx, Handle global); - - // Implemented in vm/GeneratorObject.cpp. - static bool initGenerators(JSContext* cx, Handle global); -diff -Nrup mozilla/js/src/vm/MatchPairs.h mozilla-OK/js/src/vm/MatchPairs.h ---- mozilla/js/src/vm/MatchPairs.h 2022-01-25 01:04:29.000000000 +0300 -+++ mozilla-OK/js/src/vm/MatchPairs.h 2022-06-16 00:04:45.971971252 +0300 -@@ -79,6 +79,7 @@ class MatchPairs - bool initArrayFrom(MatchPairs& copyFrom); - void forgetArray() { pairs_ = nullptr; } - -+ public: - void checkAgainst(size_t inputLength) { - #ifdef DEBUG - for (size_t i = 0; i < pairCount_; i++) { -@@ -91,7 +92,6 @@ class MatchPairs - #endif - } - -- public: - /* Querying functions in the style of RegExpStatics. */ - bool empty() const { return pairCount_ == 0; } - size_t pairCount() const { MOZ_ASSERT(pairCount_ > 0); return pairCount_; } -diff -Nrup mozilla/js/src/vm/MutexIDs.h mozilla-OK/js/src/vm/MutexIDs.h ---- mozilla/js/src/vm/MutexIDs.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/MutexIDs.h 2022-06-15 22:59:48.081388222 +0300 -@@ -50,6 +50,7 @@ - _(WasmStreamStatus, 500) \ - \ - _(IcuTimeZoneStateMutex, 600) \ -+ _(IrregexpLazyStatic, 600) \ - _(ThreadId, 600) \ - _(WasmCodeSegmentMap, 600) \ - _(TraceLoggerGraphState, 600) \ -diff -Nrup mozilla/js/src/vm/RegExpObject.cpp mozilla-OK/js/src/vm/RegExpObject.cpp ---- mozilla/js/src/vm/RegExpObject.cpp 2022-04-13 21:14:22.000000000 +0300 -+++ mozilla-OK/js/src/vm/RegExpObject.cpp 2022-06-16 00:05:05.018841907 +0300 -@@ -16,11 +16,9 @@ - #endif - - #include "builtin/RegExp.h" -+#include "builtin/SelfHostingDefines.h" - #include "frontend/TokenStream.h" --#ifdef DEBUG --#include "irregexp/RegExpBytecode.h" --#endif --#include "irregexp/RegExpParser.h" -+#include "irregexp/RegExpAPI.h" - #include "vm/MatchPairs.h" - #include "vm/RegExpStatics.h" - #include "vm/StringBuffer.h" -@@ -35,21 +33,33 @@ - #include "vm/NativeObject-inl.h" - #include "vm/Shape-inl.h" - -+#include "js/RegExp.h" -+#include "js/RegExpFlags.h" -+ - using namespace js; - - using mozilla::ArrayLength; - using mozilla::DebugOnly; - using mozilla::Maybe; - using mozilla::PodCopy; -+using JS::RegExpFlag; -+using JS::RegExpFlags; - using js::frontend::TokenStream; - - using JS::AutoCheckCannotGC; - --JS_STATIC_ASSERT(IgnoreCaseFlag == JSREG_FOLD); --JS_STATIC_ASSERT(GlobalFlag == JSREG_GLOB); --JS_STATIC_ASSERT(MultilineFlag == JSREG_MULTILINE); --JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY); --JS_STATIC_ASSERT(UnicodeFlag == JSREG_UNICODE); -+static_assert(RegExpFlag::Global == REGEXP_GLOBAL_FLAG, -+ "self-hosted JS and /g flag bits must agree"); -+static_assert(RegExpFlag::IgnoreCase == REGEXP_IGNORECASE_FLAG, -+ "self-hosted JS and /i flag bits must agree"); -+static_assert(RegExpFlag::Multiline == REGEXP_MULTILINE_FLAG, -+ "self-hosted JS and /m flag bits must agree"); -+static_assert(RegExpFlag::DotAll == REGEXP_DOTALL_FLAG, -+ "self-hosted JS and /s flag bits must agree"); -+static_assert(RegExpFlag::Unicode == REGEXP_UNICODE_FLAG, -+ "self-hosted JS and /u flag bits must agree"); -+static_assert(RegExpFlag::Sticky == REGEXP_STICKY_FLAG, -+ "self-hosted JS and /y flag bits must agree"); - - RegExpObject* - js::RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto /* = nullptr */) -@@ -126,26 +136,30 @@ RegExpObject::getShared(JSContext* cx, H - } - - /* static */ bool --RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlag* mask) -+RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlags* mask) - { - if (native == regexp_global) { -- *mask = GlobalFlag; -+ *mask = RegExpFlag::Global; - return true; - } - if (native == regexp_ignoreCase) { -- *mask = IgnoreCaseFlag; -+ *mask = RegExpFlag::IgnoreCase; - return true; - } - if (native == regexp_multiline) { -- *mask = MultilineFlag; -+ *mask = RegExpFlag::Multiline; - return true; - } - if (native == regexp_sticky) { -- *mask = StickyFlag; -+ *mask = RegExpFlag::Sticky; - return true; - } - if (native == regexp_unicode) { -- *mask = UnicodeFlag; -+ *mask = RegExpFlag::Unicode; -+ return true; -+ } -+ if (native == regexp_dotAll) { -+ *mask = RegExpFlag::DotAll; - return true; - } - -@@ -227,7 +241,7 @@ const Class RegExpObject::protoClass_ = - - template - RegExpObject* --RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, -+RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlags flags, - frontend::TokenStreamAnyChars& tokenStream, LifoAlloc& alloc, - NewObjectKind newKind) - { -@@ -242,13 +256,13 @@ RegExpObject::create(JSContext* cx, cons - } - - template RegExpObject* --RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags, -+RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlags flags, - frontend::TokenStreamAnyChars& tokenStream, LifoAlloc& alloc, - NewObjectKind newKind); - - template - RegExpObject* --RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, -+RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlags flags, - LifoAlloc& alloc, NewObjectKind newKind) - { - static_assert(mozilla::IsSame::value, -@@ -262,17 +276,17 @@ RegExpObject::create(JSContext* cx, cons - } - - template RegExpObject* --RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags, -+RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlags flags, - LifoAlloc& alloc, NewObjectKind newKind); - - RegExpObject* --RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags, -+RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlags flags, - frontend::TokenStreamAnyChars& tokenStream, - LifoAlloc& alloc, NewObjectKind newKind) - { -- if (!irregexp::ParsePatternSyntax(tokenStream, alloc, source, flags & UnicodeFlag)) -+ if (!irregexp::CheckPatternSyntax(cx, tokenStream, source, flags)) { - return nullptr; -- -+ } - Rooted regexp(cx, RegExpAlloc(cx, newKind)); - if (!regexp) - return nullptr; -@@ -283,15 +297,15 @@ RegExpObject::create(JSContext* cx, Hand - } - - RegExpObject* --RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags, LifoAlloc& alloc, -+RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlags flags, LifoAlloc& alloc, - NewObjectKind newKind) - { - CompileOptions dummyOptions(cx); - TokenStream dummyTokenStream(cx, dummyOptions, (const char16_t*) nullptr, 0, nullptr); - -- if (!irregexp::ParsePatternSyntax(dummyTokenStream, alloc, source, flags & UnicodeFlag)) -+ if (!irregexp::CheckPatternSyntax(cx, dummyTokenStream, source, flags)) { - return nullptr; -- -+ } - Rooted regexp(cx, RegExpAlloc(cx, newKind)); - if (!regexp) - return nullptr; -@@ -327,7 +341,7 @@ RegExpObject::assignInitialShape(JSConte - } - - void --RegExpObject::initIgnoringLastIndex(JSAtom* source, RegExpFlag flags) -+RegExpObject::initIgnoringLastIndex(JSAtom* source, RegExpFlags flags) - { - // If this is a re-initialization with an existing RegExpShared, 'flags' - // may not match getShared()->flags, so forget the RegExpShared. -@@ -338,7 +352,7 @@ RegExpObject::initIgnoringLastIndex(JSAt - } - - void --RegExpObject::initAndZeroLastIndex(JSAtom* source, RegExpFlag flags, JSContext* cx) -+RegExpObject::initAndZeroLastIndex(JSAtom* source, RegExpFlags flags, JSContext* cx) - { - initIgnoringLastIndex(source, flags); - zeroLastIndex(cx); -@@ -527,406 +541,12 @@ RegExpObject::toString(JSContext* cx) co - return nullptr; - if (sticky() && !sb.append('y')) - return nullptr; -+ if (dotAll() && !sb.append('s')) -+ return nullptr; - - return sb.finishString(); - } - --#ifdef DEBUG --/* static */ bool --RegExpShared::dumpBytecode(JSContext* cx, MutableHandleRegExpShared re, bool match_only, -- HandleLinearString input) --{ -- CompilationMode mode = match_only ? MatchOnly : Normal; -- if (!RegExpShared::compileIfNecessary(cx, re, input, mode, ForceByteCode)) -- return false; -- -- const uint8_t* byteCode = re->compilation(mode, input->hasLatin1Chars()).byteCode; -- const uint8_t* pc = byteCode; -- -- auto Load32Aligned = [](const uint8_t* pc) -> int32_t { -- MOZ_ASSERT((reinterpret_cast(pc) & 3) == 0); -- return *reinterpret_cast(pc); -- }; -- -- auto Load16Aligned = [](const uint8_t* pc) -> int32_t { -- MOZ_ASSERT((reinterpret_cast(pc) & 1) == 0); -- return *reinterpret_cast(pc); -- }; -- -- int32_t numRegisters = Load32Aligned(pc); -- fprintf(stderr, "numRegisters: %d\n", numRegisters); -- pc += 4; -- -- fprintf(stderr, "loc op\n"); -- fprintf(stderr, "----- --\n"); -- -- auto DumpLower = [](const char* text) { -- while (*text) { -- fprintf(stderr, "%c", unicode::ToLowerCase(*text)); -- text++; -- } -- }; -- --#define BYTECODE(NAME) \ -- case irregexp::BC_##NAME: \ -- DumpLower(#NAME); --#define ADVANCE(NAME) \ -- fprintf(stderr, "\n"); \ -- pc += irregexp::BC_##NAME##_LENGTH; \ -- maxPc = js::Max(maxPc, pc); \ -- break; --#define STOP(NAME) \ -- fprintf(stderr, "\n"); \ -- pc += irregexp::BC_##NAME##_LENGTH; \ -- break; --#define JUMP(NAME, OFFSET) \ -- fprintf(stderr, "\n"); \ -- maxPc = js::Max(maxPc, byteCode + OFFSET); \ -- pc += irregexp::BC_##NAME##_LENGTH; \ -- break; --#define BRANCH(NAME, OFFSET) \ -- fprintf(stderr, "\n"); \ -- pc += irregexp::BC_##NAME##_LENGTH; \ -- maxPc = js::Max(maxPc, js::Max(pc, byteCode + OFFSET)); \ -- break; -- -- // Bytecode has no end marker, we need to calculate the bytecode length by -- // tracing jumps and branches. -- const uint8_t* maxPc = pc; -- while (pc <= maxPc) { -- fprintf(stderr, "%05d: ", int32_t(pc - byteCode)); -- int32_t insn = Load32Aligned(pc); -- switch (insn & irregexp::BYTECODE_MASK) { -- BYTECODE(BREAK) { -- STOP(BREAK); -- } -- BYTECODE(PUSH_CP) { -- ADVANCE(PUSH_CP); -- } -- BYTECODE(PUSH_BT) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d", -- offset); -- // Pushed value is used by POP_BT for jumping. -- // Resolve maxPc here. -- BRANCH(PUSH_BT, offset); -- } -- BYTECODE(PUSH_REGISTER) { -- fprintf(stderr, " reg[%d]", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(PUSH_REGISTER); -- } -- BYTECODE(SET_REGISTER) { -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4)); -- ADVANCE(SET_REGISTER); -- } -- BYTECODE(ADVANCE_REGISTER) { -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4)); -- ADVANCE(ADVANCE_REGISTER); -- } -- BYTECODE(SET_REGISTER_TO_CP) { -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4)); -- ADVANCE(SET_REGISTER_TO_CP); -- } -- BYTECODE(SET_CP_TO_REGISTER) { -- fprintf(stderr, " reg[%d]", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(SET_CP_TO_REGISTER); -- } -- BYTECODE(SET_REGISTER_TO_SP) { -- fprintf(stderr, " reg[%d]", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(SET_REGISTER_TO_SP); -- } -- BYTECODE(SET_SP_TO_REGISTER) { -- fprintf(stderr, " reg[%d]", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(SET_SP_TO_REGISTER); -- } -- BYTECODE(POP_CP) { -- ADVANCE(POP_CP); -- } -- BYTECODE(POP_BT) { -- // Jump is already resolved in PUSH_BT. -- STOP(POP_BT); -- } -- BYTECODE(POP_REGISTER) { -- fprintf(stderr, " reg[%d]", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(POP_REGISTER); -- } -- BYTECODE(FAIL) { -- ADVANCE(FAIL); -- } -- BYTECODE(SUCCEED) { -- ADVANCE(SUCCEED); -- } -- BYTECODE(ADVANCE_CP) { -- fprintf(stderr, " %d", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(ADVANCE_CP); -- } -- BYTECODE(GOTO) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d", -- offset); -- JUMP(GOTO, offset); -- } -- BYTECODE(ADVANCE_CP_AND_GOTO) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- JUMP(ADVANCE_CP_AND_GOTO, offset); -- } -- BYTECODE(CHECK_GREEDY) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d", -- offset); -- BRANCH(CHECK_GREEDY, offset); -- } -- BYTECODE(LOAD_CURRENT_CHAR) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(LOAD_CURRENT_CHAR, offset); -- } -- BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) { -- fprintf(stderr, " %d", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(LOAD_CURRENT_CHAR_UNCHECKED); -- } -- BYTECODE(LOAD_2_CURRENT_CHARS) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(LOAD_2_CURRENT_CHARS, offset); -- } -- BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) { -- fprintf(stderr, " %d", -- insn >> irregexp::BYTECODE_SHIFT); -- ADVANCE(LOAD_2_CURRENT_CHARS_UNCHECKED); -- } -- BYTECODE(LOAD_4_CURRENT_CHARS) { -- ADVANCE(LOAD_4_CURRENT_CHARS); -- } -- BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) { -- ADVANCE(LOAD_4_CURRENT_CHARS_UNCHECKED); -- } -- BYTECODE(CHECK_4_CHARS) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d", -- Load32Aligned(pc + 4), -- offset); -- BRANCH(CHECK_4_CHARS, offset); -- } -- BYTECODE(CHECK_CHAR) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_CHAR, offset); -- } -- BYTECODE(CHECK_NOT_4_CHARS) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d", -- Load32Aligned(pc + 4), -- offset); -- BRANCH(CHECK_NOT_4_CHARS, offset); -- } -- BYTECODE(CHECK_NOT_CHAR) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_NOT_CHAR, offset); -- } -- BYTECODE(AND_CHECK_4_CHARS) { -- int32_t offset = Load32Aligned(pc + 12); -- fprintf(stderr, " %d, %d, %d", -- Load32Aligned(pc + 4), -- Load32Aligned(pc + 8), -- offset); -- BRANCH(AND_CHECK_4_CHARS, offset); -- } -- BYTECODE(AND_CHECK_CHAR) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4), -- offset); -- BRANCH(AND_CHECK_CHAR, offset); -- } -- BYTECODE(AND_CHECK_NOT_4_CHARS) { -- int32_t offset = Load32Aligned(pc + 12); -- fprintf(stderr, " %d, %d, %d", -- Load32Aligned(pc + 4), -- Load32Aligned(pc + 8), -- offset); -- BRANCH(AND_CHECK_NOT_4_CHARS, offset); -- } -- BYTECODE(AND_CHECK_NOT_CHAR) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4), -- offset); -- BRANCH(AND_CHECK_NOT_CHAR, offset); -- } -- BYTECODE(MINUS_AND_CHECK_NOT_CHAR) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d, %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load16Aligned(pc + 4), -- Load16Aligned(pc + 6), -- offset); -- BRANCH(MINUS_AND_CHECK_NOT_CHAR, offset); -- } -- BYTECODE(CHECK_CHAR_IN_RANGE) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d, %d", -- Load16Aligned(pc + 4), -- Load16Aligned(pc + 6), -- offset); -- BRANCH(CHECK_CHAR_IN_RANGE, offset); -- } -- BYTECODE(CHECK_CHAR_NOT_IN_RANGE) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " %d, %d, %d", -- Load16Aligned(pc + 4), -- Load16Aligned(pc + 6), -- offset); -- BRANCH(CHECK_CHAR_NOT_IN_RANGE, offset); -- } -- BYTECODE(CHECK_BIT_IN_TABLE) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, " -- "%02x %02x %02x %02x %02x %02x %02x %02x " -- "%02x %02x %02x %02x %02x %02x %02x %02x", -- offset, -- pc[8], pc[9], pc[10], pc[11], -- pc[12], pc[13], pc[14], pc[15], -- pc[16], pc[17], pc[18], pc[19], -- pc[20], pc[21], pc[22], pc[23]); -- BRANCH(CHECK_BIT_IN_TABLE, offset); -- } -- BYTECODE(CHECK_LT) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_LT, offset); -- } -- BYTECODE(CHECK_GT) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_GT, offset); -- } -- BYTECODE(CHECK_REGISTER_LT) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " reg[%d], %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4), -- offset); -- BRANCH(CHECK_REGISTER_LT, offset); -- } -- BYTECODE(CHECK_REGISTER_GE) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " reg[%d], %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4), -- offset); -- BRANCH(CHECK_REGISTER_GE, offset); -- } -- BYTECODE(CHECK_REGISTER_EQ_POS) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_REGISTER_EQ_POS, offset); -- } -- BYTECODE(CHECK_NOT_REGS_EQUAL) { -- int32_t offset = Load32Aligned(pc + 8); -- fprintf(stderr, " reg[%d], %d, %d", -- insn >> irregexp::BYTECODE_SHIFT, -- Load32Aligned(pc + 4), -- offset); -- BRANCH(CHECK_NOT_REGS_EQUAL, offset); -- } -- BYTECODE(CHECK_NOT_BACK_REF) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_NOT_BACK_REF, offset); -- } -- BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_NOT_BACK_REF_NO_CASE, offset); -- } -- BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_UNICODE) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " reg[%d], %d", -- insn >> irregexp::BYTECODE_SHIFT, -- offset); -- BRANCH(CHECK_NOT_BACK_REF_NO_CASE_UNICODE, offset); -- } -- BYTECODE(CHECK_AT_START) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d", -- offset); -- BRANCH(CHECK_AT_START, offset); -- } -- BYTECODE(CHECK_NOT_AT_START) { -- int32_t offset = Load32Aligned(pc + 4); -- fprintf(stderr, " %d", -- offset); -- BRANCH(CHECK_NOT_AT_START, offset); -- } -- BYTECODE(SET_CURRENT_POSITION_FROM_END) { -- fprintf(stderr, " %u", -- static_cast(insn) >> irregexp::BYTECODE_SHIFT); -- ADVANCE(SET_CURRENT_POSITION_FROM_END); -- } -- default: -- MOZ_CRASH("Bad bytecode"); -- } -- } -- --#undef BYTECODE --#undef ADVANCE --#undef STOP --#undef JUMP --#undef BRANCH -- -- return true; --} -- --/* static */ bool --RegExpObject::dumpBytecode(JSContext* cx, Handle regexp, -- bool match_only, HandleLinearString input) --{ -- RootedRegExpShared shared(cx, getShared(cx, regexp)); -- if (!shared) -- return false; -- -- return RegExpShared::dumpBytecode(cx, &shared, match_only, input); --} --#endif -- - template - static MOZ_ALWAYS_INLINE bool - IsRegExpMetaChar(CharT ch) -@@ -971,8 +591,10 @@ js::StringHasRegExpMetaChars(JSLinearStr - - /* RegExpShared */ - --RegExpShared::RegExpShared(JSAtom* source, RegExpFlag flags) -- : source(source), flags(flags), canStringMatch(false), parenCount(0) -+RegExpShared::RegExpShared(JSAtom* source, RegExpFlags flags) -+ : source(source) -+ , flags(flags) -+ , pairCount_(0) - {} - - void -@@ -983,8 +605,14 @@ RegExpShared::traceChildren(JSTracer* tr - discardJitCode(); - - TraceNullableEdge(trc, &source, "RegExpShared source"); -- for (auto& comp : compilationArray) -- TraceNullableEdge(trc, &comp.jitCode, "RegExpShared code"); -+ if (kind() == RegExpShared::Kind::Atom) { -+ TraceNullableEdge(trc, &patternAtom_, "RegExpShared pattern atom"); -+ } else { -+ for (auto& comp : compilationArray) { -+ TraceNullableEdge(trc, &comp.jitCode, "RegExpShared code"); -+ } -+ TraceNullableEdge(trc, &groupsTemplate_, "RegExpShared groups template"); -+ } - } - - void -@@ -997,219 +625,287 @@ RegExpShared::discardJitCode() - tables.clearAndFree(); - } - -+ - void - RegExpShared::finalize(FreeOp* fop) - { -- for (auto& comp : compilationArray) -- js_free(comp.byteCode); -+ for (auto& comp : compilationArray) { -+ if (comp.byteCode) { -+ js_free(comp.byteCode); -+ } -+ } -+ if (namedCaptureIndices_) { -+ js_free(namedCaptureIndices_); -+ } - tables.~JitCodeTables(); - } - --/* static */ bool --RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input, -- CompilationMode mode, ForceByteCodeEnum force) --{ -- TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx); -- AutoTraceLog logCompile(logger, TraceLogger_IrregexpCompile); -- -- RootedAtom pattern(cx, re->source); -- return compile(cx, re, pattern, input, mode, force); --} -- --/* static */ bool --RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleAtom pattern, -- HandleLinearString input, CompilationMode mode, ForceByteCodeEnum force) --{ -- if (!re->ignoreCase() && !StringHasRegExpMetaChars(pattern)) -- re->canStringMatch = true; -- -- CompileOptions options(cx); -- frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); -- -- LifoAllocScope scope(&cx->tempLifoAlloc()); -- -- /* Parse the pattern. */ -- irregexp::RegExpCompileData data; -- if (!irregexp::ParsePattern(dummyTokenStream, cx->tempLifoAlloc(), pattern, -- re->multiline(), mode == MatchOnly, re->unicode(), -- re->ignoreCase(), re->global(), re->sticky(), &data)) -- { -- return false; -+/* static */ -+bool -+RegExpShared::compileIfNecessary(JSContext* cx, -+ MutableHandleRegExpShared re, -+ HandleLinearString input, -+ RegExpShared::CodeKind codeKind) -+{ -+ if (codeKind == RegExpShared::CodeKind::Any) { -+ // We start by interpreting regexps, then compile them once they are -+ // sufficiently hot. For very long input strings, we tier up eagerly. -+ codeKind = RegExpShared::CodeKind::Bytecode; -+ if (re->markedForTierUp(cx) || input->length() > 1000) { -+ codeKind = RegExpShared::CodeKind::Jitcode; - } -+ } - -- re->parenCount = data.capture_count; -- -- JitCodeTables tables; -- irregexp::RegExpCode code = irregexp::CompilePattern(cx, re, &data, input, -- false /* global() */, -- re->ignoreCase(), -- input->hasLatin1Chars(), -- mode == MatchOnly, -- force == ForceByteCode, -- re->sticky(), -- re->unicode(), -- tables); -- if (code.empty()) -- return false; -+ // Fall back to bytecode if native codegen is not available. -+ if (!IsNativeRegExpEnabled(cx) && codeKind == RegExpShared::CodeKind::Jitcode) { -+ codeKind = RegExpShared::CodeKind::Bytecode; -+ } - -- MOZ_ASSERT(!code.jitCode || !code.byteCode); -- MOZ_ASSERT_IF(force == ForceByteCode, code.byteCode); -+ bool needsCompile = false; -+ if (re->kind() == RegExpShared::Kind::Unparsed) { -+ needsCompile = true; -+ } - -- RegExpCompilation& compilation = re->compilation(mode, input->hasLatin1Chars()); -- if (code.jitCode) { -- // First copy the tables. GC can purge the tables if the RegExpShared -- // has no JIT code, so it's important to do this right before setting -- // compilation.jitCode (to ensure no purging happens between adding the -- // tables and setting the JIT code). -- for (size_t i = 0; i < tables.length(); i++) { -- if (!re->addTable(Move(tables[i]))) -- return false; -- } -- compilation.jitCode = code.jitCode; -- } else if (code.byteCode) { -- MOZ_ASSERT(tables.empty(), "RegExpInterpreter does not use data tables"); -- compilation.byteCode = code.byteCode; -+ if (re->kind() == RegExpShared::Kind::RegExp) { -+ if (!re->isCompiled(input->hasLatin1Chars(), codeKind)) { -+ needsCompile = true; - } -+ } - -- return true; --} -- --/* static */ bool --RegExpShared::compileIfNecessary(JSContext* cx, MutableHandleRegExpShared re, -- HandleLinearString input, CompilationMode mode, -- ForceByteCodeEnum force) --{ -- if (re->isCompiled(mode, input->hasLatin1Chars(), force)) -- return true; -- return compile(cx, re, input, mode, force); -+ if (needsCompile) { -+ return irregexp::CompilePattern(cx, re, input, codeKind); -+ } -+ return true; - } - --/* static */ RegExpRunStatus --RegExpShared::execute(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input, -- size_t start, MatchPairs* matches, size_t* endIndex) -+/* static */ -+RegExpRunStatus -+RegExpShared::execute(JSContext* cx, -+ MutableHandleRegExpShared re, -+ HandleLinearString input, -+ size_t start, -+ MatchPairs* matches) - { -- MOZ_ASSERT_IF(matches, !endIndex); -- MOZ_ASSERT_IF(!matches, endIndex); -- TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx); -+ MOZ_ASSERT(matches); - -- CompilationMode mode = matches ? Normal : MatchOnly; -+ // TODO: Add tracelogger support - - /* Compile the code at point-of-use. */ -- if (!compileIfNecessary(cx, re, input, mode, DontForceByteCode)) -+ if (!compileIfNecessary(cx, re, input, RegExpShared::CodeKind::Any)) { - return RegExpRunStatus_Error; -+ } - - /* - * Ensure sufficient memory for output vector. - * No need to initialize it. The RegExp engine fills them in on a match. - */ -- if (matches && !matches->allocOrExpandArray(re->pairCount())) { -+ if (!matches->allocOrExpandArray(re->pairCount())) { - ReportOutOfMemory(cx); - return RegExpRunStatus_Error; - } - -- size_t length = input->length(); -+ if (re->kind() == RegExpShared::Kind::Atom) { -+ return RegExpShared::executeAtom(re, input, start, matches); -+ } - -- // Reset the Irregexp backtrack stack if it grows during execution. -- irregexp::RegExpStackScope stackScope(cx); -+ /* -+ * Ensure sufficient memory for output vector. -+ * No need to initialize it. The RegExp engine fills them in on a match. -+ */ -+ if (!matches->allocOrExpandArray(re->pairCount())) { -+ ReportOutOfMemory(cx); -+ return RegExpRunStatus_Error; -+ } -+ -+ uint32_t interruptRetries = 0; -+ const uint32_t maxInterruptRetries = 4; -+ do { -+ RegExpRunStatus result = irregexp::Execute(cx, re, input, start, matches); - -- if (re->canStringMatch) { -- MOZ_ASSERT(re->pairCount() == 1); -- size_t sourceLength = re->source->length(); -- if (re->sticky()) { -- // First part checks size_t overflow. -- if (sourceLength + start < sourceLength || sourceLength + start > length) -- return RegExpRunStatus_Success_NotFound; -- if (!HasSubstringAt(input, re->source, start)) -- return RegExpRunStatus_Success_NotFound; -- -- if (matches) { -- (*matches)[0].start = start; -- (*matches)[0].limit = start + sourceLength; -- -- matches->checkAgainst(length); -- } else if (endIndex) { -- *endIndex = start + sourceLength; -+ if (result == RegExpRunStatus_Error) { -+ /* Execute can return RegExpRunStatus_Error: -+ * -+ * 1. If the native stack overflowed -+ * 2. If the backtrack stack overflowed -+ * 3. If an interrupt was requested during execution. -+ * -+ * In the first two cases, we want to throw an error. In the -+ * third case, we want to handle the interrupt and try again. -+ * We cap the number of times we will retry. -+ */ -+ if (cx->hasPendingInterrupt()) { -+ if (!CheckForInterrupt(cx)) { -+ return RegExpRunStatus_Error; -+ } -+ if (interruptRetries++ < maxInterruptRetries) { -+ // The initial execution may have been interpreted, or the -+ // interrupt may have triggered a GC that discarded jitcode. -+ // To maximize the chance of succeeding before being -+ // interrupted again, we want to ensure we are compiled. -+ if (!compileIfNecessary(cx, re, input, -+ RegExpShared::CodeKind::Jitcode)) { -+ return RegExpRunStatus_Error; -+ } -+ continue; - } -- return RegExpRunStatus_Success; -+ } -+ // If we have run out of retries, this regexp takes too long to -+ // execute. -+ ReportOverRecursed(cx); -+ return RegExpRunStatus_Error; - } - -- int res = StringFindPattern(input, re->source, start); -- if (res == -1) -- return RegExpRunStatus_Success_NotFound; -+ MOZ_ASSERT(result == RegExpRunStatus_Success || -+ result == RegExpRunStatus_Success_NotFound); - -- if (matches) { -- (*matches)[0].start = res; -- (*matches)[0].limit = res + sourceLength; -- -- matches->checkAgainst(length); -- } else if (endIndex) { -- *endIndex = res + sourceLength; -- } -- return RegExpRunStatus_Success; -+ return result; -+ } while (true); -+ -+ MOZ_CRASH("Unreachable"); -+} -+ -+void RegExpShared::useAtomMatch(HandleAtom pattern) { -+ MOZ_ASSERT(kind() == RegExpShared::Kind::Unparsed); -+ kind_ = RegExpShared::Kind::Atom; -+ patternAtom_ = pattern; -+ pairCount_ = 1; -+} -+ -+void RegExpShared::useRegExpMatch(size_t pairCount) { -+ MOZ_ASSERT(kind() == RegExpShared::Kind::Unparsed); -+ kind_ = RegExpShared::Kind::RegExp; -+ pairCount_ = pairCount; -+ ticks_ = jit::JitOptions.regexpWarmUpThreshold; -+} -+ -+/* static */ -+bool -+RegExpShared::initializeNamedCaptures(JSContext* cx, -+ HandleRegExpShared re, -+ HandleNativeObject namedCaptures) -+{ -+ MOZ_ASSERT(!re->groupsTemplate_); -+ MOZ_ASSERT(!re->namedCaptureIndices_); -+ -+ // The irregexp parser returns named capture information in the form -+ // of an ArrayObject, where even elements store the capture name and -+ // odd elements store the corresponding capture index. We create a -+ // template object with a property for each capture name, and store -+ // the capture indices as a heap-allocated array. -+ MOZ_ASSERT(namedCaptures->getDenseInitializedLength() % 2 == 0); -+ uint32_t numNamedCaptures = namedCaptures->getDenseInitializedLength() / 2; -+ -+ // Create a plain template object. -+ RootedPlainObject templateObject(cx, NewObjectWithGivenProto(cx, nullptr, TenuredObject)); -+ if (!templateObject) { -+ return false; - } - -- do { -- jit::JitCode* code = re->compilation(mode, input->hasLatin1Chars()).jitCode; -- if (!code) -- break; -+ // Create a new group for the template. -+ Rooted proto(cx, templateObject->taggedProto()); -+ ObjectGroup* group = -+ ObjectGroupCompartment::makeGroup(cx, templateObject->getClass(), proto); -+ if (!group) { -+ return false; -+ } -+ templateObject->setGroup(group); - -- RegExpRunStatus result; -- { -- AutoTraceLog logJIT(logger, TraceLogger_IrregexpExecute); -- AutoCheckCannotGC nogc; -- if (input->hasLatin1Chars()) { -- const Latin1Char* chars = input->latin1Chars(nogc); -- result = irregexp::ExecuteCode(cx, code, chars, start, length, matches, endIndex); -- } else { -- const char16_t* chars = input->twoByteChars(nogc); -- result = irregexp::ExecuteCode(cx, code, chars, start, length, matches, endIndex); -- } -+ // Initialize the properties of the template. -+ RootedId id(cx); -+ RootedValue dummyString(cx, StringValue(cx->runtime()->emptyString)); -+ for (uint32_t i = 0; i < numNamedCaptures; i++) { -+ JSString* name = namedCaptures->getDenseElement(i * 2).toString(); -+ id = NameToId(name->asAtom().asPropertyName()); -+ if (!NativeDefineProperty( -+ cx, templateObject, id, dummyString, nullptr, nullptr, JSPROP_ENUMERATE)) { -+ return false; - } -+ AddTypePropertyId(cx, templateObject, id, UndefinedValue()); -+ } - -- if (result == RegExpRunStatus_Error) { -- // An 'Error' result is returned if a stack overflow guard or -- // interrupt guard failed. If CheckOverRecursed doesn't throw, break -- // out and retry the regexp in the bytecode interpreter, which can -- // execute while tolerating future interrupts. Otherwise, if we keep -- // getting interrupted we will never finish executing the regexp. -- if (!jit::CheckOverRecursed(cx)) -- return RegExpRunStatus_Error; -- break; -- } -+ // Allocate the capture index array. -+ uint32_t arraySize = numNamedCaptures * sizeof(uint32_t); -+ uint32_t* captureIndices = static_cast(js_malloc(arraySize)); -+ if (!captureIndices) { -+ ReportOutOfMemory(cx); -+ return false; -+ } - -- if (result == RegExpRunStatus_Success_NotFound) -- return RegExpRunStatus_Success_NotFound; -+ // Populate the capture index array -+ for (uint32_t i = 0; i < numNamedCaptures; i++) { -+ captureIndices[i] = namedCaptures->getDenseElement(i * 2 + 1).toInt32(); -+ } - -- MOZ_ASSERT(result == RegExpRunStatus_Success); -+ re->numNamedCaptures_ = numNamedCaptures; -+ re->groupsTemplate_ = templateObject; -+ re->namedCaptureIndices_ = captureIndices; -+ // js::AddCellMemory(re, arraySize, MemoryUse::RegExpSharedNamedCaptureData); -+ return true; -+} - -- if (matches) -- matches->checkAgainst(length); -- return RegExpRunStatus_Success; -- } while (false); -+void RegExpShared::tierUpTick() { -+ MOZ_ASSERT(kind() == RegExpShared::Kind::RegExp); -+ if (ticks_ > 0) { -+ ticks_--; -+ } -+} - -- // Compile bytecode for the RegExp if necessary. -- if (!compileIfNecessary(cx, re, input, mode, ForceByteCode)) -- return RegExpRunStatus_Error; -+bool RegExpShared::markedForTierUp(JSContext* cx) const { -+ if (!IsNativeRegExpEnabled(cx)) { -+ return false; -+ } -+ if (kind() != RegExpShared::Kind::RegExp) { -+ return false; -+ } -+ return ticks_ == 0; -+} - -- uint8_t* byteCode = re->compilation(mode, input->hasLatin1Chars()).byteCode; -- AutoTraceLog logInterpreter(logger, TraceLogger_IrregexpExecute); -+/* static */ -+RegExpRunStatus ExecuteAtomImpl(RegExpShared* re, JSLinearString* input, -+ size_t start, MatchPairs* matches) -+{ -+ MOZ_ASSERT(re->pairCount() == 1); -+ size_t length = input->length(); -+ size_t searchLength = re->patternAtom()->length(); - -- AutoStableStringChars inputChars(cx); -- if (!inputChars.init(cx, input)) -- return RegExpRunStatus_Error; -+ if (re->sticky()) { -+ // First part checks size_t overflow. -+ if (searchLength + start < searchLength || searchLength + start > length) { -+ return RegExpRunStatus_Success_NotFound; -+ } -+ if (!HasSubstringAt(input, re->patternAtom(), start)) { -+ return RegExpRunStatus_Success_NotFound; -+ } - -- RegExpRunStatus result; -- if (inputChars.isLatin1()) { -- const Latin1Char* chars = inputChars.latin1Range().begin().get(); -- result = irregexp::InterpretCode(cx, byteCode, chars, start, length, matches, endIndex); -- } else { -- const char16_t* chars = inputChars.twoByteRange().begin().get(); -- result = irregexp::InterpretCode(cx, byteCode, chars, start, length, matches, endIndex); -+ (*matches)[0].start = start; -+ (*matches)[0].limit = start + searchLength; -+ matches->checkAgainst(input->length()); -+ return RegExpRunStatus_Success; -+ } -+ -+ int res = StringFindPattern(input, re->patternAtom(), start); -+ if (res == -1) { -+ return RegExpRunStatus_Success_NotFound; - } - -- if (result == RegExpRunStatus_Success && matches) -- matches->checkAgainst(length); -- return result; -+ (*matches)[0].start = res; -+ (*matches)[0].limit = res + searchLength; -+ matches->checkAgainst(input->length()); -+ return RegExpRunStatus_Success; -+} -+ -+RegExpRunStatus js::ExecuteRegExpAtomRaw(RegExpShared* re, -+ JSLinearString* input, size_t start, -+ MatchPairs* matchPairs) { -+ JS::AutoCheckCannotGC nogc; -+ return ExecuteAtomImpl(re, input, start, matchPairs); -+} -+ -+/* static */ -+RegExpRunStatus RegExpShared::executeAtom(MutableHandleRegExpShared re, -+ HandleLinearString input, -+ size_t start, MatchPairs* matches) { -+ return ExecuteAtomImpl(re, input, start, matches); - } - - size_t -@@ -1246,14 +942,16 @@ RegExpCompartment::createMatchResultTemp - /* Create template array object */ - RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount, - nullptr, TenuredObject)); -- if (!templateObject) -- return matchResultTemplateObject_; // = nullptr -+ if (!templateObject) { -+ return nullptr; -+ } - - // Create a new group for the template. - Rooted proto(cx, templateObject->taggedProto()); - ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, templateObject->getClass(), proto); -- if (!group) -- return matchResultTemplateObject_; // = nullptr -+ if (!group) { -+ return nullptr; -+ } - templateObject->setGroup(group); - - /* Set dummy index property */ -@@ -1261,23 +959,36 @@ RegExpCompartment::createMatchResultTemp - if (!NativeDefineProperty(cx, templateObject, cx->names().index, index, nullptr, nullptr, - JSPROP_ENUMERATE)) - { -- return matchResultTemplateObject_; // = nullptr -+ return nullptr; - } - - /* Set dummy input property */ - RootedValue inputVal(cx, StringValue(cx->runtime()->emptyString)); -- if (!NativeDefineProperty(cx, templateObject, cx->names().input, inputVal, nullptr, nullptr, -- JSPROP_ENUMERATE)) -- { -- return matchResultTemplateObject_; // = nullptr -+ if (!NativeDefineProperty( -+ cx, templateObject, cx->names().input, inputVal, nullptr, nullptr, JSPROP_ENUMERATE)) { -+ return nullptr; - } - -+ /* Set dummy groups property */ -+ RootedValue groupsVal(cx, UndefinedValue()); -+ if (!NativeDefineProperty( -+ cx, templateObject, cx->names().groups, groupsVal, nullptr, nullptr, JSPROP_ENUMERATE)) { -+ return nullptr; -+ } -+ AddTypePropertyId(cx, templateObject, NameToId(cx->names().groups), TypeSet::AnyObjectType()); -+ - // Make sure that the properties are in the right slots. -- DebugOnly shape = templateObject->lastProperty(); -- MOZ_ASSERT(shape->previous()->slot() == 0 && -- shape->previous()->propidRef() == NameToId(cx->names().index)); -- MOZ_ASSERT(shape->slot() == 1 && -- shape->propidRef() == NameToId(cx->names().input)); -+#ifdef DEBUG -+ Shape* groupsShape = templateObject->lastProperty(); -+ MOZ_ASSERT(groupsShape->slot() == 0 && -+ groupsShape->propidRef() == NameToId(cx->names().groups)); -+ Shape* inputShape = groupsShape->previous().get(); -+ MOZ_ASSERT(inputShape->slot() == 1 && -+ inputShape->propidRef() == NameToId(cx->names().input)); -+ Shape* indexShape = inputShape->previous().get(); -+ MOZ_ASSERT(indexShape->slot() == 2 && -+ indexShape->propidRef() == NameToId(cx->names().index)); -+#endif - - // Make sure type information reflects the indexed properties which might - // be added. -@@ -1321,7 +1032,7 @@ RegExpCompartment::sweep() - } - - RegExpShared* --RegExpZone::get(JSContext* cx, HandleAtom source, RegExpFlag flags) -+RegExpZone::get(JSContext* cx, HandleAtom source, RegExpFlags flags) - { - DependentAddPtr p(cx, set_, Key(source, flags)); - if (p) -@@ -1344,7 +1055,7 @@ RegExpZone::get(JSContext* cx, HandleAto - RegExpShared* - RegExpZone::get(JSContext* cx, HandleAtom atom, JSString* opt) - { -- RegExpFlag flags = RegExpFlag(0); -+ RegExpFlags flags = RegExpFlag::NoFlags; - if (opt && !ParseRegExpFlags(cx, opt, &flags)) - return nullptr; - -@@ -1388,27 +1099,30 @@ js::CloneRegExpObject(JSContext* cx, Han - - template - static bool --ParseRegExpFlags(const CharT* chars, size_t length, RegExpFlag* flagsOut, char16_t* invalidFlag) -+ParseRegExpFlags(const CharT* chars, size_t length, RegExpFlags* flagsOut, char16_t* invalidFlag) - { -- *flagsOut = RegExpFlag(0); -+ *flagsOut = RegExpFlag::NoFlags; - - for (size_t i = 0; i < length; i++) { -- RegExpFlag flag; -+ uint8_t flag; - switch (chars[i]) { - case 'i': -- flag = IgnoreCaseFlag; -+ flag = RegExpFlag::IgnoreCase; - break; - case 'g': -- flag = GlobalFlag; -+ flag = RegExpFlag::Global; - break; - case 'm': -- flag = MultilineFlag; -+ flag = RegExpFlag::Multiline; - break; - case 'y': -- flag = StickyFlag; -+ flag = RegExpFlag::Sticky; - break; - case 'u': -- flag = UnicodeFlag; -+ flag = RegExpFlag::Unicode; -+ break; -+ case 's': -+ flag = RegExpFlag::DotAll; - break; - default: - *invalidFlag = chars[i]; -@@ -1418,14 +1132,14 @@ ParseRegExpFlags(const CharT* chars, siz - *invalidFlag = chars[i]; - return false; - } -- *flagsOut = RegExpFlag(*flagsOut | flag); -+ *flagsOut = RegExpFlags(*flagsOut | flag); - } - - return true; - } - - bool --js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut) -+js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlags* flagsOut) - { - JSLinearString* linear = flagStr->ensureLinear(cx); - if (!linear) -@@ -1445,7 +1159,7 @@ js::ParseRegExpFlags(JSContext* cx, JSSt - - if (!ok) { - TwoByteChars range(&invalidFlag, 1); -- UniqueChars utf8(JS::CharsToNewUTF8CharsZ(nullptr, range).c_str()); -+ UniqueChars utf8(JS::CharsToNewUTF8CharsZ(cx, range).c_str()); - if (!utf8) - return false; - JS_ReportErrorFlagsAndNumberUTF8(cx, JSREPORT_ERROR, GetErrorMessage, nullptr, -@@ -1463,18 +1177,18 @@ js::XDRScriptRegExpObject(XDRState - /* NB: Keep this in sync with CloneScriptRegExpObject. */ - - RootedAtom source(xdr->cx()); -- uint32_t flagsword = 0; -+ uint8_t flags = 0; - - if (mode == XDR_ENCODE) { - MOZ_ASSERT(objp); - RegExpObject& reobj = *objp; - source = reobj.getSource(); -- flagsword = reobj.getFlags(); -+ flags = reobj.getFlags().value(); - } -- if (!XDRAtom(xdr, &source) || !xdr->codeUint32(&flagsword)) -+ if (!XDRAtom(xdr, &source) || !xdr->codeUint8(&flags)) - return false; - if (mode == XDR_DECODE) { -- RegExpObject* reobj = RegExpObject::create(xdr->cx(), source, RegExpFlag(flagsword), -+ RegExpObject* reobj = RegExpObject::create(xdr->cx(), source, RegExpFlags(flags), - xdr->lifoAlloc(), TenuredObject); - if (!reobj) - return false; -@@ -1513,3 +1227,162 @@ JS::ubi::Concrete::size(mo - return js::gc::Arena::thingSize(gc::AllocKind::REGEXP_SHARED) + - get().sizeOfExcludingThis(mallocSizeOf); - } -+ -+/* -+ * Public API functions for Regular Expressions. -+ */ -+JS_PUBLIC_API(JSObject*) -+JS::NewRegExpObject(JSContext* cx, const char* bytes, size_t length, RegExpFlags flags) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ ScopedJSFreePtr chars(InflateString(cx, bytes, length)); -+ if (!chars) -+ return nullptr; -+ -+ return RegExpObject::create(cx, chars.get(), length, flags, cx->tempLifoAlloc(), -+ GenericObject); -+} -+ -+JS_PUBLIC_API(JSObject*) -+JS::NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, RegExpFlags flags) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ return RegExpObject::create(cx, chars, length, flags, cx->tempLifoAlloc(), -+ GenericObject); -+} -+ -+JS_PUBLIC_API(bool) -+JS::SetRegExpInput(JSContext* cx, HandleObject obj, HandleString input) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ assertSameCompartment(cx, input); -+ -+ Handle global = obj.as(); -+ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); -+ if (!res) -+ return false; -+ -+ res->reset(input); -+ return true; -+} -+ -+JS_PUBLIC_API(bool) -+JS::ClearRegExpStatics(JSContext* cx, HandleObject obj) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ MOZ_ASSERT(obj); -+ -+ Handle global = obj.as(); -+ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); -+ if (!res) -+ return false; -+ -+ res->clear(); -+ return true; -+} -+ -+JS_PUBLIC_API(bool) -+JS::ExecuteRegExp(JSContext* cx, HandleObject obj, HandleObject reobj, char16_t* chars, -+ size_t length, size_t* indexp, bool test, MutableHandleValue rval) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ Handle global = obj.as(); -+ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); -+ if (!res) -+ return false; -+ -+ RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); -+ if (!input) -+ return false; -+ -+ return ExecuteRegExpLegacy(cx, res, reobj.as(), input, indexp, test, rval); -+} -+ -+JS_PUBLIC_API(bool) -+JS::ExecuteRegExpNoStatics(JSContext* cx, HandleObject obj, char16_t* chars, size_t length, -+ size_t* indexp, bool test, MutableHandleValue rval) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); -+ if (!input) -+ return false; -+ -+ return ExecuteRegExpLegacy(cx, nullptr, obj.as(), input, indexp, test, -+ rval); -+} -+ -+JS_PUBLIC_API(bool) -+JS::ObjectIsRegExp(JSContext* cx, HandleObject obj, bool* isRegExp) -+{ -+ assertSameCompartment(cx, obj); -+ -+ ESClass cls; -+ if (!GetBuiltinClass(cx, obj, &cls)) -+ return false; -+ -+ *isRegExp = cls == ESClass::RegExp; -+ return true; -+} -+ -+JS_PUBLIC_API(RegExpFlags) -+JS::GetRegExpFlags(JSContext* cx, HandleObject obj) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ RegExpShared* shared = RegExpToShared(cx, obj); -+ if (!shared) -+ return RegExpFlag::NoFlags; -+ return shared->getFlags(); -+} -+ -+JS_PUBLIC_API(JSString*) -+JS::GetRegExpSource(JSContext* cx, HandleObject obj) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ RegExpShared* shared = RegExpToShared(cx, obj); -+ if (!shared) -+ return nullptr; -+ return shared->getSource(); -+} -+ -+JS_PUBLIC_API(bool) -+JS::CheckRegExpSyntax(JSContext* cx, -+ const char16_t* chars, -+ size_t length, -+ RegExpFlags flags, -+ MutableHandleValue error) -+{ -+ AssertHeapIsIdle(); -+ CHECK_REQUEST(cx); -+ -+ CompileOptions options(cx); -+ frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); -+ -+ mozilla::Range source(chars, length); -+ bool success = irregexp::CheckPatternSyntax(cx, dummyTokenStream, source, flags); -+ error.set(UndefinedValue()); -+ if (!success) { -+ // We can fail because of OOM or over-recursion even if the syntax is valid. -+ if (cx->isThrowingOutOfMemory() || cx->isThrowingOverRecursed()) { -+ return false; -+ } -+ if (!cx->getPendingException(error)) { -+ return false; -+ } -+ cx->clearPendingException(); -+ } -+ return true; -+} -diff -Nrup mozilla/js/src/vm/RegExpObject.h mozilla-OK/js/src/vm/RegExpObject.h ---- mozilla/js/src/vm/RegExpObject.h 2021-10-26 19:49:54.000000000 +0300 -+++ mozilla-OK/js/src/vm/RegExpObject.h 2022-06-16 00:04:24.709115620 +0300 -@@ -17,6 +17,7 @@ - #include "builtin/SelfHostingDefines.h" - #include "gc/Marking.h" - #include "js/GCHashTable.h" -+#include "js/RegExpFlags.h" - #include "proxy/Proxy.h" - #include "vm/ArrayObject.h" - #include "vm/RegExpShared.h" -@@ -73,20 +74,20 @@ class RegExpObject : public NativeObject - - template - static RegExpObject* -- create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, LifoAlloc& alloc, -+ create(JSContext* cx, const CharT* chars, size_t length, JS::RegExpFlags flags, LifoAlloc& alloc, - NewObjectKind newKind); - - template - static RegExpObject* -- create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, -+ create(JSContext* cx, const CharT* chars, size_t length, JS::RegExpFlags flags, - frontend::TokenStreamAnyChars& ts, LifoAlloc& alloc, NewObjectKind kind); - - static RegExpObject* -- create(JSContext* cx, HandleAtom atom, RegExpFlag flags, LifoAlloc& alloc, -+ create(JSContext* cx, HandleAtom atom, JS::RegExpFlags flags, LifoAlloc& alloc, - NewObjectKind newKind); - - static RegExpObject* -- create(JSContext* cx, HandleAtom atom, RegExpFlag flags, frontend::TokenStreamAnyChars& ts, -+ create(JSContext* cx, HandleAtom atom, JS::RegExpFlags flags, frontend::TokenStreamAnyChars& ts, - LifoAlloc& alloc, NewObjectKind newKind); - - /* -@@ -135,25 +136,28 @@ class RegExpObject : public NativeObject - - static unsigned flagsSlot() { return FLAGS_SLOT; } - -- RegExpFlag getFlags() const { -- return RegExpFlag(getFixedSlot(FLAGS_SLOT).toInt32()); -- } -- void setFlags(RegExpFlag flags) { -- setSlot(FLAGS_SLOT, Int32Value(flags)); -- } -+ JS::RegExpFlags getFlags() const -+ { -+ return JS::RegExpFlags(getFixedSlot(FLAGS_SLOT).toInt32()); -+ } -+ void setFlags(JS::RegExpFlags flags) { setFixedSlot(FLAGS_SLOT, Int32Value(flags.value())); }; -+ -+ bool global() const { return getFlags().global(); } -+ bool ignoreCase() const { return getFlags().ignoreCase(); } -+ bool multiline() const { return getFlags().multiline(); } -+ bool dotAll() const { return getFlags().dotAll(); } -+ bool unicode() const { return getFlags().unicode(); } -+ bool sticky() const { return getFlags().sticky(); } - -- bool ignoreCase() const { return getFlags() & IgnoreCaseFlag; } -- bool global() const { return getFlags() & GlobalFlag; } -- bool multiline() const { return getFlags() & MultilineFlag; } -- bool sticky() const { return getFlags() & StickyFlag; } -- bool unicode() const { return getFlags() & UnicodeFlag; } -- -- static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask); -+ static bool isOriginalFlagGetter(JSNative native, JS::RegExpFlags* mask); - - static RegExpShared* getShared(JSContext* cx, Handle regexp); - -- bool hasShared() { -- return !!sharedRef(); -+ bool hasShared() const { return !!sharedRef(); } -+ -+ RegExpShared* getShared() const { -+ MOZ_ASSERT(hasShared()); -+ return sharedRef(); - } - - void setShared(RegExpShared& shared) { -@@ -161,7 +165,7 @@ class RegExpObject : public NativeObject - sharedRef().init(&shared); - } - -- PreBarriered& sharedRef() { -+ PreBarriered& sharedRef() const { - auto& ref = NativeObject::privateRef(PRIVATE_SLOT); - return reinterpret_cast&>(ref); - } -@@ -169,16 +173,17 @@ class RegExpObject : public NativeObject - static void trace(JSTracer* trc, JSObject* obj); - void trace(JSTracer* trc); - -- void initIgnoringLastIndex(JSAtom* source, RegExpFlag flags); -+ void initIgnoringLastIndex(JSAtom* source, JS::RegExpFlags flags); - - // NOTE: This method is *only* safe to call on RegExps that haven't been - // exposed to script, because it requires that the "lastIndex" - // property be writable. -- void initAndZeroLastIndex(JSAtom* source, RegExpFlag flags, JSContext* cx); -+ void initAndZeroLastIndex(JSAtom* source, JS::RegExpFlags flags, JSContext* cx); - - #ifdef DEBUG -- static MOZ_MUST_USE bool dumpBytecode(JSContext* cx, Handle regexp, -- bool match_only, HandleLinearString input); -+ static MOZ_MUST_USE bool dumpBytecode(JSContext* cx, -+ Handle regexp, -+ HandleLinearString input); - #endif - - private: -@@ -199,7 +204,7 @@ class RegExpObject : public NativeObject - * N.B. flagStr must be rooted. - */ - bool --ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut); -+ParseRegExpFlags(JSContext* cx, JSString* flagStr, JS::RegExpFlags* flagsOut); - - /* Assuming GetBuiltinClass(obj) is ESClass::RegExp, return a RegExpShared for obj. */ - inline RegExpShared* -diff -Nrup mozilla/js/src/vm/RegExpShared.h mozilla-OK/js/src/vm/RegExpShared.h ---- mozilla/js/src/vm/RegExpShared.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/RegExpShared.h 2022-06-16 00:04:45.972971245 +0300 -@@ -21,8 +21,11 @@ - #include "gc/Barrier.h" - #include "gc/Heap.h" - #include "gc/Marking.h" -+#include "jit/JitOptions.h" -+#include "js/RegExpFlags.h" - #include "js/UbiNode.h" - #include "js/Vector.h" -+#include "irregexp/RegExpTypes.h" - #include "vm/ArrayObject.h" - - struct JSContext; -@@ -39,31 +42,19 @@ using RootedRegExpShared = JS::Rooted; - using MutableHandleRegExpShared = JS::MutableHandle; - --enum RegExpFlag : uint8_t -+enum RegExpRunStatus : int32_t - { -- IgnoreCaseFlag = 0x01, -- GlobalFlag = 0x02, -- MultilineFlag = 0x04, -- StickyFlag = 0x08, -- UnicodeFlag = 0x10, -- -- NoFlags = 0x00, -- AllFlags = 0x1f --}; -- --static_assert(IgnoreCaseFlag == REGEXP_IGNORECASE_FLAG && -- GlobalFlag == REGEXP_GLOBAL_FLAG && -- MultilineFlag == REGEXP_MULTILINE_FLAG && -- StickyFlag == REGEXP_STICKY_FLAG && -- UnicodeFlag == REGEXP_UNICODE_FLAG, -- "Flag values should be in sync with self-hosted JS"); -- --enum RegExpRunStatus --{ -- RegExpRunStatus_Error, -- RegExpRunStatus_Success, -- RegExpRunStatus_Success_NotFound -+ RegExpRunStatus_Error = -1, -+ RegExpRunStatus_Success = 1, -+ RegExpRunStatus_Success_NotFound = 0, - }; -+inline bool IsNativeRegExpEnabled(JSContext* cx) { -+#ifdef JS_CODEGEN_NONE -+ return false; -+#else -+ return cx->options().nativeRegExp(); -+#endif -+} - - /* - * A RegExpShared is the compiled representation of a regexp. A RegExpShared is -@@ -85,17 +76,22 @@ enum RegExpRunStatus - class RegExpShared : public gc::TenuredCell - { - public: -- enum CompilationMode { -- Normal, -- MatchOnly -+ enum class Kind -+ { -+ Unparsed, -+ Atom, -+ RegExp - }; - -- enum ForceByteCodeEnum { -- DontForceByteCode, -- ForceByteCode -+ enum class CodeKind -+ { -+ Bytecode, -+ Jitcode, -+ Any - }; - -- using JitCodeTable = UniquePtr; -+ using ByteCode = js::irregexp::ByteArrayData; -+ using JitCodeTable = js::irregexp::ByteArray; - using JitCodeTables = Vector; - - private: -@@ -105,63 +101,75 @@ class RegExpShared : public gc::TenuredC - struct RegExpCompilation - { - ReadBarriered jitCode; -- uint8_t* byteCode; -+ ByteCode* byteCode; - - RegExpCompilation() : byteCode(nullptr) {} - -- bool compiled(ForceByteCodeEnum force = DontForceByteCode) const { -- return byteCode || (force == DontForceByteCode && jitCode); -+ bool compiled(CodeKind kind = CodeKind::Any) const -+ { -+ switch (kind) { -+ case CodeKind::Bytecode: -+ return !!byteCode; -+ case CodeKind::Jitcode: -+ return !!jitCode; -+ case CodeKind::Any: -+ return !!byteCode || !!jitCode; -+ } -+ MOZ_CRASH("Unreachable"); - } - }; - - /* Source to the RegExp, for lazy compilation. */ - GCPtr source; - -- RegExpFlag flags; -- bool canStringMatch; -- size_t parenCount; -- -- RegExpCompilation compilationArray[4]; -- -- static int CompilationIndex(CompilationMode mode, bool latin1) { -- switch (mode) { -- case Normal: return latin1 ? 0 : 1; -- case MatchOnly: return latin1 ? 2 : 3; -- } -- MOZ_CRASH(); -- } -+ JS::RegExpFlags flags; -+ -+ RegExpShared::Kind kind_ = Kind::Unparsed; -+ GCPtrAtom patternAtom_; -+ uint32_t maxRegisters_ = 0; -+ uint32_t ticks_ = 0; -+ -+ uint32_t numNamedCaptures_ = {}; -+ uint32_t* namedCaptureIndices_ = {}; -+ GCPtr groupsTemplate_ = {}; -+ -+ size_t pairCount_; -+ -+ RegExpCompilation compilationArray[2]; -+ -+ static int CompilationIndex(bool latin1) { return latin1 ? 0 : 1; } - - // Tables referenced by JIT code. - JitCodeTables tables; - - /* Internal functions. */ -- RegExpShared(JSAtom* source, RegExpFlag flags); -- -- static bool compile(JSContext* cx, MutableHandleRegExpShared res, HandleLinearString input, -- CompilationMode mode, ForceByteCodeEnum force); -- static bool compile(JSContext* cx, MutableHandleRegExpShared res, HandleAtom pattern, -- HandleLinearString input, CompilationMode mode, ForceByteCodeEnum force); -+ RegExpShared(JSAtom* source, JS::RegExpFlags flags); - -- static bool compileIfNecessary(JSContext* cx, MutableHandleRegExpShared res, -- HandleLinearString input, CompilationMode mode, -- ForceByteCodeEnum force); -+ static bool compileIfNecessary(JSContext* cx, -+ MutableHandleRegExpShared res, -+ HandleLinearString input, -+ CodeKind code); - -- const RegExpCompilation& compilation(CompilationMode mode, bool latin1) const { -- return compilationArray[CompilationIndex(mode, latin1)]; -+ const RegExpCompilation& compilation(bool latin1) const { -+ return compilationArray[CompilationIndex(latin1)]; - } - -- RegExpCompilation& compilation(CompilationMode mode, bool latin1) { -- return compilationArray[CompilationIndex(mode, latin1)]; -+ RegExpCompilation& compilation(bool latin1) { -+ return compilationArray[CompilationIndex(latin1)]; - } - - public: - ~RegExpShared() = delete; - -- // Execute this RegExp on input starting from searchIndex, filling in -- // matches if specified and otherwise only determining if there is a match. -+ static RegExpRunStatus executeAtom(MutableHandleRegExpShared re, -+ HandleLinearString input, -+ size_t start, -+ MatchPairs* matches); -+ -+ // Execute this RegExp on input starting from searchIndex, filling in matches. - static RegExpRunStatus execute(JSContext* cx, MutableHandleRegExpShared res, - HandleLinearString input, size_t searchIndex, -- MatchPairs* matches, size_t* endIndex); -+ MatchPairs* matches); - - // Register a table with this RegExpShared, and take ownership. - bool addTable(JitCodeTable table) { -@@ -170,30 +178,63 @@ class RegExpShared : public gc::TenuredC - - /* Accessors */ - -- size_t getParenCount() const { -- MOZ_ASSERT(isCompiled()); -- return parenCount; -+ size_t pairCount() const { -+ MOZ_ASSERT(kind() != Kind::Unparsed); -+ return pairCount_; - } - -- /* Accounts for the "0" (whole match) pair. */ -- size_t pairCount() const { return getParenCount() + 1; } -+ RegExpShared::Kind kind() const { return kind_; } -+ -+ // Use simple string matching for this regexp. -+ void useAtomMatch(HandleAtom pattern); -+ -+ // Use the regular expression engine for this regexp. -+ void useRegExpMatch(size_t parenCount); -+ -+ static bool initializeNamedCaptures(JSContext* cx, -+ HandleRegExpShared re, -+ HandleNativeObject namedCaptures); -+ PlainObject* getGroupsTemplate() { return groupsTemplate_; } -+ -+ void tierUpTick(); -+ bool markedForTierUp(JSContext* cx) const; -+ -+ void setByteCode(ByteCode* code, bool latin1) { compilation(latin1).byteCode = code; } -+ ByteCode* getByteCode(bool latin1) const { return compilation(latin1).byteCode; } -+ void setJitCode(jit::JitCode* code, bool latin1) { compilation(latin1).jitCode = code; } -+ jit::JitCode* getJitCode(bool latin1) const { return compilation(latin1).jitCode; } -+ uint32_t getMaxRegisters() const { return maxRegisters_; } -+ void updateMaxRegisters(uint32_t numRegisters) -+ { -+ maxRegisters_ = std::max(maxRegisters_, numRegisters); -+ } -+ -+ uint32_t numNamedCaptures() const { return numNamedCaptures_; } -+ int32_t getNamedCaptureIndex(uint32_t idx) const -+ { -+ MOZ_ASSERT(idx < numNamedCaptures()); -+ MOZ_ASSERT(namedCaptureIndices_); -+ return namedCaptureIndices_[idx]; -+ } - - JSAtom* getSource() const { return source; } -- RegExpFlag getFlags() const { return flags; } -- bool ignoreCase() const { return flags & IgnoreCaseFlag; } -- bool global() const { return flags & GlobalFlag; } -- bool multiline() const { return flags & MultilineFlag; } -- bool sticky() const { return flags & StickyFlag; } -- bool unicode() const { return flags & UnicodeFlag; } -- -- bool isCompiled(CompilationMode mode, bool latin1, -- ForceByteCodeEnum force = DontForceByteCode) const { -- return compilation(mode, latin1).compiled(force); -- } -- bool isCompiled() const { -- return isCompiled(Normal, true) || isCompiled(Normal, false) -- || isCompiled(MatchOnly, true) || isCompiled(MatchOnly, false); -+ -+ JSAtom* patternAtom() const { return patternAtom_; } -+ -+ JS::RegExpFlags getFlags() const { return flags; } -+ -+ bool global() const { return flags.global(); } -+ bool ignoreCase() const { return flags.ignoreCase(); } -+ bool multiline() const { return flags.multiline(); } -+ bool dotAll() const { return flags.dotAll(); } -+ bool unicode() const { return flags.unicode(); } -+ bool sticky() const { return flags.sticky(); } -+ -+ bool isCompiled(bool latin1, CodeKind codeKind = CodeKind::Any) const -+ { -+ return compilation(latin1).compiled(codeKind); - } -+ bool isCompiled() const { return isCompiled(true) || isCompiled(false); } - - void traceChildren(JSTracer* trc); - void discardJitCode(); -@@ -203,55 +244,62 @@ class RegExpShared : public gc::TenuredC - return offsetof(RegExpShared, source); - } - -+ static size_t offsetOfPatternAtom() { -+ return offsetof(RegExpShared, patternAtom_); -+ } -+ - static size_t offsetOfFlags() { - return offsetof(RegExpShared, flags); - } - -- static size_t offsetOfParenCount() { -- return offsetof(RegExpShared, parenCount); -+ static size_t offsetOfPairCount() { -+ return offsetof(RegExpShared, pairCount_); -+ } -+ -+ static size_t offsetOfJitCode(bool latin1) -+ { -+ return offsetof(RegExpShared, compilationArray) + -+ (CompilationIndex(latin1) * sizeof(RegExpCompilation)) + -+ offsetof(RegExpCompilation, jitCode); - } - -- static size_t offsetOfLatin1JitCode(CompilationMode mode) { -- return offsetof(RegExpShared, compilationArray) -- + (CompilationIndex(mode, true) * sizeof(RegExpCompilation)) -- + offsetof(RegExpCompilation, jitCode); -- } -- static size_t offsetOfTwoByteJitCode(CompilationMode mode) { -- return offsetof(RegExpShared, compilationArray) -- + (CompilationIndex(mode, false) * sizeof(RegExpCompilation)) -- + offsetof(RegExpCompilation, jitCode); -+ static size_t offsetOfGroupsTemplate() { -+ return offsetof(RegExpShared, groupsTemplate_); - } - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); - - #ifdef DEBUG -- static bool dumpBytecode(JSContext* cx, MutableHandleRegExpShared res, bool match_only, -+ static bool dumpBytecode(JSContext* cx, -+ MutableHandleRegExpShared res, - HandleLinearString input); - #endif - }; - - class RegExpZone - { -- struct Key { -- JSAtom* atom; -- uint16_t flag; -- -- Key() {} -- Key(JSAtom* atom, RegExpFlag flag) -- : atom(atom), flag(flag) -- { } -+ struct Key -+ { -+ JSAtom* atom = nullptr; -+ JS::RegExpFlags flags = JS::RegExpFlag::NoFlags; -+ -+ Key() = default; -+ Key(JSAtom* atom, JS::RegExpFlags flags) -+ : atom(atom) -+ , flags(flags) -+ {} - MOZ_IMPLICIT Key(const ReadBarriered& shared) - : atom(shared.unbarrieredGet()->getSource()), -- flag(shared.unbarrieredGet()->getFlags()) -+ flags(shared.unbarrieredGet()->getFlags()) - { } - - typedef Key Lookup; - static HashNumber hash(const Lookup& l) { - HashNumber hash = DefaultHasher::hash(l.atom); -- return mozilla::AddToHash(hash, l.flag); -+ return mozilla::AddToHash(hash, l.flags.value()); - } - static bool match(Key l, Key r) { -- return l.atom == r.atom && l.flag == r.flag; -+ return l.atom == r.atom && l.flags == r.flags; - } - }; - -@@ -273,12 +321,12 @@ class RegExpZone - - bool empty() const { return set_.empty(); } - -- RegExpShared* maybeGet(JSAtom* source, RegExpFlag flags) const { -+ RegExpShared* maybeGet(JSAtom* source, JS::RegExpFlags flags) const { - Set::Ptr p = set_.lookup(Key(source, flags)); - return p ? *p : nullptr; - } - -- RegExpShared* get(JSContext* cx, HandleAtom source, RegExpFlag flags); -+ RegExpShared* get(JSContext* cx, HandleAtom source, JS::RegExpFlags flags); - - /* Like 'get', but compile 'maybeOpt' (if non-null). */ - RegExpShared* get(JSContext* cx, HandleAtom source, JSString* maybeOpt); -@@ -351,6 +399,9 @@ class RegExpCompartment - } - }; - -+RegExpRunStatus ExecuteRegExpAtomRaw(RegExpShared* re, JSLinearString* input, -+ size_t start, MatchPairs* matchPairs); -+ - } /* namespace js */ - - namespace JS { -diff -Nrup mozilla/js/src/vm/RegExpStatics.cpp mozilla-OK/js/src/vm/RegExpStatics.cpp ---- mozilla/js/src/vm/RegExpStatics.cpp 2021-10-26 19:49:54.000000000 +0300 -+++ mozilla-OK/js/src/vm/RegExpStatics.cpp 2022-06-15 22:48:22.896029429 +0300 -@@ -95,8 +95,7 @@ RegExpStatics::executeLazy(JSContext* cx - - /* Execute the full regular expression. */ - RootedLinearString input(cx, matchesInput); -- RegExpRunStatus status = RegExpShared::execute(cx, &shared, input, lazyIndex, &this->matches, -- nullptr); -+ RegExpRunStatus status = RegExpShared::execute(cx, &shared, input, lazyIndex, &this->matches); - if (status == RegExpRunStatus_Error) - return false; - -diff -Nrup mozilla/js/src/vm/RegExpStatics.h mozilla-OK/js/src/vm/RegExpStatics.h ---- mozilla/js/src/vm/RegExpStatics.h 2022-04-13 21:14:22.000000000 +0300 -+++ mozilla-OK/js/src/vm/RegExpStatics.h 2022-06-15 21:39:37.381986023 +0300 -@@ -31,8 +31,8 @@ class RegExpStatics - * a different compartment via evalcx(). - */ - HeapPtr lazySource; -- RegExpFlag lazyFlags; -- size_t lazyIndex; -+ JS::RegExpFlags lazyFlags; -+ size_t lazyIndex; - - /* The latest RegExp input, set before execution. */ - HeapPtr pendingInput; -@@ -279,7 +279,7 @@ RegExpStatics::clear() - matches.forgetArray(); - matchesInput = nullptr; - lazySource = nullptr; -- lazyFlags = RegExpFlag(0); -+ lazyFlags = JS::RegExpFlag::NoFlags; - lazyIndex = size_t(-1); - pendingInput = nullptr; - pendingLazyEvaluation = false; -diff -Nrup mozilla/js/src/vm/Runtime.h mozilla-OK/js/src/vm/Runtime.h ---- mozilla/js/src/vm/Runtime.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/Runtime.h 2022-06-15 23:53:18.845635886 +0300 -@@ -31,7 +31,6 @@ - #include "gc/GCRuntime.h" - #include "gc/Tracer.h" - #include "gc/ZoneGroup.h" --#include "irregexp/RegExpStack.h" - #include "js/Debug.h" - #include "js/GCVector.h" - #include "js/HashTable.h" -diff -Nrup mozilla/js/src/vm/SelfHosting.cpp mozilla-OK/js/src/vm/SelfHosting.cpp ---- mozilla/js/src/vm/SelfHosting.cpp 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/SelfHosting.cpp 2022-06-15 23:38:04.419838762 +0300 -@@ -876,6 +876,21 @@ js::intrinsic_NewStringIterator(JSContex - return true; - } - -+bool -+js::intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, Value* vp) -+{ -+ CallArgs args = CallArgsFromVp(argc, vp); -+ MOZ_ASSERT(args.length() == 0); -+ -+ JSObject* obj = NewRegExpStringIteratorObject(cx); -+ if (!obj) { -+ return false; -+ } -+ -+ args.rval().setObject(*obj); -+ return true; -+} -+ - static bool - intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp) - { -@@ -1604,7 +1619,7 @@ static bool - intrinsic_RegExpGetSubstitution(JSContext* cx, unsigned argc, Value* vp) - { - CallArgs args = CallArgsFromVp(argc, vp); -- MOZ_ASSERT(args.length() == 5); -+ MOZ_ASSERT(args.length() == 6); - - RootedArrayObject matchResult(cx, &args[0].toObject().as()); - -@@ -1622,8 +1637,17 @@ intrinsic_RegExpGetSubstitution(JSContex - int32_t firstDollarIndex = int32_t(args[4].toNumber()); - MOZ_ASSERT(firstDollarIndex >= 0); - -- return RegExpGetSubstitution(cx, matchResult, string, size_t(position), replacement, -- size_t(firstDollarIndex), args.rval()); -+ RootedValue namedCaptures(cx, args[5]); -+ MOZ_ASSERT(namedCaptures.isUndefined() || namedCaptures.isObject()); -+ -+ return RegExpGetSubstitution(cx, -+ matchResult, -+ string, -+ size_t(position), -+ replacement, -+ size_t(firstDollarIndex), -+ namedCaptures, -+ args.rval()); - } - - static bool -@@ -2352,6 +2376,10 @@ static const JSFunctionSpec intrinsic_fu - intrinsic_IsInstanceOfBuiltin, 1,0, - IntrinsicIsStringIterator), - -+ JS_INLINABLE_FN("GuardToRegExpStringIterator", -+ intrinsic_IsInstanceOfBuiltin, 1,0, -+ IntrinsicGuardToRegExpStringIterator), -+ - JS_FN("_CreateMapIterationResultPair", intrinsic_CreateMapIterationResultPair, 0, 0), - JS_INLINABLE_FN("_GetNextMapEntryForIterator", intrinsic_GetNextMapEntryForIterator, 2,0, - IntrinsicGetNextMapEntryForIterator), -@@ -2370,6 +2398,12 @@ static const JSFunctionSpec intrinsic_fu - JS_FN("CallStringIteratorMethodIfWrapped", - CallNonGenericSelfhostedMethod>, 2,0), - -+ JS_INLINABLE_FN("NewRegExpStringIterator", -+ intrinsic_NewRegExpStringIterator, 0, 0, -+ IntrinsicNewRegExpStringIterator), -+ JS_FN("CallRegExpStringIteratorMethodIfWrapped", -+ CallNonGenericSelfhostedMethod>, 2, 0), -+ - JS_FN("IsGeneratorObject", - intrinsic_IsInstanceOfBuiltin, 1,0), - JS_FN("GeneratorObjectIsClosed", intrinsic_GeneratorObjectIsClosed, 1,0), -diff -Nrup mozilla/js/src/vm/SelfHosting.h mozilla-OK/js/src/vm/SelfHosting.h ---- mozilla/js/src/vm/SelfHosting.h 2022-06-08 22:10:28.000000000 +0300 -+++ mozilla-OK/js/src/vm/SelfHosting.h 2022-06-15 23:27:12.220259825 +0300 -@@ -56,6 +56,9 @@ intrinsic_NewStringIterator(JSContext* c - bool - intrinsic_IsSuspendedGenerator(JSContext* cx, unsigned argc, JS::Value* vp); - -+bool -+intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, JS::Value* vp); -+ - } /* namespace js */ - - #endif /* vm_SelfHosting_h_ */ -diff -Nrup mozilla/js/src/vm/StructuredClone.cpp mozilla-OK/js/src/vm/StructuredClone.cpp ---- mozilla/js/src/vm/StructuredClone.cpp 2022-04-13 21:14:22.000000000 +0300 -+++ mozilla-OK/js/src/vm/StructuredClone.cpp 2022-06-15 22:16:24.019030980 +0300 -@@ -29,6 +29,7 @@ - - #include "js/StructuredClone.h" - -+#include "mozilla/Casting.h" - #include "mozilla/CheckedInt.h" - #include "mozilla/EndianUtils.h" - #include "mozilla/FloatingPoint.h" -@@ -44,6 +45,7 @@ - #include "builtin/MapObject.h" - #include "js/Date.h" - #include "js/GCHashTable.h" -+#include "js/RegExpFlags.h" - #include "vm/RegExpObject.h" - #include "vm/SavedFrame.h" - #include "vm/SharedArrayObject.h" -@@ -55,12 +57,15 @@ - - using namespace js; - -+using mozilla::AssertedCast; - using mozilla::BitwiseCast; - using mozilla::IsNaN; - using mozilla::LittleEndian; - using mozilla::NativeEndian; - using mozilla::NumbersAreIdentical; - using JS::CanonicalizeNaN; -+using JS::RegExpFlag; -+using JS::RegExpFlags; - - // When you make updates here, make sure you consider whether you need to bump the - // value of JS_STRUCTURED_CLONE_VERSION in js/public/StructuredClone.h. You will -@@ -1485,7 +1490,7 @@ JSStructuredCloneWriter::startWrite(Hand - RegExpShared* re = RegExpToShared(context(), obj); - if (!re) - return false; -- return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags()) && -+ return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags().value()) && - writeString(SCTAG_STRING, re->getSource()); - } else if (cls == ESClass::Date) { - RootedValue unboxed(context()); -@@ -2126,7 +2131,14 @@ JSStructuredCloneReader::startRead(Mutab - } - - case SCTAG_REGEXP_OBJECT: { -- RegExpFlag flags = RegExpFlag(data); -+ if ((data & RegExpFlag::AllFlags) != data) { -+ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, -+ JSMSG_SC_BAD_SERIALIZED_DATA, "regexp"); -+ return false; -+ } -+ -+ RegExpFlags flags(AssertedCast(data)); -+ - uint32_t tag2, stringData; - if (!in.readPair(&tag2, &stringData)) - return false; -@@ -2136,6 +2148,7 @@ JSStructuredCloneReader::startRead(Mutab - "regexp"); - return false; - } -+ - JSString* str = readString(stringData); - if (!str) - return false; -diff -Nrup mozilla/js/src/vm/UnicodeNonBMP.h mozilla-OK/js/src/vm/UnicodeNonBMP.h ---- mozilla/js/src/vm/UnicodeNonBMP.h 2020-08-10 14:30:35.000000000 +0300 -+++ mozilla-OK/js/src/vm/UnicodeNonBMP.h 2022-06-16 00:04:24.709115620 +0300 -@@ -48,32 +48,4 @@ - macro(0x16e60, 0x16e7f, 0xd81b, 0xde60, 0xde7f, -32) \ - macro(0x1e922, 0x1e943, 0xd83a, 0xdd22, 0xdd43, -34) - --// U+10400 DESERET CAPITAL LETTER LONG I .. U+10427 DESERET CAPITAL LETTER EW --// U+104B0 OSAGE CAPITAL LETTER A .. U+104D3 OSAGE CAPITAL LETTER ZHA --// U+10C80 OLD HUNGARIAN CAPITAL LETTER A .. U+10CB2 OLD HUNGARIAN CAPITAL LETTER US --// U+118A0 WARANG CITI CAPITAL LETTER NGAA .. U+118BF WARANG CITI CAPITAL LETTER VIYO --// U+16E40 MEDEFAIDRIN CAPITAL LETTER M .. U+16E5F MEDEFAIDRIN CAPITAL LETTER Y --// U+1E900 ADLAM CAPITAL LETTER ALIF .. U+1E921 ADLAM CAPITAL LETTER SHA --#define FOR_EACH_NON_BMP_CASE_FOLDING(macro) \ -- macro(0x10400, 0x10427, 0xd801, 0xdc00, 0xdc27, 40) \ -- macro(0x104b0, 0x104d3, 0xd801, 0xdcb0, 0xdcd3, 40) \ -- macro(0x10c80, 0x10cb2, 0xd803, 0xdc80, 0xdcb2, 64) \ -- macro(0x118a0, 0x118bf, 0xd806, 0xdca0, 0xdcbf, 32) \ -- macro(0x16e40, 0x16e5f, 0xd81b, 0xde40, 0xde5f, 32) \ -- macro(0x1e900, 0x1e921, 0xd83a, 0xdd00, 0xdd21, 34) -- --// U+10428 DESERET SMALL LETTER LONG I .. U+1044F DESERET SMALL LETTER EW --// U+104D8 OSAGE SMALL LETTER A .. U+104FB OSAGE SMALL LETTER ZHA --// U+10CC0 OLD HUNGARIAN SMALL LETTER A .. U+10CF2 OLD HUNGARIAN SMALL LETTER US --// U+118C0 WARANG CITI SMALL LETTER NGAA .. U+118DF WARANG CITI SMALL LETTER VIYO --// U+16E60 MEDEFAIDRIN SMALL LETTER M .. U+16E7F MEDEFAIDRIN SMALL LETTER Y --// U+1E922 ADLAM SMALL LETTER ALIF .. U+1E943 ADLAM SMALL LETTER SHA --#define FOR_EACH_NON_BMP_REV_CASE_FOLDING(macro) \ -- macro(0x10428, 0x1044f, 0xd801, 0xdc28, 0xdc4f, -40) \ -- macro(0x104d8, 0x104fb, 0xd801, 0xdcd8, 0xdcfb, -40) \ -- macro(0x10cc0, 0x10cf2, 0xd803, 0xdcc0, 0xdcf2, -64) \ -- macro(0x118c0, 0x118df, 0xd806, 0xdcc0, 0xdcdf, -32) \ -- macro(0x16e60, 0x16e7f, 0xd81b, 0xde60, 0xde7f, -32) \ -- macro(0x1e922, 0x1e943, 0xd83a, 0xdd22, 0xdd43, -34) -- - #endif /* vm_UnicodeNonBMP_h */ -diff -Nrup mozilla/js/src/vm/make_unicode.py mozilla-OK/js/src/vm/make_unicode.py ---- mozilla/js/src/vm/make_unicode.py 2020-08-10 14:30:35.000000000 +0300 -+++ mozilla-OK/js/src/vm/make_unicode.py 2022-06-16 00:04:24.710115613 +0300 -@@ -393,18 +393,11 @@ def process_case_folding(case_folding): - folding_tests = [] - folding_codes = set() - -- non_bmp_folding_map = {} -- non_bmp_rev_folding_map = {} -- - for row in read_case_folding(case_folding): - code = row[0] - mapping = row[2] - folding_map[code] = mapping - -- if code > MAX_BMP: -- non_bmp_folding_map[code] = mapping -- non_bmp_rev_folding_map[mapping] = code -- - if mapping not in rev_folding_map: - rev_folding_map[mapping] = [code] - else: -@@ -459,7 +452,6 @@ def process_case_folding(case_folding): - folding_index[code] = i - return ( - folding_table, folding_index, -- non_bmp_folding_map, non_bmp_rev_folding_map, - folding_tests - ) - -@@ -604,7 +596,6 @@ def process_special_casing(special_casin - - def make_non_bmp_file(version, - non_bmp_lower_map, non_bmp_upper_map, -- non_bmp_folding_map, non_bmp_rev_folding_map, - codepoint_table): - file_name = 'UnicodeNonBMP.h'; - with io.open(file_name, mode='wb') as non_bmp_file: -@@ -631,10 +622,6 @@ def make_non_bmp_file(version, - make_non_bmp_convert_macro(non_bmp_file, 'LOWERCASE', non_bmp_lower_map, codepoint_table) - non_bmp_file.write('\n') - make_non_bmp_convert_macro(non_bmp_file, 'UPPERCASE', non_bmp_upper_map, codepoint_table) -- non_bmp_file.write('\n') -- make_non_bmp_convert_macro(non_bmp_file, 'CASE_FOLDING', non_bmp_folding_map, codepoint_table) -- non_bmp_file.write('\n') -- make_non_bmp_convert_macro(non_bmp_file, 'REV_CASE_FOLDING', non_bmp_rev_folding_map, codepoint_table) - - non_bmp_file.write(""" - #endif /* util_UnicodeNonBMP_h */ -@@ -1287,203 +1274,6 @@ def splitbins(t): - assert t[i] == t2[(t1[i >> shift] << shift) + (i & mask)] - return best - --def make_irregexp_tables(version, -- table, index, -- folding_table, folding_index, -- codepoint_table): -- import string -- -- MAX_ASCII = 0x7F -- MAX_LATIN1 = 0xFF -- LEAD_SURROGATE_MIN = 0xD800 -- TRAIL_SURROGATE_MAX = 0xDFFF -- -- def hex2(n): -- assert 0 <= n and n < 16**2 -- return '0x{:02X}'.format(n) -- -- def hex4(n): -- assert 0 <= n and n < 16**4 -- return '0x{:04X}'.format(n) -- -- def uhex4(n): -- assert 0 <= n and n < 16**4 -- return 'U+{:04X}'.format(n) -- -- def case_info(code): -- assert 0 <= code and code <= MAX_BMP -- (upper, lower, flags) = table[index[code]] -- return ((code + upper) & 0xffff, (code + lower) & 0xffff, flags) -- -- def is_space(code): -- (_, _, flags) = case_info(code) -- return bool(flags & FLAG_SPACE) -- -- def to_upper(code): -- (upper, _, _) = case_info(code) -- return upper -- -- def casefold(code): -- assert 0 <= code and code <= MAX_BMP -- (folding, _, _, _) = folding_table[folding_index[code]] -- return (code + folding) & 0xffff -- -- def casefolds_to_ascii(code): -- return casefold(code) <= MAX_ASCII -- -- def casefolds_to_latin1(code): -- return casefold(code) <= MAX_LATIN1 -- -- def casemaps_to_nonlatin1(code): -- upper = to_upper(code) -- return upper > MAX_LATIN1 -- -- def char_name(code): -- assert 0 <= code and code <= MAX_BMP -- if code not in codepoint_table: -- return '' -- if code == LEAD_SURROGATE_MIN: -- return '' -- if code == TRAIL_SURROGATE_MAX: -- return '' -- (_, _, name, alias) = codepoint_table[code] -- return name if not name.startswith('<') else alias -- -- def write_character_range(println, name, characters): -- char_ranges = list(int_ranges(characters)) -- println('') -- println('const int js::irregexp::k{}Ranges[] = {{'.format(name)) -- for (start, end) in char_ranges: -- s_name = char_name(start) -- e_name = char_name(end) -- println(' {}, {} + 1, // {}'.format(hex4(start), hex4(end), -- '{}..{}'.format(s_name, e_name) -- if start != end else s_name)) -- println(' {} + 1'.format(hex4(MAX_BMP))) -- println('};') -- println('const int js::irregexp::k{}RangeCount = {};'.format(name, -- len(char_ranges) * 2 + 1)) -- -- def write_character_test(println, test, consequent, default): -- # Latin1 characters which, when case-mapped through -- # String.prototype.toUpperCase(), canonicalize to a non-Latin1 character. -- # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize -- casemapped_to_nonlatin1 = ifilter(casemaps_to_nonlatin1, xrange(0, MAX_LATIN1 + 1)) -- -- def casemap_closure(ch): -- upper = to_upper(ch) -- return (ch, [c for c in xrange(MAX_LATIN1 + 1, MAX_BMP + 1) if upper == to_upper(c)]) -- -- # Mapping from Latin1 characters to the list of case map equivalent -- # non-Latin1 characters. -- casemap_for_latin1 = dict(chain(imap(casemap_closure, casemapped_to_nonlatin1))) -- -- # Non-latin1 characters which, when Unicode case-folded, canonicalize to -- # a Latin1 character. -- # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize -- casefolded_to_latin1 = ifilter(casefolds_to_latin1, xrange(MAX_LATIN1 + 1, MAX_BMP + 1)) -- -- println(' if (unicode) {') -- for ch in casefolded_to_latin1: -- casefolded = casefold(ch) -- # Skip if also handled below for case mapping. -- if casefolded in casemap_for_latin1 and ch in casemap_for_latin1[casefolded]: -- continue -- println(' // "{}" case folds to "{}".'.format(char_name(ch), -- char_name(casefolded))) -- println(' if ({})'.format(test(ch))) -- println(' return {};'.format(consequent(casefolded))) -- println(' }') -- println('') -- for (ch, casemapped_chars) in casemap_for_latin1.iteritems(): -- for casemapped in casemapped_chars: -- println(' // "{}" case maps to "{}".'.format(char_name(casemapped), -- char_name(ch))) -- println(' if ({})'.format(' || '.join(imap(test, casemapped_chars)))) -- println(' return {};'.format(consequent(ch))) -- println(' return {};'.format(default)) -- -- with io.open('../irregexp/RegExpCharacters-inl.h', 'wb') as chars_file: -- write = partial(print, file=chars_file, sep='', end='') -- println = partial(write, end='\n') -- -- write(warning_message) -- write(unicode_version_message.format(version)) -- -- println('#ifndef V8_JSREGEXPCHARACTERS_INL_H_') -- println('#define V8_JSREGEXPCHARACTERS_INL_H_') -- println('') -- println('namespace js {') -- println('') -- println('namespace irregexp {') -- println('') -- -- println('static inline bool') -- println('RangeContainsLatin1Equivalents(CharacterRange range, bool unicode)') -- println('{') -- write_character_test(println, lambda ch: 'range.Contains({})'.format(hex4(ch)), -- lambda _: 'true', 'false') -- println('}') -- -- println('') -- println('} } // namespace js::irregexp') -- println('') -- println('#endif // V8_JSREGEXPCHARACTERS_INL_H_') -- -- with io.open('../irregexp/RegExpCharacters.cpp', 'wb') as chars_file: -- write = partial(print, file=chars_file, sep='', end='') -- println = partial(write, end='\n') -- character_range = partial(write_character_range, println) -- -- # Characters in \s, 21.2.2.12 CharacterClassEscape. -- space_chars = filter(is_space, xrange(0, MAX_BMP + 1)) -- -- # Characters in \d, 21.2.2.12 CharacterClassEscape. -- digit_chars = map(ord, string.digits) -- assert all(ch <= MAX_ASCII for ch in digit_chars) -- -- # Characters in \w, 21.2.2.12 CharacterClassEscape. -- word_chars = map(ord, string.digits + string.ascii_letters + '_') -- assert all(ch <= MAX_ASCII for ch in word_chars) -- -- # Characters which case-fold to characters in \w. -- ignorecase_word_chars = (word_chars + -- filter(casefolds_to_ascii, xrange(MAX_ASCII + 1, MAX_BMP + 1))) -- -- # Surrogate characters. -- surrogate_chars = range(LEAD_SURROGATE_MIN, TRAIL_SURROGATE_MAX + 1) -- -- write(warning_message) -- write(unicode_version_message.format(version)) -- println('#include "irregexp/RegExpCharacters.h"') -- println('') -- println('#include "mozilla/Assertions.h"') -- println('') -- -- println('char16_t') -- println('js::irregexp::ConvertNonLatin1ToLatin1(char16_t c, bool unicode)') -- println('{') -- println(' MOZ_ASSERT(c > {}, "Character mustn\'t be Latin1");'.format(hex2(MAX_LATIN1))) -- write_character_test(println, lambda ch: 'c == {}'.format(hex4(ch)), hex2, '0') -- println('}') -- -- character_range('Space', space_chars) -- character_range('SpaceAndSurrogate', space_chars + surrogate_chars) -- -- character_range('Word', word_chars) -- character_range('IgnoreCaseWord', ignorecase_word_chars) -- character_range('WordAndSurrogate', word_chars + surrogate_chars) -- character_range('NegatedIgnoreCaseWordAndSurrogate', -- set(xrange(0, MAX_BMP + 1)) - set(ignorecase_word_chars + surrogate_chars)) -- -- character_range('Digit', digit_chars) -- character_range('DigitAndSurrogate', digit_chars + surrogate_chars) -- -- character_range('Surrogate', surrogate_chars) -- -- character_range('LineTerminator', line_terminator) -- character_range('LineTerminatorAndSurrogate', line_terminator + surrogate_chars) -- - def update_unicode(args): - import urllib2 - -@@ -1542,7 +1332,6 @@ def update_unicode(args): - ) = process_unicode_data(unicode_data, derived_core_properties) - ( - folding_table, folding_index, -- non_bmp_folding_map, non_bmp_rev_folding_map, - folding_tests - ) = process_case_folding(case_folding) - ( -@@ -1560,12 +1349,7 @@ def update_unicode(args): - codepoint_table) - make_non_bmp_file(unicode_version, - non_bmp_lower_map, non_bmp_upper_map, -- non_bmp_folding_map, non_bmp_rev_folding_map, - codepoint_table) -- make_irregexp_tables(unicode_version, -- table, index, -- folding_table, folding_index, -- codepoint_table) - - make_bmp_mapping_test(unicode_version, - codepoint_table, unconditional_tolower, unconditional_toupper) -diff -Nrup mozilla/toolkit/components/extensions/MatchPattern.cpp mozilla-OK/toolkit/components/extensions/MatchPattern.cpp ---- mozilla/toolkit/components/extensions/MatchPattern.cpp 2022-01-25 01:04:33.000000000 +0300 -+++ mozilla-OK/toolkit/components/extensions/MatchPattern.cpp 2022-06-15 21:38:08.879586373 +0300 -@@ -6,6 +6,7 @@ - #include "mozilla/extensions/MatchPattern.h" - #include "mozilla/extensions/MatchGlob.h" - -+#include "js/RegExp.h" // JS::NewUCRegExpObject, JS::ExecuteRegExpNoStatics - #include "mozilla/dom/ScriptSettings.h" - #include "mozilla/HoldDropJSObjects.h" - #include "mozilla/Unused.h" -@@ -697,7 +698,7 @@ MatchGlob::Init(JSContext* aCx, const ns - // TODO: Switch to the Rust regexp crate, when Rust integration is easier. - // It uses a much more efficient, linear time matching algorithm, and - // doesn't require special casing for the literal and prefix cases. -- mRegExp = JS_NewUCRegExpObject(aCx, escaped.get(), escaped.Length(), 0); -+ mRegExp = JS::NewUCRegExpObject(aCx, escaped.get(), escaped.Length(), 0); - if (mRegExp) { - mozilla::HoldJSObjects(this); - } else { -@@ -721,7 +722,7 @@ MatchGlob::Matches(const nsAString& aStr - nsString input(aString); - - size_t index = 0; -- if (!JS_ExecuteRegExpNoStatics(cx, regexp, input.BeginWriting(), aString.Length(), -+ if (!JS::ExecuteRegExpNoStatics(cx, regexp, input.BeginWriting(), aString.Length(), - &index, true, &result)) { - return false; - } diff --git a/seamonkey-2.53.14-cbindgen.patch b/seamonkey-2.53.14-cbindgen.patch deleted file mode 100644 index 72d112f..0000000 --- a/seamonkey-2.53.14-cbindgen.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- mozilla/build/moz.configure/rust.configure 2022-08-24 22:55:10.000000000 +0300 -+++ mozilla/build/moz.configure/rust.configure-OK 2022-09-01 01:59:26.229300749 +0300 -@@ -363,8 +363,8 @@ set_config('MOZ_RUST_TESTS', rust_tests) - - # cbindgen is needed by the style system build. - cbindgen = check_prog('CBINDGEN', ['cbindgen'], paths=toolchain_search_path, -- when=depends(build_project) -- (lambda build_project: build_project != 'js')) -+ when=depends(stylo_config, build_project) -+ (lambda stylo_config, build_project: stylo_config.build and build_project != 'js')) - - - @depends_if(cbindgen) diff --git a/seamonkey-2.53.14-mozilla-1434478.patch b/seamonkey-2.53.14-mozilla-1434478.patch deleted file mode 100644 index 5196e9e..0000000 --- a/seamonkey-2.53.14-mozilla-1434478.patch +++ /dev/null @@ -1,715 +0,0 @@ -# -# Backport of https://bugzilla.mozilla.org/show_bug.cgi?id=1434478, parts 1-6. -# -# Under certain conditions (fe. an odd page width and some zoom level), -# some page elements became invisible. -# - -diff -Nrup mozilla-OLD/layout/base/LayoutConstants.h mozilla/layout/base/LayoutConstants.h ---- mozilla-OLD/layout/base/LayoutConstants.h 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla/layout/base/LayoutConstants.h 2022-08-30 20:19:40.368291085 +0300 -@@ -0,0 +1,31 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+/* constants used throughout the Layout module */ -+ -+#ifndef LayoutConstants_h___ -+#define LayoutConstants_h___ -+ -+#include "nsSize.h" // for NS_MAXSIZE -+ -+/** -+ * Constant used to indicate an unconstrained size. -+ */ -+#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE -+ -+// NOTE: There are assumptions all over that these have the same value, -+// namely NS_UNCONSTRAINEDSIZE. -+#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE -+#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE -+#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE -+ -+// +1 is to avoid clamped huge margin values being processed as auto margins -+#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) -+ -+#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN -+ -+ -+#endif // LayoutConstants_h___ -diff -Nrup mozilla-OLD/layout/base/moz.build mozilla/layout/base/moz.build ---- mozilla-OLD/layout/base/moz.build 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/base/moz.build 2022-08-30 20:19:40.368291085 +0300 -@@ -35,6 +35,7 @@ XPIDL_MODULE = 'layout_base' - EXPORTS += [ - 'CaretAssociationHint.h', - 'FrameProperties.h', -+ 'LayoutConstants.h', - 'LayoutLogging.h', - 'MobileViewportManager.h', - 'nsAutoLayoutPhase.h', -diff -Nrup mozilla-OLD/layout/base/nsLayoutUtils.cpp mozilla/layout/base/nsLayoutUtils.cpp ---- mozilla-OLD/layout/base/nsLayoutUtils.cpp 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/base/nsLayoutUtils.cpp 2022-08-30 20:19:40.371291066 +0300 -@@ -4975,8 +4975,6 @@ GetDefiniteSize(const nsStyleCoord& - nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) - : aPercentageBasis.value().BSize(wm); - if (pb == NS_UNCONSTRAINEDSIZE) { -- // XXXmats given that we're calculating an intrinsic size here, -- // maybe we should back-compute the calc-size using AddPercents? - return false; - } - *aResult = std::max(0, calc->mLength + -@@ -5220,12 +5218,9 @@ AddIntrinsicSizeOffset(gfxContext* aRend - nscoord result = aContentSize; - nscoord min = aContentMinSize; - nscoord coordOutsideSize = 0; -- float pctOutsideSize = 0; -- float pctTotal = 0.0f; - - if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) { - coordOutsideSize += aOffsets.hPadding; -- pctOutsideSize += aOffsets.hPctPadding; - } - - coordOutsideSize += aOffsets.hBorder; -@@ -5233,21 +5228,15 @@ AddIntrinsicSizeOffset(gfxContext* aRend - if (aBoxSizing == StyleBoxSizing::Border) { - min += coordOutsideSize; - result = NSCoordSaturatingAdd(result, coordOutsideSize); -- pctTotal += pctOutsideSize; - - coordOutsideSize = 0; -- pctOutsideSize = 0.0f; - } - - coordOutsideSize += aOffsets.hMargin; -- pctOutsideSize += aOffsets.hPctMargin; - - min += coordOutsideSize; - result = NSCoordSaturatingAdd(result, coordOutsideSize); -- pctTotal += pctOutsideSize; - -- const bool shouldAddPercent = aType == nsLayoutUtils::PREF_ISIZE || -- (aFlags & nsLayoutUtils::ADD_PERCENTS); - nscoord size; - if (aType == nsLayoutUtils::MIN_ISIZE && - (((aStyleSize.HasPercent() || aStyleMaxSize.HasPercent()) && -@@ -5265,18 +5254,6 @@ AddIntrinsicSizeOffset(gfxContext* aRend - GetIntrinsicCoord(aStyleSize, aRenderingContext, aFrame, - PROP_WIDTH, size)) { - result = size + coordOutsideSize; -- if (shouldAddPercent) { -- result = nsLayoutUtils::AddPercents(result, pctOutsideSize); -- } -- } else { -- // NOTE: We could really do a lot better for percents and for some -- // cases of calc() containing percent (certainly including any where -- // the coefficient on the percent is positive and there are no max() -- // expressions). However, doing better for percents wouldn't be -- // backwards compatible. -- if (shouldAddPercent) { -- result = nsLayoutUtils::AddPercents(result, pctTotal); -- } - } - - nscoord maxSize = aFixedMaxSize ? *aFixedMaxSize : 0; -@@ -5284,9 +5261,6 @@ AddIntrinsicSizeOffset(gfxContext* aRend - GetIntrinsicCoord(aStyleMaxSize, aRenderingContext, aFrame, - PROP_MAX_WIDTH, maxSize)) { - maxSize += coordOutsideSize; -- if (shouldAddPercent) { -- maxSize = nsLayoutUtils::AddPercents(maxSize, pctOutsideSize); -- } - if (result > maxSize) { - result = maxSize; - } -@@ -5297,17 +5271,11 @@ AddIntrinsicSizeOffset(gfxContext* aRend - GetIntrinsicCoord(aStyleMinSize, aRenderingContext, aFrame, - PROP_MIN_WIDTH, minSize)) { - minSize += coordOutsideSize; -- if (shouldAddPercent) { -- minSize = nsLayoutUtils::AddPercents(minSize, pctOutsideSize); -- } - if (result < minSize) { - result = minSize; - } - } - -- if (shouldAddPercent) { -- min = nsLayoutUtils::AddPercents(min, pctTotal); -- } - if (result < min) { - result = min; - } -@@ -5324,9 +5292,6 @@ AddIntrinsicSizeOffset(gfxContext* aRend - : devSize.width); - // GetMinimumWidgetSize() returns a border-box width. - themeSize += aOffsets.hMargin; -- if (shouldAddPercent) { -- themeSize = nsLayoutUtils::AddPercents(themeSize, aOffsets.hPctMargin); -- } - if (themeSize > result || !canOverride) { - result = themeSize; - } -@@ -5632,9 +5597,7 @@ nsLayoutUtils::MinSizeContributionForAxi - aWM.IsVertical() ? "vertical" : "horizontal"); - #endif - -- // Note: this method is only meant for grid/flex items which always -- // include percentages in their intrinsic size. -- aFlags |= nsLayoutUtils::ADD_PERCENTS; -+ // Note: this method is only meant for grid/flex items. - const nsStylePosition* const stylePos = aFrame->StylePosition(); - const nsStyleCoord* style = aAxis == eAxisHorizontal ? &stylePos->mMinWidth - : &stylePos->mMinHeight; -diff -Nrup mozilla-OLD/layout/base/nsLayoutUtils.h mozilla/layout/base/nsLayoutUtils.h ---- mozilla-OLD/layout/base/nsLayoutUtils.h 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/base/nsLayoutUtils.h 2022-08-30 20:19:40.373291053 +0300 -@@ -6,6 +6,7 @@ - #ifndef nsLayoutUtils_h__ - #define nsLayoutUtils_h__ - -+#include "LayoutConstants.h" - #include "mozilla/MemoryReporting.h" - #include "mozilla/ArrayUtils.h" - #include "mozilla/Maybe.h" -@@ -1410,7 +1411,6 @@ public: - IGNORE_PADDING = 0x01, - BAIL_IF_REFLOW_NEEDED = 0x02, // returns NS_INTRINSIC_WIDTH_UNKNOWN if so - MIN_INTRINSIC_ISIZE = 0x04, // use min-width/height instead of width/height -- ADD_PERCENTS = 0x08, // apply AddPercents also for MIN_ISIZE - }; - static nscoord - IntrinsicForAxis(mozilla::PhysicalAxis aAxis, -@@ -1451,23 +1451,6 @@ public: - IntrinsicISizeType aType, - uint32_t aFlags = 0); - -- /** -- * This function increases an initial intrinsic size, 'aCurrent', according -- * to the given 'aPercent', such that the size-increase makes up exactly -- * 'aPercent' percent of the returned value. If 'aPercent' or 'aCurrent' are -- * less than or equal to zero the original 'aCurrent' value is returned. -- * If 'aPercent' is greater than or equal to 1.0 the value nscoord_MAX is -- * returned. -- */ -- static nscoord AddPercents(nscoord aCurrent, float aPercent) -- { -- if (aPercent > 0.0f && aCurrent > 0) { -- return MOZ_UNLIKELY(aPercent >= 1.0f) ? nscoord_MAX -- : NSToCoordRound(float(aCurrent) / (1.0f - aPercent)); -- } -- return aCurrent; -- } -- - /* - * Convert nsStyleCoord to nscoord when percentages depend on the - * containing block size. -@@ -3098,6 +3081,62 @@ public: - - static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag); - -+ /** -+ * Resolve a CSS value to a definite size. -+ */ -+ template -+ static nscoord ResolveToLength(const nsStyleCoord& aCoord, -+ nscoord aPercentageBasis) -+ { -+ NS_WARNING_ASSERTION(aPercentageBasis >= nscoord(0), "nscoord overflow?"); -+ -+ switch (aCoord.GetUnit()) { -+ case eStyleUnit_Coord: -+ MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetCoordValue() >= 0, -+ "This value should have been rejected by the style system"); -+ return aCoord.GetCoordValue(); -+ case eStyleUnit_Percent: -+ if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { -+ return nscoord(0); -+ } -+ MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetPercentValue() >= 0, -+ "This value should have been rejected by the style system"); -+ return NSToCoordFloorClamped(aPercentageBasis * -+ aCoord.GetPercentValue()); -+ case eStyleUnit_Calc: { -+ nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); -+ nscoord result; -+ if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { -+ result = calc->mLength; -+ } else { -+ result = calc->mLength + -+ NSToCoordFloorClamped(aPercentageBasis * calc->mPercent); -+ } -+ if (clampNegativeResultToZero && result < 0) { -+ return nscoord(0); -+ } -+ return result; -+ } -+ default: -+ MOZ_ASSERT_UNREACHABLE("Unexpected unit!"); -+ return nscoord(0); -+ } -+ } -+ -+ /** -+ * Resolve a column-gap/row-gap to a definite size. -+ * @note This method resolves 'normal' to zero. -+ * Callers who want different behavior should handle 'normal' on their own. -+ */ -+ static nscoord ResolveGapToLength(const nsStyleCoord& aGap, -+ nscoord aPercentageBasis) -+ { -+ if (aGap.GetUnit() == eStyleUnit_Normal) { -+ return nscoord(0); -+ } -+ return ResolveToLength(aGap, aPercentageBasis); -+ } -+ - private: - static uint32_t sFontSizeInflationEmPerLine; - static uint32_t sFontSizeInflationMinTwips; -diff -Nrup mozilla-OLD/layout/generic/nsFrame.cpp mozilla/layout/generic/nsFrame.cpp ---- mozilla-OLD/layout/generic/nsFrame.cpp 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/generic/nsFrame.cpp 2022-08-30 20:19:40.376291035 +0300 -@@ -5404,7 +5404,7 @@ nsIFrame::InlinePrefISizeData::ForceBrea - static void - AddCoord(const nsStyleCoord& aStyle, - nsIFrame* aFrame, -- nscoord* aCoord, float* aPercent, -+ nscoord* aCoord, - bool aClampNegativeToZero) - { - switch (aStyle.GetUnit()) { -@@ -5417,18 +5417,14 @@ AddCoord(const nsStyleCoord& aStyle, - case eStyleUnit_Percent: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetPercentValue() >= 0.0f, - "unexpected negative value"); -- *aPercent += aStyle.GetPercentValue(); - return; - } - case eStyleUnit_Calc: { - const nsStyleCoord::Calc *calc = aStyle.GetCalcValue(); - if (aClampNegativeToZero) { -- // This is far from ideal when one is negative and one is positive. - *aCoord += std::max(calc->mLength, 0); -- *aPercent += std::max(calc->mPercent, 0.0f); - } else { - *aCoord += calc->mLength; -- *aPercent += calc->mPercent; - } - return; - } -@@ -5447,22 +5443,18 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, b - bool verticalAxis = aForISize == wm.IsVertical(); - AddCoord(verticalAxis ? styleMargin->mMargin.GetTop() - : styleMargin->mMargin.GetLeft(), -- aFrame, &result.hMargin, &result.hPctMargin, -- false); -+ aFrame, &result.hMargin, false); - AddCoord(verticalAxis ? styleMargin->mMargin.GetBottom() - : styleMargin->mMargin.GetRight(), -- aFrame, &result.hMargin, &result.hPctMargin, -- false); -+ aFrame, &result.hMargin, false); - - const nsStylePadding* stylePadding = aFrame->StylePadding(); - AddCoord(verticalAxis ? stylePadding->mPadding.GetTop() - : stylePadding->mPadding.GetLeft(), -- aFrame, &result.hPadding, &result.hPctPadding, -- true); -+ aFrame, &result.hPadding, true); - AddCoord(verticalAxis ? stylePadding->mPadding.GetBottom() - : stylePadding->mPadding.GetRight(), -- aFrame, &result.hPadding, &result.hPctPadding, -- true); -+ aFrame, &result.hPadding, true); - - const nsStyleBorder* styleBorder = aFrame->StyleBorder(); - if (verticalAxis) { -@@ -5492,7 +5484,6 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, b - result.hPadding = - presContext->DevPixelsToAppUnits(verticalAxis ? padding.TopBottom() - : padding.LeftRight()); -- result.hPctPadding = 0; - } - } - return result; -diff -Nrup mozilla-OLD/layout/generic/nsGridContainerFrame.cpp mozilla/layout/generic/nsGridContainerFrame.cpp ---- mozilla-OLD/layout/generic/nsGridContainerFrame.cpp 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/generic/nsGridContainerFrame.cpp 2022-08-30 20:21:20.644678494 +0300 -@@ -8,9 +8,9 @@ - - #include "nsGridContainerFrame.h" - --#include // for std::stable_sort - #include - #include -+#include // for div() - #include "gfxContext.h" - #include "mozilla/CSSAlignUtils.h" - #include "mozilla/CSSOrderAwareFrameIterator.h" -@@ -123,42 +123,6 @@ ResolveToDefiniteSize(const nsStyleCoord - return std::max(nscoord(0), aCoord.ComputeCoordPercentCalc(aPercentBasis)); - } - --static bool --GetPercentSizeParts(const nsStyleCoord& aCoord, nscoord* aLength, float* aPercent) --{ -- switch (aCoord.GetUnit()) { -- case eStyleUnit_Percent: -- *aLength = 0; -- *aPercent = aCoord.GetPercentValue(); -- return true; -- case eStyleUnit_Calc: { -- nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); -- *aLength = calc->mLength; -- *aPercent = calc->mPercent; -- return true; -- } -- default: -- return false; -- } --} -- --static void --ResolvePercentSizeParts(const nsStyleCoord& aCoord, nscoord aPercentBasis, -- nscoord* aLength, float* aPercent) --{ -- MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit()); -- if (aPercentBasis != NS_UNCONSTRAINEDSIZE) { -- *aLength = std::max(nscoord(0), -- aCoord.ComputeCoordPercentCalc(aPercentBasis)); -- *aPercent = 0.0f; -- return; -- } -- if (!GetPercentSizeParts(aCoord, aLength, aPercent)) { -- *aLength = aCoord.ToLength(); -- *aPercent = 0.0f; -- } --} -- - // Synthesize a baseline from a border box. For an alphabetical baseline - // this is the end edge of the border box. For a central baseline it's - // the center of the border box. -@@ -914,7 +878,7 @@ struct nsGridContainerFrame::TrackSizing - return 1; - } - nscoord repeatTrackSize = 0; -- // Note that the repeat() track size is included in |sum| in this loop. -+ // Note that one repeat() track size is included in |sum| in this loop. - nscoord sum = 0; - const nscoord percentBasis = aSize; - for (uint32_t i = 0; i < numTracks; ++i) { -@@ -931,54 +895,31 @@ struct nsGridContainerFrame::TrackSizing - } - nscoord trackSize = ::ResolveToDefiniteSize(*coord, percentBasis); - if (i == mRepeatAutoStart) { -- if (percentBasis != NS_UNCONSTRAINEDSIZE) { -- // Use a minimum 1px for the repeat() track-size. -- if (trackSize < AppUnitsPerCSSPixel()) { -- trackSize = AppUnitsPerCSSPixel(); -- } -+ // Use a minimum 1px for the repeat() track-size. -+ if (trackSize < AppUnitsPerCSSPixel()) { -+ trackSize = AppUnitsPerCSSPixel(); - } - repeatTrackSize = trackSize; - } - sum += trackSize; - } -- nscoord gridGap; -- float percentSum = 0.0f; -- float gridGapPercent; -- ResolvePercentSizeParts(aGridGap, percentBasis, &gridGap, &gridGapPercent); -+ nscoord gridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aSize); - if (numTracks > 1) { - // Add grid-gaps for all the tracks including the repeat() track. - sum += gridGap * (numTracks - 1); -- percentSum = gridGapPercent * (numTracks - 1); - } - // Calculate the max number of tracks that fits without overflow. - nscoord available = maxFill != NS_UNCONSTRAINEDSIZE ? maxFill : aMinSize; -- nscoord size = nsLayoutUtils::AddPercents(sum, percentSum); -- if (available - size < 0) { -+ nscoord spaceToFill = available - sum; -+ if (spaceToFill <= 0) { - // "if any number of repetitions would overflow, then 1 repetition" - return 1; - } -- uint32_t numRepeatTracks = 1; -- bool exactFit = false; -- while (true) { -- sum += gridGap + repeatTrackSize; -- percentSum += gridGapPercent; -- nscoord newSize = nsLayoutUtils::AddPercents(sum, percentSum); -- if (newSize <= size) { -- // Adding more repeat-tracks won't make forward progress. -- return numRepeatTracks; -- } -- size = newSize; -- nscoord remaining = available - size; -- exactFit = remaining == 0; -- if (remaining >= 0) { -- ++numRepeatTracks; -- } -- if (remaining <= 0) { -- break; -- } -- } -- -- if (!exactFit && maxFill == NS_UNCONSTRAINEDSIZE) { -+ // Calculate the max number of tracks that fits without overflow. -+ div_t q = div(spaceToFill, repeatTrackSize + gridGap); -+ // The +1 here is for the one repeat track we already accounted for above. -+ uint32_t numRepeatTracks = q.quot + 1; -+ if (q.rem != 0 && maxFill == NS_UNCONSTRAINEDSIZE) { - // "Otherwise, if the grid container has a definite min size in - // the relevant axis, the number of repetitions is the largest possible - // positive integer that fulfills that minimum requirement." -@@ -1519,13 +1460,6 @@ struct nsGridContainerFrame::Tracks - WritingMode aWM, - const LogicalSize& aContainerSize); - -- /** -- * Return the intrinsic size by back-computing percentages as: -- * IntrinsicSize = SumOfCoordSizes / (1 - SumOfPercentages). -- */ -- nscoord BackComputedIntrinsicSize(const TrackSizingFunctions& aFunctions, -- const nsStyleCoord& aGridGap) const; -- - nscoord GridLineEdge(uint32_t aLine, GridLineSide aSide) const - { - if (MOZ_UNLIKELY(mSizes.IsEmpty())) { -@@ -1835,11 +1769,10 @@ struct MOZ_STACK_CLASS nsGridContainerFr - } - - /** -- * Calculate our track sizes. If the given aContentBox block-axis size is -- * unconstrained, it is assigned to the resulting intrinsic block-axis size. -+ * Calculate our track sizes. - */ - void CalculateTrackSizes(const Grid& aGrid, -- LogicalSize& aContentBox, -+ const LogicalSize& aContentBox, - SizingConstraint aConstraint); - - /** -@@ -2325,7 +2258,7 @@ struct MOZ_STACK_CLASS nsGridContainerFr - void - nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( - const Grid& aGrid, -- LogicalSize& aContentBox, -+ const LogicalSize& aContentBox, - SizingConstraint aConstraint) - { - mCols.Initialize(mColFunctions, mGridStyle->mGridColumnGap, -@@ -2343,12 +2276,6 @@ nsGridContainerFrame::GridReflowInput::C - mRows.CalculateSizes(*this, mGridItems, mRowFunctions, - aContentBox.BSize(mWM), &GridArea::mRows, - aConstraint); -- if (aContentBox.BSize(mWM) == NS_AUTOHEIGHT) { -- aContentBox.BSize(mWM) = -- mRows.BackComputedIntrinsicSize(mRowFunctions, mGridStyle->mGridRowGap); -- mRows.mGridGap = -- ::ResolveToDefiniteSize(mGridStyle->mGridRowGap, aContentBox.BSize(mWM)); -- } - } - - /** -@@ -3431,7 +3358,7 @@ nsGridContainerFrame::Tracks::Initialize - aFunctions.MinSizingFor(i), - aFunctions.MaxSizingFor(i)); - } -- mGridGap = ::ResolveToDefiniteSize(aGridGap, aContentBoxSize); -+ mGridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aContentBoxSize); - mContentBoxSize = aContentBoxSize; - } - -@@ -3522,8 +3449,7 @@ ContentContribution(const GridItemInfo& - PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis)); - nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint, - aPercentageBasis, -- aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED | -- nsLayoutUtils::ADD_PERCENTS, -+ aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED, - aMinSizeClamp); - if (size == NS_INTRINSIC_WIDTH_UNKNOWN) { - // We need to reflow the child to find its BSize contribution. -@@ -3560,15 +3486,7 @@ ContentContribution(const GridItemInfo& - LogicalSize availableSize(childWM, availISize, availBSize); - size = ::MeasuringReflow(child, aState.mReflowInput, aRC, availableSize, - cbSize, iMinSizeClamp, bMinSizeClamp); -- nsIFrame::IntrinsicISizeOffsetData offsets = child->IntrinsicBSizeOffsets(); -- size += offsets.hMargin; -- auto percent = offsets.hPctMargin; -- if (availBSize == NS_UNCONSTRAINEDSIZE) { -- // We always want to add in percent padding too, unless we already did so -- // using a resolved column size above. -- percent += offsets.hPctPadding; -- } -- size = nsLayoutUtils::AddPercents(size, percent); -+ size += child->GetLogicalUsedMargin(childWM).BStartEnd(childWM); - nscoord overflow = size - aMinSizeClamp; - if (MOZ_UNLIKELY(overflow > 0)) { - nscoord contentSize = child->ContentBSize(childWM); -@@ -4757,36 +4675,6 @@ nsGridContainerFrame::Tracks::AlignJusti - MOZ_ASSERT(!roundingError, "we didn't distribute all rounding error?"); - } - --nscoord --nsGridContainerFrame::Tracks::BackComputedIntrinsicSize( -- const TrackSizingFunctions& aFunctions, -- const nsStyleCoord& aGridGap) const --{ -- // Sum up the current sizes (where percentage tracks were treated as 'auto') -- // in 'size'. -- nscoord size = 0; -- for (size_t i = 0, len = mSizes.Length(); i < len; ++i) { -- size += mSizes[i].mBase; -- } -- -- // Add grid-gap contributions to 'size' and calculate a 'percent' sum. -- float percent = 0.0f; -- size_t numTracks = mSizes.Length(); -- if (numTracks > 1) { -- const size_t gridGapCount = numTracks - 1; -- nscoord gridGapLength; -- float gridGapPercent; -- if (::GetPercentSizeParts(aGridGap, &gridGapLength, &gridGapPercent)) { -- percent = gridGapCount * gridGapPercent; -- } else { -- gridGapLength = aGridGap.ToLength(); -- } -- size += gridGapCount * gridGapLength; -- } -- -- return std::max(0, nsLayoutUtils::AddPercents(size, percent)); --} -- - void - nsGridContainerFrame::LineRange::ToPositionAndLength( - const nsTArray& aTrackSizes, nscoord* aPos, nscoord* aLength) const -@@ -5961,7 +5849,7 @@ nsGridContainerFrame::Reflow(nsPresConte - LogicalSize computedSize(wm, computedISize, computedBSize); - - nscoord consumedBSize = 0; -- nscoord bSize; -+ nscoord bSize = 0; - if (!prevInFlow) { - Grid grid; - grid.PlaceGridItems(gridReflowInput, aReflowInput.ComputedMinSize(), -@@ -5969,7 +5857,12 @@ nsGridContainerFrame::Reflow(nsPresConte - - gridReflowInput.CalculateTrackSizes(grid, computedSize, - SizingConstraint::eNoConstraint); -- bSize = computedSize.BSize(wm); -+ // Note: we can't use GridLineEdge here since we haven't calculated -+ // the rows' mPosition yet (happens in AlignJustifyContent below). -+ for (const auto& sz : gridReflowInput.mRows.mSizes) { -+ bSize += sz.mBase; -+ } -+ bSize += gridReflowInput.mRows.SumOfGridGaps(); - } else { - consumedBSize = ConsumedBSize(wm); - gridReflowInput.InitializeForContinuation(this, consumedBSize); -@@ -6368,8 +6261,14 @@ nsGridContainerFrame::IntrinsicISize(gfx - state.mCols.CalculateSizes(state, state.mGridItems, state.mColFunctions, - NS_UNCONSTRAINEDSIZE, &GridArea::mCols, - constraint); -- return state.mCols.BackComputedIntrinsicSize(state.mColFunctions, -- state.mGridStyle->mGridColumnGap); -+ state.mCols.mGridGap = -+ nsLayoutUtils::ResolveGapToLength(state.mGridStyle->mGridColumnGap, -+ NS_UNCONSTRAINEDSIZE); -+ nscoord length = 0; -+ for (const TrackSize& sz : state.mCols.mSizes) { -+ length += sz.mBase; -+ } -+ return length + state.mCols.SumOfGridGaps(); - } - - nscoord -diff -Nrup mozilla-OLD/layout/generic/nsIFrame.h mozilla/layout/generic/nsIFrame.h ---- mozilla-OLD/layout/generic/nsIFrame.h 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/generic/nsIFrame.h 2022-08-30 20:19:40.380291010 +0300 -@@ -50,6 +50,7 @@ - - #include "CaretAssociationHint.h" - #include "FrameProperties.h" -+#include "LayoutConstants.h" - #include "mozilla/layout/FrameChildList.h" - #include "mozilla/Maybe.h" - #include "mozilla/SmallPointerArray.h" -@@ -166,30 +167,12 @@ typedef uint32_t nsSplittableType; - #define NS_FRAME_IS_NOT_SPLITTABLE(type)\ - (0 == ((type) & NS_FRAME_SPLITTABLE)) - --#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN -- - //---------------------------------------------------------------------- - - #define NS_SUBTREE_DIRTY(_frame) \ - (((_frame)->GetStateBits() & \ - (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0) - --/** -- * Constant used to indicate an unconstrained size. -- * -- * @see #Reflow() -- */ --#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE -- --#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE --#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE --// +1 is to avoid clamped huge margin values being processed as auto margins --#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) --#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE --// NOTE: there are assumptions all over that these have the same value, namely NS_UNCONSTRAINEDSIZE --// if any are changed to be a value other than NS_UNCONSTRAINEDSIZE --// at least update AdjustComputedHeight/Width and test ad nauseum -- - // 1 million CSS pixels less than our max app unit measure. - // For reflowing with an "infinite" available inline space per [css-sizing]. - // (reflowing with an NS_UNCONSTRAINEDSIZE available inline size isn't allowed -@@ -2393,11 +2376,9 @@ public: - */ - struct IntrinsicISizeOffsetData { - nscoord hPadding, hBorder, hMargin; -- float hPctPadding, hPctMargin; - - IntrinsicISizeOffsetData() - : hPadding(0), hBorder(0), hMargin(0) -- , hPctPadding(0.0f), hPctMargin(0.0f) - {} - }; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() = 0; -diff -Nrup mozilla-OLD/layout/tables/nsTableCellFrame.cpp mozilla/layout/tables/nsTableCellFrame.cpp ---- mozilla-OLD/layout/tables/nsTableCellFrame.cpp 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/tables/nsTableCellFrame.cpp 2022-08-30 20:19:40.381291004 +0300 -@@ -760,7 +760,6 @@ nsTableCellFrame::IntrinsicISizeOffsets( - IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); - - result.hMargin = 0; -- result.hPctMargin = 0; - - WritingMode wm = GetWritingMode(); - result.hBorder = GetBorderWidth(wm).IStartEnd(wm); -diff -Nrup mozilla-OLD/layout/tables/nsTableFrame.cpp mozilla/layout/tables/nsTableFrame.cpp ---- mozilla-OLD/layout/tables/nsTableFrame.cpp 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla/layout/tables/nsTableFrame.cpp 2022-08-30 20:19:40.383290991 +0300 -@@ -1817,11 +1817,9 @@ nsTableFrame::IntrinsicISizeOffsets() - IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); - - result.hMargin = 0; -- result.hPctMargin = 0; - - if (IsBorderCollapse()) { - result.hPadding = 0; -- result.hPctPadding = 0; - - WritingMode wm = GetWritingMode(); - LogicalMargin outerBC = GetIncludedOuterBCBorder(wm); diff --git a/seamonkey-2.53.15-GNUmakefile b/seamonkey-2.53.15-GNUmakefile deleted file mode 100644 index 2986033..0000000 --- a/seamonkey-2.53.15-GNUmakefile +++ /dev/null @@ -1,199 +0,0 @@ -# -# Front-end based on GNU make, intended for a more friendly -# integration of the build system with Linux/UNIX distributions, -# as well as for those who still allergy using mach command. -# -# Place it as `mozilla/GNUmakefile' (instead of the existing stub), -# and work under `mozilla/' dir. -# - -# -# For build, just use -# -# make -# -# (If you want to separate config stage, use "make configure" and then "make", -# but normally it is done automatically). -# -# For install, use -# -# make install DESTDIR=where_you_want_to_install -# -# -# Additionally, before install you can use: -# -# make locales -# -# to provide all the shipped locales (will appear in a form of langpack extensions). -# If irc and/or calendar are built, their data will be included too. -# (See below for more details about locales target). -# - -# -# For clarity, some comparison with the other build methods -# (assume `-jN' is the option for parallel builds, ie. `-j4' for 4-cpu system): -# -# Build stage: -# -# client.mk: make -f client.mk build MOZ_MAKE_FLAGS=-jN -# mach: ./mach build -jN -# THIS: make -jN -# -# Install stage: -# -# client.mk: DESTDIR=where... make -f client.mk install -# mach: DESTDIR=where... make -C $OBJDIR... install -# THIS: make install DESTDIR=where... -# - - -ifeq (,$(wildcard .mozconfig)) -$(error Cannot find .mozconfig file in the current directory) -endif - -MACH_CMD = ./mach --log-no-times - -OBJDIR := $(shell $(MACH_CMD) environment --format=json | sed -e 's/.*"topobjdir": "//' -e 's/".*//') - -OBJDIR_TARGETS = install distribution source-package package clobber - - -.PHONY: all configure build clean distclean $(OBJDIR_TARGETS) - - -all: build - - -configure: $(OBJDIR)/Makefile - - -$(OBJDIR)/Makefile: .mozconfig - $(MACH_CMD) configure - - -build: $(OBJDIR)/Makefile - $(MAKE) -C $(OBJDIR) - - -$(OBJDIR_TARGETS): - $(MAKE) -C $(OBJDIR) $@ - - -clean: - $(MACH_CMD) clobber - -distclean: clean - rm -f configure js/src/configure - rm -rf $(OBJDIR) - - -# -# LOCALES -# -# -# The target `locales' creates all the needed langpacks. -# -# By default, all available locales will be used. You can change it -# by overriding SHIPPED_LOCALES variable on the command line. -# -# Additionally, you can use `make locale-LANG' to create one (or several) -# langpack separately. -# -# For example, to build `fr' and 'it' only, use: -# -# make locales SHIPPED_LOCALES="fr it" -# -# to create just `ru' langpack: -# -# make locale-ru -# -# Use `clear-locales' for clearing. -# -# -# NOTE! NOTE! NOTE! -# -# Do NOT use parallel builds (-jN) for locale targets! -# -# It is better to use `-j1' explicitly (`make -j1 locales') to avoid issues. -# - -.PHONY: locales clear-locales dictionaries clear-dictionaries - - -drop_extra := $(if $(or $(filter Windows_NT,$(OS)),$(filter-out Darwin,$(shell uname))),ja-JP-mac,ja) - -SHIPPED_LOCALES := $(shell while read loc rest; do echo $$loc; done > $@/chrome/$*.manifest ; \ - done < $$manifest ; \ - done - - sed 's,$*/locale/$*,chrome/&,' $@/chrome/$*.manifest | sort > $@/chrome.manifest - rm -f $@/chrome/$*.manifest - -# Spanish locales other than es-ES are from Latam, where the es-AR langpack is most preferred - [ $* = es-AR ] && sed -i '/^locale/ s/ es-AR / es /' $@/chrome.manifest || : - - -locale-%: REL_NAME = extensions/langpack-$*@seamonkey.mozilla.org.xpi -locale-%: DEST_NAME = $(OBJDIR)/dist/bin/$(REL_NAME) -locale-%: manifest_entry = @RESPATH@/$(REL_NAME) - -# To avoid performance issues in multi-locale installs, put the manifest files -# into the beginning of the archive, and do not compress them. - -locale-%: $(stage)-% $(PACKAGE_MANIFEST) - rm -f $(DEST_NAME) - cd $<; zip -0 -D -X $(DEST_NAME) chrome.manifest install.rdf - cd $<; zip -g -r -9 -D -X $(DEST_NAME) chrome/$* - fgrep $(manifest_entry) $(PACKAGE_MANIFEST) || echo $(manifest_entry) >>$(PACKAGE_MANIFEST) - - -clear-locales: - sed -i '/langpack-.*@seamonkey.mozilla.org.xpi/ d' $(PACKAGE_MANIFEST) - rm -f $(OBJDIR)/dist/bin/extensions/langpack-*@seamonkey.mozilla.org.xpi - - -# -# Dictionaries -# -# It is better to use system dictionaries, specifying directory path for them -# by "spellchecker.dictionary_path" preference (or even use symlink when possible). -# - -DICT_DEST := $(OBJDIR)/dist/bin/dictionaries - -dictionaries: $(SHIPPED_LOCALES:%=$(stage)-%) - cp -f -d $(wildcard $(foreach loc,$(SHIPPED_LOCALES),$(stage)-$(loc)/dictionaries/$(loc).aff $(stage)-$(loc)/dictionaries/$(loc).dic)) $(DICT_DEST) - -clear-dictionaries: - rm -f $(filter-out $(DICT_DEST)/en-US.%,$(wildcard $(DICT_DEST)/*.aff $(DICT_DEST)/*.dic)) - diff --git a/seamonkey-2.53.15-ffmpeg59-1750760.patch b/seamonkey-2.53.15-ffmpeg59-1750760.patch deleted file mode 100644 index 82f8c82..0000000 --- a/seamonkey-2.53.15-ffmpeg59-1750760.patch +++ /dev/null @@ -1,268 +0,0 @@ -# -# Add support for ffmpeg-5.0 (libavcodec.so.59) for SeaMonkey -# -# Manual backport of bug 1750760: -# 1750760-1 (.../ffmpeg59/* stuff go to separate fmpeg59-headers patch) -# 1750760-3 -# 1750760-4 -# -# with stripped Wayland and va-api parts (yet not supported by SM for now). -# -# Part 2 and following bugs 1758610, 1759137 and 1762725 are skipped, -# since they are related to code which is not ported to SM yet. -# - - -diff -Nrup mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp mozilla/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp ---- mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp 2022-07-05 02:05:51.965672188 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp 2022-07-05 01:37:11.421689330 +0300 -@@ -7,6 +7,7 @@ - #include "mozilla/TaskQueue.h" - - #include "FFmpegAudioDecoder.h" -+#include "FFmpegLog.h" - #include "TimeUnits.h" - #include "VideoUtils.h" - -@@ -207,15 +208,49 @@ FFmpegAudioDecoder::DoDecode( - media::TimeUnit pts = aSample->mTime; - - while (packet.size > 0) { -- int decoded; -- int bytesConsumed = -+ int decoded = false; -+ int bytesConsumed = -1; -+#if LIBAVCODEC_VERSION_MAJOR < 59 -+ bytesConsumed = - mLib->avcodec_decode_audio4(mCodecContext, mFrame, &decoded, &packet); -- - if (bytesConsumed < 0) { - NS_WARNING("FFmpeg audio decoder error."); - return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, - RESULT_DETAIL("FFmpeg audio error:%d", bytesConsumed)); - } -+#else -+# define AVRESULT_OK 0 -+ -+ int ret = mLib->avcodec_receive_frame(mCodecContext, mFrame); -+ switch (ret) { -+ case AVRESULT_OK: -+ decoded = true; -+ break; -+ case AVERROR(EAGAIN): -+ break; -+ case AVERROR_EOF: { -+ FFMPEG_LOG(" End of stream."); -+ return MediaResult(NS_ERROR_DOM_MEDIA_END_OF_STREAM, -+ RESULT_DETAIL("End of stream")); -+ } -+ } -+ ret = mLib->avcodec_send_packet(mCodecContext, &packet); -+ switch (ret) { -+ case AVRESULT_OK: -+ bytesConsumed = packet.size; -+ break; -+ case AVERROR(EAGAIN): -+ break; -+ case AVERROR_EOF: -+ FFMPEG_LOG(" End of stream."); -+ return MediaResult(NS_ERROR_DOM_MEDIA_END_OF_STREAM, -+ RESULT_DETAIL("End of stream")); -+ default: -+ NS_WARNING("FFmpeg audio decoder error."); -+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, -+ RESULT_DETAIL("FFmpeg audio error")); -+ } -+#endif - - if (decoded) { - if (mFrame->format != AV_SAMPLE_FMT_FLT && -diff -Nrup mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp mozilla/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp ---- mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp 2022-11-02 23:12:10.000000000 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp 2022-12-11 03:37:39.151778299 +0300 -@@ -62,13 +62,15 @@ FFmpegLibWrapper::Link() - AV_FUNC_56 = 1 << 3, - AV_FUNC_57 = 1 << 4, - AV_FUNC_58 = 1 << 5, -+ AV_FUNC_59 = 1 << 6, - AV_FUNC_AVUTIL_53 = AV_FUNC_53 | AV_FUNC_AVUTIL_MASK, - AV_FUNC_AVUTIL_54 = AV_FUNC_54 | AV_FUNC_AVUTIL_MASK, - AV_FUNC_AVUTIL_55 = AV_FUNC_55 | AV_FUNC_AVUTIL_MASK, - AV_FUNC_AVUTIL_56 = AV_FUNC_56 | AV_FUNC_AVUTIL_MASK, - AV_FUNC_AVUTIL_57 = AV_FUNC_57 | AV_FUNC_AVUTIL_MASK, - AV_FUNC_AVUTIL_58 = AV_FUNC_58 | AV_FUNC_AVUTIL_MASK, -- AV_FUNC_AVCODEC_ALL = AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58, -+ AV_FUNC_AVUTIL_59 = AV_FUNC_59 | AV_FUNC_AVUTIL_MASK, -+ AV_FUNC_AVCODEC_ALL = AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59, - AV_FUNC_AVUTIL_ALL = AV_FUNC_AVCODEC_ALL | AV_FUNC_AVUTIL_MASK - }; - -@@ -91,6 +93,9 @@ FFmpegLibWrapper::Link() - case 58: - version = AV_FUNC_58; - break; -+ case 59: -+ version = AV_FUNC_59; -+ break; - default: - FFMPEG_LOG("Unknown avcodec version"); - Unlink(); -@@ -120,15 +125,19 @@ FFmpegLibWrapper::Link() - : LinkResult::MissingLibAVFunction; \ - } - -- AV_FUNC(av_lockmgr_register, AV_FUNC_AVCODEC_ALL) -+ AV_FUNC(av_lockmgr_register, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | -+ AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58) - AV_FUNC(avcodec_alloc_context3, AV_FUNC_AVCODEC_ALL) - AV_FUNC(avcodec_close, AV_FUNC_AVCODEC_ALL) -- AV_FUNC(avcodec_decode_audio4, AV_FUNC_AVCODEC_ALL) -- AV_FUNC(avcodec_decode_video2, AV_FUNC_AVCODEC_ALL) -+ AV_FUNC(avcodec_decode_audio4, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | -+ AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58) -+ AV_FUNC(avcodec_decode_video2, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | -+ AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58) - AV_FUNC(avcodec_find_decoder, AV_FUNC_AVCODEC_ALL) - AV_FUNC(avcodec_flush_buffers, AV_FUNC_AVCODEC_ALL) - AV_FUNC(avcodec_open2, AV_FUNC_AVCODEC_ALL) -- AV_FUNC(avcodec_register_all, AV_FUNC_AVCODEC_ALL) -+ AV_FUNC(avcodec_register_all, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | -+ AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58) - AV_FUNC(av_init_packet, AV_FUNC_AVCODEC_ALL) - AV_FUNC(av_parser_init, AV_FUNC_AVCODEC_ALL) - AV_FUNC(av_parser_close, AV_FUNC_AVCODEC_ALL) -@@ -136,22 +145,30 @@ FFmpegLibWrapper::Link() - AV_FUNC(avcodec_alloc_frame, (AV_FUNC_53 | AV_FUNC_54)) - AV_FUNC(avcodec_get_frame_defaults, (AV_FUNC_53 | AV_FUNC_54)) - AV_FUNC(avcodec_free_frame, AV_FUNC_54) -- AV_FUNC(avcodec_send_packet, AV_FUNC_58) -- AV_FUNC(avcodec_receive_frame, AV_FUNC_58) -+ AV_FUNC(avcodec_send_packet, AV_FUNC_58 | AV_FUNC_59) -+ AV_FUNC(avcodec_receive_frame, AV_FUNC_58 | AV_FUNC_59) - AV_FUNC_OPTION(av_rdft_init, AV_FUNC_AVCODEC_ALL) - AV_FUNC_OPTION(av_rdft_calc, AV_FUNC_AVCODEC_ALL) - AV_FUNC_OPTION(av_rdft_end, AV_FUNC_AVCODEC_ALL) - AV_FUNC(av_log_set_level, AV_FUNC_AVUTIL_ALL) - AV_FUNC(av_malloc, AV_FUNC_AVUTIL_ALL) - AV_FUNC(av_freep, AV_FUNC_AVUTIL_ALL) -- AV_FUNC(av_frame_alloc, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | AV_FUNC_AVUTIL_58)) -- AV_FUNC(av_frame_free, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | AV_FUNC_AVUTIL_58)) -- AV_FUNC(av_frame_unref, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | AV_FUNC_AVUTIL_58)) -+ AV_FUNC(av_frame_alloc, -+ (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | -+ AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59)) -+ AV_FUNC(av_frame_free, -+ (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | -+ AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59)) -+ AV_FUNC(av_frame_unref, -+ (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | -+ AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59)) - AV_FUNC_OPTION(av_frame_get_colorspace, AV_FUNC_AVUTIL_ALL) - #undef AV_FUNC - #undef AV_FUNC_OPTION - -- avcodec_register_all(); -+ if (avcodec_register_all) { -+ avcodec_register_all(); -+ } - if (MOZ_LOG_TEST(sPDMLog, LogLevel::Debug)) { - av_log_set_level(AV_LOG_DEBUG); - } else if (MOZ_LOG_TEST(sPDMLog, LogLevel::Info)) { -diff -Nrup mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp mozilla/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp ---- mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp 2022-07-05 02:05:51.991672031 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp 2022-07-05 00:41:37.255958365 +0300 -@@ -26,6 +26,7 @@ static FFmpegLibWrapper sLibAV; - - static const char* sLibs[] = { - #if defined(XP_DARWIN) -+ "libavcodec.59.dylib", - "libavcodec.58.dylib", - "libavcodec.57.dylib", - "libavcodec.56.dylib", -@@ -33,7 +34,9 @@ static const char* sLibs[] = { - "libavcodec.54.dylib", - "libavcodec.53.dylib", - #else -+ "libavcodec.so.59", - "libavcodec.so.58", -+ "libavcodec-ffmpeg.so.59", - "libavcodec-ffmpeg.so.58", - "libavcodec-ffmpeg.so.57", - "libavcodec-ffmpeg.so.56", -@@ -138,6 +141,7 @@ FFmpegRuntimeLinker::CreateDecoderModule - case 56: module = FFmpegDecoderModule<55>::Create(&sLibAV); break; - case 57: module = FFmpegDecoderModule<57>::Create(&sLibAV); break; - case 58: module = FFmpegDecoderModule<58>::Create(&sLibAV); break; -+ case 59: module = FFmpegDecoderModule<59>::Create(&sLibAV); break; - default: module = nullptr; - } - return module.forget(); -diff -Nrup mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp mozilla/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp ---- mozilla-OLD/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2022-07-05 02:05:51.992672025 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2022-07-05 01:08:00.142345410 +0300 -@@ -23,6 +23,9 @@ - #define AV_PIX_FMT_YUV444P10LE PIX_FMT_YUV444P10LE - #define AV_PIX_FMT_NONE PIX_FMT_NONE - #endif -+#if LIBAVCODEC_VERSION_MAJOR > 58 -+#define AV_PIX_FMT_VAAPI_VLD AV_PIX_FMT_VAAPI -+#endif - #include "mozilla/PodOperations.h" - #include "mozilla/TaskQueue.h" - #include "nsThreadUtils.h" -@@ -183,6 +186,14 @@ FFmpegVideoDecoder::InitCodec - mCodecContext->get_format = ChoosePixelFormat; - } - -+static int64_t GetFramePts(AVFrame* aFrame) { -+#if LIBAVCODEC_VERSION_MAJOR > 58 -+ return aFrame->pts; -+#else -+ return aFrame->pkt_pts; -+#endif -+} -+ - MediaResult - FFmpegVideoDecoder::DoDecode(MediaRawData* aSample, - uint8_t* aData, int aSize, -@@ -231,7 +242,7 @@ FFmpegVideoDecoder::DoDecode( - return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, - RESULT_DETAIL("avcodec_receive_frame error: %d", res)); - } -- MediaResult rv = CreateImage(mFrame->pkt_pos, mFrame->pkt_pts, -+ MediaResult rv = CreateImage(mFrame->pkt_pos, GetFramePts(mFrame), - mFrame->pkt_duration, aResults); - if (NS_FAILED(rv)) { - return rv; -@@ -263,9 +274,9 @@ FFmpegVideoDecoder::DoDecode( - - FFMPEG_LOG("DoDecodeFrame:decode_video: rv=%d decoded=%d " - "(Input: pts(%" PRId64 ") dts(%" PRId64 ") Output: pts(%" PRId64 ") " -- "opaque(%" PRId64 ") pkt_pts(%" PRId64 ") pkt_dts(%" PRId64 "))", -+ "opaque(%" PRId64 ") pts(%" PRId64 ") pkt_dts(%" PRId64 "))", - bytesConsumed, decoded, packet.pts, packet.dts, mFrame->pts, -- mFrame->reordered_opaque, mFrame->pkt_pts, mFrame->pkt_dts); -+ mFrame->reordered_opaque, mFrame->pts, mFrame->pkt_dts); - - if (bytesConsumed < 0) { - return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, -@@ -294,7 +305,7 @@ FFmpegVideoDecoder::DoDecode( - } - - // If we've decoded a frame then we need to output it -- int64_t pts = mPtsContext.GuessCorrectPts(mFrame->pkt_pts, mFrame->pkt_dts); -+ int64_t pts = mPtsContext.GuessCorrectPts(GetFramePts(mFrame), mFrame->pkt_dts); - // Retrieve duration from dts. - // We use the first entry found matching this dts (this is done to - // handle damaged file with multiple frames with the same dts) -diff -Nrup mozilla-OLD/dom/media/platforms/ffmpeg/moz.build mozilla/dom/media/platforms/ffmpeg/moz.build ---- mozilla-OLD/dom/media/platforms/ffmpeg/moz.build 2022-07-05 02:05:51.992672025 +0300 -+++ mozilla/dom/media/platforms/ffmpeg/moz.build 2022-07-05 00:27:24.477123880 +0300 -@@ -14,6 +14,7 @@ DIRS += [ - 'libav55', - 'ffmpeg57', - 'ffmpeg58', -+ 'ffmpeg59', - ] - - UNIFIED_SOURCES += [ diff --git a/seamonkey-2.53.15-mozilla-1464782.patch b/seamonkey-2.53.15-mozilla-1464782.patch deleted file mode 100644 index 1ad892a..0000000 --- a/seamonkey-2.53.15-mozilla-1464782.patch +++ /dev/null @@ -1,2474 +0,0 @@ -diff -Nrbu mozilla/browser/base/content/abouthome/aboutHome.css mozilla-OK/browser/base/content/abouthome/aboutHome.css ---- mozilla/browser/base/content/abouthome/aboutHome.css 2020-02-18 02:37:46.000000000 +0300 -+++ mozilla-OK/browser/base/content/abouthome/aboutHome.css 2023-01-21 23:06:22.863203389 +0300 -@@ -363,7 +363,7 @@ - display: block; - position: absolute; - top: 12px; -- offset-inline-end: 12px; -+ inset-inline-end: 12px; - width: 67px; - height: 19px; - } -diff -Nrbu mozilla/browser/base/content/browser.css mozilla-OK/browser/base/content/browser.css ---- mozilla/browser/base/content/browser.css 2022-04-13 21:14:20.000000000 +0300 -+++ mozilla-OK/browser/base/content/browser.css 2023-01-21 23:06:22.875203320 +0300 -@@ -998,8 +998,8 @@ - } - - statuspanel[mirror] { -- offset-inline-start: auto; -- offset-inline-end: 0; -+ inset-inline-start: auto; -+ inset-inline-end: 0; - } - - statuspanel[sizelimit] { -diff -Nrbu mozilla/browser/themes/shared/incontentprefs/preferences.inc.css mozilla-OK/browser/themes/shared/incontentprefs/preferences.inc.css ---- mozilla/browser/themes/shared/incontentprefs/preferences.inc.css 2022-04-13 21:14:20.000000000 +0300 -+++ mozilla-OK/browser/themes/shared/incontentprefs/preferences.inc.css 2023-01-21 23:06:22.895203203 +0300 -@@ -664,7 +664,7 @@ - border: 7px solid transparent; - border-top-color: #d7b600; - top: 100%; -- offset-inline-start: calc(50% - 7px); -+ inset-inline-start: calc(50% - 7px); - } - - .search-tooltip::after { -@@ -673,7 +673,7 @@ - border: 6px solid transparent; - border-top-color: #ffe900; - top: 100%; -- offset-inline-start: calc(50% - 6px); -+ inset-inline-start: calc(50% - 6px); - } - - .search-tooltip-parent { -diff -Nrbu mozilla/browser/themes/shared/privatebrowsing/aboutPrivateBrowsing.css.1464782.later mozilla-OK/browser/themes/shared/privatebrowsing/aboutPrivateBrowsing.css.1464782.later ---- mozilla/browser/themes/shared/privatebrowsing/aboutPrivateBrowsing.css.1464782.later 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/browser/themes/shared/privatebrowsing/aboutPrivateBrowsing.css.1464782.later 2023-01-21 23:06:22.895203203 +0300 -@@ -0,0 +1,20 @@ -+--- aboutPrivateBrowsing.css -++++ aboutPrivateBrowsing.css -+@@ -144,16 +144,16 @@ a.button { -+ } -+ -+ .toggle:checked + .toggle-btn { -+ background: #16da00; -+ border-color: #0CA700; -+ } -+ -+ .toggle:checked + .toggle-btn::after { -+- offset-inline-start: 21px; -++ inset-inline-start: 21px; -+ } -+ -+ .toggle:-moz-focusring + .toggle-btn { -+ outline: 2px solid rgba(0, 149, 221, 0.5); -+ outline-offset: 1px; -+ -moz-outline-radius: 2px; -+ } -diff -Nrbu mozilla/devtools/client/debugger/new/debugger.css mozilla-OK/devtools/client/debugger/new/debugger.css ---- mozilla/devtools/client/debugger/new/debugger.css 2022-08-24 22:55:10.000000000 +0300 -+++ mozilla-OK/devtools/client/debugger/new/debugger.css 2023-01-21 23:06:22.900203174 +0300 -@@ -2655,8 +2655,8 @@ - - .breakpoint .close-btn { - position: absolute; -- offset-inline-end: 13px; -- offset-inline-start: auto; -+ inset-inline-end: 13px; -+ inset-inline-start: auto; - top: 9px; - } - -@@ -2724,7 +2724,7 @@ - - .expression-container__close-btn { - position: absolute; -- offset-inline-end: 0px; -+ inset-inline-end: 0px; - top: 4px; - } - -@@ -3212,8 +3212,8 @@ - position: absolute; - top: auto; - bottom: 0; -- offset-inline-end: 0; -- offset-inline-start: auto; -+ inset-inline-end: 0; -+ inset-inline-start: auto; - } - - .shortcutKeys { -diff -Nrbu mozilla/devtools/client/shared/test/unit/test_suggestion-picker.js mozilla-OK/devtools/client/shared/test/unit/test_suggestion-picker.js ---- mozilla/devtools/client/shared/test/unit/test_suggestion-picker.js 2021-03-01 21:17:56.000000000 +0300 -+++ mozilla-OK/devtools/client/shared/test/unit/test_suggestion-picker.js 2023-01-21 23:06:22.910203116 +0300 -@@ -99,10 +99,10 @@ - items: [ - "object-fit", - "object-position", -- "offset-block-end", -- "offset-block-start", -- "offset-inline-end", -- "offset-inline-start", -+ "inset-block-end", -+ "inset-block-start", -+ "inset-inline-end", -+ "inset-inline-start", - "opacity", - "order", - "orphans", -diff -Nrbu mozilla/devtools/client/themes/breadcrumbs.css mozilla-OK/devtools/client/themes/breadcrumbs.css ---- mozilla/devtools/client/themes/breadcrumbs.css 2022-06-08 22:10:25.000000000 +0300 -+++ mozilla-OK/devtools/client/themes/breadcrumbs.css 2023-01-21 23:06:22.916203081 +0300 -@@ -112,7 +112,7 @@ - content: ""; - position: absolute; - top: 1px; -- offset-inline-start: 0; -+ inset-inline-start: 0; - width: 12px; - height: 22px; - background-repeat: no-repeat; -diff -Nrbu mozilla/devtools/client/themes/common.css mozilla-OK/devtools/client/themes/common.css ---- mozilla/devtools/client/themes/common.css 2022-04-13 21:14:20.000000000 +0300 -+++ mozilla-OK/devtools/client/themes/common.css 2023-01-21 23:06:22.917203075 +0300 -@@ -536,7 +536,7 @@ - .devtools-searchinput-clear { - position: absolute; - top: 3.5px; -- offset-inline-end: 7px; -+ inset-inline-end: 7px; - padding: 0; - border: 0; - width: 16px; -@@ -686,7 +686,7 @@ - position: absolute; - - top: 0; -- offset-inline-end: 0; -+ inset-inline-end: 0; - width: 15px; - height: 100%; - -diff -Nrbu mozilla/devtools/client/themes/fonts.css.1464782.later mozilla-OK/devtools/client/themes/fonts.css.1464782.later ---- mozilla/devtools/client/themes/fonts.css.1464782.later 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/devtools/client/themes/fonts.css.1464782.later 2023-01-21 23:06:22.917203075 +0300 -@@ -0,0 +1,21 @@ -+--- fonts.css -++++ fonts.css -+@@ -97,17 +97,17 @@ -+ .font-css-code { -+ direction: ltr; -+ margin: 0; -+ overflow: hidden; -+ text-overflow: ellipsis; -+ color: var(--theme-toolbar-color); -+ grid-column: span 2; -+ position: relative; -+- offset-inline-start: -4px; -++ inset-inline-start: -4px; -+ } -+ -+ .font-css-code-expander::before { -+ content: "\2026"; -+ display: inline-block; -+ width: 12px; -+ height: 8px; -+ margin: 0 2px; -diff -Nrbu mozilla/devtools/client/themes/toolbox.css.1464782.later mozilla-OK/devtools/client/themes/toolbox.css.1464782.later ---- mozilla/devtools/client/themes/toolbox.css.1464782.later 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/devtools/client/themes/toolbox.css.1464782.later 2023-01-21 23:06:22.918203069 +0300 -@@ -0,0 +1,21 @@ -+--- toolbox.css -++++ toolbox.css -+@@ -176,17 +176,17 @@ -+ -moz-context-properties: fill; -+ fill: var(--theme-toolbar-photon-icon-color); -+ } -+ -+ /* Toolbox controls */ -+ -+ #tools-chevron-menu-button::before { -+ top: 0; -+- offset-inline-end: 0; -++ inset-inline-end: 0; -+ background-image: var(--command-chevron-image); -+ background-position: center; -+ } -+ -+ .tools-chevron-menu:-moz-locale-dir(rtl) { -+ transform: rotate(180deg); -+ } -+ -diff -Nrbu mozilla/devtools/docs/contributing/css.md mozilla-OK/devtools/docs/contributing/css.md ---- mozilla/devtools/docs/contributing/css.md 2020-02-18 02:37:48.000000000 +0300 -+++ mozilla-OK/devtools/docs/contributing/css.md 2023-01-21 23:06:22.939202947 +0300 -@@ -95,7 +95,7 @@ - ### Text Direction - * For margins, padding and borders, use `inline-start`/`inline-end` rather than `left`/`right`. - * Example: Use `margin-inline-start: 3px;` not `margin-left: 3px`. --* For RTL-aware positioning (left/right), use `offset-inline-start/end`. -+* For RTL-aware positioning (left/right), use `inset-inline-start/end`. - * When there is no special RTL-aware property (eg. `float: left|right`) available, use the pseudo `:-moz-locale-dir(ltr|rtl)` (for XUL files) or `:dir(ltr|rtl)` (for HTML files). - * Remember that while a tab content's scrollbar still shows on the right in RTL, an overflow scrollbar will show on the left. - * Write `padding: 0 3px 4px;` instead of `padding: 0 3px 4px 3px;`. This makes it more obvious that the padding is symmetrical (so RTL won't be an issue). -diff -Nrbu mozilla/devtools/server/actors/animation-type-longhand.js.1464782.later mozilla-OK/devtools/server/actors/animation-type-longhand.js.1464782.later ---- mozilla/devtools/server/actors/animation-type-longhand.js.1464782.later 1970-01-01 03:00:00.000000000 +0300 -+++ mozilla-OK/devtools/server/actors/animation-type-longhand.js.1464782.later 2023-01-21 23:06:22.939202947 +0300 -@@ -0,0 +1,37 @@ -+--- animation-type-longhand.js -++++ animation-type-longhand.js -+@@ -190,30 +190,30 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [ -+ "border-inline-start-color", -+ "border-inline-start-style", -+ "border-inline-start-width", -+ "-moz-context-properties", -+ "-moz-control-character-visibility", -+ "display", -+ "font-optical-sizing", -+ "inline-size", -++ "inset-block-end", -++ "inset-block-start", -++ "inset-inline-end", -++ "inset-inline-start", -+ "margin-block-end", -+ "margin-block-start", -+ "margin-inline-end", -+ "margin-inline-start", -+ "-moz-math-display", -+ "max-block-size", -+ "max-inline-size", -+ "min-block-size", -+ "-moz-min-font-size-ratio", -+ "min-inline-size", -+- "offset-block-end", -+- "offset-block-start", -+- "offset-inline-end", -+- "offset-inline-start", -+ "padding-block-end", -+ "padding-block-start", -+ "padding-inline-end", -+ "padding-inline-start", -+ "rotate", -+ "scale", -+ "-moz-script-level", -+ "-moz-top-layer", -diff -Nrbu mozilla/devtools/server/actors/highlighters.css mozilla-OK/devtools/server/actors/highlighters.css ---- mozilla/devtools/server/actors/highlighters.css 2022-04-13 21:14:20.000000000 +0300 -+++ mozilla-OK/devtools/server/actors/highlighters.css 2023-01-21 23:06:22.949202889 +0300 -@@ -538,8 +538,8 @@ - width: 16px; - height: 16px; - position: absolute; -- offset-inline-start: 3px; -- offset-block-start: 3px; -+ inset-inline-start: 3px; -+ inset-block-start: 3px; - box-shadow: 0px 0px 0px black; - border: solid 1px #fff; - } -diff -Nrbu mozilla/devtools/shared/css/generated/properties-db.js mozilla-OK/devtools/shared/css/generated/properties-db.js ---- mozilla/devtools/shared/css/generated/properties-db.js 2022-08-24 22:55:10.000000000 +0300 -+++ mozilla-OK/devtools/shared/css/generated/properties-db.js 2023-01-21 23:06:25.890185823 +0300 -@@ -3091,10 +3091,10 @@ - "mix-blend-mode", - "object-fit", - "object-position", -- "offset-block-end", -- "offset-block-start", -- "offset-inline-end", -- "offset-inline-start", -+ "inset-block-start", -+ "inset-block-end", -+ "inset-inline-start", -+ "inset-inline-end", - "opacity", - "order", - "-moz-orient", -@@ -7093,6 +7093,74 @@ - "unset" - ] - }, -+ "inset-block-end": { -+ "isInherited": false, -+ "subproperties": [ -+ "inset-block-end" -+ ], -+ "supports": [ -+ 6, -+ 8 -+ ], -+ "values": [ -+ "auto", -+ "calc", -+ "inherit", -+ "initial", -+ "unset" -+ ] -+ }, -+ "inset-block-start": { -+ "isInherited": false, -+ "subproperties": [ -+ "inset-block-start" -+ ], -+ "supports": [ -+ 6, -+ 8 -+ ], -+ "values": [ -+ "auto", -+ "calc", -+ "inherit", -+ "initial", -+ "unset" -+ ] -+ }, -+ "inset-inline-end": { -+ "isInherited": false, -+ "subproperties": [ -+ "inset-inline-end" -+ ], -+ "supports": [ -+ 6, -+ 8 -+ ], -+ "values": [ -+ "auto", -+ "calc", -+ "inherit", -+ "initial", -+ "unset" -+ ] -+ }, -+ "inset-inline-start": { -+ "isInherited": false, -+ "subproperties": [ -+ "inset-inline-start" -+ ], -+ "supports": [ -+ 6, -+ 8 -+ ], -+ "values": [ -+ "auto", -+ "calc", -+ "inherit", -+ "initial", -+ "unset" -+ ] -+ }, - "isolation": { - "isInherited": false, - "subproperties": [ -@@ -8038,74 +8106,6 @@ - "unset" - ] - }, -- "offset-block-end": { -- "isInherited": false, -- "subproperties": [ -- "offset-block-end" -- ], -- "supports": [ -- 6, -- 8 -- ], -- "values": [ -- "auto", -- "calc", -- "inherit", -- "initial", -- "unset" -- ] -- }, -- "offset-block-start": { -- "isInherited": false, -- "subproperties": [ -- "offset-block-start" -- ], -- "supports": [ -- 6, -- 8 -- ], -- "values": [ -- "auto", -- "calc", -- "inherit", -- "initial", -- "unset" -- ] -- }, -- "offset-inline-end": { -- "isInherited": false, -- "subproperties": [ -- "offset-inline-end" -- ], -- "supports": [ -- 6, -- 8 -- ], -- "values": [ -- "auto", -- "calc", -- "inherit", -- "initial", -- "unset" -- ] -- }, -- "offset-inline-start": { -- "isInherited": false, -- "subproperties": [ -- "offset-inline-start" -- ], -- "supports": [ -- 6, -- 8 -- ], -- "values": [ -- "auto", -- "calc", -- "inherit", -- "initial", -- "unset" -- ] -- }, - "opacity": { - "isInherited": false, - "subproperties": [ -diff -Nrbu mozilla/layout/base/tests/bug1354478-1-ref.html mozilla-OK/layout/base/tests/bug1354478-1-ref.html ---- mozilla/layout/base/tests/bug1354478-1-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-1-ref.html 2023-01-21 23:06:19.530222725 +0300 -@@ -12,7 +12,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-1.html mozilla-OK/layout/base/tests/bug1354478-1.html ---- mozilla/layout/base/tests/bug1354478-1.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-1.html 2023-01-21 23:06:19.531222719 +0300 -@@ -12,7 +12,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-2-ref.html mozilla-OK/layout/base/tests/bug1354478-2-ref.html ---- mozilla/layout/base/tests/bug1354478-2-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-2-ref.html 2023-01-21 23:06:19.532222713 +0300 -@@ -12,7 +12,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-2.html mozilla-OK/layout/base/tests/bug1354478-2.html ---- mozilla/layout/base/tests/bug1354478-2.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-2.html 2023-01-21 23:06:19.532222713 +0300 -@@ -12,7 +12,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-3-ref.html mozilla-OK/layout/base/tests/bug1354478-3-ref.html ---- mozilla/layout/base/tests/bug1354478-3-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-3-ref.html 2023-01-21 23:06:19.532222713 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-3.html mozilla-OK/layout/base/tests/bug1354478-3.html ---- mozilla/layout/base/tests/bug1354478-3.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-3.html 2023-01-21 23:06:19.532222713 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-4-ref.html mozilla-OK/layout/base/tests/bug1354478-4-ref.html ---- mozilla/layout/base/tests/bug1354478-4-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-4-ref.html 2023-01-21 23:06:19.532222713 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-4.html mozilla-OK/layout/base/tests/bug1354478-4.html ---- mozilla/layout/base/tests/bug1354478-4.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-4.html 2023-01-21 23:06:19.533222707 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-5-ref.html mozilla-OK/layout/base/tests/bug1354478-5-ref.html ---- mozilla/layout/base/tests/bug1354478-5-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-5-ref.html 2023-01-21 23:06:19.533222707 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-5.html mozilla-OK/layout/base/tests/bug1354478-5.html ---- mozilla/layout/base/tests/bug1354478-5.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-5.html 2023-01-21 23:06:19.533222707 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-6-ref.html mozilla-OK/layout/base/tests/bug1354478-6-ref.html ---- mozilla/layout/base/tests/bug1354478-6-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-6-ref.html 2023-01-21 23:06:19.533222707 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/base/tests/bug1354478-6.html mozilla-OK/layout/base/tests/bug1354478-6.html ---- mozilla/layout/base/tests/bug1354478-6.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/base/tests/bug1354478-6.html 2023-01-21 23:06:19.533222707 +0300 -@@ -15,7 +15,7 @@ - inline-size: 200px; - block-size: 20px; - position: relative; -- offset-block-start: -20px; -+ inset-block-start: -20px; - background: silver; - } - -diff -Nrbu mozilla/layout/reftests/css-grid/grid-align-content-001-ref.html mozilla-OK/layout/reftests/css-grid/grid-align-content-001-ref.html ---- mozilla/layout/reftests/css-grid/grid-align-content-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-align-content-001-ref.html 2023-01-21 23:06:19.534222701 +0300 -@@ -45,20 +45,20 @@ - .vlr { writing-mode: vertical-lr; direction:rtl; } - .vrl { writing-mode: vertical-rl; direction:ltr; } - --.aend *, .aflexend * { offset-block-start:25px; } --.acenter * { offset-block-start:12.5px; } -+.aend *, .aflexend * { inset-block-start:25px; } -+.acenter * { inset-block-start:12.5px; } - - --.aspace-between item2 { offset-block-start:12.5px; } --.aspace-between item3 { offset-block-start:25px; } -+.aspace-between item2 { inset-block-start:12.5px; } -+.aspace-between item3 { inset-block-start:25px; } - --.aspace-around item1 { offset-block-start:4.1666px; } --.aspace-around item2 { offset-block-start:12.5px; } --.aspace-around item3 { offset-block-start:20.8333px; } -+.aspace-around item1 { inset-block-start:4.1666px; } -+.aspace-around item2 { inset-block-start:12.5px; } -+.aspace-around item3 { inset-block-start:20.8333px; } - --.aspace-evenly item1 { offset-block-start:6.25px; } --.aspace-evenly item2 { offset-block-start:12.5px; } --.aspace-evenly item3 { offset-block-start:18.75px; } -+.aspace-evenly item1 { inset-block-start:6.25px; } -+.aspace-evenly item2 { inset-block-start:12.5px; } -+.aspace-evenly item3 { inset-block-start:18.75px; } - - .astretch2 { grid-template-rows: 1fr 5px 7px; } - .astretch3 { grid-template-rows: 15.5px 17.5px 7px; } -diff -Nrbu mozilla/layout/reftests/css-grid/grid-item-align-001-ref.html mozilla-OK/layout/reftests/css-grid/grid-item-align-001-ref.html ---- mozilla/layout/reftests/css-grid/grid-item-align-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-item-align-001-ref.html 2023-01-21 23:06:19.534222701 +0300 -@@ -34,7 +34,7 @@ - border-block-start: 2px solid blue; - border-inline-start: 2px solid lime; - margin: 1px 1px 2px 2px; -- offset-inline-start: 1px; -+ inset-inline-start: 1px; - } - - abs1,abs2,abs3,abs4 { -@@ -63,11 +63,11 @@ - - .astart,.aflexstart,.aleft,.aright,.astretch1,.astretch2,.astretch2,.astretch3, - .astretch4,.astretch5,.astretch6,.astretch7,.aauto { -- offset-block-start: 3px; -+ inset-block-start: 3px; - } - --.aend,.aflexend { offset-block-start: 9px; } --.acenter { offset-block-start: 5px; margin-block-start:2px; } -+.aend,.aflexend { inset-block-start: 9px; } -+.acenter { inset-block-start: 5px; margin-block-start:2px; } - - .hl .astretch2, .hr .astretch2 { height: 15px; } - .hl .astretch3, .hr .astretch3 { height: 15px; } -@@ -80,7 +80,7 @@ - .astretch7 { width:0; height:9px; } - - .hl .hr {margin-left:4px;} --.hl .vl {offset-block-start: 1px; offset-inline-start:3px;} -+.hl .vl {inset-block-start: 1px; inset-inline-start:3px;} - .hl .vl.aend, .hl .vl.aflexend { margin-top: 7px; } - .hl .vl.acenter { margin-top:4px; } - -@@ -115,7 +115,7 @@ - .hr .vrl.aend, .hr .vrl.aflexend {margin-top:9px; margin-right:-7px; } - .hr .vrl.acenter {margin-top:6px; margin-right:-3px; } - --.vl span { offset-block-start: 1px; offset-inline-start: 3px; } -+.vl span { inset-block-start: 1px; inset-inline-start: 3px; } - .vl .astretch4 { width:15px; } - .vl .astretch5 { width:13px; } - -diff -Nrbu mozilla/layout/reftests/css-grid/grid-item-align-002-ref.html mozilla-OK/layout/reftests/css-grid/grid-item-align-002-ref.html ---- mozilla/layout/reftests/css-grid/grid-item-align-002-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-item-align-002-ref.html 2023-01-21 23:06:19.534222701 +0300 -@@ -28,7 +28,7 @@ - wrap { - display: block; - position: relative; -- offset-inline-start:1px; -+ inset-inline-start:1px; - background: white; - block-size:20px; - inline-size:32px; -diff -Nrbu mozilla/layout/reftests/css-grid/grid-item-align-003-ref.html mozilla-OK/layout/reftests/css-grid/grid-item-align-003-ref.html ---- mozilla/layout/reftests/css-grid/grid-item-align-003-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-item-align-003-ref.html 2023-01-21 23:06:19.534222701 +0300 -@@ -29,7 +29,7 @@ - wrap { - display: block; - position: relative; -- offset-inline-start:1px; -+ inset-inline-start:1px; - background: white; - block-size:20px; - inline-size:32px; -@@ -65,10 +65,10 @@ - .vlr { writing-mode: vertical-lr; direction:rtl; } - .vrl { writing-mode: vertical-rl; direction:ltr; } - --.unsafe.hl.aend, .unsafe.hl.aflexend { offset-block-start:-15px; } --.unsafe.vrl.aend, .unsafe.vrl.aflexend { offset-inline-start:-15px; } --.unsafe.hl.acenter { offset-block-start:-7px; } --.unsafe.vrl.acenter { offset-inline-start:-7px; } -+.unsafe.hl.aend, .unsafe.hl.aflexend { inset-block-start:-15px; } -+.unsafe.vrl.aend, .unsafe.vrl.aflexend { inset-inline-start:-15px; } -+.unsafe.hl.acenter { inset-block-start:-7px; } -+.unsafe.vrl.acenter { inset-inline-start:-7px; } - .astretch2 { width:40px; height:15px; } - .astretch3 { height:15px; } - .astretch4 { width:0; } -diff -Nrbu mozilla/layout/reftests/css-grid/grid-item-justify-001-ref.html mozilla-OK/layout/reftests/css-grid/grid-item-justify-001-ref.html ---- mozilla/layout/reftests/css-grid/grid-item-justify-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-item-justify-001-ref.html 2023-01-21 23:06:19.534222701 +0300 -@@ -29,7 +29,7 @@ - wrap { - display: block; - position: relative; -- offset-inline-start: 1px; -+ inset-inline-start: 1px; - background: white; - block-size: 20px; - inline-size: 32px; -diff -Nrbu mozilla/layout/reftests/css-grid/grid-item-justify-002-ref.html mozilla-OK/layout/reftests/css-grid/grid-item-justify-002-ref.html ---- mozilla/layout/reftests/css-grid/grid-item-justify-002-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-item-justify-002-ref.html 2023-01-21 23:06:19.535222695 +0300 -@@ -29,7 +29,7 @@ - wrap { - display: block; - position: relative; -- offset-inline-start: 1px; -+ inset-inline-start: 1px; - background: white; - block-size: 20px; - inline-size: 32px; -diff -Nrbu mozilla/layout/reftests/css-grid/grid-justify-content-001-ref.html mozilla-OK/layout/reftests/css-grid/grid-justify-content-001-ref.html ---- mozilla/layout/reftests/css-grid/grid-justify-content-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-justify-content-001-ref.html 2023-01-21 23:06:19.535222695 +0300 -@@ -45,21 +45,21 @@ - .vlr { writing-mode: vertical-lr; direction:rtl; } - .vrl { writing-mode: vertical-rl; direction:ltr; } - --.jend * , .jflexend * { offset-inline-start:17px; } --.jcenter * { offset-inline-start:8.5px; } --.hr.jleft * , .vlr.jleft * { offset-inline-start:17px; } --.hl.jright * , .vrl.jright * , .vl.jright * , .vr.jright * { offset-inline-start:17px; } -+.jend * , .jflexend * { inset-inline-start:17px; } -+.jcenter * { inset-inline-start:8.5px; } -+.hr.jleft * , .vlr.jleft * { inset-inline-start:17px; } -+.hl.jright * , .vrl.jright * , .vl.jright * , .vr.jright * { inset-inline-start:17px; } - --.jspace-between item2 { offset-inline-start:8.5px; } --.jspace-between item3 { offset-inline-start:17px; } -+.jspace-between item2 { inset-inline-start:8.5px; } -+.jspace-between item3 { inset-inline-start:17px; } - --.jspace-around item1 { offset-inline-start:2.85px; } --.jspace-around item2 { offset-inline-start:8.5px; } --.jspace-around item3 { offset-inline-start:14.16px; } -+.jspace-around item1 { inset-inline-start:2.85px; } -+.jspace-around item2 { inset-inline-start:8.5px; } -+.jspace-around item3 { inset-inline-start:14.16px; } - --.jspace-evenly item1 { offset-inline-start:4.25px; } --.jspace-evenly item2 { offset-inline-start:8.5px; } --.jspace-evenly item3 { offset-inline-start:12.75px; } -+.jspace-evenly item1 { inset-inline-start:4.25px; } -+.jspace-evenly item2 { inset-inline-start:8.5px; } -+.jspace-evenly item3 { inset-inline-start:12.75px; } - - .jstretch2 { grid-template-columns:1fr 7px 5px; } - .jstretch3 { grid-template-columns:19.5px 15.5px 5px; } -diff -Nrbu mozilla/layout/reftests/css-grid/grid-row-gap-001-ref.html mozilla-OK/layout/reftests/css-grid/grid-row-gap-001-ref.html ---- mozilla/layout/reftests/css-grid/grid-row-gap-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/grid-row-gap-001-ref.html 2023-01-21 23:06:19.535222695 +0300 -@@ -45,20 +45,20 @@ - .vlr { writing-mode: vertical-lr; direction:rtl; } - .vrl { writing-mode: vertical-rl; direction:ltr; } - --.aend *, .aflexend * { offset-block-start:23px; } --.acenter * { offset-block-start:11.5px; } -+.aend *, .aflexend * { inset-block-start:23px; } -+.acenter * { inset-block-start:11.5px; } - - --.aspace-between item2 { offset-block-start:11.5px; } --.aspace-between item3 { offset-block-start:23px; } -+.aspace-between item2 { inset-block-start:11.5px; } -+.aspace-between item3 { inset-block-start:23px; } - --.aspace-around item1 { offset-block-start:4.1666px; } --.aspace-around item2 { offset-block-start:11.5px; } --.aspace-around item3 { offset-block-start:18.8333px; } -+.aspace-around item1 { inset-block-start:4.1666px; } -+.aspace-around item2 { inset-block-start:11.5px; } -+.aspace-around item3 { inset-block-start:18.8333px; } - --.aspace-evenly item1 { offset-block-start:6.25px; } --.aspace-evenly item2 { offset-block-start:11.5px; } --.aspace-evenly item3 { offset-block-start:16.75px; } -+.aspace-evenly item1 { inset-block-start:6.25px; } -+.aspace-evenly item2 { inset-block-start:11.5px; } -+.aspace-evenly item3 { inset-block-start:16.75px; } - - .astretch2 { grid-template-rows: 1fr 1px 5px 1px 7px; } - .astretch3 { grid-template-rows: 14.5px 1px 16.3333px 1px 7px; } -diff -Nrbu mozilla/layout/reftests/css-grid/rtl-grid-placement-auto-row-sparse-001-ref.html mozilla-OK/layout/reftests/css-grid/rtl-grid-placement-auto-row-sparse-001-ref.html ---- mozilla/layout/reftests/css-grid/rtl-grid-placement-auto-row-sparse-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/rtl-grid-placement-auto-row-sparse-001-ref.html 2023-01-21 23:06:19.535222695 +0300 -@@ -21,126 +21,126 @@ - } - - .test1 .a { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 20px; - block-size: 20px; - } - .test1 .b { -- offset-block-start: 20px; -- offset-inline-start: 20px; -+ inset-block-start: 20px; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test1 .c { -- offset-block-start: 0; -- offset-inline-start: 80px; -+ inset-block-start: 0; -+ inset-inline-start: 80px; - inline-size: 60px; - block-size: 40px; - } - .test1 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test1 .d2 { -- offset-block-start: 0px; -- offset-inline-start: 40px; -+ inset-block-start: 0px; -+ inset-inline-start: 40px; - } - - .test2 .a { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test2 .b { -- offset-block-start: 20px; -- offset-inline-start: 20px; -+ inset-block-start: 20px; -+ inset-inline-start: 20px; - inline-size: 20px; - block-size: 20px; - } - .test2 .c { -- offset-block-start: 0; -- offset-inline-start: 80px; -+ inset-block-start: 0; -+ inset-inline-start: 80px; - inline-size: 60px; - block-size: 40px; - } - .test2 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test2 .d2 { -- offset-block-start: 20px; -- offset-inline-start: 40px; -+ inset-block-start: 20px; -+ inset-inline-start: 40px; - } - - .test3 .a { -- offset-block-start: 0; -- offset-inline-start: 0; -+ inset-block-start: 0; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 40px; - } - .test3 .b { -- offset-block-start: 40px; -- offset-inline-start: 20px; -+ inset-block-start: 40px; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test3 .c { -- offset-block-start: 60px; -- offset-inline-start: 0px; -+ inset-block-start: 60px; -+ inset-inline-start: 0px; - inline-size: 60px; - block-size: 40px; - } --.test3 .d { offset-block-start: 60px; offset-inline-start:60px; } -+.test3 .d { inset-block-start: 60px; inset-inline-start:60px; } - .test3 .e { -- offset-block-start: 20px; -- offset-inline-start: 60px; -+ inset-block-start: 20px; -+ inset-inline-start: 60px; - } - .test3 .d2 { -- offset-block-start: 80px; -- offset-inline-start: 60px; -+ inset-block-start: 80px; -+ inset-inline-start: 60px; - } - - .test4 .c { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 40px; - } --.test4 .d { offset-block-start: 40px; } -+.test4 .d { inset-block-start: 40px; } - .test4 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test4 .d2 { -- offset-block-start: 40px; -- offset-inline-start: 20px; -+ inset-block-start: 40px; -+ inset-inline-start: 20px; - } - - .test5 .c { -- offset-block-start: 20px; -- offset-inline-start: 0; -+ inset-block-start: 20px; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 20px; - } - .test5 .e { -- offset-block-start: 20px; -- offset-inline-start: 60px; -+ inset-block-start: 20px; -+ inset-inline-start: 60px; - } - .test5 .d2 { -- offset-block-start: 0px; -- offset-inline-start: 20px; -+ inset-block-start: 0px; -+ inset-inline-start: 20px; - } - --.test6 { offset-inline-start: 0px; offset-block-start: 20px;} -+.test6 { inset-inline-start: 0px; inset-block-start: 20px;} - .test6d2 { -- offset-block-start: 20px; -- offset-inline-start: 140px; -+ inset-block-start: 20px; -+ inset-inline-start: 140px; - } - .test6e { -- offset-block-start: 20px; -- offset-inline-start: 160px; -+ inset-block-start: 20px; -+ inset-inline-start: 160px; - } - - -diff -Nrbu mozilla/layout/reftests/css-grid/rtl-grid-placement-definite-001-ref.html mozilla-OK/layout/reftests/css-grid/rtl-grid-placement-definite-001-ref.html ---- mozilla/layout/reftests/css-grid/rtl-grid-placement-definite-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/rtl-grid-placement-definite-001-ref.html 2023-01-21 23:06:19.536222690 +0300 -@@ -24,26 +24,26 @@ - } - - .a { -- offset-inline-start: 40px; -- offset-block-start: 0px; -+ inset-inline-start: 40px; -+ inset-block-start: 0px; - inline-size: 60px; - block-size: 40px; - } - .b { -- offset-inline-start: 20px; -- offset-block-start: 40px; -+ inset-inline-start: 20px; -+ inset-block-start: 40px; - inline-size: 60px; - block-size: 20px; - } - .c { -- offset-inline-start: 80px; -- offset-block-start: 40px; -+ inset-inline-start: 80px; -+ inset-block-start: 40px; - inline-size: 60px; - block-size: 20px; - } - .d { -- offset-inline-start: 0px; -- offset-block-start: 0px; -+ inset-inline-start: 0px; -+ inset-block-start: 0px; - inline-size: 20px; - block-size: 60px; - } -diff -Nrbu mozilla/layout/reftests/css-grid/vlr-grid-placement-auto-row-sparse-001-ref.html mozilla-OK/layout/reftests/css-grid/vlr-grid-placement-auto-row-sparse-001-ref.html ---- mozilla/layout/reftests/css-grid/vlr-grid-placement-auto-row-sparse-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/vlr-grid-placement-auto-row-sparse-001-ref.html 2023-01-21 23:06:19.536222690 +0300 -@@ -25,126 +25,126 @@ - } - - .test1 .a { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 20px; - block-size: 20px; - } - .test1 .b { -- offset-block-start: 20px; -- offset-inline-start: 20px; -+ inset-block-start: 20px; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test1 .c { -- offset-block-start: 0; -- offset-inline-start: 80px; -+ inset-block-start: 0; -+ inset-inline-start: 80px; - inline-size: 60px; - block-size: 40px; - } - .test1 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test1 .d2 { -- offset-block-start: 0px; -- offset-inline-start: 40px; -+ inset-block-start: 0px; -+ inset-inline-start: 40px; - } - - .test2 .a { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test2 .b { -- offset-block-start: 20px; -- offset-inline-start: 20px; -+ inset-block-start: 20px; -+ inset-inline-start: 20px; - inline-size: 20px; - block-size: 20px; - } - .test2 .c { -- offset-block-start: 0; -- offset-inline-start: 80px; -+ inset-block-start: 0; -+ inset-inline-start: 80px; - inline-size: 60px; - block-size: 40px; - } - .test2 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test2 .d2 { -- offset-block-start: 20px; -- offset-inline-start: 40px; -+ inset-block-start: 20px; -+ inset-inline-start: 40px; - } - - .test3 .a { -- offset-block-start: 0; -- offset-inline-start: 0; -+ inset-block-start: 0; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 40px; - } - .test3 .b { -- offset-block-start: 40px; -- offset-inline-start: 20px; -+ inset-block-start: 40px; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test3 .c { -- offset-block-start: 60px; -- offset-inline-start: 0px; -+ inset-block-start: 60px; -+ inset-inline-start: 0px; - inline-size: 60px; - block-size: 40px; - } --.test3 .d { offset-block-start: 60px; offset-inline-start:60px; } -+.test3 .d { inset-block-start: 60px; inset-inline-start:60px; } - .test3 .e { -- offset-block-start: 20px; -- offset-inline-start: 60px; -+ inset-block-start: 20px; -+ inset-inline-start: 60px; - } - .test3 .d2 { -- offset-block-start: 80px; -- offset-inline-start: 60px; -+ inset-block-start: 80px; -+ inset-inline-start: 60px; - } - - .test4 .c { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 40px; - } --.test4 .d { offset-block-start: 40px; } -+.test4 .d { inset-block-start: 40px; } - .test4 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test4 .d2 { -- offset-block-start: 40px; -- offset-inline-start: 20px; -+ inset-block-start: 40px; -+ inset-inline-start: 20px; - } - - .test5 .c { -- offset-block-start: 20px; -- offset-inline-start: 0; -+ inset-block-start: 20px; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 20px; - } - .test5 .e { -- offset-block-start: 20px; -- offset-inline-start: 60px; -+ inset-block-start: 20px; -+ inset-inline-start: 60px; - } - .test5 .d2 { -- offset-block-start: 0px; -- offset-inline-start: 20px; -+ inset-block-start: 0px; -+ inset-inline-start: 20px; - } - --.test6 { offset-inline-start: 0px; offset-block-start: 20px;} -+.test6 { inset-inline-start: 0px; inset-block-start: 20px;} - .test6d2 { -- offset-block-start: 20px; -- offset-inline-start: 140px; -+ inset-block-start: 20px; -+ inset-inline-start: 140px; - } - .test6e { -- offset-block-start: 20px; -- offset-inline-start: 160px; -+ inset-block-start: 20px; -+ inset-inline-start: 160px; - } - - -diff -Nrbu mozilla/layout/reftests/css-grid/vrl-grid-placement-auto-row-sparse-001-ref.html mozilla-OK/layout/reftests/css-grid/vrl-grid-placement-auto-row-sparse-001-ref.html ---- mozilla/layout/reftests/css-grid/vrl-grid-placement-auto-row-sparse-001-ref.html 2020-02-18 02:37:56.000000000 +0300 -+++ mozilla-OK/layout/reftests/css-grid/vrl-grid-placement-auto-row-sparse-001-ref.html 2023-01-21 23:06:19.536222690 +0300 -@@ -25,144 +25,144 @@ - } - - .test1 .a { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 20px; - block-size: 20px; - } - .test1 .b { -- offset-block-start: 20px; -- offset-inline-start: 20px; -+ inset-block-start: 20px; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test1 .c { -- offset-block-start: 0; -- offset-inline-start: 80px; -+ inset-block-start: 0; -+ inset-inline-start: 80px; - inline-size: 60px; - block-size: 40px; - } - .test1 .d { -- offset-block-start: 0; -- offset-inline-start: 0; -+ inset-block-start: 0; -+ inset-inline-start: 0; - } - .test1 .e { -- offset-block-start: 20px; -- offset-inline-start: 0; -+ inset-block-start: 20px; -+ inset-inline-start: 0; - } - .test1 .d2 { -- offset-block-start: 0; -- offset-inline-start: 40px; -+ inset-block-start: 0; -+ inset-inline-start: 40px; - } - - .test2 .a { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test2 .b { -- offset-block-start: 20px; -- offset-inline-start: 20px; -+ inset-block-start: 20px; -+ inset-inline-start: 20px; - inline-size: 20px; - block-size: 20px; - } - .test2 .c { -- offset-block-start: 0; -- offset-inline-start: 80px; -+ inset-block-start: 0; -+ inset-inline-start: 80px; - inline-size: 60px; - block-size: 40px; - } - .test2 .d { -- offset-block-start: 0; -- offset-inline-start: 0; -+ inset-block-start: 0; -+ inset-inline-start: 0; - } - .test2 .e { -- offset-block-start: 20px; -- offset-inline-start: 0; -+ inset-block-start: 20px; -+ inset-inline-start: 0; - } - .test2 .d2 { -- offset-block-start: 20px; -- offset-inline-start: 40px; -+ inset-block-start: 20px; -+ inset-inline-start: 40px; - } - - .test3 .a { -- offset-block-start: 0; -- offset-inline-start: 0; -+ inset-block-start: 0; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 40px; - } - .test3 .b { -- offset-block-start: 40px; -- offset-inline-start: 20px; -+ inset-block-start: 40px; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 20px; - } - .test3 .c { -- offset-block-start: 60px; -- offset-inline-start: 0; -+ inset-block-start: 60px; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 40px; - } --.test3 .d { offset-block-start: 60px; offset-inline-start:60px; } -+.test3 .d { inset-block-start: 60px; inset-inline-start:60px; } - .test3 .e { -- offset-block-start: 20px; -- offset-inline-start: 60px; -+ inset-block-start: 20px; -+ inset-inline-start: 60px; - } - .test3 .d2 { -- offset-block-start: 80px; -- offset-inline-start: 60px; -+ inset-block-start: 80px; -+ inset-inline-start: 60px; - } - - .test4 .c { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - inline-size: 60px; - block-size: 40px; - } - .test4 .d { -- offset-block-start: 40px; -- offset-inline-start: 0; -+ inset-block-start: 40px; -+ inset-inline-start: 0; - } - .test4 .e { -- offset-block-start: 20px; -- offset-inline-start: 0px; -+ inset-block-start: 20px; -+ inset-inline-start: 0px; - } - .test4 .d2 { -- offset-block-start: 40px; -- offset-inline-start: 20px; -+ inset-block-start: 40px; -+ inset-inline-start: 20px; - } - - .test5 .c { -- offset-block-start: 20px; -- offset-inline-start: 0; -+ inset-block-start: 20px; -+ inset-inline-start: 0; - inline-size: 60px; - block-size: 20px; - } - .test5 .d { -- offset-block-start: 0; -- offset-inline-start: 0; -+ inset-block-start: 0; -+ inset-inline-start: 0; - } - .test5 .e { -- offset-block-start: 20px; -- offset-inline-start: 60px; -+ inset-block-start: 20px; -+ inset-inline-start: 60px; - } - .test5 .d2 { -- offset-block-start: 0; -- offset-inline-start: 20px; -+ inset-block-start: 0; -+ inset-inline-start: 20px; - } - - .test6 { -- offset-inline-start: 0; -- offset-block-start: 20px; -+ inset-inline-start: 0; -+ inset-block-start: 20px; - } - .test6d2 { -- offset-block-start: 20px; -- offset-inline-start: 140px; -+ inset-block-start: 20px; -+ inset-inline-start: 140px; - } - .test6e { -- offset-block-start: 20px; -- offset-inline-start: 160px; -+ inset-block-start: 20px; -+ inset-inline-start: 160px; - } - - -diff -Nrbu mozilla/layout/reftests/font-features/1376231-vertical-gpos-adjustments-ref.html mozilla-OK/layout/reftests/font-features/1376231-vertical-gpos-adjustments-ref.html ---- mozilla/layout/reftests/font-features/1376231-vertical-gpos-adjustments-ref.html 2020-08-10 14:30:35.000000000 +0300 -+++ mozilla-OK/layout/reftests/font-features/1376231-vertical-gpos-adjustments-ref.html 2023-01-21 23:06:19.536222690 +0300 -@@ -27,7 +27,7 @@ - } - .overlay { - position: relative; -- offset-block-start: -3em; -+ inset-block-start: -3em; - } - - -diff -Nrbu mozilla/layout/reftests/font-features/1376231-vertical-gpos-adjustments.html mozilla-OK/layout/reftests/font-features/1376231-vertical-gpos-adjustments.html ---- mozilla/layout/reftests/font-features/1376231-vertical-gpos-adjustments.html 2020-08-10 14:30:35.000000000 +0300 -+++ mozilla-OK/layout/reftests/font-features/1376231-vertical-gpos-adjustments.html 2023-01-21 23:06:19.537222684 +0300 -@@ -52,7 +52,7 @@ - } - .overlay { - position: relative; -- offset-block-start: -3em; -+ inset-block-start: -3em; - } - - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-005-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-005-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-005-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-005-ref.html 2023-01-21 23:06:19.537222684 +0300 -@@ -44,11 +44,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-006-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-006-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-006-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-006-ref.html 2023-01-21 23:06:19.537222684 +0300 -@@ -45,11 +45,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-007-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-007-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-007-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-007-ref.html 2023-01-21 23:06:19.537222684 +0300 -@@ -44,11 +44,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-008-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-008-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-008-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-008-ref.html 2023-01-21 23:06:19.537222684 +0300 -@@ -45,11 +45,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-009-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-009-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-009-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-009-ref.html 2023-01-21 23:06:19.538222678 +0300 -@@ -44,11 +44,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-010-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-010-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-010-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-010-ref.html 2023-01-21 23:06:19.538222678 +0300 -@@ -45,11 +45,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-011-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-011-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-011-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-011-ref.html 2023-01-21 23:06:19.538222678 +0300 -@@ -44,11 +44,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-012-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-012-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-012-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-border-box-border-radius-012-ref.html 2023-01-21 23:06:19.538222678 +0300 -@@ -45,11 +45,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-048-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-048-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-048-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-048-ref.html 2023-01-21 23:06:19.538222678 +0300 -@@ -43,12 +43,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-049-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-049-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-049-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-049-ref.html 2023-01-21 23:06:19.539222672 +0300 -@@ -44,12 +44,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-050-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-050-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-050-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-050-ref.html 2023-01-21 23:06:19.539222672 +0300 -@@ -43,12 +43,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-051-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-051-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-051-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-051-ref.html 2023-01-21 23:06:19.539222672 +0300 -@@ -43,12 +43,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-052-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-052-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-052-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-052-ref.html 2023-01-21 23:06:19.539222672 +0300 -@@ -43,12 +43,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-053-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-053-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-053-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-053-ref.html 2023-01-21 23:06:19.539222672 +0300 -@@ -44,12 +44,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-054-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-054-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-054-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-054-ref.html 2023-01-21 23:06:19.540222666 +0300 -@@ -43,12 +43,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-055-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-055-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-055-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-circle-055-ref.html 2023-01-21 23:06:19.540222666 +0300 -@@ -44,12 +44,12 @@ - - -
--
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-046-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-046-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-046-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-046-ref.html 2023-01-21 23:06:19.540222666 +0300 -@@ -38,9 +38,9 @@ - - -
--
--
--
--
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-047-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-047-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-047-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-047-ref.html 2023-01-21 23:06:19.540222666 +0300 -@@ -39,9 +39,9 @@ - - -
--
--
--
--
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-048-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-048-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-048-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-048-ref.html 2023-01-21 23:06:19.540222666 +0300 -@@ -38,9 +38,9 @@ - - -
--
--
--
--
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-049-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-049-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-049-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-049-ref.html 2023-01-21 23:06:19.541222661 +0300 -@@ -39,9 +39,9 @@ - - -
--
--
--
--
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-050-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-050-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-050-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-050-ref.html 2023-01-21 23:06:19.541222661 +0300 -@@ -38,9 +38,9 @@ - - -
--
--
--
--
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-051-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-051-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-051-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-ellipse-051-ref.html 2023-01-21 23:06:19.541222661 +0300 -@@ -39,9 +39,9 @@ - - -
--
--
--
--
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-020-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-020-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-020-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-020-ref.html 2023-01-21 23:06:19.541222661 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-021-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-021-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-021-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-021-ref.html 2023-01-21 23:06:19.541222661 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-022-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-022-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-022-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-022-ref.html 2023-01-21 23:06:19.542222655 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-023-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-023-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-023-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-023-ref.html 2023-01-21 23:06:19.542222655 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-024-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-024-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-024-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-024-ref.html 2023-01-21 23:06:19.542222655 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-025-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-025-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-025-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-025-ref.html 2023-01-21 23:06:19.542222655 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-026-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-026-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-026-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-026-ref.html 2023-01-21 23:06:19.542222655 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-027-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-027-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-027-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-inset-027-ref.html 2023-01-21 23:06:19.543222649 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-020-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-020-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-020-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-020-ref.html 2023-01-21 23:06:19.543222649 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-021-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-021-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-021-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-021-ref.html 2023-01-21 23:06:19.543222649 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-022-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-022-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-022-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-022-ref.html 2023-01-21 23:06:19.543222649 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-023-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-023-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-023-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-023-ref.html 2023-01-21 23:06:19.543222649 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-024-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-024-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-024-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-024-ref.html 2023-01-21 23:06:19.544222643 +0300 -@@ -41,11 +41,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-025-ref.html mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-025-ref.html ---- mozilla/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-025-ref.html 2020-02-18 02:37:57.000000000 +0300 -+++ mozilla-OK/layout/reftests/w3c-css/submitted/shapes1/shape-outside-polygon-025-ref.html 2023-01-21 23:06:19.544222643 +0300 -@@ -42,11 +42,11 @@ - - -
--
--
--
--
--
--
-+
-+
-+
-+
-+
-+
- - -diff -Nrbu mozilla/layout/style/nsCSSPropList.h mozilla-OK/layout/style/nsCSSPropList.h ---- mozilla/layout/style/nsCSSPropList.h 2022-11-02 23:12:32.000000000 +0300 -+++ mozilla-OK/layout/style/nsCSSPropList.h 2023-01-21 23:06:19.545222637 +0300 -@@ -3032,9 +3032,9 @@ - offsetof(nsStylePosition, mObjectPosition), - eStyleAnimType_Custom) - CSS_PROP_LOGICAL( -- offset-block-end, -- offset_block_end, -- OffsetBlockEnd, -+ inset-block-end, -+ inset_block_end, -+ InsetBlockEnd, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | -@@ -3044,14 +3044,14 @@ - "", - VARIANT_AHLP | VARIANT_CALC, - nullptr, -- Offset, -+ Inset, - Position, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) - CSS_PROP_LOGICAL( -- offset-block-start, -- offset_block_start, -- OffsetBlockStart, -+ inset-block-start, -+ inset_block_start, -+ InsetBlockStart, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | -@@ -3060,14 +3060,14 @@ - "", - VARIANT_AHLP | VARIANT_CALC, - nullptr, -- Offset, -+ Inset, - Position, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) - CSS_PROP_LOGICAL( -- offset-inline-end, -- offset_inline_end, -- OffsetInlineEnd, -+ inset-inline-end, -+ inset_inline_end, -+ InsetInlineEnd, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | -@@ -3076,14 +3076,14 @@ - "", - VARIANT_AHLP | VARIANT_CALC, - nullptr, -- Offset, -+ Inset, - Position, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) - CSS_PROP_LOGICAL( -- offset-inline-start, -- offset_inline_start, -- OffsetInlineStart, -+ inset-inline-start, -+ inset_inline_start, -+ InsetInlineStart, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | -@@ -3091,7 +3091,7 @@ - "", - VARIANT_AHLP | VARIANT_CALC, - nullptr, -- Offset, -+ Inset, - Position, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) -diff -Nrbu mozilla/layout/style/nsCSSPropLogicalGroupList.h mozilla-OK/layout/style/nsCSSPropLogicalGroupList.h ---- mozilla/layout/style/nsCSSPropLogicalGroupList.h 2022-11-02 23:12:32.000000000 +0300 -+++ mozilla-OK/layout/style/nsCSSPropLogicalGroupList.h 2023-01-21 23:06:19.545222637 +0300 -@@ -32,7 +32,7 @@ - // properties are a set of four box properties which are not - // already represented by an existing shorthand property. For - // example, the logical property group for --// offset-{block,inline}-{start,end} contains the top, right, -+// inset-{block,inline}-{start,end} contains the top, right, - // bottom and left physical properties, but there is no shorthand - // that sets those four properties. A table must be defined in - // nsCSSProps.cpp named gLogicalGroupTable containing the -@@ -52,7 +52,7 @@ - CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderWidth) - CSS_PROP_LOGICAL_GROUP_SHORTHAND(Margin) - CSS_PROP_LOGICAL_GROUP_AXIS(MaxSize) --CSS_PROP_LOGICAL_GROUP_BOX(Offset) -+CSS_PROP_LOGICAL_GROUP_BOX(Inset) - CSS_PROP_LOGICAL_GROUP_SHORTHAND(Padding) - CSS_PROP_LOGICAL_GROUP_AXIS(MinSize) - CSS_PROP_LOGICAL_GROUP_AXIS(Size) -diff -Nrbu mozilla/layout/style/nsCSSProps.cpp mozilla-OK/layout/style/nsCSSProps.cpp ---- mozilla/layout/style/nsCSSProps.cpp 2022-11-02 23:12:32.000000000 +0300 -+++ mozilla-OK/layout/style/nsCSSProps.cpp 2023-01-21 23:06:19.546222631 +0300 -@@ -3067,7 +3067,7 @@ - }; - - --static const nsCSSPropertyID gOffsetLogicalGroupTable[] = { -+static const nsCSSPropertyID gInsetLogicalGroupTable[] = { - eCSSProperty_top, - eCSSProperty_right, - eCSSProperty_bottom, -diff -Nrbu mozilla/layout/style/res/html.css mozilla-OK/layout/style/res/html.css ---- mozilla/layout/style/res/html.css 2022-08-24 22:55:12.000000000 +0300 -+++ mozilla-OK/layout/style/res/html.css 2023-01-21 23:06:19.546222631 +0300 -@@ -820,8 +820,8 @@ - - dialog { - position: absolute; -- offset-inline-start: 0; -- offset-inline-end: 0; -+ inset-inline-start: 0; -+ inset-inline-end: 0; - color: black; - margin: auto; - border-width: initial; -diff -Nrbu mozilla/layout/style/test/gtest/example.css mozilla-OK/layout/style/test/gtest/example.css ---- mozilla/layout/style/test/gtest/example.css 2020-02-18 02:37:58.000000000 +0300 -+++ mozilla-OK/layout/style/test/gtest/example.css 2023-01-21 23:06:19.547222626 +0300 -@@ -2278,7 +2278,7 @@ - - .expression-container .close-btn { - position: absolute; -- offset-inline-end: 6px; -+ inset-inline-end: 6px; - top: 6px; - } - -@@ -2411,7 +2411,7 @@ - - .breakpoint .close-btn { - position: absolute; -- offset-inline-end: 6px; -+ inset-inline-end: 6px; - top: 12px; - } - -diff -Nrbu mozilla/layout/style/test/property_database.js mozilla-OK/layout/style/test/property_database.js ---- mozilla/layout/style/test/property_database.js 2022-11-02 23:12:32.000000000 +0300 -+++ mozilla-OK/layout/style/test/property_database.js 2023-01-21 23:06:19.549222614 +0300 -@@ -6052,8 +6052,8 @@ - ], - invalid_values: [ "none", "5" ] - }, -- "offset-block-end": { -- domProp: "offsetBlockEnd", -+ "inset-block-end": { -+ domProp: "insetBlockEnd", - inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, -@@ -6072,8 +6072,8 @@ - ], - invalid_values: [] - }, -- "offset-block-start": { -- domProp: "offsetBlockStart", -+ "inset-block-start": { -+ domProp: "insetBlockStart", - inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, -@@ -6092,8 +6092,8 @@ - ], - invalid_values: [] - }, -- "offset-inline-end": { -- domProp: "offsetInlineEnd", -+ "inset-inline-end": { -+ domProp: "insetInlineEnd", - inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, -@@ -6112,8 +6112,8 @@ - ], - invalid_values: [] - }, -- "offset-inline-start": { -- domProp: "offsetInlineStart", -+ "inset-inline-start": { -+ domProp: "insetInlineStart", - inherited: false, - type: CSS_TYPE_LONGHAND, - logical: true, -@@ -6132,6 +6132,42 @@ - ], - invalid_values: [] - }, -+ "offset-block-start": { -+ domProp: "offsetBlockStart", -+ inherited: false, -+ type: CSS_TYPE_SHORTHAND_AND_LONGHAND, -+ logical: true, -+ get_computed: logical_box_prop_get_computed, -+ alias_for: "inset-block-start", -+ subproperties: [ "inset-block-start" ], -+ }, -+ "offset-block-end": { -+ domProp: "offsetBlockEnd", -+ inherited: false, -+ type: CSS_TYPE_SHORTHAND_AND_LONGHAND, -+ logical: true, -+ get_computed: logical_box_prop_get_computed, -+ alias_for: "inset-block-end", -+ subproperties: [ "inset-block-end" ], -+ }, -+ "offset-inline-start": { -+ domProp: "offsetInlineStart", -+ inherited: false, -+ type: CSS_TYPE_SHORTHAND_AND_LONGHAND, -+ logical: true, -+ get_computed: logical_box_prop_get_computed, -+ alias_for: "inset-inline-start", -+ subproperties: [ "inset-inline-start" ], -+ }, -+ "offset-block-end": { -+ domProp: "offsetInlineEnd", -+ inherited: false, -+ type: CSS_TYPE_SHORTHAND_AND_LONGHAND, -+ logical: true, -+ get_computed: logical_box_prop_get_computed, -+ alias_for: "inset-inline-end", -+ subproperties: [ "inset-inline-end" ], -+ }, - "padding-block-end": { - domProp: "paddingBlockEnd", - inherited: false, -@@ -6290,8 +6326,8 @@ - - if (/^-moz-/.test(property)) { - property = physicalize(property.substring(5), inlineMapping, ""); -- } else if (/^offset-(block|inline)-(start|end)/.test(property)) { -- property = property.substring(7); // we want "top" not "offset-top", e.g. -+ } else if (/^(offset|inset)-(block|inline)-(start|end)/.test(property)) { -+ property = property.replace("offset-", "").replace("inset-", ""); // we want "top" not "offset-top", e.g. - property = physicalize(property, blockMapping, "block-"); - property = physicalize(property, inlineMapping, "inline-"); - } else if (/-(block|inline)-(start|end)/.test(property)) { -diff -Nrbu mozilla/layout/style/test/test_logical_properties.html mozilla-OK/layout/style/test/test_logical_properties.html ---- mozilla/layout/style/test/test_logical_properties.html 2020-02-18 02:37:58.000000000 +0300 -+++ mozilla-OK/layout/style/test/test_logical_properties.html 2023-01-21 23:06:19.549222614 +0300 -@@ -94,7 +94,7 @@ - type == CSS_TYPE_LONGHAND && gCSSProperties[p].logical) && - /-inline-end/.test(p)) { - var valueType; -- if (/margin|padding|width|offset/.test(p)) { -+ if (/margin|padding|width|inset|offset/.test(p)) { - valueType = "length"; - } else if (/color/.test(p)) { - valueType = "color"; -@@ -110,7 +110,7 @@ - blockEnd: p.replace("-inline-end", "-block-end"), - type: valueType - }; -- if (/^offset/.test(p)) { -+ if (/^(offset|inset)/.test(p)) { - group.left = "left"; - group.right = "right"; - group.top = "top"; -diff -Nrbu mozilla/servo/components/style/properties/helpers.mako.rs mozilla-OK/servo/components/style/properties/helpers.mako.rs ---- mozilla/servo/components/style/properties/helpers.mako.rs 2022-08-24 22:55:13.000000000 +0300 -+++ mozilla-OK/servo/components/style/properties/helpers.mako.rs 2023-01-21 23:06:19.550222608 +0300 -@@ -840,7 +840,7 @@ - elif len(maybe_size) == 1: - size = maybe_size[0] - def phys_ident(side, phy_side): -- return to_rust_ident(name.replace(side, phy_side).replace("offset-", "")) -+ return to_rust_ident(name.replace(side, phy_side).replace("inset-", "")) - %> - % if side is not None: - use logical_geometry::PhysicalSide; -diff -Nrbu mozilla/servo/components/style/properties/longhand/position.mako.rs mozilla-OK/servo/components/style/properties/longhand/position.mako.rs ---- mozilla/servo/components/style/properties/longhand/position.mako.rs 2022-08-24 22:55:13.000000000 +0300 -+++ mozilla-OK/servo/components/style/properties/longhand/position.mako.rs 2023-01-21 23:06:19.550222608 +0300 -@@ -16,11 +16,12 @@ - animation_value_type="ComputedValue", - allow_quirks=True)} - % endfor --// offset-* logical properties, map to "top" / "left" / "bottom" / "right" -+// inset-* logical properties, map to "top" / "left" / "bottom" / "right" - % for side in LOGICAL_SIDES: -- ${helpers.predefined_type("offset-%s" % side, "LengthOrPercentageOrAuto", -+ ${helpers.predefined_type("inset-%s" % side, "LengthOrPercentageOrAuto", - "computed::LengthOrPercentageOrAuto::Auto", -- spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side, -+ spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side, -+ alias="offset-%s" % side, - animation_value_type="ComputedValue", logical=True)} - % endfor - diff --git a/seamonkey-2.53.15-mozilla-1720968.patch b/seamonkey-2.53.15-mozilla-1720968.patch deleted file mode 100644 index e2f0063..0000000 --- a/seamonkey-2.53.15-mozilla-1720968.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- mozilla/dom/events/EventStateManager.cpp.orig 2022-12-11 02:49:39.383632451 +0300 -+++ mozilla/dom/events/EventStateManager.cpp 2022-12-11 03:07:56.516825422 +0300 -@@ -644,16 +644,19 @@ EventStateManager::PreHandleEvent(nsPres - } - case eMouseUp: { - switch (mouseEvent->button) { - case WidgetMouseEvent::eLeftButton: - if (Prefs::ClickHoldContextMenu()) { - KillClickHoldTimer(); - } - StopTrackingDragGesture(); -+ if (sActiveESM && sActiveESM != this) { -+ sActiveESM->StopTrackingDragGesture(); -+ } - sNormalLMouseEventInProcess = false; - // then fall through... - MOZ_FALLTHROUGH; - case WidgetMouseEvent::eRightButton: - case WidgetMouseEvent::eMiddleButton: - SetClickCount(mouseEvent, aStatus); - NotifyTargetUserActivation(aEvent, aTargetContent); - break; diff --git a/seamonkey-2.53.15-post-regexp.patch b/seamonkey-2.53.15-post-regexp.patch deleted file mode 100644 index d692d40..0000000 --- a/seamonkey-2.53.15-post-regexp.patch +++ /dev/null @@ -1,15 +0,0 @@ -# -# Just to make the regexp patch against 2.53.13 useful against 2.53.15 as well -# (to avoid two mostly identical too big patches for different releases). -# - ---- js/src/moz.build 2022-12-11 04:36:27.287937035 +0300 -+++ js/src/moz.build-OK 2022-12-11 04:41:34.949032599 +0300 -@@ -204,7 +204,6 @@ - 'devtools/sharkctl.cpp', - 'ds/Bitmap.cpp', - 'ds/LifoAlloc.cpp', -- 'ds/MemoryProtectionExceptionHandler.cpp', - 'jsalloc.cpp', - 'jsapi.cpp', - 'jsarray.cpp', diff --git a/seamonkey-2.53.15-pre-regexp.patch b/seamonkey-2.53.15-pre-regexp.patch deleted file mode 100644 index 60bff39..0000000 --- a/seamonkey-2.53.15-pre-regexp.patch +++ /dev/null @@ -1,26 +0,0 @@ -# -# Just to make the regexp patch against 2.53.13 useful against 2.53.15 as well -# (to avoid two mostly identical too big patches for different releases). -# - ---- .clang-format-ignore 2022-08-24 22:55:10.000000000 +0300 -+++ .clang-format-ignore-OK 2022-08-31 01:09:36.742429707 +0300 -@@ -131,7 +131,7 @@ - third_party/python/which/.* - third_party/rust/.* - toolkit/components/jsoncpp/.* --toolkit/components/protobuf/.* - toolkit/components/url-classifier/chromium/.* -+toolkit/components/protobuf/.* - toolkit/crashreporter/google-breakpad/.* - tools/fuzzing/libfuzzer.* ---- js/src/moz.build 2022-11-09 01:03:23.000000000 +0300 -+++ js/src/moz.build-OK 2022-12-11 03:25:36.099255746 +0300 -@@ -198,6 +198,7 @@ - 'devtools/sharkctl.cpp', - 'ds/Bitmap.cpp', - 'ds/LifoAlloc.cpp', -+ 'ds/MemoryProtectionExceptionHandler.cpp', - 'irregexp/NativeRegExpMacroAssembler.cpp', - 'irregexp/RegExpAST.cpp', - 'irregexp/RegExpCharacters.cpp', diff --git a/seamonkey-2.53.16-GNUmakefile b/seamonkey-2.53.16-GNUmakefile new file mode 100644 index 0000000..e31c58c --- /dev/null +++ b/seamonkey-2.53.16-GNUmakefile @@ -0,0 +1,189 @@ +# +# Front-end based on GNU make, intended for a more friendly +# integration of the build system with Linux/UNIX distributions, +# as well as for those who still allergy using mach command. +# +# Place it as `mozilla/GNUmakefile' (instead of the existing stub), +# and work under `mozilla/' dir. +# + +# +# For build, just use +# +# make +# +# (If you want to separate config stage, use "make configure" and then "make", +# but normally it is done automatically). +# +# For install, use +# +# make install DESTDIR=where_you_want_to_install +# +# +# Additionally, before install you can use: +# +# make locales +# +# to provide all the shipped locales (will appear in a form of langpack extensions). +# If irc and/or calendar are built, their data will be included too. +# (See below for more details about locales target). +# + +# +# For clarity, some comparison with the other build methods +# (assume `-jN' is the option for parallel builds, ie. `-j4' for 4-cpu system): +# +# Build stage: +# +# client.mk: make -f client.mk build MOZ_MAKE_FLAGS=-jN +# mach: ./mach build -jN +# THIS: make -jN +# +# Install stage: +# +# client.mk: DESTDIR=where... make -f client.mk install +# mach: DESTDIR=where... make -C $OBJDIR... install +# THIS: make install DESTDIR=where... +# + + +ifeq (,$(wildcard .mozconfig)) +$(error Cannot find .mozconfig file in the current directory) +endif + +MACH_CMD = ./mach --log-no-times + +OBJDIR := $(shell $(MACH_CMD) environment --format=json | sed -e 's/.*"topobjdir": "//' -e 's/".*//') + +OBJDIR_TARGETS = install distribution source-package package clobber + + +.PHONY: all configure build clean distclean $(OBJDIR_TARGETS) + + +all: build + + +configure: $(OBJDIR)/Makefile + + +$(OBJDIR)/Makefile: .mozconfig + $(MACH_CMD) configure + + +build: $(OBJDIR)/Makefile + $(MAKE) -C $(OBJDIR) + + +$(OBJDIR_TARGETS): + $(MAKE) -C $(OBJDIR) $@ + + +clean: + $(MACH_CMD) clobber + +distclean: clean + rm -f configure js/src/configure + rm -rf $(OBJDIR) + + +# +# LOCALES +# +# +# The target `locales' creates all the needed langpacks. +# +# By default, all available locales will be used. You can change it +# by overriding SHIPPED_LOCALES variable on the command line. +# +# Additionally, you can use `make locale-LANG' to create one (or several) +# langpack separately. +# +# For example, to build `fr' and 'it' only, use: +# +# make locales SHIPPED_LOCALES="fr it" +# +# to create just `ru' langpack: +# +# make locale-ru +# +# Use `clear-locales' for clearing. +# +# +# NOTE! NOTE! NOTE! +# +# Do NOT use parallel builds (-jN) for locale targets! +# +# It is better to use `-j1' explicitly (`make -j1 locales') to avoid issues. +# + +.PHONY: locales clear-locales dictionaries clear-dictionaries + + +drop_extra := $(if $(or $(filter Windows_NT,$(OS)),$(filter-out Darwin,$(shell uname))),ja-JP-mac,ja) + +SHIPPED_LOCALES := $(shell while read loc rest; do echo $$loc; done >$(PACKAGE_MANIFEST) + + +clear-locales: + sed -i '/langpack-.*@seamonkey.mozilla.org.xpi/ d' $(PACKAGE_MANIFEST) + rm -f $(OBJDIR)/dist/bin/extensions/langpack-*@seamonkey.mozilla.org.xpi + + +# +# Dictionaries +# +# It is better to use system dictionaries, specifying directory path for them +# by "spellchecker.dictionary_path" preference (or even use symlink when possible). +# + +DICT_DEST := $(OBJDIR)/dist/bin/dictionaries + +dictionaries: $(SHIPPED_LOCALES:%=$(stage)-%) + cp -f -d $(wildcard $(foreach loc,$(SHIPPED_LOCALES),$(stage)-$(loc)/dictionaries/$(loc).aff $(stage)-$(loc)/dictionaries/$(loc).dic)) $(DICT_DEST) + +clear-dictionaries: + rm -f $(filter-out $(DICT_DEST)/en-US.%,$(wildcard $(DICT_DEST)/*.aff $(DICT_DEST)/*.dic)) + diff --git a/seamonkey-2.53.16-mozilla-1434478.patch b/seamonkey-2.53.16-mozilla-1434478.patch new file mode 100644 index 0000000..1dbde2d --- /dev/null +++ b/seamonkey-2.53.16-mozilla-1434478.patch @@ -0,0 +1,715 @@ +# +# Backport of https://bugzilla.mozilla.org/show_bug.cgi?id=1434478, parts 1-6. +# +# Under certain conditions (fe. an odd page width and some zoom level), +# some page elements became invisible. +# + +diff -Nrup mozilla-OLD/layout/base/LayoutConstants.h mozilla/layout/base/LayoutConstants.h +--- mozilla-OLD/layout/base/LayoutConstants.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla/layout/base/LayoutConstants.h 2023-02-27 05:28:13.925420706 +0300 +@@ -0,0 +1,31 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* vim: set ts=8 sts=2 et sw=2 tw=80: */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++/* constants used throughout the Layout module */ ++ ++#ifndef LayoutConstants_h___ ++#define LayoutConstants_h___ ++ ++#include "nsSize.h" // for NS_MAXSIZE ++ ++/** ++ * Constant used to indicate an unconstrained size. ++ */ ++#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE ++ ++// NOTE: There are assumptions all over that these have the same value, ++// namely NS_UNCONSTRAINEDSIZE. ++#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE ++#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE ++#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE ++ ++// +1 is to avoid clamped huge margin values being processed as auto margins ++#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) ++ ++#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN ++ ++ ++#endif // LayoutConstants_h___ +diff -Nrup mozilla-OLD/layout/base/moz.build mozilla/layout/base/moz.build +--- mozilla-OLD/layout/base/moz.build 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/base/moz.build 2023-02-27 05:28:13.925420706 +0300 +@@ -35,6 +35,7 @@ XPIDL_MODULE = 'layout_base' + EXPORTS += [ + 'CaretAssociationHint.h', + 'FrameProperties.h', ++ 'LayoutConstants.h', + 'LayoutLogging.h', + 'MobileViewportManager.h', + 'nsAutoLayoutPhase.h', +diff -Nrup mozilla-OLD/layout/base/nsLayoutUtils.cpp mozilla/layout/base/nsLayoutUtils.cpp +--- mozilla-OLD/layout/base/nsLayoutUtils.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/base/nsLayoutUtils.cpp 2023-02-27 05:28:13.927420692 +0300 +@@ -4912,8 +4912,6 @@ GetDefiniteSize(const nsStyleCoord& + nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) + : aPercentageBasis.value().BSize(wm); + if (pb == NS_UNCONSTRAINEDSIZE) { +- // XXXmats given that we're calculating an intrinsic size here, +- // maybe we should back-compute the calc-size using AddPercents? + return false; + } + *aResult = std::max(0, calc->mLength + +@@ -5157,12 +5155,9 @@ AddIntrinsicSizeOffset(gfxContext* aRend + nscoord result = aContentSize; + nscoord min = aContentMinSize; + nscoord coordOutsideSize = 0; +- float pctOutsideSize = 0; +- float pctTotal = 0.0f; + + if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) { + coordOutsideSize += aOffsets.hPadding; +- pctOutsideSize += aOffsets.hPctPadding; + } + + coordOutsideSize += aOffsets.hBorder; +@@ -5170,21 +5165,15 @@ AddIntrinsicSizeOffset(gfxContext* aRend + if (aBoxSizing == StyleBoxSizing::Border) { + min += coordOutsideSize; + result = NSCoordSaturatingAdd(result, coordOutsideSize); +- pctTotal += pctOutsideSize; + + coordOutsideSize = 0; +- pctOutsideSize = 0.0f; + } + + coordOutsideSize += aOffsets.hMargin; +- pctOutsideSize += aOffsets.hPctMargin; + + min += coordOutsideSize; + result = NSCoordSaturatingAdd(result, coordOutsideSize); +- pctTotal += pctOutsideSize; + +- const bool shouldAddPercent = aType == nsLayoutUtils::PREF_ISIZE || +- (aFlags & nsLayoutUtils::ADD_PERCENTS); + nscoord size; + if (aType == nsLayoutUtils::MIN_ISIZE && + (((aStyleSize.HasPercent() || aStyleMaxSize.HasPercent()) && +@@ -5202,18 +5191,6 @@ AddIntrinsicSizeOffset(gfxContext* aRend + GetIntrinsicCoord(aStyleSize, aRenderingContext, aFrame, + PROP_WIDTH, size)) { + result = size + coordOutsideSize; +- if (shouldAddPercent) { +- result = nsLayoutUtils::AddPercents(result, pctOutsideSize); +- } +- } else { +- // NOTE: We could really do a lot better for percents and for some +- // cases of calc() containing percent (certainly including any where +- // the coefficient on the percent is positive and there are no max() +- // expressions). However, doing better for percents wouldn't be +- // backwards compatible. +- if (shouldAddPercent) { +- result = nsLayoutUtils::AddPercents(result, pctTotal); +- } + } + + nscoord maxSize = aFixedMaxSize ? *aFixedMaxSize : 0; +@@ -5221,9 +5198,6 @@ AddIntrinsicSizeOffset(gfxContext* aRend + GetIntrinsicCoord(aStyleMaxSize, aRenderingContext, aFrame, + PROP_MAX_WIDTH, maxSize)) { + maxSize += coordOutsideSize; +- if (shouldAddPercent) { +- maxSize = nsLayoutUtils::AddPercents(maxSize, pctOutsideSize); +- } + if (result > maxSize) { + result = maxSize; + } +@@ -5234,17 +5208,11 @@ AddIntrinsicSizeOffset(gfxContext* aRend + GetIntrinsicCoord(aStyleMinSize, aRenderingContext, aFrame, + PROP_MIN_WIDTH, minSize)) { + minSize += coordOutsideSize; +- if (shouldAddPercent) { +- minSize = nsLayoutUtils::AddPercents(minSize, pctOutsideSize); +- } + if (result < minSize) { + result = minSize; + } + } + +- if (shouldAddPercent) { +- min = nsLayoutUtils::AddPercents(min, pctTotal); +- } + if (result < min) { + result = min; + } +@@ -5261,9 +5229,6 @@ AddIntrinsicSizeOffset(gfxContext* aRend + : devSize.width); + // GetMinimumWidgetSize() returns a border-box width. + themeSize += aOffsets.hMargin; +- if (shouldAddPercent) { +- themeSize = nsLayoutUtils::AddPercents(themeSize, aOffsets.hPctMargin); +- } + if (themeSize > result || !canOverride) { + result = themeSize; + } +@@ -5558,9 +5523,7 @@ nsLayoutUtils::MinSizeContributionForAxi + aWM.IsVertical() ? "vertical" : "horizontal"); + #endif + +- // Note: this method is only meant for grid/flex items which always +- // include percentages in their intrinsic size. +- aFlags |= nsLayoutUtils::ADD_PERCENTS; ++ // Note: this method is only meant for grid/flex items. + const nsStylePosition* const stylePos = aFrame->StylePosition(); + const nsStyleCoord* style = aAxis == eAxisHorizontal ? &stylePos->mMinWidth + : &stylePos->mMinHeight; +diff -Nrup mozilla-OLD/layout/base/nsLayoutUtils.h mozilla/layout/base/nsLayoutUtils.h +--- mozilla-OLD/layout/base/nsLayoutUtils.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/base/nsLayoutUtils.h 2023-02-27 05:30:45.937319628 +0300 +@@ -7,6 +7,7 @@ + #ifndef nsLayoutUtils_h__ + #define nsLayoutUtils_h__ + ++#include "LayoutConstants.h" + #include "mozilla/MemoryReporting.h" + #include "mozilla/ArrayUtils.h" + #include "mozilla/LookAndFeel.h" +@@ -1414,7 +1415,6 @@ public: + IGNORE_PADDING = 0x01, + BAIL_IF_REFLOW_NEEDED = 0x02, // returns NS_INTRINSIC_WIDTH_UNKNOWN if so + MIN_INTRINSIC_ISIZE = 0x04, // use min-width/height instead of width/height +- ADD_PERCENTS = 0x08, // apply AddPercents also for MIN_ISIZE + }; + static nscoord + IntrinsicForAxis(mozilla::PhysicalAxis aAxis, +@@ -1455,23 +1455,6 @@ public: + IntrinsicISizeType aType, + uint32_t aFlags = 0); + +- /** +- * This function increases an initial intrinsic size, 'aCurrent', according +- * to the given 'aPercent', such that the size-increase makes up exactly +- * 'aPercent' percent of the returned value. If 'aPercent' or 'aCurrent' are +- * less than or equal to zero the original 'aCurrent' value is returned. +- * If 'aPercent' is greater than or equal to 1.0 the value nscoord_MAX is +- * returned. +- */ +- static nscoord AddPercents(nscoord aCurrent, float aPercent) +- { +- if (aPercent > 0.0f && aCurrent > 0) { +- return MOZ_UNLIKELY(aPercent >= 1.0f) ? nscoord_MAX +- : NSToCoordRound(float(aCurrent) / (1.0f - aPercent)); +- } +- return aCurrent; +- } +- + /* + * Convert nsStyleCoord to nscoord when percentages depend on the + * containing block size. +@@ -3118,6 +3101,62 @@ public: + + static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag); + ++ /** ++ * Resolve a CSS value to a definite size. ++ */ ++ template ++ static nscoord ResolveToLength(const nsStyleCoord& aCoord, ++ nscoord aPercentageBasis) ++ { ++ NS_WARNING_ASSERTION(aPercentageBasis >= nscoord(0), "nscoord overflow?"); ++ ++ switch (aCoord.GetUnit()) { ++ case eStyleUnit_Coord: ++ MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetCoordValue() >= 0, ++ "This value should have been rejected by the style system"); ++ return aCoord.GetCoordValue(); ++ case eStyleUnit_Percent: ++ if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { ++ return nscoord(0); ++ } ++ MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetPercentValue() >= 0, ++ "This value should have been rejected by the style system"); ++ return NSToCoordFloorClamped(aPercentageBasis * ++ aCoord.GetPercentValue()); ++ case eStyleUnit_Calc: { ++ nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); ++ nscoord result; ++ if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { ++ result = calc->mLength; ++ } else { ++ result = calc->mLength + ++ NSToCoordFloorClamped(aPercentageBasis * calc->mPercent); ++ } ++ if (clampNegativeResultToZero && result < 0) { ++ return nscoord(0); ++ } ++ return result; ++ } ++ default: ++ MOZ_ASSERT_UNREACHABLE("Unexpected unit!"); ++ return nscoord(0); ++ } ++ } ++ ++ /** ++ * Resolve a column-gap/row-gap to a definite size. ++ * @note This method resolves 'normal' to zero. ++ * Callers who want different behavior should handle 'normal' on their own. ++ */ ++ static nscoord ResolveGapToLength(const nsStyleCoord& aGap, ++ nscoord aPercentageBasis) ++ { ++ if (aGap.GetUnit() == eStyleUnit_Normal) { ++ return nscoord(0); ++ } ++ return ResolveToLength(aGap, aPercentageBasis); ++ } ++ + private: + static uint32_t sFontSizeInflationEmPerLine; + static uint32_t sFontSizeInflationMinTwips; +diff -Nrup mozilla-OLD/layout/generic/nsFrame.cpp mozilla/layout/generic/nsFrame.cpp +--- mozilla-OLD/layout/generic/nsFrame.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/generic/nsFrame.cpp 2023-02-27 05:28:13.931420663 +0300 +@@ -5453,7 +5453,7 @@ nsIFrame::InlinePrefISizeData::ForceBrea + static void + AddCoord(const nsStyleCoord& aStyle, + nsIFrame* aFrame, +- nscoord* aCoord, float* aPercent, ++ nscoord* aCoord, + bool aClampNegativeToZero) + { + switch (aStyle.GetUnit()) { +@@ -5466,18 +5466,14 @@ AddCoord(const nsStyleCoord& aStyle, + case eStyleUnit_Percent: { + NS_ASSERTION(!aClampNegativeToZero || aStyle.GetPercentValue() >= 0.0f, + "unexpected negative value"); +- *aPercent += aStyle.GetPercentValue(); + return; + } + case eStyleUnit_Calc: { + const nsStyleCoord::Calc *calc = aStyle.GetCalcValue(); + if (aClampNegativeToZero) { +- // This is far from ideal when one is negative and one is positive. + *aCoord += std::max(calc->mLength, 0); +- *aPercent += std::max(calc->mPercent, 0.0f); + } else { + *aCoord += calc->mLength; +- *aPercent += calc->mPercent; + } + return; + } +@@ -5496,22 +5492,18 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, b + bool verticalAxis = aForISize == wm.IsVertical(); + AddCoord(verticalAxis ? styleMargin->mMargin.GetTop() + : styleMargin->mMargin.GetLeft(), +- aFrame, &result.hMargin, &result.hPctMargin, +- false); ++ aFrame, &result.hMargin, false); + AddCoord(verticalAxis ? styleMargin->mMargin.GetBottom() + : styleMargin->mMargin.GetRight(), +- aFrame, &result.hMargin, &result.hPctMargin, +- false); ++ aFrame, &result.hMargin, false); + + const nsStylePadding* stylePadding = aFrame->StylePadding(); + AddCoord(verticalAxis ? stylePadding->mPadding.GetTop() + : stylePadding->mPadding.GetLeft(), +- aFrame, &result.hPadding, &result.hPctPadding, +- true); ++ aFrame, &result.hPadding, true); + AddCoord(verticalAxis ? stylePadding->mPadding.GetBottom() + : stylePadding->mPadding.GetRight(), +- aFrame, &result.hPadding, &result.hPctPadding, +- true); ++ aFrame, &result.hPadding, true); + + const nsStyleBorder* styleBorder = aFrame->StyleBorder(); + if (verticalAxis) { +@@ -5541,7 +5533,6 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, b + result.hPadding = + presContext->DevPixelsToAppUnits(verticalAxis ? padding.TopBottom() + : padding.LeftRight()); +- result.hPctPadding = 0; + } + } + return result; +diff -Nrup mozilla-OLD/layout/generic/nsGridContainerFrame.cpp mozilla/layout/generic/nsGridContainerFrame.cpp +--- mozilla-OLD/layout/generic/nsGridContainerFrame.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/generic/nsGridContainerFrame.cpp 2023-02-27 05:28:13.932420656 +0300 +@@ -8,9 +8,9 @@ + + #include "nsGridContainerFrame.h" + +-#include // for std::stable_sort + #include + #include ++#include // for div() + #include "gfxContext.h" + #include "mozilla/CSSAlignUtils.h" + #include "mozilla/CSSOrderAwareFrameIterator.h" +@@ -125,42 +125,6 @@ ResolveToDefiniteSize(const nsStyleCoord + return std::max(nscoord(0), aCoord.ComputeCoordPercentCalc(aPercentBasis)); + } + +-static bool +-GetPercentSizeParts(const nsStyleCoord& aCoord, nscoord* aLength, float* aPercent) +-{ +- switch (aCoord.GetUnit()) { +- case eStyleUnit_Percent: +- *aLength = 0; +- *aPercent = aCoord.GetPercentValue(); +- return true; +- case eStyleUnit_Calc: { +- nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); +- *aLength = calc->mLength; +- *aPercent = calc->mPercent; +- return true; +- } +- default: +- return false; +- } +-} +- +-static void +-ResolvePercentSizeParts(const nsStyleCoord& aCoord, nscoord aPercentBasis, +- nscoord* aLength, float* aPercent) +-{ +- MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit()); +- if (aPercentBasis != NS_UNCONSTRAINEDSIZE) { +- *aLength = std::max(nscoord(0), +- aCoord.ComputeCoordPercentCalc(aPercentBasis)); +- *aPercent = 0.0f; +- return; +- } +- if (!GetPercentSizeParts(aCoord, aLength, aPercent)) { +- *aLength = aCoord.ToLength(); +- *aPercent = 0.0f; +- } +-} +- + // Synthesize a baseline from a border box. For an alphabetical baseline + // this is the end edge of the border box. For a central baseline it's + // the center of the border box. +@@ -925,7 +889,7 @@ struct nsGridContainerFrame::TrackSizing + return 1; + } + nscoord repeatTrackSize = 0; +- // Note that the repeat() track size is included in |sum| in this loop. ++ // Note that one repeat() track size is included in |sum| in this loop. + nscoord sum = 0; + const nscoord percentBasis = aSize; + for (uint32_t i = 0; i < numTracks; ++i) { +@@ -942,54 +906,31 @@ struct nsGridContainerFrame::TrackSizing + } + nscoord trackSize = ::ResolveToDefiniteSize(*coord, percentBasis); + if (i == mRepeatAutoStart) { +- if (percentBasis != NS_UNCONSTRAINEDSIZE) { +- // Use a minimum 1px for the repeat() track-size. +- if (trackSize < AppUnitsPerCSSPixel()) { +- trackSize = AppUnitsPerCSSPixel(); +- } ++ // Use a minimum 1px for the repeat() track-size. ++ if (trackSize < AppUnitsPerCSSPixel()) { ++ trackSize = AppUnitsPerCSSPixel(); + } + repeatTrackSize = trackSize; + } + sum += trackSize; + } +- nscoord gridGap; +- float percentSum = 0.0f; +- float gridGapPercent; +- ResolvePercentSizeParts(aGridGap, percentBasis, &gridGap, &gridGapPercent); ++ nscoord gridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aSize); + if (numTracks > 1) { + // Add grid-gaps for all the tracks including the repeat() track. + sum += gridGap * (numTracks - 1); +- percentSum = gridGapPercent * (numTracks - 1); + } + // Calculate the max number of tracks that fits without overflow. + nscoord available = maxFill != NS_UNCONSTRAINEDSIZE ? maxFill : aMinSize; +- nscoord size = nsLayoutUtils::AddPercents(sum, percentSum); +- if (available - size < 0) { ++ nscoord spaceToFill = available - sum; ++ if (spaceToFill <= 0) { + // "if any number of repetitions would overflow, then 1 repetition" + return 1; + } +- uint32_t numRepeatTracks = 1; +- bool exactFit = false; +- while (true) { +- sum += gridGap + repeatTrackSize; +- percentSum += gridGapPercent; +- nscoord newSize = nsLayoutUtils::AddPercents(sum, percentSum); +- if (newSize <= size) { +- // Adding more repeat-tracks won't make forward progress. +- return numRepeatTracks; +- } +- size = newSize; +- nscoord remaining = available - size; +- exactFit = remaining == 0; +- if (remaining >= 0) { +- ++numRepeatTracks; +- } +- if (remaining <= 0) { +- break; +- } +- } +- +- if (!exactFit && maxFill == NS_UNCONSTRAINEDSIZE) { ++ // Calculate the max number of tracks that fits without overflow. ++ div_t q = div(spaceToFill, repeatTrackSize + gridGap); ++ // The +1 here is for the one repeat track we already accounted for above. ++ uint32_t numRepeatTracks = q.quot + 1; ++ if (q.rem != 0 && maxFill == NS_UNCONSTRAINEDSIZE) { + // "Otherwise, if the grid container has a definite min size in + // the relevant axis, the number of repetitions is the largest possible + // positive integer that fulfills that minimum requirement." +@@ -1636,13 +1577,6 @@ struct nsGridContainerFrame::Tracks + WritingMode aWM, + const LogicalSize& aContainerSize); + +- /** +- * Return the intrinsic size by back-computing percentages as: +- * IntrinsicSize = SumOfCoordSizes / (1 - SumOfPercentages). +- */ +- nscoord BackComputedIntrinsicSize(const TrackSizingFunctions& aFunctions, +- const nsStyleCoord& aGridGap) const; +- + nscoord GridLineEdge(uint32_t aLine, GridLineSide aSide) const + { + if (MOZ_UNLIKELY(mSizes.IsEmpty())) { +@@ -1946,11 +1880,10 @@ struct MOZ_STACK_CLASS nsGridContainerFr + } + + /** +- * Calculate our track sizes. If the given aContentBox block-axis size is +- * unconstrained, it is assigned to the resulting intrinsic block-axis size. ++ * Calculate our track sizes. + */ + void CalculateTrackSizes(const Grid& aGrid, +- LogicalSize& aContentBox, ++ const LogicalSize& aContentBox, + SizingConstraint aConstraint); + + /** +@@ -2436,7 +2369,7 @@ struct MOZ_STACK_CLASS nsGridContainerFr + void + nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( + const Grid& aGrid, +- LogicalSize& aContentBox, ++ const LogicalSize& aContentBox, + SizingConstraint aConstraint) + { + mCols.Initialize(mColFunctions, mGridStyle->mGridColumnGap, +@@ -2454,12 +2387,6 @@ nsGridContainerFrame::GridReflowInput::C + mRows.CalculateSizes(*this, mGridItems, mRowFunctions, + aContentBox.BSize(mWM), &GridArea::mRows, + aConstraint); +- if (aContentBox.BSize(mWM) == NS_AUTOHEIGHT) { +- aContentBox.BSize(mWM) = +- mRows.BackComputedIntrinsicSize(mRowFunctions, mGridStyle->mGridRowGap); +- mRows.mGridGap = +- ::ResolveToDefiniteSize(mGridStyle->mGridRowGap, aContentBox.BSize(mWM)); +- } + } + + /** +@@ -3561,7 +3488,7 @@ nsGridContainerFrame::Tracks::Initialize + aFunctions.MinSizingFor(i), + aFunctions.MaxSizingFor(i)); + } +- mGridGap = ::ResolveToDefiniteSize(aGridGap, aContentBoxSize); ++ mGridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aContentBoxSize); + mContentBoxSize = aContentBoxSize; + } + +@@ -3652,8 +3579,7 @@ ContentContribution(const GridItemInfo& + PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis)); + nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint, + aPercentageBasis, +- aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED | +- nsLayoutUtils::ADD_PERCENTS, ++ aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED, + aMinSizeClamp); + if (size == NS_INTRINSIC_WIDTH_UNKNOWN) { + // We need to reflow the child to find its BSize contribution. +@@ -3690,15 +3616,7 @@ ContentContribution(const GridItemInfo& + LogicalSize availableSize(childWM, availISize, availBSize); + size = ::MeasuringReflow(child, aState.mReflowInput, aRC, availableSize, + cbSize, iMinSizeClamp, bMinSizeClamp); +- nsIFrame::IntrinsicISizeOffsetData offsets = child->IntrinsicBSizeOffsets(); +- size += offsets.hMargin; +- auto percent = offsets.hPctMargin; +- if (availBSize == NS_UNCONSTRAINEDSIZE) { +- // We always want to add in percent padding too, unless we already did so +- // using a resolved column size above. +- percent += offsets.hPctPadding; +- } +- size = nsLayoutUtils::AddPercents(size, percent); ++ size += child->GetLogicalUsedMargin(childWM).BStartEnd(childWM); + nscoord overflow = size - aMinSizeClamp; + if (MOZ_UNLIKELY(overflow > 0)) { + nscoord contentSize = child->ContentBSize(childWM); +@@ -4849,36 +4767,6 @@ nsGridContainerFrame::Tracks::AlignJusti + MOZ_ASSERT(!roundingError, "we didn't distribute all rounding error?"); + } + +-nscoord +-nsGridContainerFrame::Tracks::BackComputedIntrinsicSize( +- const TrackSizingFunctions& aFunctions, +- const nsStyleCoord& aGridGap) const +-{ +- // Sum up the current sizes (where percentage tracks were treated as 'auto') +- // in 'size'. +- nscoord size = 0; +- for (size_t i = 0, len = mSizes.Length(); i < len; ++i) { +- size += mSizes[i].mBase; +- } +- +- // Add grid-gap contributions to 'size' and calculate a 'percent' sum. +- float percent = 0.0f; +- size_t numTracks = mSizes.Length(); +- if (numTracks > 1) { +- const size_t gridGapCount = numTracks - 1; +- nscoord gridGapLength; +- float gridGapPercent; +- if (::GetPercentSizeParts(aGridGap, &gridGapLength, &gridGapPercent)) { +- percent = gridGapCount * gridGapPercent; +- } else { +- gridGapLength = aGridGap.ToLength(); +- } +- size += gridGapCount * gridGapLength; +- } +- +- return std::max(0, nsLayoutUtils::AddPercents(size, percent)); +-} +- + void + nsGridContainerFrame::LineRange::ToPositionAndLength( + const nsTArray& aTrackSizes, nscoord* aPos, nscoord* aLength) const +@@ -6066,7 +5954,7 @@ nsGridContainerFrame::Reflow(nsPresConte + LogicalSize computedSize(wm, computedISize, computedBSize); + + nscoord consumedBSize = 0; +- nscoord bSize; ++ nscoord bSize = 0; + if (!prevInFlow) { + Grid grid; + grid.PlaceGridItems(gridReflowInput, aReflowInput.ComputedMinSize(), +@@ -6074,7 +5962,12 @@ nsGridContainerFrame::Reflow(nsPresConte + + gridReflowInput.CalculateTrackSizes(grid, computedSize, + SizingConstraint::eNoConstraint); +- bSize = computedSize.BSize(wm); ++ // Note: we can't use GridLineEdge here since we haven't calculated ++ // the rows' mPosition yet (happens in AlignJustifyContent below). ++ for (const auto& sz : gridReflowInput.mRows.mSizes) { ++ bSize += sz.mBase; ++ } ++ bSize += gridReflowInput.mRows.SumOfGridGaps(); + } else { + consumedBSize = ConsumedBSize(wm); + gridReflowInput.InitializeForContinuation(this, consumedBSize); +@@ -6497,8 +6390,14 @@ nsGridContainerFrame::IntrinsicISize(gfx + state.mCols.CalculateSizes(state, state.mGridItems, state.mColFunctions, + NS_UNCONSTRAINEDSIZE, &GridArea::mCols, + constraint); +- return state.mCols.BackComputedIntrinsicSize(state.mColFunctions, +- state.mGridStyle->mGridColumnGap); ++ state.mCols.mGridGap = ++ nsLayoutUtils::ResolveGapToLength(state.mGridStyle->mGridColumnGap, ++ NS_UNCONSTRAINEDSIZE); ++ nscoord length = 0; ++ for (const TrackSize& sz : state.mCols.mSizes) { ++ length += sz.mBase; ++ } ++ return length + state.mCols.SumOfGridGaps(); + } + + nscoord +diff -Nrup mozilla-OLD/layout/generic/nsIFrame.h mozilla/layout/generic/nsIFrame.h +--- mozilla-OLD/layout/generic/nsIFrame.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/generic/nsIFrame.h 2023-02-27 05:28:13.933420648 +0300 +@@ -50,6 +50,7 @@ + + #include "CaretAssociationHint.h" + #include "FrameProperties.h" ++#include "LayoutConstants.h" + #include "mozilla/layout/FrameChildList.h" + #include "mozilla/Maybe.h" + #include "mozilla/SmallPointerArray.h" +@@ -166,30 +167,12 @@ typedef uint32_t nsSplittableType; + #define NS_FRAME_IS_NOT_SPLITTABLE(type)\ + (0 == ((type) & NS_FRAME_SPLITTABLE)) + +-#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN +- + //---------------------------------------------------------------------- + + #define NS_SUBTREE_DIRTY(_frame) \ + (((_frame)->GetStateBits() & \ + (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0) + +-/** +- * Constant used to indicate an unconstrained size. +- * +- * @see #Reflow() +- */ +-#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE +- +-#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE +-#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE +-// +1 is to avoid clamped huge margin values being processed as auto margins +-#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) +-#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE +-// NOTE: there are assumptions all over that these have the same value, namely NS_UNCONSTRAINEDSIZE +-// if any are changed to be a value other than NS_UNCONSTRAINEDSIZE +-// at least update AdjustComputedHeight/Width and test ad nauseum +- + // 1 million CSS pixels less than our max app unit measure. + // For reflowing with an "infinite" available inline space per [css-sizing]. + // (reflowing with an NS_UNCONSTRAINEDSIZE available inline size isn't allowed +@@ -2393,11 +2376,9 @@ public: + */ + struct IntrinsicISizeOffsetData { + nscoord hPadding, hBorder, hMargin; +- float hPctPadding, hPctMargin; + + IntrinsicISizeOffsetData() + : hPadding(0), hBorder(0), hMargin(0) +- , hPctPadding(0.0f), hPctMargin(0.0f) + {} + }; + virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() = 0; +diff -Nrup mozilla-OLD/layout/tables/nsTableCellFrame.cpp mozilla/layout/tables/nsTableCellFrame.cpp +--- mozilla-OLD/layout/tables/nsTableCellFrame.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/tables/nsTableCellFrame.cpp 2023-02-27 05:28:13.934420641 +0300 +@@ -784,7 +784,6 @@ nsTableCellFrame::IntrinsicISizeOffsets( + IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); + + result.hMargin = 0; +- result.hPctMargin = 0; + + WritingMode wm = GetWritingMode(); + result.hBorder = GetBorderWidth(wm).IStartEnd(wm); +diff -Nrup mozilla-OLD/layout/tables/nsTableFrame.cpp mozilla/layout/tables/nsTableFrame.cpp +--- mozilla-OLD/layout/tables/nsTableFrame.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/layout/tables/nsTableFrame.cpp 2023-02-27 05:28:13.935420634 +0300 +@@ -1817,11 +1817,9 @@ nsTableFrame::IntrinsicISizeOffsets() + IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); + + result.hMargin = 0; +- result.hPctMargin = 0; + + if (IsBorderCollapse()) { + result.hPadding = 0; +- result.hPctPadding = 0; + + WritingMode wm = GetWritingMode(); + LogicalMargin outerBC = GetIncludedOuterBCBorder(wm); diff --git a/seamonkey-2.53.16-mozilla-1519319.patch b/seamonkey-2.53.16-mozilla-1519319.patch new file mode 100644 index 0000000..59f0f65 --- /dev/null +++ b/seamonkey-2.53.16-mozilla-1519319.patch @@ -0,0 +1,91 @@ +# +# Backport of https://bugzilla.mozilla.org/show_bug.cgi?id=1519319, part 2 only. +# + +diff -Nrup mozilla/build/moz.configure/bindgen.configure mozilla-OK/build/moz.configure/bindgen.configure +--- mozilla/build/moz.configure/bindgen.configure 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/build/moz.configure/bindgen.configure 2023-02-27 13:12:13.961830695 +0300 +@@ -4,6 +4,40 @@ + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + ++# cbindgen is needed by the style system build. ++cbindgen = check_prog('CBINDGEN', ['cbindgen'], paths=toolchain_search_path, ++ when=depends(build_project) ++ (lambda build_project: build_project != 'js')) ++ ++ ++@depends_if(cbindgen) ++@checking('cbindgen version') ++@imports(_from='textwrap', _import='dedent') ++def cbindgen_version(cbindgen): ++ cbindgen_min_version = Version('0.6.1') ++ ++ # cbindgen x.y.z ++ version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1]) ++ ++ if version < cbindgen_min_version: ++ die(dedent('''\ ++ cbindgen version {} is too old. At least version {} is required. ++ ++ Please update using 'cargo install cbindgen --force' or running ++ './mach bootstrap', after removing the existing executable located at ++ {}. ++ '''.format(version, cbindgen_min_version, cbindgen))) ++ ++ return version ++ ++ ++# Bindgen can use rustfmt to format Rust file, but it's not required. ++js_option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program') ++ ++rustfmt = check_prog('RUSTFMT', ['rustfmt'], paths=toolchain_search_path, ++ input='RUSTFMT', allow_missing=True) ++ ++ + # We support setting up the appropriate options for bindgen via setting + # LLVM_CONFIG or by providing explicit configure options. The Windows + # installer of LLVM/Clang doesn't provide llvm-config, so we need both +diff -Nrup mozilla/build/moz.configure/rust.configure mozilla-OK/build/moz.configure/rust.configure +--- mozilla/build/moz.configure/rust.configure 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/build/moz.configure/rust.configure 2023-02-27 13:11:02.817343076 +0300 +@@ -362,39 +362,6 @@ def rust_tests(enable_rust_tests, rustdo + + set_config('MOZ_RUST_TESTS', rust_tests) + +-# cbindgen is needed by the style system build. +-cbindgen = check_prog('CBINDGEN', ['cbindgen'], paths=toolchain_search_path, +- when=depends(build_project) +- (lambda build_project: build_project != 'js')) +- +- +-@depends_if(cbindgen) +-@checking('cbindgen version') +-@imports(_from='textwrap', _import='dedent') +-def cbindgen_version(cbindgen): +- cbindgen_min_version = Version('0.6.1') +- +- # cbindgen x.y.z +- version = Version(check_cmd_output(cbindgen, '--version').strip().split(" ")[1]) +- +- if version < cbindgen_min_version: +- die(dedent('''\ +- cbindgen version {} is too old. At least version {} is required. +- +- Please update using 'cargo install cbindgen --force' or running +- './mach bootstrap', after removing the existing executable located at +- {}. +- '''.format(version, cbindgen_min_version, cbindgen))) +- +- return version +- +- +-# Bindgen can use rustfmt to format Rust file, but it's not required. +-js_option(env='RUSTFMT', nargs=1, help='Path to the rustfmt program') +- +-rustfmt = check_prog('RUSTFMT', ['rustfmt'], paths=toolchain_search_path, +- input='RUSTFMT', allow_missing=True) +- + js_option(env='WIN64_LINK', nargs=1, help='Path to link.exe that targets win64') + js_option(env='WIN64_LIB', nargs=1, help='Paths to libraries for the win64 linker') + diff --git a/seamonkey-2.53.16-mozilla-1720968.patch b/seamonkey-2.53.16-mozilla-1720968.patch new file mode 100644 index 0000000..376215e --- /dev/null +++ b/seamonkey-2.53.16-mozilla-1720968.patch @@ -0,0 +1,22 @@ +--- mozilla/dom/events/EventStateManager.cpp.orig 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/dom/events/EventStateManager.cpp 2023-02-27 06:12:51.493057539 +0300 +@@ -645,16 +645,19 @@ EventStateManager::PreHandleEvent(nsPres + case eMouseUp: { + switch (mouseEvent->button) { + case WidgetMouseEvent::eLeftButton: + if (Prefs::ClickHoldContextMenu()) { + KillClickHoldTimer(); + } + mInTouchDrag = false; + StopTrackingDragGesture(); ++ if (sActiveESM && sActiveESM != this) { ++ sActiveESM->StopTrackingDragGesture(); ++ } + sNormalLMouseEventInProcess = false; + // then fall through... + MOZ_FALLTHROUGH; + case WidgetMouseEvent::eRightButton: + case WidgetMouseEvent::eMiddleButton: + SetClickCount(mouseEvent, aStatus); + NotifyTargetUserActivation(aEvent, aTargetContent); + break; diff --git a/seamonkey-2.53.16-regexp.patch b/seamonkey-2.53.16-regexp.patch new file mode 100644 index 0000000..d97e641 --- /dev/null +++ b/seamonkey-2.53.16-regexp.patch @@ -0,0 +1,15299 @@ +diff -Nrup mozilla/.clang-format-ignore mozilla-OK/.clang-format-ignore +--- mozilla/.clang-format-ignore 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/.clang-format-ignore 2023-02-27 07:59:40.452242923 +0300 +@@ -134,3 +134,7 @@ toolkit/components/protobuf/.* + toolkit/components/url-classifier/chromium/.* + toolkit/crashreporter/google-breakpad/.* + tools/fuzzing/libfuzzer.* ++ ++# Don't want to reformat irregexp (third-party code) ++js/src/irregexp/imported/.* ++ +diff -Nrup mozilla/config/system-headers.mozbuild mozilla-OK/config/system-headers.mozbuild +--- mozilla/config/system-headers.mozbuild 2023-02-27 08:23:54.745950153 +0300 ++++ mozilla-OK/config/system-headers.mozbuild 2023-02-27 08:21:42.310882111 +0300 +@@ -1348,6 +1348,7 @@ if CONFIG['MOZ_SYSTEM_ICU']: + 'unicode/udatpg.h', + 'unicode/udisplaycontext.h', + 'unicode/uenum.h', ++ 'unicode/uniset.h', + 'unicode/unistr.h', + 'unicode/unorm.h', + 'unicode/unum.h', +diff -Nrup mozilla/dom/base/nsContentUtils.cpp mozilla-OK/dom/base/nsContentUtils.cpp +--- mozilla/dom/base/nsContentUtils.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/dom/base/nsContentUtils.cpp 2023-02-27 07:34:26.385980755 +0300 +@@ -20,6 +20,7 @@ + #include "imgRequestProxy.h" + #include "jsapi.h" + #include "jsfriendapi.h" ++#include "js/RegExp.h" + #include "js/Value.h" + #include "Layers.h" + #include "nsAppRunner.h" +@@ -7272,28 +7273,17 @@ nsContentUtils::FindInternalContentViewe + } + + static void +-ReportPatternCompileFailure(nsAString& aPattern, nsIDocument* aDocument, ++ReportPatternCompileFailure(nsAString& aPattern, ++ nsIDocument* aDocument, ++ JS::MutableHandle error, + JSContext* cx) + { +- MOZ_ASSERT(JS_IsExceptionPending(cx)); +- +- JS::RootedValue exn(cx); +- if (!JS_GetPendingException(cx, &exn)) { +- return; +- } +- if (!exn.isObject()) { +- // If pending exception is not an object, it should be OOM. +- return; +- } +- + JS::AutoSaveExceptionState savedExc(cx); +- JS::RootedObject exnObj(cx, &exn.toObject()); ++ JS::RootedObject exnObj(cx, &error.toObject()); + JS::RootedValue messageVal(cx); + if (!JS_GetProperty(cx, exnObj, "message", &messageVal)) { + return; + } +- MOZ_ASSERT(messageVal.isString()); +- + JS::RootedString messageStr(cx, messageVal.toString()); + MOZ_ASSERT(messageStr); + +@@ -7327,25 +7317,36 @@ nsContentUtils::IsPatternMatching(nsAStr + // regexp evaluation, not actual script execution. + JSAutoCompartment ac(cx, xpc::UnprivilegedJunkScope()); + ++ // Check if the pattern by itself is valid first, and not that it only becomes ++ // valid once we add ^(?: and )$. ++ JS::RootedValue error(cx); ++ if (!JS::CheckRegExpSyntax( ++ cx, static_cast(aPattern.BeginWriting()), ++ aPattern.Length(), JS::RegExpFlag::Unicode, &error)) { ++ return true; ++ } ++ ++ if (!error.isUndefined()) { ++ ReportPatternCompileFailure(aPattern, aDocument, &error, cx); ++ return true; ++ } ++ + // The pattern has to match the entire value. + aPattern.InsertLiteral(u"^(?:", 0); + aPattern.AppendLiteral(")$"); + + JS::Rooted re(cx, +- JS_NewUCRegExpObject(cx, ++ JS::NewUCRegExpObject(cx, + static_cast(aPattern.BeginWriting()), +- aPattern.Length(), JSREG_UNICODE)); ++ aPattern.Length(), JS::RegExpFlag::Unicode)); ++ + if (!re) { +- // Remove extra patterns added above to report with the original pattern. +- aPattern.Cut(0, 4); +- aPattern.Cut(aPattern.Length() - 2, 2); +- ReportPatternCompileFailure(aPattern, aDocument, cx); + return true; + } + + JS::Rooted rval(cx, JS::NullValue()); + size_t idx = 0; +- if (!JS_ExecuteRegExpNoStatics(cx, re, ++ if (!JS::ExecuteRegExpNoStatics(cx, re, + static_cast(aValue.BeginWriting()), + aValue.Length(), &idx, true, &rval)) { + return true; +diff -Nrup mozilla/js/ipc/WrapperAnswer.cpp mozilla-OK/js/ipc/WrapperAnswer.cpp +--- mozilla/js/ipc/WrapperAnswer.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/ipc/WrapperAnswer.cpp 2023-02-27 07:04:13.322911916 +0300 +@@ -12,6 +12,7 @@ + #include "mozilla/dom/ScriptSettings.h" + #include "xpcprivate.h" + #include "js/Class.h" ++#include "js/RegExp.h" + #include "jsfriendapi.h" + + using namespace JS; +@@ -681,7 +682,7 @@ WrapperAnswer::RecvRegExpToShared(const + if (!obj) + return deadCPOW(jsapi, rs); + +- RootedString sourceJSStr(cx, JS_GetRegExpSource(cx, obj)); ++ RootedString sourceJSStr(cx, JS::GetRegExpSource(cx, obj)); + if (!sourceJSStr) + return fail(jsapi, rs); + nsAutoJSString sourceStr; +@@ -689,7 +690,7 @@ WrapperAnswer::RecvRegExpToShared(const + return fail(jsapi, rs); + source->Assign(sourceStr); + +- *flags = JS_GetRegExpFlags(cx, obj); ++ *flags = JS::GetRegExpFlags(cx, obj).value(); + + return ok(rs); + } +diff -Nrup mozilla/js/ipc/WrapperOwner.cpp mozilla-OK/js/ipc/WrapperOwner.cpp +--- mozilla/js/ipc/WrapperOwner.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/ipc/WrapperOwner.cpp 2023-02-27 07:04:13.322911916 +0300 +@@ -11,6 +11,8 @@ + #include "mozilla/dom/BindingUtils.h" + #include "jsfriendapi.h" + #include "js/CharacterEncoding.h" ++#include "js/RegExp.h" ++#include "js/RegExpFlags.h" + #include "xpcprivate.h" + #include "CPOWTimer.h" + #include "WrapperFactory.h" +@@ -877,7 +879,8 @@ WrapperOwner::regexp_toShared(JSContext* + return nullptr; + + RootedObject regexp(cx); +- regexp = JS_NewUCRegExpObject(cx, source.get(), source.Length(), flags); ++ regexp = JS::NewUCRegExpObject( ++ cx, source.get(), source.Length(), RegExpFlags(flags)); + if (!regexp) + return nullptr; + +diff -Nrup mozilla/js/moz.configure mozilla-OK/js/moz.configure +--- mozilla/js/moz.configure 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/moz.configure 2023-02-27 07:59:18.114401269 +0300 +@@ -418,16 +418,3 @@ def enable_pipeline_operator(value): + + set_config('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator) + set_define('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator) +- +-# Initial support for new regexp engine +-# ================================================== +- +-js_option('--enable-new-regexp', default=False, help='Enable new regexp engine') +- +-@depends('--enable-new-regexp') +-def enable_new_regexp(value): +- if value: +- return True +- +-set_config('ENABLE_NEW_REGEXP', enable_new_regexp) +-set_define('ENABLE_NEW_REGEXP', enable_new_regexp) +diff -Nrup mozilla/js/public/Class.h mozilla-OK/js/public/Class.h +--- mozilla/js/public/Class.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/public/Class.h 2023-02-27 07:46:51.293696342 +0300 +@@ -851,7 +851,7 @@ static const uint32_t JSCLASS_FOREGROUND + // application. + static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5; + static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT = +- JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 38; ++ JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 39; + + #define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \ + (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) +diff -Nrup mozilla/js/public/RegExp.h mozilla-OK/js/public/RegExp.h +--- mozilla/js/public/RegExp.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/public/RegExp.h 2023-02-27 07:34:26.381980784 +0300 +@@ -0,0 +1,107 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ * ++ * This Source Code Form is "Incompatible With Secondary Licenses", as ++ * defined by the Mozilla Public License, v. 2.0. ++ */ ++ ++/* Public JS API for Regular Expressions. */ ++ ++#ifndef js_RegExp_h ++#define js_RegExp_h ++ ++#include // size_t ++ ++#include "jstypes.h" // JS_PUBLIC_API ++ ++#include "js/RegExpFlags.h" // JS::RegExpFlags ++#include "js/RootingAPI.h" // JS::{,Mutable}Handle ++#include "js/Value.h" // JS::Value ++ ++struct JSContext; ++class JSString; ++ ++namespace JS { ++ ++/* ++ * Create a new RegExp for the given Latin-1-encoded source and flags. ++ */ ++extern JS_PUBLIC_API(JSObject*) NewRegExpObject(JSContext* cx, ++ const char* bytes, ++ size_t length, ++ RegExpFlags flags); ++ ++/* ++ * Create a new RegExp for the given UC source and flags. ++ */ ++extern JS_PUBLIC_API(JSObject*) NewUCRegExpObject(JSContext* cx, ++ const char16_t* chars, ++ size_t length, ++ RegExpFlags flags); ++ ++extern JS_PUBLIC_API(bool) ++ SetRegExpInput(JSContext* cx, Handle obj, Handle input); ++ ++extern JS_PUBLIC_API(bool) ++ ClearRegExpStatics(JSContext* cx, Handle obj); ++ ++/* RegExp interface for callers with a global object. */ ++ ++extern JS_PUBLIC_API(bool) ExecuteRegExp(JSContext* cx, ++ Handle obj, ++ Handle reobj, ++ char16_t* chars, ++ size_t length, ++ size_t* indexp, ++ bool test, ++ MutableHandle rval); ++ ++/* RegExp interface for callers without a global object. */ ++ ++extern JS_PUBLIC_API(bool) ExecuteRegExpNoStatics(JSContext* cx, ++ Handle reobj, ++ char16_t* chars, ++ size_t length, ++ size_t* indexp, ++ bool test, ++ MutableHandle rval); ++ ++/* ++ * Returns true on success, setting |*isRegExp| to true if |obj| is a RegExp ++ * object or a wrapper around one, or to false if not. Returns false on failure. ++ * ++ * This method returns true with |*isRegExp == false| when passed an ES6 proxy ++ * whose target is a RegExp, or when passed a revoked proxy. ++ */ ++extern JS_PUBLIC_API(bool) ++ ObjectIsRegExp(JSContext* cx, Handle obj, bool* isRegExp); ++ ++/* ++ * Given a RegExp object (or a wrapper around one), return all JS::RegExpFlag::* for it. ++ */ ++extern JS_PUBLIC_API(RegExpFlags) ++ GetRegExpFlags(JSContext* cx, Handle obj); ++ ++/* ++ * Return the source text for a RegExp object (or a wrapper around one), or null on failure. ++ */ ++extern JS_PUBLIC_API(JSString*) ++ GetRegExpSource(JSContext* cx, Handle obj); ++ ++/** ++ * Check whether the given source is a valid regexp. If the regexp parses ++ * successfully, returns true and sets |error| to undefined. If the regexp ++ * has a syntax error, returns true, sets |error| to that error object, and ++ * clears the exception. Returns false on OOM or over-recursion. ++ */ ++extern JS_PUBLIC_API(bool) CheckRegExpSyntax(JSContext* cx, ++ const char16_t* chars, ++ size_t length, ++ RegExpFlags flags, ++ MutableHandle error); ++ ++} // namespace JS ++ ++#endif // js_RegExp_h +diff -Nrup mozilla/js/public/RegExpFlags.h mozilla-OK/js/public/RegExpFlags.h +--- mozilla/js/public/RegExpFlags.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/public/RegExpFlags.h 2023-02-27 07:32:28.065820181 +0300 +@@ -0,0 +1,171 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ * ++ * This Source Code Form is "Incompatible With Secondary Licenses", as ++ * defined by the Mozilla Public License, v. 2.0. ++ */ ++ ++/* Regular Expression flags. */ ++ ++#ifndef js_RegExpFlags_h ++#define js_RegExpFlags_h ++ ++#include "mozilla/Assertions.h" // for MOZ_ASSERT ++#include "mozilla/Attributes.h" // for MOZ_IMPLICIT ++#include ++ ++namespace JS { ++ ++/* ++ * Regular Expression flag values, suitable for initializing a collection of ++ * regular expression flags as defined below in |RegExpFlags|. ++ * Flags are listed in alphabetical order by syntax: /g, /i, /m, /s, /u, /y. ++ */ ++ ++class RegExpFlag ++{ ++ // WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can change): ++ // ++ // Flag-bit values appear in XDR and structured clone data formats, so none of ++ // these values can be changed (including to assign values in numerically ++ // ascending order) unless you also add a translation layer. ++public: ++ /** ++ * Act globally and find *all* matches (rather than stopping after just the ++ * first one), i.e. /g. ++ */ ++ static uint8_t const Global = 0x02; ++ ++ /** ++ * Interpret regular expression source text case-insensitively by folding ++ * uppercase letters to lowercase, i.e. /i. ++ */ ++ static uint8_t const IgnoreCase = 0x01; ++ ++ /** Treat ^ and $ as begin and end of line, i.e. /m. */ ++ static uint8_t const Multiline = 0x04; ++ ++ /** Match '.' to any character including newlines, i.e. /s. */ ++ static uint8_t const DotAll = 0x20; ++ ++ /** Use Unicode semantics, i.e. /u. */ ++ static uint8_t const Unicode = 0x10; ++ ++ /** Only match starting from .lastIndex, i.e. /y. */ ++ static uint8_t const Sticky = 0x08; ++ ++ /** No regular expression flags. */ ++ static uint8_t const NoFlags = 0x00; ++ ++ /** All regular expression flags. */ ++ static uint8_t const AllFlags = 0x3F; //All supported bits set: 0b11'1111 ++}; ++ ++/* ++ * A collection of regular expression flags. Individual flag values may be ++ * combined into a collection using bitwise operators. ++ */ ++class RegExpFlags ++{ ++public: ++ using Flag = uint8_t; ++ ++private: ++ Flag flags_; ++ ++public: ++ RegExpFlags() = default; ++ ++ MOZ_IMPLICIT RegExpFlags(Flag flags) ++ : flags_(flags) ++ { ++ MOZ_ASSERT((flags & RegExpFlag::AllFlags) == flags, ++ "flags must not contain unrecognized flags"); ++ } ++ ++ RegExpFlags(const RegExpFlags&) = default; ++ ++ bool operator==(const RegExpFlags& other) const ++ { ++ return flags_ == other.flags_; ++ } ++ ++ bool operator!=(const RegExpFlags& other) const { return !(*this == other); } ++ ++ RegExpFlags& operator&=(const RegExpFlags& rhs) ++ { ++ flags_ &= rhs.flags_; ++ return *this; ++ } ++ ++ RegExpFlags& operator|=(const RegExpFlags& rhs) ++ { ++ flags_ |= rhs.flags_; ++ return *this; ++ } ++ ++ RegExpFlags operator&(Flag flag) const { return RegExpFlags(flags_ & flag); } ++ ++ RegExpFlags operator|(Flag flag) const { return RegExpFlags(flags_ | flag); } ++ ++ RegExpFlags operator^(Flag flag) const { return RegExpFlags(flags_ ^ flag); } ++ ++ RegExpFlags operator~() const ++ { ++ return RegExpFlags(~flags_ & RegExpFlag::AllFlags); ++ } ++ ++ bool global() const { return flags_ & RegExpFlag::Global; } ++ bool ignoreCase() const { return flags_ & RegExpFlag::IgnoreCase; } ++ bool multiline() const { return flags_ & RegExpFlag::Multiline; } ++ bool dotAll() const { return flags_ & RegExpFlag::DotAll; } ++ bool unicode() const { return flags_ & RegExpFlag::Unicode; } ++ bool sticky() const { return flags_ & RegExpFlag::Sticky; } ++ ++ explicit operator bool() const { return flags_ != 0; } ++ ++ Flag value() const { return flags_; } ++}; ++ ++inline RegExpFlags& ++operator&=(RegExpFlags& flags, RegExpFlags::Flag flag) ++{ ++ flags = flags & flag; ++ return flags; ++} ++ ++inline RegExpFlags& ++operator|=(RegExpFlags& flags, RegExpFlags::Flag flag) ++{ ++ flags = flags | flag; ++ return flags; ++} ++ ++inline RegExpFlags& ++operator^=(RegExpFlags& flags, RegExpFlags::Flag flag) ++{ ++ flags = flags ^ flag; ++ return flags; ++} ++ ++inline RegExpFlags ++operator&(const RegExpFlags& lhs, const RegExpFlags& rhs) ++{ ++ RegExpFlags result = lhs; ++ result &= rhs; ++ return lhs; ++} ++ ++inline RegExpFlags ++operator|(const RegExpFlags& lhs, const RegExpFlags& rhs) ++{ ++ RegExpFlags result = lhs; ++ result |= rhs; ++ return result; ++} ++ ++} // namespace JS ++ ++#endif // js_RegExpFlags_h +diff -Nrup mozilla/js/public/Value.h mozilla-OK/js/public/Value.h +--- mozilla/js/public/Value.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/public/Value.h 2023-02-27 07:34:10.653092389 +0300 +@@ -691,7 +691,7 @@ class MOZ_NON_PARAM alignas(8) Value + return data.s.payload.u32; + } + +- uint64_t asRawBits() const { ++ constexpr uint64_t asRawBits() const { + return data.asBits; + } + +diff -Nrup mozilla/js/src/.clang-format mozilla-OK/js/src/.clang-format +--- mozilla/js/src/.clang-format 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/.clang-format 1970-01-01 03:00:00.000000000 +0300 +@@ -1,10 +0,0 @@ +-# Clang-format style for SpiderMonkey code which is different than the standard Mozilla style. +-BasedOnStyle: Mozilla +-ColumnLimit: 99 +-IndentWidth: 4 +- +-# Ignore all comments because they aren't reflowed properly. +-# We require 80-col comments and 99-col code. +-CommentPragmas: "^" +- +-SortIncludes: false +diff -Nrup mozilla/js/src/builtin/RegExp.cpp mozilla-OK/js/src/builtin/RegExp.cpp +--- mozilla/js/src/builtin/RegExp.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/RegExp.cpp 2023-02-27 08:10:08.164795473 +0300 +@@ -6,14 +6,17 @@ + + #include "builtin/RegExp.h" + ++#include "mozilla/Casting.h" + #include "mozilla/CheckedInt.h" + #include "mozilla/TypeTraits.h" + + #include "jscntxt.h" + + #include "frontend/TokenStream.h" +-#include "irregexp/RegExpParser.h" ++#include "irregexp/RegExpAPI.h" + #include "jit/InlinableNatives.h" ++#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags ++#include "vm/NativeObject-inl.h" + #include "vm/RegExpStatics.h" + #include "vm/SelfHosting.h" + #include "vm/StringBuffer.h" +@@ -28,17 +31,25 @@ using namespace js; + using namespace js::unicode; + + using mozilla::ArrayLength; ++using mozilla::AssertedCast; + using mozilla::CheckedInt; + using mozilla::Maybe; + ++using JS::RegExpFlag; ++using JS::RegExpFlags; ++ + /* +- * ES 2017 draft rev 6a13789aa9e7c6de4e96b7d3e24d9e6eba6584ad 21.2.5.2.2 +- * steps 3, 16-25. ++ * ES 2021 draft 21.2.5.2.2: Steps 16-28 ++ * https://tc39.es/ecma262/#sec-regexpbuiltinexec + */ + bool +-js::CreateRegExpMatchResult(JSContext* cx, HandleString input, const MatchPairs& matches, ++js::CreateRegExpMatchResult(JSContext* cx, ++ HandleRegExpShared re, ++ HandleString input, ++ const MatchPairs& matches, + MutableHandleValue rval) + { ++ MOZ_ASSERT(re); + MOZ_ASSERT(input); + + /* +@@ -49,23 +60,42 @@ js::CreateRegExpMatchResult(JSContext* c + * 1..pairCount-1: paren matches + * input: input string + * index: start index for the match ++ * groups: named capture groups for the match + */ + + /* Get the templateObject that defines the shape and type of the output object */ + JSObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx); +- if (!templateObject) ++ if (!templateObject) { + return false; ++ } + ++ // Step 16 + size_t numPairs = matches.length(); + MOZ_ASSERT(numPairs > 0); + +- /* Step 17. */ ++ // Steps 18-19 + RootedArrayObject arr(cx, NewDenseFullyAllocatedArrayWithTemplate(cx, numPairs, templateObject)); +- if (!arr) ++ if (!arr) { + return false; ++ } + +- /* Steps 22-24. +- * Store a Value for each pair. */ ++ // Step 24 (reordered) ++ RootedNativeObject groups(cx); ++ bool groupsInDictionaryMode = false; ++ if (re->numNamedCaptures() > 0) { ++ RootedNativeObject groupsTemplate(cx, re->getGroupsTemplate()); ++ if (groupsTemplate->inDictionaryMode()) { ++ groups = NewObjectWithGivenProto(cx, nullptr); ++ groups->setGroup(groupsTemplate->group()); ++ groupsInDictionaryMode = true; ++ } else { ++ JS_TRY_VAR_OR_RETURN_FALSE( ++ cx, groups, NativeObject::createWithTemplate(cx, gc::DefaultHeap, groupsTemplate)); ++ } ++ } ++ ++ // Steps 22-23 and 27 a-e. ++ // Store a Value for each pair. + for (size_t i = 0; i < numPairs; i++) { + const MatchPair& pair = matches[i]; + +@@ -82,6 +112,36 @@ js::CreateRegExpMatchResult(JSContext* c + } + } + ++ // Step 27 f. ++ // The groups template object stores the names of the named captures in the ++ // the order in which they are defined. The named capture indices vector ++ // stores the corresponding capture indices. If we are not in dictionary mode, ++ // we simply fill in the slots with the correct values. In dictionary mode, ++ // we have to define the properties explicitly. ++ if (!groupsInDictionaryMode) { ++ for (uint32_t i = 0; i < re->numNamedCaptures(); i++) { ++ uint32_t idx = re->getNamedCaptureIndex(i); ++ groups->setSlot(i, arr->getDenseElement(idx)); ++ } ++ } else { ++ AutoIdVector keys(cx); ++ RootedPlainObject groupsTemplate(cx, re->getGroupsTemplate()); ++ if (!GetPropertyKeys(cx, groupsTemplate, 0, &keys)) { ++ return false; ++ } ++ MOZ_ASSERT(keys.length() == re->numNamedCaptures()); ++ RootedId key(cx); ++ RootedValue val(cx); ++ for (uint32_t i = 0; i < keys.length(); i++) { ++ key = keys[i]; ++ uint32_t idx = re->getNamedCaptureIndex(i); ++ val = arr->getDenseElement(idx); ++ if (!NativeDefineProperty(cx, groups, key, val, nullptr, nullptr, JSPROP_ENUMERATE)) { ++ return false; ++ } ++ } ++ } ++ + /* Step 20 (reordered). + * Set the |index| property. (TemplateObject positions it in slot 0) */ + arr->setSlot(0, Int32Value(matches[0].start)); +@@ -90,6 +150,10 @@ js::CreateRegExpMatchResult(JSContext* c + * Set the |input| property. (TemplateObject positions it in slot 1) */ + arr->setSlot(1, StringValue(input)); + ++ // Steps 25-26 (reordered) ++ // Set the |groups| property. ++ arr->setSlot(2, groups ? ObjectValue(*groups) : UndefinedValue()); ++ + #ifdef DEBUG + RootedValue test(cx); + RootedId id(cx, NameToId(cx->names().index)); +@@ -102,7 +166,7 @@ js::CreateRegExpMatchResult(JSContext* c + MOZ_ASSERT(test == arr->getSlot(1)); + #endif + +- /* Step 25. */ ++ // Step 28. + rval.setObject(*arr); + return true; + } +@@ -123,19 +187,19 @@ CreateRegExpSearchResult(const MatchPair + * steps 3, 9-14, except 12.a.i, 12.c.i.1. + */ + static RegExpRunStatus +-ExecuteRegExpImpl(JSContext* cx, RegExpStatics* res, MutableHandleRegExpShared re, +- HandleLinearString input, size_t searchIndex, MatchPairs* matches, +- size_t* endIndex) ++ExecuteRegExpImpl(JSContext* cx, ++ RegExpStatics* res, ++ MutableHandleRegExpShared re, ++ HandleLinearString input, ++ size_t searchIndex, ++ MatchPairs* matches) + { +- RegExpRunStatus status = RegExpShared::execute(cx, re, input, searchIndex, matches, endIndex); ++ RegExpRunStatus status = RegExpShared::execute(cx, re, input, searchIndex, matches); + + /* Out of spec: Update RegExpStatics. */ + if (status == RegExpRunStatus_Success && res) { +- if (matches) { +- if (!res->updateFromMatchPairs(cx, input, *matches)) +- return RegExpRunStatus_Error; +- } else { +- res->updateLazily(cx, input, re, searchIndex); ++ if (!res->updateFromMatchPairs(cx, input, *matches)) { ++ return RegExpRunStatus_Error; + } + } + return status; +@@ -154,7 +218,7 @@ js::ExecuteRegExpLegacy(JSContext* cx, R + ScopedMatchPairs matches(&cx->tempLifoAlloc()); + + RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &shared, input, *lastIndex, +- &matches, nullptr); ++ &matches); + if (status == RegExpRunStatus_Error) + return false; + +@@ -172,25 +236,25 @@ js::ExecuteRegExpLegacy(JSContext* cx, R + return true; + } + +- return CreateRegExpMatchResult(cx, input, matches, rval); ++ return CreateRegExpMatchResult(cx, shared, input, matches, rval); + } + + static bool +-CheckPatternSyntaxSlow(JSContext* cx, HandleAtom pattern, RegExpFlag flags) ++CheckPatternSyntaxSlow(JSContext* cx, HandleAtom pattern, RegExpFlags flags) + { + CompileOptions options(cx); + frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); +- return irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern, +- flags & UnicodeFlag); ++ return irregexp::CheckPatternSyntax(cx, dummyTokenStream, pattern, flags); + } + + static RegExpShared* +-CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlag flags) ++CheckPatternSyntax(JSContext* cx, HandleAtom pattern, RegExpFlags flags) + { + // If we already have a RegExpShared for this pattern/flags, we can + // avoid the much slower CheckPatternSyntaxSlow call. + +- if (RegExpShared* shared = cx->zone()->regExps.maybeGet(pattern, flags)) { ++ RootedRegExpShared shared(cx, cx->zone()->regExps.maybeGet(pattern, flags)); ++ if (shared) { + #ifdef DEBUG + // Assert the pattern is valid. + if (!CheckPatternSyntaxSlow(cx, pattern, flags)) { +@@ -240,7 +304,7 @@ RegExpInitializeIgnoringLastIndex(JSCont + } + + /* Step 3. */ +- RegExpFlag flags = RegExpFlag(0); ++ RegExpFlags flags = RegExpFlag::NoFlags; + if (!flagsValue.isUndefined()) { + /* Step 4. */ + RootedString flagStr(cx, ToString(cx, flagsValue)); +@@ -343,12 +407,11 @@ regexp_compile_impl(JSContext* cx, const + } + + // Beware! |patternObj| might be a proxy into another compartment, so +- // don't assume |patternObj.is()|. For the same reason, +- // don't reuse the RegExpShared below. ++ // don't assume |patternObj.is()|. + RootedObject patternObj(cx, &patternValue.toObject()); + + RootedAtom sourceAtom(cx); +- RegExpFlag flags; ++ RegExpFlags flags = RegExpFlag::NoFlags; + { + // Step 3b. + RegExpShared* shared = RegExpToShared(cx, patternObj); +@@ -442,7 +505,7 @@ js::regexp_construct(JSContext* cx, unsi + RootedObject patternObj(cx, &patternValue.toObject()); + + RootedAtom sourceAtom(cx); +- RegExpFlag flags; ++ RegExpFlags flags; + RootedRegExpShared shared(cx); + { + // Step 4.a. +@@ -472,7 +535,7 @@ js::regexp_construct(JSContext* cx, unsi + // Step 8. + if (args.hasDefined(1)) { + // Step 4.c / 21.2.3.2.2 RegExpInitialize step 4. +- RegExpFlag flagsArg = RegExpFlag(0); ++ RegExpFlags flagsArg = RegExpFlag::NoFlags; + RootedString flagStr(cx, ToString(cx, args[1])); + if (!flagStr) + return false; +@@ -483,7 +546,7 @@ js::regexp_construct(JSContext* cx, unsi + if (flags != flagsArg) + shared = nullptr; + +- if (!(flags & UnicodeFlag) && flagsArg & UnicodeFlag) { ++ if (!flags.unicode() && flagsArg.unicode()) { + // Have to check syntax again when adding 'u' flag. + + // ES 2017 draft rev 9b49a888e9dfe2667008a01b2754c3662059ae56 +@@ -562,7 +625,7 @@ js::regexp_construct_raw_flags(JSContext + return false; + + // Step 4.c. +- int32_t flags = int32_t(args[1].toNumber()); ++ RegExpFlags flags = AssertedCast(int32_t(args[1].toNumber())); + + // Step 7. + RegExpObject* regexp = RegExpAlloc(cx, GenericObject); +@@ -570,7 +633,7 @@ js::regexp_construct_raw_flags(JSContext + return false; + + // Step 8. +- regexp->initAndZeroLastIndex(sourceAtom, RegExpFlag(flags), cx); ++ regexp->initAndZeroLastIndex(sourceAtom, flags, cx); + args.rval().setObject(*regexp); + return true; + } +@@ -702,6 +765,33 @@ regexp_source(JSContext* cx, unsigned ar + return CallNonGenericMethod(cx, args); + } + ++// ES 2018 dotAll ++MOZ_ALWAYS_INLINE bool ++regexp_dotAll_impl(JSContext* cx, const CallArgs& args) ++{ ++ MOZ_ASSERT(IsRegExpObject(args.thisv())); ++ ++ // Steps 4-6. ++ RegExpObject* reObj = &args.thisv().toObject().as(); ++ args.rval().setBoolean(reObj->dotAll()); ++ return true; ++} ++ ++bool ++js::regexp_dotAll(JSContext* cx, unsigned argc, JS::Value* vp) ++{ ++ CallArgs args = CallArgsFromVp(argc, vp); ++ ++ // Step 3.a. ++ if (IsRegExpPrototype(args.thisv())) { ++ args.rval().setUndefined(); ++ return true; ++ } ++ ++ // Steps 1-3. ++ return CallNonGenericMethod(cx, args); ++} ++ + // ES 2017 draft 21.2.5.12. + MOZ_ALWAYS_INLINE bool + regexp_sticky_impl(JSContext* cx, const CallArgs& args) +@@ -764,6 +854,7 @@ const JSPropertySpec js::regexp_properti + JS_PSG("source", regexp_source, 0), + JS_PSG("sticky", regexp_sticky, 0), + JS_PSG("unicode", regexp_unicode, 0), ++ JS_PSG("dotAll", regexp_dotAll, 0), + JS_PS_END + }; + +@@ -776,6 +867,7 @@ const JSFunctionSpec js::regexp_methods[ + JS_SELF_HOSTED_FN("exec", "RegExp_prototype_Exec", 1,0), + JS_SELF_HOSTED_FN("test", "RegExpTest" , 1,0), + JS_SELF_HOSTED_SYM_FN(match, "RegExpMatch", 1,0), ++ JS_SELF_HOSTED_SYM_FN(matchAll, "RegExpMatchAll", 1, 0), + JS_SELF_HOSTED_SYM_FN(replace, "RegExpReplace", 2,0), + JS_SELF_HOSTED_SYM_FN(search, "RegExpSearch", 1,0), + JS_SELF_HOSTED_SYM_FN(split, "RegExpSplit", 2,0), +@@ -910,7 +1002,7 @@ IsTrailSurrogateWithLeadSurrogate(Handle + */ + static RegExpRunStatus + ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string, int32_t lastIndex, +- MatchPairs* matches, size_t* endIndex) ++ MatchPairs* matches) + { + /* + * WARNING: Despite the presence of spec step comment numbers, this +@@ -967,7 +1059,7 @@ ExecuteRegExp(JSContext* cx, HandleObjec + } + + /* Steps 3, 11-14, except 12.a.i, 12.c.i.1. */ +- RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &re, input, lastIndex, matches, endIndex); ++ RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &re, input, lastIndex, matches); + if (status == RegExpRunStatus_Error) + return RegExpRunStatus_Error; + +@@ -988,7 +1080,7 @@ RegExpMatcherImpl(JSContext* cx, HandleO + ScopedMatchPairs matches(&cx->tempLifoAlloc()); + + /* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */ +- RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr); ++ RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches); + if (status == RegExpRunStatus_Error) + return false; + +@@ -999,7 +1091,8 @@ RegExpMatcherImpl(JSContext* cx, HandleO + } + + /* Steps 16-25 */ +- return CreateRegExpMatchResult(cx, string, matches, rval); ++ RootedRegExpShared shared(cx, regexp->as().getShared()); ++ return CreateRegExpMatchResult(cx, shared, string, matches, rval); + } + + /* +@@ -1038,8 +1131,11 @@ js::RegExpMatcherRaw(JSContext* cx, Hand + + // The MatchPairs will always be passed in, but RegExp execution was + // successful only if the pairs have actually been filled in. +- if (maybeMatches && maybeMatches->pairsRaw()[0] >= 0) +- return CreateRegExpMatchResult(cx, input, *maybeMatches, output); ++ if (maybeMatches && maybeMatches->pairsRaw()[0] >= 0) { ++ RootedRegExpShared shared(cx, regexp->as().getShared()); ++ return CreateRegExpMatchResult(cx, shared, input, *maybeMatches, output); ++ } ++ + return RegExpMatcherImpl(cx, regexp, input, lastIndex, output); + } + +@@ -1057,7 +1153,7 @@ RegExpSearcherImpl(JSContext* cx, Handle + ScopedMatchPairs matches(&cx->tempLifoAlloc()); + + /* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */ +- RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr); ++ RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches); + if (status == RegExpRunStatus_Error) + return false; + +@@ -1139,15 +1235,15 @@ js::RegExpTester(JSContext* cx, unsigned + MOZ_ALWAYS_TRUE(ToInt32(cx, args[2], &lastIndex)); + + /* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */ +- size_t endIndex = 0; +- RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, nullptr, &endIndex); ++ ScopedMatchPairs matches(&cx->tempLifoAlloc()); ++ RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches); + + if (status == RegExpRunStatus_Error) + return false; + + if (status == RegExpRunStatus_Success) { +- MOZ_ASSERT(endIndex <= INT32_MAX); +- args.rval().setInt32(int32_t(endIndex)); ++ int32_t endIndex = matches[0].limit; ++ args.rval().setInt32(endIndex); + } else { + args.rval().setInt32(-1); + } +@@ -1164,12 +1260,11 @@ js::RegExpTesterRaw(JSContext* cx, Handl + { + MOZ_ASSERT(lastIndex >= 0); + +- size_t endIndexTmp = 0; +- RegExpRunStatus status = ExecuteRegExp(cx, regexp, input, lastIndex, nullptr, &endIndexTmp); ++ ScopedMatchPairs matches(&cx->tempLifoAlloc()); ++ RegExpRunStatus status = ExecuteRegExp(cx, regexp, input, lastIndex, &matches); + + if (status == RegExpRunStatus_Success) { +- MOZ_ASSERT(endIndexTmp <= INT32_MAX); +- *endIndex = int32_t(endIndexTmp); ++ *endIndex = matches[0].limit; + return true; + } + if (status == RegExpRunStatus_Success_NotFound) { +@@ -1212,13 +1307,21 @@ GetParen(JSLinearString* matched, const + out->init(&captureLinear, 0, captureLinear.length()); + } + +-template ++template + static bool +-InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position, size_t tailPos, +- Handle captures, JSLinearString* replacement, +- const CharT* replacementBegin, const CharT* currentDollar, ++InterpretDollar(JSLinearString* matched, ++ JSLinearString* string, ++ size_t position, ++ size_t tailPos, ++ Handle captures, ++ Handle namedCaptures, ++ JSLinearString* replacement, ++ const CharT* replacementBegin, ++ const CharT* currentDollar, + const CharT* replacementEnd, +- JSSubString* out, size_t* skip) ++ JSSubString* out, ++ size_t* skip, ++ uint32_t* currentNamedCapture) + { + MOZ_ASSERT(*currentDollar == '$'); + +@@ -1226,13 +1329,14 @@ InterpretDollar(JSLinearString* matched, + if (currentDollar + 1 >= replacementEnd) + return false; + +- /* ES 2016 draft Mar 25, 2016 Table 46. */ ++ // ES 2021 Table 52 ++ // https://tc39.es/ecma262/#table-45 (sic) + char16_t c = currentDollar[1]; + if (JS7_ISDEC(c)) { + /* $n, $nn */ + unsigned num = JS7_UNDEC(c); + if (num > captures.length()) { +- // The result is implementation-defined, do not substitute. ++ // The result is implementation-defined. Do not substitute. + return false; + } + +@@ -1251,8 +1355,7 @@ InterpretDollar(JSLinearString* matched, + } + + if (num == 0) { +- // The result is implementation-defined. +- // Do not substitute. ++ // The result is implementation-defined. Do not substitute. + return false; + } + +@@ -1264,7 +1367,35 @@ InterpretDollar(JSLinearString* matched, + return true; + } + +- *skip = 2; ++ // '$<': Named Captures ++ if (c == '<') { ++ // Step 1. ++ if (namedCaptures.length() == 0) { ++ return false; ++ } ++ ++ // Step 2.b ++ const CharT* nameStart = currentDollar + 2; ++ const CharT* nameEnd = js_strchr_limit(nameStart, '>', replacementEnd); ++ ++ // Step 2.c ++ if (!nameEnd) { ++ return false; ++ } ++ ++ // Step 2.d ++ // We precompute named capture replacements in InitNamedCaptures. ++ // They are stored in the order in which we will need them, so here ++ // we can just take the next one in the list. ++ size_t nameLength = nameEnd - nameStart; ++ *skip = nameLength + 3; // $<...> ++ ++ // Steps 2.d.iii-iv ++ GetParen(matched, namedCaptures[*currentNamedCapture], out); ++ *currentNamedCapture += 1; ++ return true; ++ } ++ + switch (c) { + default: + return false; +@@ -1288,14 +1419,23 @@ InterpretDollar(JSLinearString* matched, + out->init(string, tailPos, string->length() - tailPos); + break; + } ++ ++ *skip = 2; + return true; + } + +-template ++template + static bool +-FindReplaceLengthString(JSContext* cx, HandleLinearString matched, HandleLinearString string, +- size_t position, size_t tailPos, Handle captures, +- HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep) ++FindReplaceLengthString(JSContext* cx, ++ HandleLinearString matched, ++ HandleLinearString string, ++ size_t position, ++ size_t tailPos, ++ Handle captures, ++ Handle namedCaptures, ++ HandleLinearString replacement, ++ size_t firstDollarIndex, ++ size_t* sizep) + { + CheckedInt replen = replacement->length(); + +@@ -1304,12 +1444,23 @@ FindReplaceLengthString(JSContext* cx, H + const CharT* replacementBegin = replacement->chars(nogc); + const CharT* currentDollar = replacementBegin + firstDollarIndex; + const CharT* replacementEnd = replacementBegin + replacement->length(); ++ uint32_t currentNamedCapture = 0; + do { + JSSubString sub; + size_t skip; +- if (InterpretDollar(matched, string, position, tailPos, captures, replacement, +- replacementBegin, currentDollar, replacementEnd, &sub, &skip)) +- { ++ if (InterpretDollar(matched, ++ string, ++ position, ++ tailPos, ++ captures, ++ namedCaptures, ++ replacement, ++ replacementBegin, ++ currentDollar, ++ replacementEnd, ++ &sub, ++ &skip, ++ ¤tNamedCapture)) { + if (sub.length > skip) + replen += sub.length - skip; + else +@@ -1332,15 +1483,37 @@ FindReplaceLengthString(JSContext* cx, H + } + + static bool +-FindReplaceLength(JSContext* cx, HandleLinearString matched, HandleLinearString string, +- size_t position, size_t tailPos, Handle captures, +- HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep) +-{ +- return replacement->hasLatin1Chars() +- ? FindReplaceLengthString(cx, matched, string, position, tailPos, captures, +- replacement, firstDollarIndex, sizep) +- : FindReplaceLengthString(cx, matched, string, position, tailPos, captures, +- replacement, firstDollarIndex, sizep); ++FindReplaceLength(JSContext* cx, ++ HandleLinearString matched, ++ HandleLinearString string, ++ size_t position, ++ size_t tailPos, ++ Handle captures, ++ Handle namedCaptures, ++ HandleLinearString replacement, ++ size_t firstDollarIndex, ++ size_t* sizep) ++{ ++ return replacement->hasLatin1Chars() ? FindReplaceLengthString(cx, ++ matched, ++ string, ++ position, ++ tailPos, ++ captures, ++ namedCaptures, ++ replacement, ++ firstDollarIndex, ++ sizep) ++ : FindReplaceLengthString(cx, ++ matched, ++ string, ++ position, ++ tailPos, ++ captures, ++ namedCaptures, ++ replacement, ++ firstDollarIndex, ++ sizep); + } + + /* +@@ -1348,11 +1521,17 @@ FindReplaceLength(JSContext* cx, HandleL + * derived from FindReplaceLength), and has been inflated to TwoByte if + * necessary. + */ +-template ++template + static void +-DoReplace(HandleLinearString matched, HandleLinearString string, +- size_t position, size_t tailPos, Handle captures, +- HandleLinearString replacement, size_t firstDollarIndex, StringBuffer &sb) ++DoReplace(HandleLinearString matched, ++ HandleLinearString string, ++ size_t position, ++ size_t tailPos, ++ Handle captures, ++ Handle namedCaptures, ++ HandleLinearString replacement, ++ size_t firstDollarIndex, ++ StringBuffer& sb) + { + JS::AutoCheckCannotGC nogc; + const CharT* replacementBegin = replacement->chars(nogc); +@@ -1361,6 +1540,7 @@ DoReplace(HandleLinearString matched, Ha + MOZ_ASSERT(firstDollarIndex < replacement->length()); + const CharT* currentDollar = replacementBegin + firstDollarIndex; + const CharT* replacementEnd = replacementBegin + replacement->length(); ++ uint32_t currentNamedCapture = 0; + do { + /* Move one of the constant portions of the replacement value. */ + size_t len = currentDollar - currentChar; +@@ -1369,9 +1549,19 @@ DoReplace(HandleLinearString matched, Ha + + JSSubString sub; + size_t skip; +- if (InterpretDollar(matched, string, position, tailPos, captures, replacement, +- replacementBegin, currentDollar, replacementEnd, &sub, &skip)) +- { ++ if (InterpretDollar(matched, ++ string, ++ position, ++ tailPos, ++ captures, ++ namedCaptures, ++ replacement, ++ replacementBegin, ++ currentDollar, ++ replacementEnd, ++ &sub, ++ &skip, ++ ¤tNamedCapture)) { + sb.infallibleAppendSubstring(sub.base, sub.offset, sub.length); + currentChar += skip; + currentDollar += skip; +@@ -1384,9 +1574,120 @@ DoReplace(HandleLinearString matched, Ha + sb.infallibleAppend(currentChar, replacement->length() - (currentChar - replacementBegin)); + } + ++/* ++ * This function finds the list of named captures of the form ++ * "$" in a replacement string and converts them into jsids, for ++ * use in InitNamedReplacements. ++ */ ++template ++static bool CollectNames(JSContext* cx, HandleLinearString replacement, ++ size_t firstDollarIndex, ++ MutableHandle> names) { ++ JS::AutoCheckCannotGC nogc; ++ MOZ_ASSERT(firstDollarIndex < replacement->length()); ++ ++ const CharT* replacementBegin = replacement->chars(nogc); ++ const CharT* currentDollar = replacementBegin + firstDollarIndex; ++ const CharT* replacementEnd = replacementBegin + replacement->length(); ++ ++ // https://tc39.es/ecma262/#table-45, "$<" section ++ while (currentDollar && currentDollar + 1 < replacementEnd) { ++ if (currentDollar[1] == '<') { ++ // Step 2.b ++ const CharT* nameStart = currentDollar + 2; ++ const CharT* nameEnd = js_strchr_limit(nameStart, '>', replacementEnd); ++ ++ // Step 2.c ++ if (!nameEnd) { ++ return true; ++ } ++ ++ // Step 2.d.i ++ size_t nameLength = nameEnd - nameStart; ++ JSAtom* atom = AtomizeChars(cx, nameStart, nameLength); ++ if (!atom || !names.append(AtomToId(atom))) { ++ return false; ++ } ++ currentDollar = nameEnd + 1; ++ } else { ++ currentDollar += 2; ++ } ++ currentDollar = js_strchr_limit(currentDollar, '$', replacementEnd); ++ } ++ return true; ++} ++ ++/* ++ * When replacing named captures, the spec requires us to perform ++ * `Get(match.groups, name)` for each "$". These `Get`s can be ++ * script-visible; for example, RegExp can be extended with an `exec` ++ * method that wraps `groups` in a proxy. To make sure that we do the ++ * right thing, if a regexp has named captures, we find the named ++ * capture replacements before beginning the actual replacement. ++ * This guarantees that we will call GetProperty once and only once for ++ * each "$" in the replacement string, in the correct order. ++ * ++ * This function precomputes the results of step 2 of the '$<' case ++ * here: https://tc39.es/proposal-regexp-named-groups/#table-45, so ++ * that when we need to access the nth named capture in InterpretDollar, ++ * we can just use the nth value stored in namedCaptures. ++ */ ++static bool InitNamedCaptures(JSContext* cx, HandleLinearString replacement, ++ HandleObject groups, size_t firstDollarIndex, ++ MutableHandle namedCaptures) { ++ Rooted> names(cx, GCVector(cx)); ++ if (replacement->hasLatin1Chars()) { ++ if (!CollectNames(cx, replacement, firstDollarIndex, &names)) { ++ return false; ++ } ++ } else { ++ if (!CollectNames(cx, replacement, firstDollarIndex, &names)) { ++ return false; ++ } ++ } ++ ++ // https://tc39.es/ecma262/#table-45, "$<" section ++ RootedId id(cx); ++ RootedValue capture(cx); ++ for (uint32_t i = 0; i < names.length(); i++) { ++ // Step 2.d.i ++ id = names[i]; ++ ++ // Step 2.d.ii ++ if (!GetProperty(cx, groups, groups, id, &capture)) { ++ return false; ++ } ++ ++ // Step 2.d.iii ++ if (capture.isUndefined()) { ++ if (!namedCaptures.append(capture)) { ++ return false; ++ } ++ } else { ++ // Step 2.d.iv ++ JSString* str = ToString(cx, capture); ++ if (!str) { ++ return false; ++ } ++ JSLinearString* linear = str->ensureLinear(cx); ++ if (!linear) { ++ return false; ++ } ++ if (!namedCaptures.append(StringValue(linear))) { ++ return false; ++ } ++ } ++ } ++ ++ return true; ++} ++ + static bool +-NeedTwoBytes(HandleLinearString string, HandleLinearString replacement, +- HandleLinearString matched, Handle captures) ++NeedTwoBytes(HandleLinearString string, ++ HandleLinearString replacement, ++ HandleLinearString matched, ++ Handle captures, ++ Handle namedCaptures) + { + if (string->hasTwoByteChars()) + return true; +@@ -1395,22 +1696,36 @@ NeedTwoBytes(HandleLinearString string, + if (matched->hasTwoByteChars()) + return true; + +- for (size_t i = 0, len = captures.length(); i < len; i++) { +- const Value& capture = captures[i]; ++ for (const Value& capture : captures) { + if (capture.isUndefined()) + continue; + if (capture.toString()->hasTwoByteChars()) + return true; + } + ++ for (const Value& capture : namedCaptures) { ++ if (capture.isUndefined()) { ++ continue; ++ } ++ if (capture.toString()->hasTwoByteChars()) { ++ return true; ++ } ++ } ++ + return false; + } + +-/* ES 2016 draft Mar 25, 2016 21.1.3.14.1. */ ++/* ES 2021 21.1.3.17.1 */ ++// https://tc39.es/ecma262/#sec-getsubstitution + bool +-js::RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLinearString string, +- size_t position, HandleLinearString replacement, +- size_t firstDollarIndex, MutableHandleValue rval) ++js::RegExpGetSubstitution(JSContext* cx, ++ HandleArrayObject matchResult, ++ HandleLinearString string, ++ size_t position, ++ HandleLinearString replacement, ++ size_t firstDollarIndex, ++ HandleValue groups, ++ MutableHandleValue rval) + { + MOZ_ASSERT(firstDollarIndex < replacement->length()); + +@@ -1454,6 +1769,16 @@ js::RegExpGetSubstitution(JSContext* cx, + captures.infallibleAppend(StringValue(captureLinear)); + } + ++ Rooted namedCaptures(cx, CapturesVector(cx)); ++ if (groups.isObject()) { ++ RootedObject groupsObj(cx, &groups.toObject()); ++ if (!InitNamedCaptures(cx, replacement, groupsObj, firstDollarIndex, &namedCaptures)) { ++ return false; ++ } ++ } else { ++ MOZ_ASSERT(groups.isUndefined()); ++ } ++ + // Step 8 (skipped). + + // Step 9. +@@ -1468,27 +1793,36 @@ js::RegExpGetSubstitution(JSContext* cx, + + // Step 11. + size_t reserveLength; +- if (!FindReplaceLength(cx, matched, string, position, tailPos, captures, replacement, +- firstDollarIndex, &reserveLength)) +- { ++ if (!FindReplaceLength(cx, ++ matched, ++ string, ++ position, ++ tailPos, ++ captures, ++ namedCaptures, ++ replacement, ++ firstDollarIndex, ++ &reserveLength)) { + return false; + } + + StringBuffer result(cx); +- if (NeedTwoBytes(string, replacement, matched, captures)) { +- if (!result.ensureTwoByteChars()) ++ if (NeedTwoBytes(string, replacement, matched, captures, namedCaptures)) { ++ if (!result.ensureTwoByteChars()) { + return false; ++ } + } + +- if (!result.reserve(reserveLength)) ++ if (!result.reserve(reserveLength)) { + return false; ++ } + + if (replacement->hasLatin1Chars()) { + DoReplace(matched, string, position, tailPos, captures, +- replacement, firstDollarIndex, result); ++ namedCaptures, replacement, firstDollarIndex, result); + } else { + DoReplace(matched, string, position, tailPos, captures, +- replacement, firstDollarIndex, result); ++ namedCaptures, replacement, firstDollarIndex, result); + } + + // Step 12. +@@ -1623,6 +1957,13 @@ js::RegExpPrototypeOptimizableRaw(JSCont + if (unicodeGetter != regexp_unicode) + return false; + ++ JSNative dotAllGetter; ++ if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().dotAll), &dotAllGetter)) ++ return false; ++ ++ if (dotAllGetter != regexp_dotAll) ++ return false; ++ + // Check if @@match, @@search, and exec are own data properties, + // those values should be tested in selfhosted JS. + bool has = false; +diff -Nrup mozilla/js/src/builtin/RegExp.h mozilla-OK/js/src/builtin/RegExp.h +--- mozilla/js/src/builtin/RegExp.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/RegExp.h 2023-02-27 07:42:05.794721513 +0300 +@@ -33,7 +33,10 @@ ExecuteRegExpLegacy(JSContext* cx, RegEx + + /* Translation from MatchPairs to a JS array in regexp_exec()'s output format. */ + MOZ_MUST_USE bool +-CreateRegExpMatchResult(JSContext* cx, HandleString input, const MatchPairs& matches, ++CreateRegExpMatchResult(JSContext* cx, ++ HandleRegExpShared re, ++ HandleString input, ++ const MatchPairs& matches, + MutableHandleValue rval); + + extern MOZ_MUST_USE bool +@@ -100,7 +103,7 @@ RegExpInstanceOptimizableRaw(JSContext* + extern MOZ_MUST_USE bool + RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLinearString string, + size_t position, HandleLinearString replacement, size_t firstDollarIndex, +- MutableHandleValue rval); ++ HandleValue namedCaptures, MutableHandleValue rval); + + extern MOZ_MUST_USE bool + GetFirstDollarIndex(JSContext* cx, unsigned argc, Value* vp); +@@ -129,6 +132,8 @@ extern MOZ_MUST_USE bool + regexp_sticky(JSContext* cx, unsigned argc, JS::Value* vp); + extern MOZ_MUST_USE bool + regexp_unicode(JSContext* cx, unsigned argc, JS::Value* vp); ++extern MOZ_MUST_USE bool ++regexp_dotAll(JSContext* cx, unsigned argc, JS::Value* vp); + + } /* namespace js */ + +diff -Nrup mozilla/js/src/builtin/RegExp.js mozilla-OK/js/src/builtin/RegExp.js +--- mozilla/js/src/builtin/RegExp.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/RegExp.js 2023-02-27 08:15:57.814319072 +0300 +@@ -2,7 +2,8 @@ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +-// ES6 draft rev34 (2015/02/20) 21.2.5.3 get RegExp.prototype.flags ++// ECMAScript 2020 draft (2020/03/12) 21.2.5.4 get RegExp.prototype.flags ++// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags + function RegExpFlagsGetter() { + // Steps 1-2. + var R = this; +@@ -12,27 +13,31 @@ function RegExpFlagsGetter() { + // Step 3. + var result = ""; + +- // Steps 4-6. ++ // Steps 4-5. + if (R.global) + result += "g"; + +- // Steps 7-9. ++ // Steps 6-7. + if (R.ignoreCase) + result += "i"; + +- // Steps 10-12. ++ // Steps 8-9. + if (R.multiline) + result += "m"; + +- // Steps 13-15. ++ // Steps 10-11. ++ if (R.dotAll) ++ result += "s"; ++ ++ // Steps 12-13. + if (R.unicode) + result += "u"; + +- // Steps 16-18. ++ // Steps 14-15. + if (R.sticky) + result += "y"; + +- // Step 19. ++ // Step 16. + return result; + } + _SetCanonicalName(RegExpFlagsGetter, "get flags"); +@@ -225,6 +230,7 @@ function RegExpGlobalMatchOpt(rx, S, ful + // * global + // * ignoreCase + // * multiline ++// * dotAll + // * sticky + // * unicode + // * exec +@@ -389,7 +395,7 @@ function RegExpReplaceSlowPath(rx, S, le + + var n, capN, replacement; + if (functionalReplace || firstDollarIndex !== -1) { +- // Steps 14.g-j. ++ // Steps 14.g-k. + replacement = RegExpGetComplexReplacement(result, matched, S, position, + nCaptures, replaceValue, + functionalReplace, firstDollarIndex); +@@ -404,16 +410,22 @@ function RegExpReplaceSlowPath(rx, S, le + if (capN !== undefined) + ToString(capN); + } ++ // Step 14.j, 14.l., GetSubstitution Step 11. ++ // We don't need namedCaptures, but ToObject is visible to script. ++ var namedCaptures = result.groups; ++ if (namedCaptures !== undefined) ++ ToObject(namedCaptures); ++ + replacement = replaceValue; + } + +- // Step 14.l. ++ // Step 14.m. + if (position >= nextSourcePosition) { +- // Step 14.l.ii. ++ // Step 14.m.ii. + accumulatedResult += Substring(S, nextSourcePosition, + position - nextSourcePosition) + replacement; + +- // Step 14.l.iii. ++ // Step 14.m.iii. + nextSourcePosition = position + matchLength; + } + } +@@ -426,8 +438,9 @@ function RegExpReplaceSlowPath(rx, S, le + return accumulatedResult + Substring(S, nextSourcePosition, lengthS - nextSourcePosition); + } + +-// ES 2017 draft rev 03bfda119d060aca4099d2b77cf43f6d4f11cfa2 21.2.5.8 +-// steps 14.g-k. ++// ES 2021 draft 21.2.5.10 ++// https://tc39.es/ecma262/#sec-regexp.prototype-@@replace ++// steps 14.g-l. + // Calculates functional/substitution replacement from match result. + // Used in the following functions: + // * RegExpReplaceSlowPath +@@ -439,7 +452,7 @@ function RegExpGetComplexReplacement(res + var captures = new_List(); + var capturesLength = 0; + +- // Step 14.j.i (reordered). ++ // Step 14.k.i (reordered). + _DefineDataProperty(captures, capturesLength++, matched); + + // Step 14.g, 14.i, 14.i.iv. +@@ -456,34 +469,46 @@ function RegExpGetComplexReplacement(res + } + + // Step 14.j. ++ var namedCaptures = result.groups; ++ ++ // Step 14.k. + if (functionalReplace) { + // For `nCaptures` <= 4 case, call `replaceValue` directly, otherwise + // use `std_Function_apply` with all arguments stored in `captures`. +- switch (nCaptures) { +- case 0: +- return ToString(replaceValue(SPREAD(captures, 1), position, S)); +- case 1: +- return ToString(replaceValue(SPREAD(captures, 2), position, S)); +- case 2: +- return ToString(replaceValue(SPREAD(captures, 3), position, S)); +- case 3: +- return ToString(replaceValue(SPREAD(captures, 4), position, S)); +- case 4: +- return ToString(replaceValue(SPREAD(captures, 5), position, S)); +- default: +- // Steps 14.j.ii-v. +- _DefineDataProperty(captures, capturesLength++, position); +- _DefineDataProperty(captures, capturesLength++, S); +- return ToString(callFunction(std_Function_apply, replaceValue, undefined, captures)); ++ if (namedCaptures === undefined) { ++ switch (nCaptures) { ++ case 0: ++ return ToString(replaceValue(SPREAD(captures, 1), position, S)); ++ case 1: ++ return ToString(replaceValue(SPREAD(captures, 2), position, S)); ++ case 2: ++ return ToString(replaceValue(SPREAD(captures, 3), position, S)); ++ case 3: ++ return ToString(replaceValue(SPREAD(captures, 4), position, S)); ++ case 4: ++ return ToString(replaceValue(SPREAD(captures, 5), position, S)); ++ } + } ++ // Steps 14.k.ii-v. ++ _DefineDataProperty(captures, capturesLength++, position); ++ _DefineDataProperty(captures, capturesLength++, S); ++ if (namedCaptures !== undefined) { ++ _DefineDataProperty(captures, capturesLength++, namedCaptures); ++ } ++ return ToString(callFunction(std_Function_apply, replaceValue, undefined, captures)); + } + +- // Steps 14.k.i. +- return RegExpGetSubstitution(captures, S, position, replaceValue, firstDollarIndex); ++ // Step 14.l. ++ if (namedCaptures !== undefined) { ++ namedCaptures = ToObject(namedCaptures); ++ } ++ return RegExpGetSubstitution(captures, S, position, replaceValue, firstDollarIndex, ++ namedCaptures); + } + +-// ES 2017 draft rev 03bfda119d060aca4099d2b77cf43f6d4f11cfa2 21.2.5.8 +-// steps 14.g-j. ++// ES 2021 draft 21.2.5.10 ++// https://tc39.es/ecma262/#sec-regexp.prototype-@@replace ++// steps 14.g-k. + // Calculates functional replacement from match result. + // Used in the following functions: + // * RegExpGlobalReplaceOptFunc +@@ -495,20 +520,25 @@ function RegExpGetFunctionalReplacement( + assert(result.length >= 1, "RegExpMatcher doesn't return an empty array"); + var nCaptures = result.length - 1; + +- switch (nCaptures) { +- case 0: +- return ToString(replaceValue(SPREAD(result, 1), position, S)); +- case 1: +- return ToString(replaceValue(SPREAD(result, 2), position, S)); +- case 2: +- return ToString(replaceValue(SPREAD(result, 3), position, S)); +- case 3: +- return ToString(replaceValue(SPREAD(result, 4), position, S)); +- case 4: +- return ToString(replaceValue(SPREAD(result, 5), position, S)); ++ // Step 14.j (reordered) ++ var namedCaptures = result.groups; ++ ++ if (namedCaptures === undefined) { ++ switch (nCaptures) { ++ case 0: ++ return ToString(replaceValue(SPREAD(result, 1), position, S)); ++ case 1: ++ return ToString(replaceValue(SPREAD(result, 2), position, S)); ++ case 2: ++ return ToString(replaceValue(SPREAD(result, 3), position, S)); ++ case 3: ++ return ToString(replaceValue(SPREAD(result, 4), position, S)); ++ case 4: ++ return ToString(replaceValue(SPREAD(result, 5), position, S)); ++ } + } + +- // Steps 14.g-i, 14.j.i-ii. ++ // Steps 14.g-i, 14.k.i-ii. + var captures = new_List(); + for (var n = 0; n <= nCaptures; n++) { + assert(typeof result[n] === "string" || result[n] === undefined, +@@ -516,11 +546,16 @@ function RegExpGetFunctionalReplacement( + _DefineDataProperty(captures, n, result[n]); + } + +- // Step 14.j.iii. ++ // Step 14.k.iii. + _DefineDataProperty(captures, nCaptures + 1, position); + _DefineDataProperty(captures, nCaptures + 2, S); + +- // Steps 14.j.iv-v. ++ // Step 14.k.iv. ++ if (namedCaptures !== undefined) { ++ _DefineDataProperty(captures, nCaptures + 3, namedCaptures); ++ } ++ ++ // Steps 14.k.v-vi. + return ToString(callFunction(std_Function_apply, replaceValue, undefined, captures)); + } + +@@ -975,7 +1010,7 @@ function RegExpExec(R, S, forTest) { + var result = callContentFunction(exec, R, S); + + // Step 5.c. +- if (typeof result !== "object") ++ if (result !== null && !IsObject(result)) + ThrowTypeError(JSMSG_EXEC_NOT_OBJORNULL); + + // Step 5.d. +@@ -1095,3 +1130,235 @@ function RegExpSpecies() { + return this; + } + _SetCanonicalName(RegExpSpecies, "get [Symbol.species]"); ++ ++function IsRegExpMatchAllOptimizable(rx, C) { ++ if (!IsRegExpObject(rx)) ++ return false; ++ ++ var RegExpCtor = GetBuiltinConstructor("RegExp"); ++ if (C !== RegExpCtor) ++ return false; ++ ++ var RegExpProto = RegExpCtor.prototype; ++ return RegExpPrototypeOptimizable(RegExpProto) && ++ RegExpInstanceOptimizable(rx, RegExpProto); ++} ++ ++// String.prototype.matchAll proposal. ++// ++// RegExp.prototype [ @@matchAll ] ( string ) ++function RegExpMatchAll(string) { ++ // Step 1. ++ var rx = this; ++ ++ // Step 2. ++ if (!IsObject(rx)) ++ ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, rx === null ? "null" : typeof rx); ++ ++ // Step 3. ++ var str = ToString(string); ++ ++ // Step 4. ++ var C = SpeciesConstructor(rx, GetBuiltinConstructor("RegExp")); ++ ++ var source, flags, matcher, lastIndex; ++ if (IsRegExpMatchAllOptimizable(rx, C)) { ++ // Step 5, 9-12. ++ source = UnsafeGetStringFromReservedSlot(rx, REGEXP_SOURCE_SLOT); ++ flags = UnsafeGetInt32FromReservedSlot(rx, REGEXP_FLAGS_SLOT); ++ ++ // Step 6. ++ matcher = rx; ++ ++ // Step 7. ++ lastIndex = ToLength(rx.lastIndex); ++ ++ // Step 8 (not applicable for the optimized path). ++ } else { ++ // Step 5. ++ source = ""; ++ flags = ToString(rx.flags); ++ ++ // Step 6. ++ matcher = new C(rx, flags); ++ ++ // Steps 7-8. ++ matcher.lastIndex = ToLength(rx.lastIndex); ++ ++ // Steps 9-12. ++ flags = (callFunction(std_String_includes, flags, "g") ? REGEXP_GLOBAL_FLAG : 0); ++// XXXX (callFunction(std_String_includes, flags, "u") ? REGEXP_UNICODE_FLAG : 0); ++ ++ // Take the non-optimized path. ++ lastIndex = REGEXP_STRING_ITERATOR_LASTINDEX_SLOW; ++ } ++ ++ // Step 13. ++ return CreateRegExpStringIterator(matcher, str, source, flags, lastIndex); ++} ++ ++// String.prototype.matchAll proposal. ++// ++// CreateRegExpStringIterator ( R, S, global, fullUnicode ) ++function CreateRegExpStringIterator(regexp, string, source, flags, lastIndex) { ++ // Step 1. ++ assert(typeof string === "string", "|string| is a string value"); ++ ++ // Steps 2-3. ++ assert(typeof flags === "number", "|flags| is a number value"); ++ ++ assert(typeof source === "string", "|source| is a string value"); ++ assert(typeof lastIndex === "number", "|lastIndex| is a number value"); ++ ++ // Steps 4-9. ++ var iterator = NewRegExpStringIterator(); ++ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_REGEXP_SLOT, regexp); ++ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_STRING_SLOT, string); ++ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_SOURCE_SLOT, source); ++ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_FLAGS_SLOT, flags | 0); ++ UnsafeSetReservedSlot(iterator, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, lastIndex); ++ ++ // Step 10. ++ return iterator; ++} ++ ++function IsRegExpStringIteratorNextOptimizable() { ++ var RegExpProto = GetBuiltinPrototype("RegExp"); ++ // If RegExpPrototypeOptimizable succeeds, `RegExpProto.exec` is ++ // guaranteed to be a data property. ++ return RegExpPrototypeOptimizable(RegExpProto) && ++ RegExpProto.exec === RegExp_prototype_Exec; ++} ++ ++// String.prototype.matchAll proposal. ++// ++// %RegExpStringIteratorPrototype%.next ( ) ++function RegExpStringIteratorNext() { ++ // Steps 1-3. ++ if (!IsObject(this) || !GuardToRegExpStringIterator(this)) { ++ return callFunction(CallRegExpStringIteratorMethodIfWrapped, this, ++ "RegExpStringIteratorNext"); ++ } ++ ++ var result = { value: undefined, done: false }; ++ ++ // Step 4. ++ var lastIndex = UnsafeGetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT); ++ if (lastIndex === REGEXP_STRING_ITERATOR_LASTINDEX_DONE) { ++ result.done = true; ++ return result; ++ } ++ ++ // Step 5. ++ var regexp = UnsafeGetObjectFromReservedSlot(this, REGEXP_STRING_ITERATOR_REGEXP_SLOT); ++ ++ // Step 6. ++ var string = UnsafeGetStringFromReservedSlot(this, REGEXP_STRING_ITERATOR_STRING_SLOT); ++ ++ // Steps 7-8. ++ var flags = UnsafeGetInt32FromReservedSlot(this, REGEXP_STRING_ITERATOR_FLAGS_SLOT); ++ var global = !!(flags & REGEXP_GLOBAL_FLAG); ++ var fullUnicode = !!(flags & REGEXP_UNICODE_FLAG); ++ ++ if (lastIndex >= 0) { ++ assert(IsRegExpObject(regexp), "|regexp| is a RegExp object"); ++ ++ var source = UnsafeGetStringFromReservedSlot(this, REGEXP_STRING_ITERATOR_SOURCE_SLOT); ++ if (IsRegExpStringIteratorNextOptimizable() && ++ UnsafeGetStringFromReservedSlot(regexp, REGEXP_SOURCE_SLOT) === source && ++ UnsafeGetInt32FromReservedSlot(regexp, REGEXP_FLAGS_SLOT) === flags) ++ { ++ // Step 9 (Inlined RegExpBuiltinExec). ++ var globalOrSticky = !!(flags & (REGEXP_GLOBAL_FLAG | REGEXP_STICKY_FLAG)); ++ if (!globalOrSticky) ++ lastIndex = 0; ++ ++ var match = (lastIndex <= string.length) ++ ? RegExpMatcher(regexp, string, lastIndex) ++ : null; ++ ++ // Step 10. ++ if (match === null) { ++ // Step 10.a. ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, ++ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); ++ ++ // Step 10.b. ++ result.done = true; ++ return result; ++ } ++ ++ // Step 11.a. ++ if (global) { ++ // Step 11.a.i. ++ var matchLength = match[0].length; ++ lastIndex = match.index + matchLength; ++ ++ // Step 11.a.ii. ++ if (matchLength === 0) { ++ // Steps 11.a.ii.1-3. ++ lastIndex = fullUnicode ? AdvanceStringIndex(string, lastIndex) : lastIndex + 1; ++ } ++ ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, lastIndex); ++ } else { ++ // Step 11.b.i. ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, ++ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); ++ } ++ ++ // Steps 11.a.iii and 11.b.ii. ++ result.value = match; ++ return result; ++ } ++ ++ // Reify the RegExp object. ++ regexp = regexp_construct_raw_flags(source, flags); ++ regexp.lastIndex = lastIndex; ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_REGEXP_SLOT, regexp); ++ ++ // Mark the iterator as no longer optimizable. ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, ++ REGEXP_STRING_ITERATOR_LASTINDEX_SLOW); ++ } ++ ++ // Step 9. ++ var match = RegExpExec(regexp, string, false); ++ ++ // Step 10. ++ if (match === null) { ++ // Step 10.a. ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, ++ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); ++ ++ // Step 10.b. ++ result.done = true; ++ return result; ++ } ++ ++ // Step 11.a. ++ if (global) { ++ // Step 11.a.i. ++ var matchStr = ToString(match[0]); ++ ++ // Step 11.a.ii. ++ if (matchStr.length === 0) { ++ // Step 11.a.ii.1. ++ var thisIndex = ToLength(regexp.lastIndex); ++ ++ // Step 11.a.ii.2. ++ var nextIndex = fullUnicode ? AdvanceStringIndex(string, thisIndex) : thisIndex + 1; ++ ++ // Step 11.a.ii.3. ++ regexp.lastIndex = nextIndex; ++ } ++ } else { ++ // Step 11.b.i. ++ UnsafeSetReservedSlot(this, REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, ++ REGEXP_STRING_ITERATOR_LASTINDEX_DONE); ++ } ++ ++ // Steps 11.a.iii and 11.b.ii. ++ result.value = match; ++ return result; ++} +diff -Nrup mozilla/js/src/builtin/RegExpGlobalReplaceOpt.h.js mozilla-OK/js/src/builtin/RegExpGlobalReplaceOpt.h.js +--- mozilla/js/src/builtin/RegExpGlobalReplaceOpt.h.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/RegExpGlobalReplaceOpt.h.js 2023-02-27 07:42:05.795721506 +0300 +@@ -69,12 +69,19 @@ function FUNC_NAME(rx, S, lengthS, repla + var position = result.index | 0; + lastIndex = position + matchLength; + +- // Steps g-k. ++ // Steps g-l. + var replacement; + #if defined(FUNCTIONAL) + replacement = RegExpGetFunctionalReplacement(result, S, position, replaceValue); + #elif defined(SUBSTITUTION) +- replacement = RegExpGetSubstitution(result, S, position, replaceValue, firstDollarIndex); ++ // Step l.i ++ var namedCaptures = result.groups; ++ if (namedCaptures !== undefined) { ++ namedCaptures = ToObject(namedCaptures); ++ } ++ // Step l.ii ++ replacement = RegExpGetSubstitution(result, S, position, replaceValue, ++ firstDollarIndex, namedCaptures); + #elif defined(ELEMBASE) + if (IsObject(elemBase)) { + var prop = GetStringDataProperty(elemBase, matched); +@@ -93,11 +100,11 @@ function FUNC_NAME(rx, S, lengthS, repla + replacement = replaceValue; + #endif + +- // Step 14.l.ii. ++ // Step 14.m.ii. + accumulatedResult += Substring(S, nextSourcePosition, + position - nextSourcePosition) + replacement; + +- // Step 14.l.iii. ++ // Step 14.m.iii. + nextSourcePosition = lastIndex; + + // Step 11.c.iii.2. +diff -Nrup mozilla/js/src/builtin/RegExpLocalReplaceOpt.h.js mozilla-OK/js/src/builtin/RegExpLocalReplaceOpt.h.js +--- mozilla/js/src/builtin/RegExpLocalReplaceOpt.h.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/RegExpLocalReplaceOpt.h.js 2023-02-27 07:42:05.795721506 +0300 +@@ -91,7 +91,7 @@ function FUNC_NAME(rx, S, lengthS, repla + // Step 14.e-f. + var position = result.index; + +- // Step 14.l.iii (reordered) ++ // Step 14.m.iii (reordered) + // To set rx.lastIndex before RegExpGetFunctionalReplacement. + var nextSourcePosition = position + matchLength; + #else +@@ -109,16 +109,23 @@ function FUNC_NAME(rx, S, lengthS, repla + rx.lastIndex = nextSourcePosition; + + var replacement; +- // Steps g-j. ++ // Steps g-l. + #if defined(FUNCTIONAL) + replacement = RegExpGetFunctionalReplacement(result, S, position, replaceValue); + #elif defined(SUBSTITUTION) +- replacement = RegExpGetSubstitution(result, S, position, replaceValue, firstDollarIndex); ++ // Step l.i ++ var namedCaptures = result.groups; ++ if (namedCaptures !== undefined) { ++ namedCaptures = ToObject(namedCaptures); ++ } ++ // Step l.ii ++ replacement = RegExpGetSubstitution(result, S, position, replaceValue, firstDollarIndex, ++ namedCaptures); + #else + replacement = replaceValue; + #endif + +- // Step 14.l.ii. ++ // Step 14.m.ii. + var accumulatedResult = Substring(S, 0, position) + replacement; + + // Step 15. +diff -Nrup mozilla/js/src/builtin/SelfHostingDefines.h mozilla-OK/js/src/builtin/SelfHostingDefines.h +--- mozilla/js/src/builtin/SelfHostingDefines.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/SelfHostingDefines.h 2023-02-27 07:46:51.295696327 +0300 +@@ -99,6 +99,16 @@ + #define REGEXP_MULTILINE_FLAG 0x04 + #define REGEXP_STICKY_FLAG 0x08 + #define REGEXP_UNICODE_FLAG 0x10 ++#define REGEXP_DOTALL_FLAG 0x20 ++ ++#define REGEXP_STRING_ITERATOR_REGEXP_SLOT 0 ++#define REGEXP_STRING_ITERATOR_STRING_SLOT 1 ++#define REGEXP_STRING_ITERATOR_SOURCE_SLOT 2 ++#define REGEXP_STRING_ITERATOR_FLAGS_SLOT 3 ++#define REGEXP_STRING_ITERATOR_LASTINDEX_SLOT 4 ++ ++#define REGEXP_STRING_ITERATOR_LASTINDEX_DONE -1 ++#define REGEXP_STRING_ITERATOR_LASTINDEX_SLOW -2 + + #define MODULE_OBJECT_ENVIRONMENT_SLOT 1 + #define MODULE_OBJECT_STATUS_SLOT 3 +diff -Nrup mozilla/js/src/builtin/String.js mozilla-OK/js/src/builtin/String.js +--- mozilla/js/src/builtin/String.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/String.js 2023-02-27 07:57:08.968316921 +0300 +@@ -62,6 +62,49 @@ function String_generic_match(thisValue, + return callFunction(String_match, thisValue, regexp); + } + ++// String.prototype.matchAll proposal. ++// ++// String.prototype.matchAll ( regexp ) ++function String_matchAll(regexp) { ++ // Step 1. ++ RequireObjectCoercible(this); ++ ++ // Step 2. ++ if (regexp !== undefined && regexp !== null) { ++ // Steps 2.a-b. ++ if (IsRegExp(regexp)) { ++ // Step 2.b.i. ++ var flags = regexp.flags; ++ ++ // Step 2.b.ii. ++ if (flags === undefined || flags === null) { ++ ThrowTypeError(JSMSG_FLAGS_UNDEFINED_OR_NULL); ++ } ++ ++ // Step 2.b.iii. ++ if (!callFunction(std_String_includes, ToString(flags), "g")) { ++ ThrowTypeError(JSMSG_REQUIRES_GLOBAL_REGEXP, "matchAll"); ++ } ++ } ++ ++ // Step 2.c. ++ var matcher = GetMethod(regexp, std_matchAll); ++ ++ // Step 2.d. ++ if (matcher !== undefined) ++ return callContentFunction(matcher, regexp, this); ++ } ++ ++ // Step 3. ++ var string = ToString(this); ++ ++ // Step 4. ++ var rx = RegExpCreate(regexp, "g"); ++ ++ // Step 5. ++ return callContentFunction(GetMethod(rx, std_matchAll), rx, string); ++} ++ + /** + * A helper function implementing the logic for both String.prototype.padStart + * and String.prototype.padEnd as described in ES7 Draft March 29, 2016 +diff -Nrup mozilla/js/src/builtin/TestingFunctions.cpp mozilla-OK/js/src/builtin/TestingFunctions.cpp +--- mozilla/js/src/builtin/TestingFunctions.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/TestingFunctions.cpp 2023-02-27 07:59:18.117401248 +0300 +@@ -30,13 +30,11 @@ + #include "builtin/SelfHostingDefines.h" + #ifdef DEBUG + #include "frontend/TokenStream.h" +-#include "irregexp/RegExpAST.h" +-#include "irregexp/RegExpEngine.h" +-#include "irregexp/RegExpParser.h" + #endif + #include "jit/InlinableNatives.h" + #include "js/Debug.h" + #include "js/HashTable.h" ++#include "js/RegExpFlags.h" + #include "js/StructuredClone.h" + #include "js/UbiNode.h" + #include "js/UbiNodeBreadthFirst.h" +@@ -71,6 +69,9 @@ using namespace js; + using mozilla::ArrayLength; + using mozilla::Move; + ++using JS::RegExpFlag; ++using JS::RegExpFlags; ++ + // If fuzzingSafe is set, remove functionality that could cause problems with + // fuzzers. Set this via the environment variable MOZ_FUZZING_SAFE. + static mozilla::Atomic fuzzingSafe(false); +@@ -4405,372 +4406,6 @@ GetModuleEnvironmentValue(JSContext* cx, + return true; + } + +-#ifdef DEBUG +-static const char* +-AssertionTypeToString(irregexp::RegExpAssertion::AssertionType type) +-{ +- switch (type) { +- case irregexp::RegExpAssertion::START_OF_LINE: +- return "START_OF_LINE"; +- case irregexp::RegExpAssertion::START_OF_INPUT: +- return "START_OF_INPUT"; +- case irregexp::RegExpAssertion::END_OF_LINE: +- return "END_OF_LINE"; +- case irregexp::RegExpAssertion::END_OF_INPUT: +- return "END_OF_INPUT"; +- case irregexp::RegExpAssertion::BOUNDARY: +- return "BOUNDARY"; +- case irregexp::RegExpAssertion::NON_BOUNDARY: +- return "NON_BOUNDARY"; +- case irregexp::RegExpAssertion::NOT_AFTER_LEAD_SURROGATE: +- return "NOT_AFTER_LEAD_SURROGATE"; +- case irregexp::RegExpAssertion::NOT_IN_SURROGATE_PAIR: +- return "NOT_IN_SURROGATE_PAIR"; +- } +- MOZ_CRASH("unexpected AssertionType"); +-} +- +-static JSObject* +-ConvertRegExpTreeToObject(JSContext* cx, irregexp::RegExpTree* tree) +-{ +- RootedObject obj(cx, JS_NewPlainObject(cx)); +- if (!obj) +- return nullptr; +- +- auto IntProp = [](JSContext* cx, HandleObject obj, +- const char* name, int32_t value) { +- RootedValue val(cx, Int32Value(value)); +- return JS_SetProperty(cx, obj, name, val); +- }; +- +- auto BooleanProp = [](JSContext* cx, HandleObject obj, +- const char* name, bool value) { +- RootedValue val(cx, BooleanValue(value)); +- return JS_SetProperty(cx, obj, name, val); +- }; +- +- auto StringProp = [](JSContext* cx, HandleObject obj, +- const char* name, const char* value) { +- RootedString valueStr(cx, JS_NewStringCopyZ(cx, value)); +- if (!valueStr) +- return false; +- +- RootedValue val(cx, StringValue(valueStr)); +- return JS_SetProperty(cx, obj, name, val); +- }; +- +- auto ObjectProp = [](JSContext* cx, HandleObject obj, +- const char* name, HandleObject value) { +- RootedValue val(cx, ObjectValue(*value)); +- return JS_SetProperty(cx, obj, name, val); +- }; +- +- auto CharVectorProp = [](JSContext* cx, HandleObject obj, +- const char* name, const irregexp::CharacterVector& data) { +- RootedString valueStr(cx, JS_NewUCStringCopyN(cx, data.begin(), data.length())); +- if (!valueStr) +- return false; +- +- RootedValue val(cx, StringValue(valueStr)); +- return JS_SetProperty(cx, obj, name, val); +- }; +- +- auto TreeProp = [&ObjectProp](JSContext* cx, HandleObject obj, +- const char* name, irregexp::RegExpTree* tree) { +- RootedObject treeObj(cx, ConvertRegExpTreeToObject(cx, tree)); +- if (!treeObj) +- return false; +- return ObjectProp(cx, obj, name, treeObj); +- }; +- +- auto TreeVectorProp = [&ObjectProp](JSContext* cx, HandleObject obj, +- const char* name, +- const irregexp::RegExpTreeVector& nodes) { +- size_t len = nodes.length(); +- RootedObject array(cx, JS_NewArrayObject(cx, len)); +- if (!array) +- return false; +- +- for (size_t i = 0; i < len; i++) { +- RootedObject child(cx, ConvertRegExpTreeToObject(cx, nodes[i])); +- if (!child) +- return false; +- +- RootedValue childVal(cx, ObjectValue(*child)); +- if (!JS_SetElement(cx, array, i, childVal)) +- return false; +- } +- return ObjectProp(cx, obj, name, array); +- }; +- +- auto CharRangesProp = [&ObjectProp](JSContext* cx, HandleObject obj, +- const char* name, +- const irregexp::CharacterRangeVector& ranges) { +- size_t len = ranges.length(); +- RootedObject array(cx, JS_NewArrayObject(cx, len)); +- if (!array) +- return false; +- +- for (size_t i = 0; i < len; i++) { +- const irregexp::CharacterRange& range = ranges[i]; +- RootedObject rangeObj(cx, JS_NewPlainObject(cx)); +- if (!rangeObj) +- return false; +- +- auto CharProp = [](JSContext* cx, HandleObject obj, +- const char* name, char16_t c) { +- RootedString valueStr(cx, JS_NewUCStringCopyN(cx, &c, 1)); +- if (!valueStr) +- return false; +- RootedValue val(cx, StringValue(valueStr)); +- return JS_SetProperty(cx, obj, name, val); +- }; +- +- if (!CharProp(cx, rangeObj, "from", range.from())) +- return false; +- if (!CharProp(cx, rangeObj, "to", range.to())) +- return false; +- +- RootedValue rangeVal(cx, ObjectValue(*rangeObj)); +- if (!JS_SetElement(cx, array, i, rangeVal)) +- return false; +- } +- return ObjectProp(cx, obj, name, array); +- }; +- +- auto ElemProp = [&ObjectProp](JSContext* cx, HandleObject obj, +- const char* name, const irregexp::TextElementVector& elements) { +- size_t len = elements.length(); +- RootedObject array(cx, JS_NewArrayObject(cx, len)); +- if (!array) +- return false; +- +- for (size_t i = 0; i < len; i++) { +- const irregexp::TextElement& element = elements[i]; +- RootedObject elemTree(cx, ConvertRegExpTreeToObject(cx, element.tree())); +- if (!elemTree) +- return false; +- +- RootedValue elemTreeVal(cx, ObjectValue(*elemTree)); +- if (!JS_SetElement(cx, array, i, elemTreeVal)) +- return false; +- } +- return ObjectProp(cx, obj, name, array); +- }; +- +- if (tree->IsDisjunction()) { +- if (!StringProp(cx, obj, "type", "Disjunction")) +- return nullptr; +- irregexp::RegExpDisjunction* t = tree->AsDisjunction(); +- if (!TreeVectorProp(cx, obj, "alternatives", t->alternatives())) +- return nullptr; +- return obj; +- } +- if (tree->IsAlternative()) { +- if (!StringProp(cx, obj, "type", "Alternative")) +- return nullptr; +- irregexp::RegExpAlternative* t = tree->AsAlternative(); +- if (!TreeVectorProp(cx, obj, "nodes", t->nodes())) +- return nullptr; +- return obj; +- } +- if (tree->IsAssertion()) { +- if (!StringProp(cx, obj, "type", "Assertion")) +- return nullptr; +- irregexp::RegExpAssertion* t = tree->AsAssertion(); +- if (!StringProp(cx, obj, "assertion_type", AssertionTypeToString(t->assertion_type()))) +- return nullptr; +- return obj; +- } +- if (tree->IsCharacterClass()) { +- if (!StringProp(cx, obj, "type", "CharacterClass")) +- return nullptr; +- irregexp::RegExpCharacterClass* t = tree->AsCharacterClass(); +- if (!BooleanProp(cx, obj, "is_negated", t->is_negated())) +- return nullptr; +- LifoAlloc* alloc = &cx->tempLifoAlloc(); +- if (!CharRangesProp(cx, obj, "ranges", t->ranges(alloc))) +- return nullptr; +- return obj; +- } +- if (tree->IsAtom()) { +- if (!StringProp(cx, obj, "type", "Atom")) +- return nullptr; +- irregexp::RegExpAtom* t = tree->AsAtom(); +- if (!CharVectorProp(cx, obj, "data", t->data())) +- return nullptr; +- return obj; +- } +- if (tree->IsText()) { +- if (!StringProp(cx, obj, "type", "Text")) +- return nullptr; +- irregexp::RegExpText* t = tree->AsText(); +- if (!ElemProp(cx, obj, "elements", t->elements())) +- return nullptr; +- return obj; +- } +- if (tree->IsQuantifier()) { +- if (!StringProp(cx, obj, "type", "Quantifier")) +- return nullptr; +- irregexp::RegExpQuantifier* t = tree->AsQuantifier(); +- if (!IntProp(cx, obj, "min", t->min())) +- return nullptr; +- if (!IntProp(cx, obj, "max", t->max())) +- return nullptr; +- if (!StringProp(cx, obj, "quantifier_type", +- t->is_possessive() ? "POSSESSIVE" +- : t->is_non_greedy() ? "NON_GREEDY" +- : "GREEDY")) +- return nullptr; +- if (!TreeProp(cx, obj, "body", t->body())) +- return nullptr; +- return obj; +- } +- if (tree->IsCapture()) { +- if (!StringProp(cx, obj, "type", "Capture")) +- return nullptr; +- irregexp::RegExpCapture* t = tree->AsCapture(); +- if (!IntProp(cx, obj, "index", t->index())) +- return nullptr; +- if (!TreeProp(cx, obj, "body", t->body())) +- return nullptr; +- return obj; +- } +- if (tree->IsLookahead()) { +- if (!StringProp(cx, obj, "type", "Lookahead")) +- return nullptr; +- irregexp::RegExpLookahead* t = tree->AsLookahead(); +- if (!BooleanProp(cx, obj, "is_positive", t->is_positive())) +- return nullptr; +- if (!TreeProp(cx, obj, "body", t->body())) +- return nullptr; +- return obj; +- } +- if (tree->IsBackReference()) { +- if (!StringProp(cx, obj, "type", "BackReference")) +- return nullptr; +- irregexp::RegExpBackReference* t = tree->AsBackReference(); +- if (!IntProp(cx, obj, "index", t->index())) +- return nullptr; +- return obj; +- } +- if (tree->IsEmpty()) { +- if (!StringProp(cx, obj, "type", "Empty")) +- return nullptr; +- return obj; +- } +- +- MOZ_CRASH("unexpected RegExpTree type"); +-} +- +-static bool +-ParseRegExp(JSContext* cx, unsigned argc, Value* vp) +-{ +- CallArgs args = CallArgsFromVp(argc, vp); +- RootedObject callee(cx, &args.callee()); +- +- if (args.length() == 0) { +- ReportUsageErrorASCII(cx, callee, "Wrong number of arguments"); +- return false; +- } +- +- if (!args[0].isString()) { +- ReportUsageErrorASCII(cx, callee, "First argument must be a String"); +- return false; +- } +- +- RegExpFlag flags = RegExpFlag(0); +- if (!args.get(1).isUndefined()) { +- if (!args.get(1).isString()) { +- ReportUsageErrorASCII(cx, callee, "Second argument, if present, must be a String"); +- return false; +- } +- RootedString flagStr(cx, args[1].toString()); +- if (!ParseRegExpFlags(cx, flagStr, &flags)) +- return false; +- } +- +- bool match_only = false; +- if (!args.get(2).isUndefined()) { +- if (!args.get(2).isBoolean()) { +- ReportUsageErrorASCII(cx, callee, "Third argument, if present, must be a Boolean"); +- return false; +- } +- match_only = args[2].toBoolean(); +- } +- +- RootedAtom pattern(cx, AtomizeString(cx, args[0].toString())); +- if (!pattern) +- return false; +- +- CompileOptions options(cx); +- frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); +- +- irregexp::RegExpCompileData data; +- if (!irregexp::ParsePattern(dummyTokenStream, cx->tempLifoAlloc(), pattern, +- flags & MultilineFlag, match_only, +- flags & UnicodeFlag, flags & IgnoreCaseFlag, +- flags & GlobalFlag, flags & StickyFlag, +- &data)) +- { +- return false; +- } +- +- RootedObject obj(cx, ConvertRegExpTreeToObject(cx, data.tree)); +- if (!obj) +- return false; +- +- args.rval().setObject(*obj); +- return true; +-} +- +-static bool +-DisRegExp(JSContext* cx, unsigned argc, Value* vp) +-{ +- CallArgs args = CallArgsFromVp(argc, vp); +- RootedObject callee(cx, &args.callee()); +- +- if (args.length() == 0) { +- ReportUsageErrorASCII(cx, callee, "Wrong number of arguments"); +- return false; +- } +- +- if (!args[0].isObject() || !args[0].toObject().is()) { +- ReportUsageErrorASCII(cx, callee, "First argument must be a RegExp"); +- return false; +- } +- +- Rooted reobj(cx, &args[0].toObject().as()); +- +- bool match_only = false; +- if (!args.get(1).isUndefined()) { +- if (!args.get(1).isBoolean()) { +- ReportUsageErrorASCII(cx, callee, "Second argument, if present, must be a Boolean"); +- return false; +- } +- match_only = args[1].toBoolean(); +- } +- +- RootedLinearString input(cx, cx->runtime()->emptyString); +- if (!args.get(2).isUndefined()) { +- if (!args.get(2).isString()) { +- ReportUsageErrorASCII(cx, callee, "Third argument, if present, must be a String"); +- return false; +- } +- RootedString inputStr(cx, args[2].toString()); +- input = inputStr->ensureLinear(cx); +- if (!input) +- return false; +- } +- +- if (!RegExpObject::dumpBytecode(cx, reobj, match_only, input)) +- return false; +- +- args.rval().setUndefined(); +- return true; +-} +-#endif // DEBUG +- + static bool + EnableForEach(JSContext* cx, unsigned argc, Value* vp) + { +@@ -5683,16 +5318,6 @@ gc::ZealModeHelpText), + }; + + static const JSFunctionSpecWithHelp FuzzingUnsafeTestingFunctions[] = { +-#ifdef DEBUG +- JS_FN_HELP("parseRegExp", ParseRegExp, 3, 0, +-"parseRegExp(pattern[, flags[, match_only])", +-" Parses a RegExp pattern and returns a tree, potentially throwing."), +- +- JS_FN_HELP("disRegExp", DisRegExp, 3, 0, +-"disRegExp(regexp[, match_only[, input]])", +-" Dumps RegExp bytecode."), +-#endif +- + JS_FN_HELP("getErrorNotes", GetErrorNotes, 1, 0, + "getErrorNotes(error)", + " Returns an array of error notes."), +diff -Nrup mozilla/js/src/builtin/intl/RelativeTimeFormat.cpp mozilla-OK/js/src/builtin/intl/RelativeTimeFormat.cpp +--- mozilla/js/src/builtin/intl/RelativeTimeFormat.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/builtin/intl/RelativeTimeFormat.cpp 2023-02-27 07:32:34.259776233 +0300 +@@ -128,7 +128,7 @@ RelativeTimeFormat(JSContext* cx, unsign + void + js::RelativeTimeFormatObject::finalize(FreeOp* fop, JSObject* obj) + { +- MOZ_ASSERT(fop->onActiveCooperatingThread()); ++ MOZ_ASSERT(fop->onMainThread()); + + constexpr auto RT_FORMAT_SLOT = RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT; + const Value& slot = obj->as().getReservedSlot(RT_FORMAT_SLOT); +diff -Nrup mozilla/js/src/devtools/rootAnalysis/annotations.js mozilla-OK/js/src/devtools/rootAnalysis/annotations.js +--- mozilla/js/src/devtools/rootAnalysis/annotations.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/devtools/rootAnalysis/annotations.js 2023-02-27 07:34:10.654092382 +0300 +@@ -248,6 +248,9 @@ var ignoreFunctions = { + "uint8 nsContentUtils::IsExpandedPrincipal(nsIPrincipal*)" : true, + + "void mozilla::AutoProfilerLabel::~AutoProfilerLabel(int32)" : true, ++ ++ // Calls MergeSort ++ "uint8 v8::internal::RegExpDisjunction::SortConsecutiveAtoms(v8::internal::RegExpCompiler*)": true, + }; + + function extraGCFunctions() { +@@ -274,6 +277,12 @@ function isGTest(name) + return name.match(/\btesting::/); + } + ++function isICU(name) ++{ ++ return name.match(/\bicu_\d+::/) || ++ name.match(/u(prv_malloc|prv_realloc|prv_free|case_toFullLower)_\d+/) ++} ++ + function ignoreGCFunction(mangled) + { + assert(mangled in readableNames, mangled + " not in readableNames"); +@@ -284,8 +293,9 @@ function ignoreGCFunction(mangled) + + // The protobuf library, and [de]serialization code generated by the + // protobuf compiler, uses a _ton_ of function pointers but they are all +- // internal. Easiest to just ignore that mess here. +- if (isProtobuf(fun)) ++ // internal. The same is true for ICU. Easiest to just ignore that mess ++ // here. ++ if (isProtobuf(fun) || isICU(fun)) + return true; + + // Ignore anything that goes through heap snapshot GTests or mocked classes +diff -Nrup mozilla/js/src/frontend/Parser.cpp mozilla-OK/js/src/frontend/Parser.cpp +--- mozilla/js/src/frontend/Parser.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/frontend/Parser.cpp 2023-02-27 08:03:52.217458122 +0300 +@@ -35,7 +35,8 @@ + #include "frontend/BytecodeCompiler.h" + #include "frontend/FoldConstants.h" + #include "frontend/TokenStream.h" +-#include "irregexp/RegExpParser.h" ++#include "irregexp/RegExpAPI.h" ++#include "js/RegExpFlags.h" + #include "vm/RegExpObject.h" + #include "wasm/AsmJS.h" + +@@ -56,6 +57,7 @@ using mozilla::PodZero; + using mozilla::Some; + + using JS::AutoGCRooter; ++using JS::RegExpFlags; + + namespace js { + namespace frontend { +@@ -9197,7 +9199,7 @@ Parser::newRegE + // Create the regexp and check its syntax. + const CharT* chars = tokenStream.getTokenbuf().begin(); + size_t length = tokenStream.getTokenbuf().length(); +- RegExpFlag flags = anyChars.currentToken().regExpFlags(); ++ RegExpFlags flags = anyChars.currentToken().regExpFlags(); + + Rooted reobj(context); + reobj = RegExpObject::create(context, chars, length, flags, anyChars, alloc, TenuredObject); +@@ -9219,12 +9221,12 @@ Parser::newRe + // Only check the regexp's syntax, but don't create a regexp object. + const CharT* chars = tokenStream.getTokenbuf().begin(); + size_t length = tokenStream.getTokenbuf().length(); +- RegExpFlag flags = anyChars.currentToken().regExpFlags(); ++ RegExpFlags flags = anyChars.currentToken().regExpFlags(); + + mozilla::Range source(chars, length); +- if (!js::irregexp::ParsePatternSyntax(anyChars, alloc, source, flags & UnicodeFlag)) +- return null(); +- ++ if (!irregexp::CheckPatternSyntax(context, anyChars, source, flags)) { ++ return null(); ++ } + return handler.newRegExp(SyntaxParseHandler::NodeGeneric, pos(), *this); + } + +diff -Nrup mozilla/js/src/frontend/TokenStream.cpp mozilla-OK/js/src/frontend/TokenStream.cpp +--- mozilla/js/src/frontend/TokenStream.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/frontend/TokenStream.cpp 2023-02-27 07:04:13.330911860 +0300 +@@ -27,6 +27,7 @@ + #include "frontend/Parser.h" + #include "frontend/ReservedWords.h" + #include "js/CharacterEncoding.h" ++#include "js/RegExpFlags.h" // JS::RegExpFlags + #include "js/UniquePtr.h" + #include "vm/HelperThreads.h" + #include "vm/StringBuffer.h" +@@ -39,6 +40,9 @@ using mozilla::PodAssign; + using mozilla::PodCopy; + using mozilla::PodZero; + ++using JS::RegExpFlag; ++using JS::RegExpFlags; ++ + struct ReservedWordInfo + { + const char* chars; // C string with reserved word text +@@ -2027,21 +2031,23 @@ TokenStreamSpecific + { +@@ -1587,6 +1585,12 @@ class MOZ_STACK_CLASS TokenStream final + {} + }; + ++class MOZ_STACK_CLASS DummyTokenStream final : public TokenStream { ++ public: ++ DummyTokenStream(JSContext* cx, const JS::ReadOnlyCompileOptions& options) ++ : TokenStream(cx, options, nullptr, 0, nullptr) {} ++}; ++ + template + /* static */ inline TokenStreamAnyChars& + TokenStreamAnyCharsAccess::anyChars(TokenStreamSpecific* tss) +diff -Nrup mozilla/js/src/irregexp/IRREGEXP_VERSION mozilla-OK/js/src/irregexp/IRREGEXP_VERSION +--- mozilla/js/src/irregexp/IRREGEXP_VERSION 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/IRREGEXP_VERSION 2023-02-27 08:17:24.841702693 +0300 +@@ -0,0 +1,2 @@ ++Imported using import-irregexp.py from: ++https://github.com/v8/v8/tree/8732b2ee52b567ad4e15ca91d141fd6e27499e99/src/regexp +diff -Nrup mozilla/js/src/irregexp/RegExpAPI.cpp mozilla-OK/js/src/irregexp/RegExpAPI.cpp +--- mozilla/js/src/irregexp/RegExpAPI.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpAPI.cpp 2023-02-27 08:17:58.256466040 +0300 +@@ -0,0 +1,703 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++// Copyright 2020 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#include "irregexp/RegExpAPI.h" ++ ++#include "mozilla/ArrayUtils.h" ++#include "mozilla/Casting.h" ++ ++#include "irregexp/imported/regexp-ast.h" ++#include "irregexp/imported/regexp-bytecode-generator.h" ++#include "irregexp/imported/regexp-compiler.h" ++#include "irregexp/imported/regexp-interpreter.h" ++#include "irregexp/imported/regexp-macro-assembler-arch.h" ++#include "irregexp/imported/regexp-parser.h" ++#include "irregexp/imported/regexp-stack.h" ++#include "irregexp/imported/regexp.h" ++#include "irregexp/RegExpShim.h" ++#include "jit/JitCommon.h" ++ ++#include "util/Text.h" ++#include "vm/ErrorReporting.h" ++#include "vm/MatchPairs.h" ++#include "vm/RegExpShared.h" ++#include "vm/StringBuffer.h" ++ ++namespace js { ++namespace irregexp { ++ ++using namespace mozilla; ++ ++using frontend::DummyTokenStream; ++using frontend::TokenStreamAnyChars; ++ ++using v8::internal::DisallowGarbageCollection; ++using v8::internal::FlatStringReader; ++using v8::internal::HandleScope; ++using v8::internal::InputOutputData; ++using v8::internal::IrregexpInterpreter; ++using v8::internal::NativeRegExpMacroAssembler; ++using v8::internal::RegExpBytecodeGenerator; ++using v8::internal::RegExpCompileData; ++using v8::internal::RegExpCompiler; ++using v8::internal::RegExpError; ++using v8::internal::RegExpMacroAssembler; ++using v8::internal::RegExpNode; ++using v8::internal::RegExpParser; ++using v8::internal::SMRegExpMacroAssembler; ++using v8::internal::Zone; ++ ++using V8HandleString = v8::internal::Handle; ++using V8HandleRegExp = v8::internal::Handle; ++ ++using namespace v8::internal::regexp_compiler_constants; ++ ++static uint32_t ErrorNumber(RegExpError err) { ++ switch (err) { ++ case RegExpError::kNone: ++ return JSMSG_NOT_AN_ERROR; ++ case RegExpError::kStackOverflow: ++ return JSMSG_OVER_RECURSED; ++ case RegExpError::kAnalysisStackOverflow: ++ return JSMSG_OVER_RECURSED; ++ case RegExpError::kTooLarge: ++ return JSMSG_TOO_MANY_PARENS; ++ case RegExpError::kUnterminatedGroup: ++ return JSMSG_MISSING_PAREN; ++ case RegExpError::kUnmatchedParen: ++ return JSMSG_UNMATCHED_RIGHT_PAREN; ++ case RegExpError::kEscapeAtEndOfPattern: ++ return JSMSG_ESCAPE_AT_END_OF_REGEXP; ++ case RegExpError::kInvalidPropertyName: ++ return JSMSG_INVALID_PROPERTY_NAME; ++ case RegExpError::kInvalidEscape: ++ return JSMSG_INVALID_IDENTITY_ESCAPE; ++ case RegExpError::kInvalidDecimalEscape: ++ return JSMSG_INVALID_DECIMAL_ESCAPE; ++ case RegExpError::kInvalidUnicodeEscape: ++ return JSMSG_INVALID_UNICODE_ESCAPE; ++ case RegExpError::kNothingToRepeat: ++ return JSMSG_NOTHING_TO_REPEAT; ++ case RegExpError::kLoneQuantifierBrackets: ++ // Note: V8 reports the same error for both ']' and '}'. ++ return JSMSG_RAW_BRACKET_IN_REGEXP; ++ case RegExpError::kRangeOutOfOrder: ++ return JSMSG_NUMBERS_OUT_OF_ORDER; ++ case RegExpError::kIncompleteQuantifier: ++ return JSMSG_INCOMPLETE_QUANTIFIER; ++ case RegExpError::kInvalidQuantifier: ++ return JSMSG_INVALID_QUANTIFIER; ++ case RegExpError::kInvalidGroup: ++ return JSMSG_INVALID_GROUP; ++ case RegExpError::kMultipleFlagDashes: ++ case RegExpError::kRepeatedFlag: ++ case RegExpError::kInvalidFlagGroup: ++ // V8 contains experimental support for turning regexp flags on ++ // and off in the middle of a regular expression. Unless it ++ // becomes standardized, SM does not support this feature. ++ MOZ_CRASH("Mode modifiers not supported"); ++ case RegExpError::kNotLinear: ++ // V8 has an experimental non-backtracking engine. We do not ++ // support it yet. ++ MOZ_CRASH("Non-backtracking execution not supported"); ++ case RegExpError::kTooManyCaptures: ++ return JSMSG_TOO_MANY_PARENS; ++ case RegExpError::kInvalidCaptureGroupName: ++ return JSMSG_INVALID_CAPTURE_NAME; ++ case RegExpError::kDuplicateCaptureGroupName: ++ return JSMSG_DUPLICATE_CAPTURE_NAME; ++ case RegExpError::kInvalidNamedReference: ++ return JSMSG_INVALID_NAMED_REF; ++ case RegExpError::kInvalidNamedCaptureReference: ++ return JSMSG_INVALID_NAMED_CAPTURE_REF; ++ case RegExpError::kInvalidClassEscape: ++ return JSMSG_RANGE_WITH_CLASS_ESCAPE; ++ case RegExpError::kInvalidClassPropertyName: ++ return JSMSG_INVALID_CLASS_PROPERTY_NAME; ++ case RegExpError::kInvalidCharacterClass: ++ return JSMSG_RANGE_WITH_CLASS_ESCAPE; ++ case RegExpError::kUnterminatedCharacterClass: ++ return JSMSG_UNTERM_CLASS; ++ case RegExpError::kOutOfOrderCharacterClass: ++ return JSMSG_BAD_CLASS_RANGE; ++ case RegExpError::NumErrors: ++ MOZ_CRASH("Unreachable"); ++ } ++ MOZ_CRASH("Unreachable"); ++} ++ ++Isolate* CreateIsolate(JSContext* cx) { ++ auto isolate = MakeUnique(cx); ++ if (!isolate || !isolate->init()) { ++ return nullptr; ++ } ++ return isolate.release(); ++} ++ ++void DestroyIsolate(Isolate* isolate) { ++ MOZ_ASSERT(isolate->liveHandles() == 0); ++ MOZ_ASSERT(isolate->livePseudoHandles() == 0); ++ js_delete(isolate); ++} ++ ++size_t IsolateSizeOfIncludingThis(Isolate* isolate, ++ mozilla::MallocSizeOf mallocSizeOf) { ++ return isolate->sizeOfIncludingThis(mallocSizeOf); ++} ++ ++static size_t ComputeColumn(const Latin1Char* begin, const Latin1Char* end) { ++ return mozilla::PointerRangeSize(begin, end); ++} ++ ++static size_t ComputeColumn(const char16_t* begin, const char16_t* end) { ++ return unicode::CountCodePoints(begin, end); ++} ++ ++// This function is varargs purely so it can call ReportCompileErrorLatin1. ++// We never call it with additional arguments. ++template ++static void ReportSyntaxError(TokenStreamAnyChars& ts, RegExpCompileData& result, ++ CharT* start, size_t length, ...) { ++ gc::AutoSuppressGC suppressGC(ts.context()); ++ uint32_t errorNumber = ErrorNumber(result.error); ++ ++ if (errorNumber == JSMSG_OVER_RECURSED) { ++ ReportOverRecursed(ts.context()); ++ return; ++ } ++ ++ uint32_t offset = std::max(result.error_pos, 0); ++ MOZ_ASSERT(offset <= length); ++ ++ ErrorMetadata err; ++ ++ // Ordinarily this indicates whether line-of-context information can be ++ // added, but we entirely ignore that here because we create a ++ // a line of context based on the expression source. ++ uint32_t location = ts.currentToken().pos.begin; ++ if (ts.fillExcludingContext(&err, location)) { ++ // Line breaks are not significant in pattern text in the same way as ++ // in source text, so act as though pattern text is a single line, then ++ // compute a column based on "code point" count (treating a lone ++ // surrogate as a "code point" in UTF-16). Gak. ++ err.lineNumber = 1; ++ err.columnNumber = ++ AssertedCast(ComputeColumn(start, start + offset)); ++ } ++ ++ // For most error reporting, the line of context derives from the token ++ // stream. So when location information doesn't come from the token ++ // stream, we can't give a line of context. But here the "line of context" ++ // can be (and is) derived from the pattern text, so we can provide it no ++ // matter if the location is derived from the caller. ++ ++ const CharT* windowStart = ++ (offset > ErrorMetadata::lineOfContextRadius) ++ ? start + (offset - ErrorMetadata::lineOfContextRadius) ++ : start; ++ ++ const CharT* windowEnd = ++ (length - offset > ErrorMetadata::lineOfContextRadius) ++ ? start + offset + ErrorMetadata::lineOfContextRadius ++ : start + length; ++ ++ size_t windowLength = PointerRangeSize(windowStart, windowEnd); ++ MOZ_ASSERT(windowLength <= ErrorMetadata::lineOfContextRadius * 2); ++ ++ // Create the windowed string, not including the potential line ++ // terminator. ++ StringBuffer windowBuf(ts.context()); ++ if (!windowBuf.append(windowStart, windowEnd)) { ++ return; ++ } ++ ++ // The line of context must be null-terminated, and StringBuffer doesn't ++ // make that happen unless we force it to. ++ if (!windowBuf.append('\0')) { ++ return; ++ } ++ ++ err.lineOfContext.reset(windowBuf.stealChars()); ++ if (!err.lineOfContext) { ++ return; ++ } ++ ++ err.lineLength = windowLength; ++ err.tokenOffset = offset - (windowStart - start); ++ ++ va_list args; ++ va_start(args, length); ++ ReportCompileError(ts.context(), std::move(err), nullptr, /* notes/report */ ++ JSREPORT_ERROR, /*flags*/ ++ errorNumber, args); ++ va_end(args); ++} ++ ++static void ReportSyntaxError(TokenStreamAnyChars& ts, RegExpCompileData& result, ++ HandleAtom pattern) { ++ JS::AutoCheckCannotGC nogc_; ++ if (pattern->hasLatin1Chars()) { ++ ReportSyntaxError(ts, result, pattern->latin1Chars(nogc_), ++ pattern->length()); ++ } else { ++ ReportSyntaxError(ts, result, pattern->twoByteChars(nogc_), ++ pattern->length()); ++ } ++} ++ ++static bool CheckPatternSyntaxImpl(JSContext* cx, FlatStringReader* pattern, ++ JS::RegExpFlags flags, ++ RegExpCompileData* result) { ++ LifoAllocScope allocScope(&cx->tempLifoAlloc()); ++ Zone zone(allocScope.alloc()); ++ ++ HandleScope handleScope(cx->isolate); ++ DisallowGarbageCollection no_gc; ++ return RegExpParser::VerifyRegExpSyntax(cx->isolate, &zone, pattern, flags, ++ result, no_gc); ++} ++ ++bool CheckPatternSyntax(JSContext* cx, TokenStreamAnyChars& ts, ++ const mozilla::Range chars, ++ JS::RegExpFlags flags) { ++ FlatStringReader reader(chars); ++ RegExpCompileData result; ++ if (!CheckPatternSyntaxImpl(cx, &reader, flags, &result)) { ++ ReportSyntaxError(ts, result, chars.begin().get(), chars.length()); ++ return false; ++ } ++ return true; ++} ++ ++bool CheckPatternSyntax(JSContext* cx, TokenStreamAnyChars& ts, HandleAtom pattern, ++ JS::RegExpFlags flags) { ++ FlatStringReader reader(cx, pattern); ++ RegExpCompileData result; ++ if (!CheckPatternSyntaxImpl(cx, &reader, flags, &result)) { ++ ReportSyntaxError(ts, result, pattern); ++ return false; ++ } ++ return true; ++} ++ ++// A regexp is a good candidate for Boyer-Moore if it has at least 3 ++// times as many characters as it has unique characters. Note that ++// table lookups in irregexp are done modulo tableSize (128). ++template ++static bool HasFewDifferentCharacters(const CharT* chars, size_t length) { ++ const uint32_t tableSize = ++ v8::internal::NativeRegExpMacroAssembler::kTableSize; ++ bool character_found[tableSize]; ++ uint32_t different = 0; ++ memset(&character_found[0], 0, sizeof(character_found)); ++ for (uint32_t i = 0; i < length; i++) { ++ uint32_t ch = chars[i] % tableSize; ++ if (!character_found[ch]) { ++ character_found[ch] = true; ++ different++; ++ // We declare a regexp low-alphabet if it has at least 3 times as many ++ // characters as it has different characters. ++ if (different * 3 > length) { ++ return false; ++ } ++ } ++ } ++ return true; ++} ++ ++// Identifies the sort of pattern where Boyer-Moore is faster than string search ++static bool UseBoyerMoore(HandleAtom pattern, JS::AutoCheckCannotGC& nogc) { ++ size_t length = ++ std::min(size_t(kMaxLookaheadForBoyerMoore), pattern->length()); ++ if (length <= kPatternTooShortForBoyerMoore) { ++ return false; ++ } ++ ++ if (pattern->hasLatin1Chars()) { ++ return HasFewDifferentCharacters(pattern->latin1Chars(nogc), length); ++ } ++ MOZ_ASSERT(pattern->hasTwoByteChars()); ++ return HasFewDifferentCharacters(pattern->twoByteChars(nogc), length); ++} ++ ++// Sample character frequency information for use in Boyer-Moore. ++static void SampleCharacters(FlatStringReader* sample_subject, ++ RegExpCompiler& compiler) { ++ static const int kSampleSize = 128; ++ int chars_sampled = 0; ++ ++ int length = sample_subject->length(); ++ ++ int half_way = (length - kSampleSize) / 2; ++ for (int i = std::max(0, half_way); i < length && chars_sampled < kSampleSize; ++ i++, chars_sampled++) { ++ compiler.frequency_collator()->CountCharacter(sample_subject->Get(i)); ++ } ++} ++ ++// Recursively walking the AST for a deeply nested regexp (like ++// `/(a(a(a(a(a(a(a(...(a)...))))))))/`) may overflow the stack while ++// compiling. To avoid this, we use V8's implementation of the Visitor ++// pattern to walk the AST first with an overly large stack frame. ++class RegExpDepthCheck final : public v8::internal::RegExpVisitor { ++ public: ++ explicit RegExpDepthCheck(JSContext* cx) : cx_(cx) {} ++ ++ bool check(v8::internal::RegExpTree* root) { ++ return !!root->Accept(this, nullptr); ++ } ++ ++ // Leaf nodes with no children ++#define LEAF_DEPTH(Kind) \ ++ void* Visit##Kind(v8::internal::RegExp##Kind* node, void*) override { \ ++ uint8_t padding[FRAME_PADDING]; \ ++ dummy_ = padding; /* Prevent padding from being optimized away.*/ \ ++ return (void*)CheckRecursionLimitDontReport(cx_); \ ++ } ++ ++ LEAF_DEPTH(Assertion) ++ LEAF_DEPTH(Atom) ++ LEAF_DEPTH(BackReference) ++ LEAF_DEPTH(CharacterClass) ++ LEAF_DEPTH(Empty) ++ LEAF_DEPTH(Text) ++#undef LEAF_DEPTH ++ ++ // Wrapper nodes with one child ++#define WRAPPER_DEPTH(Kind) \ ++ void* Visit##Kind(v8::internal::RegExp##Kind* node, void*) override { \ ++ uint8_t padding[FRAME_PADDING]; \ ++ dummy_ = padding; /* Prevent padding from being optimized away.*/ \ ++ if (!CheckRecursionLimitDontReport(cx_)) { \ ++ return nullptr; \ ++ } \ ++ return node->body()->Accept(this, nullptr); \ ++ } ++ ++ WRAPPER_DEPTH(Capture) ++ WRAPPER_DEPTH(Group) ++ WRAPPER_DEPTH(Lookaround) ++ WRAPPER_DEPTH(Quantifier) ++#undef WRAPPER_DEPTH ++ ++ void* VisitAlternative(v8::internal::RegExpAlternative* node, ++ void*) override { ++ uint8_t padding[FRAME_PADDING]; ++ dummy_ = padding; /* Prevent padding from being optimized away.*/ ++ if (!CheckRecursionLimitDontReport(cx_)) { ++ return nullptr; ++ } ++ for (auto* child : *node->nodes()) { ++ if (!child->Accept(this, nullptr)) { ++ return nullptr; ++ } ++ } ++ return (void*)true; ++ } ++ void* VisitDisjunction(v8::internal::RegExpDisjunction* node, ++ void*) override { ++ uint8_t padding[FRAME_PADDING]; ++ dummy_ = padding; /* Prevent padding from being optimized away.*/ ++ if (!CheckRecursionLimitDontReport(cx_)) { ++ return nullptr; ++ } ++ for (auto* child : *node->alternatives()) { ++ if (!child->Accept(this, nullptr)) { ++ return nullptr; ++ } ++ } ++ return (void*)true; ++ } ++ ++ private: ++ JSContext* cx_; ++ void* dummy_ = nullptr; ++ ++ // This size is picked to be comfortably larger than any ++ // RegExp*::ToNode stack frame. ++ static const size_t FRAME_PADDING = 256; ++}; ++ ++enum class AssembleResult { ++ Success, ++ TooLarge, ++ OutOfMemory, ++}; ++ ++static MOZ_MUST_USE AssembleResult Assemble(JSContext* cx, ++ RegExpCompiler* compiler, ++ RegExpCompileData* data, ++ MutableHandleRegExpShared re, ++ HandleAtom pattern, Zone* zone, ++ bool useNativeCode, bool isLatin1) { ++ // Because we create a StackMacroAssembler, this function is not allowed ++ // to GC. If needed, we allocate and throw errors in the caller. ++ Maybe jctx; ++ Maybe stack_masm; ++ UniquePtr masm; ++ if (useNativeCode) { ++ NativeRegExpMacroAssembler::Mode mode = ++ isLatin1 ? NativeRegExpMacroAssembler::LATIN1 ++ : NativeRegExpMacroAssembler::UC16; ++ // If we are compiling native code, we need a macroassembler, ++ // which needs a jit context. ++ jctx.emplace(cx, nullptr); ++ stack_masm.emplace(); ++ uint32_t num_capture_registers = re->pairCount() * 2; ++ masm = MakeUnique(cx, stack_masm.ref(), zone, mode, ++ num_capture_registers); ++ } else { ++ masm = MakeUnique(cx->isolate, zone); ++ } ++ if (!masm) { ++ return AssembleResult::OutOfMemory; ++ } ++ ++ bool isLargePattern = ++ pattern->length() > v8::internal::RegExp::kRegExpTooLargeToOptimize; ++ masm->set_slow_safe(isLargePattern); ++ if (compiler->optimize()) { ++ compiler->set_optimize(!isLargePattern); ++ } ++ ++ // When matching a regexp with known maximum length that is anchored ++ // at the end, we may be able to skip the beginning of long input ++ // strings. This decision is made here because it depends on ++ // information in the AST that isn't replicated in the Node ++ // structure used inside the compiler. ++ bool is_start_anchored = data->tree->IsAnchoredAtStart(); ++ bool is_end_anchored = data->tree->IsAnchoredAtEnd(); ++ int max_length = data->tree->max_match(); ++ static const int kMaxBacksearchLimit = 1024; ++ if (is_end_anchored && !is_start_anchored && !re->sticky() && ++ max_length < kMaxBacksearchLimit) { ++ masm->SetCurrentPositionFromEnd(max_length); ++ } ++ ++ if (re->global()) { ++ RegExpMacroAssembler::GlobalMode mode = RegExpMacroAssembler::GLOBAL; ++ if (data->tree->min_match() > 0) { ++ mode = RegExpMacroAssembler::GLOBAL_NO_ZERO_LENGTH_CHECK; ++ } else if (re->unicode()) { ++ mode = RegExpMacroAssembler::GLOBAL_UNICODE; ++ } ++ masm->set_global_mode(mode); ++ } ++ ++ // Compile the regexp. ++ V8HandleString wrappedPattern(v8::internal::String(pattern), cx->isolate); ++ RegExpCompiler::CompilationResult result = compiler->Assemble( ++ cx->isolate, masm.get(), data->node, data->capture_count, wrappedPattern); ++ if (!result.Succeeded()) { ++ MOZ_ASSERT(result.error == RegExpError::kTooLarge); ++ return AssembleResult::TooLarge; ++ } ++ if (result.code->value().isUndefined()) { ++ // SMRegExpMacroAssembler::GetCode returns undefined on OOM. ++ MOZ_ASSERT(useNativeCode); ++ return AssembleResult::OutOfMemory; ++ } ++ ++ re->updateMaxRegisters(result.num_registers); ++ if (useNativeCode) { ++ // Transfer ownership of the tables from the macroassembler to the ++ // RegExpShared. ++ SMRegExpMacroAssembler::TableVector& tables = ++ static_cast(masm.get())->tables(); ++ for (uint32_t i = 0; i < tables.length(); i++) { ++ if (!re->addTable(std::move(tables[i]))) { ++ return AssembleResult::OutOfMemory; ++ } ++ } ++ re->setJitCode(v8::internal::Code::cast(*result.code).inner(), isLatin1); ++ } else { ++ // Transfer ownership of the bytecode from the HandleScope to the ++ // RegExpShared. ++ ByteArray bytecode = ++ v8::internal::ByteArray::cast(*result.code).takeOwnership(cx->isolate); ++ uint32_t length = bytecode->length; ++ re->setByteCode(bytecode.release(), isLatin1); ++ // js::AddCellMemory(re, length, MemoryUse::RegExpSharedBytecode); ++ } ++ ++ return AssembleResult::Success; ++} ++ ++bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re, ++ HandleLinearString input, RegExpShared::CodeKind codeKind) { ++ RootedAtom pattern(cx, re->getSource()); ++ JS::RegExpFlags flags = re->getFlags(); ++ LifoAllocScope allocScope(&cx->tempLifoAlloc()); ++ HandleScope handleScope(cx->isolate); ++ Zone zone(allocScope.alloc()); ++ ++ RegExpCompileData data; ++ { ++ FlatStringReader patternBytes(cx, pattern); ++ if (!RegExpParser::ParseRegExp(cx->isolate, &zone, &patternBytes, flags, ++ &data)) { ++ MOZ_ASSERT(data.error == RegExpError::kStackOverflow); ++ JS::CompileOptions options(cx); ++ DummyTokenStream dummyTokenStream(cx, options); ++ ReportSyntaxError(dummyTokenStream, data, pattern); ++ return false; ++ } ++ } ++ ++ // Avoid stack overflow while recursively walking the AST. ++ RegExpDepthCheck depthCheck(cx); ++ if (!depthCheck.check(data.tree)) { ++ JS_ReportErrorASCII(cx, "regexp too big"); ++ return false; ++ } ++ ++ if (re->kind() == RegExpShared::Kind::Unparsed) { ++ // This is the first time we have compiled this regexp. ++ // First, check to see if we should use simple string search ++ // with an atom. ++ if (!flags.ignoreCase() && !flags.sticky()) { ++ RootedAtom searchAtom(cx); ++ if (data.simple) { ++ // The parse-tree is a single atom that is equal to the pattern. ++ searchAtom = re->getSource(); ++ } else if (data.tree->IsAtom() && data.capture_count == 0) { ++ // The parse-tree is a single atom that is not equal to the pattern. ++ v8::internal::RegExpAtom* atom = data.tree->AsAtom(); ++ const char16_t* twoByteChars = atom->data().begin(); ++ searchAtom = AtomizeChars(cx, twoByteChars, atom->length()); ++ if (!searchAtom) { ++ return false; ++ } ++ } ++ JS::AutoCheckCannotGC nogc(cx); ++ if (searchAtom && !UseBoyerMoore(searchAtom, nogc)) { ++ re->useAtomMatch(searchAtom); ++ return true; ++ } ++ } ++ if (!data.capture_name_map.is_null()) { ++ RootedNativeObject namedCaptures(cx, data.capture_name_map->inner()); ++ if (!RegExpShared::initializeNamedCaptures(cx, re, namedCaptures)) { ++ return false; ++ } ++ } ++ // All fallible initialization has succeeded, so we can change state. ++ // Add one to capture_count to account for the whole-match capture. ++ uint32_t pairCount = data.capture_count + 1; ++ re->useRegExpMatch(pairCount); ++ } ++ ++ MOZ_ASSERT(re->kind() == RegExpShared::Kind::RegExp); ++ ++ RegExpCompiler compiler(cx->isolate, &zone, data.capture_count, ++ input->hasLatin1Chars()); ++ ++ bool isLatin1 = input->hasLatin1Chars(); ++ ++ FlatStringReader sample_subject(cx, input); ++ SampleCharacters(&sample_subject, compiler); ++ data.node = compiler.PreprocessRegExp(&data, flags, isLatin1); ++ data.error = AnalyzeRegExp(cx->isolate, isLatin1, data.node); ++ if (data.error != RegExpError::kNone) { ++ MOZ_ASSERT(data.error == RegExpError::kAnalysisStackOverflow); ++ ReportOverRecursed(cx); ++ return false; ++ } ++ ++ bool useNativeCode = codeKind == RegExpShared::CodeKind::Jitcode; ++ MOZ_ASSERT_IF(useNativeCode, IsNativeRegExpEnabled(cx)); ++ ++ switch (Assemble(cx, &compiler, &data, re, pattern, &zone, useNativeCode, ++ isLatin1)) { ++ case AssembleResult::TooLarge: ++ JS_ReportErrorASCII(cx, "regexp too big"); ++ return false; ++ case AssembleResult::OutOfMemory: ++ ReportOutOfMemory(cx); ++ return false; ++ case AssembleResult::Success: ++ break; ++ } ++ return true; ++} ++ ++template ++RegExpRunStatus ExecuteRaw(jit::JitCode* code, const CharT* chars, ++ size_t length, size_t startIndex, ++ MatchPairs* matches) { ++ InputOutputData data(chars, chars + length, startIndex, matches); ++ ++ static_assert(RegExpRunStatus_Error == ++ v8::internal::RegExp::kInternalRegExpException); ++ static_assert(RegExpRunStatus_Success == ++ v8::internal::RegExp::kInternalRegExpSuccess); ++ static_assert(RegExpRunStatus_Success_NotFound == ++ v8::internal::RegExp::kInternalRegExpFailure); ++ ++ typedef int (*RegExpCodeSignature)(InputOutputData*); ++ auto function = reinterpret_cast(code->raw()); ++ { ++ JS::AutoSuppressGCAnalysis nogc; ++ return (RegExpRunStatus)CALL_GENERATED_1(function, &data); ++ } ++} ++ ++RegExpRunStatus Interpret(JSContext* cx, MutableHandleRegExpShared re, ++ HandleLinearString input, size_t startIndex, ++ MatchPairs* matches) { ++ MOZ_ASSERT(re->getByteCode(input->hasLatin1Chars())); ++ ++ HandleScope handleScope(cx->isolate); ++ V8HandleRegExp wrappedRegExp(v8::internal::JSRegExp(re), cx->isolate); ++ V8HandleString wrappedInput(v8::internal::String(input), cx->isolate); ++ ++ static_assert(RegExpRunStatus_Error == ++ v8::internal::RegExp::kInternalRegExpException); ++ static_assert(RegExpRunStatus_Success == ++ v8::internal::RegExp::kInternalRegExpSuccess); ++ static_assert(RegExpRunStatus_Success_NotFound == ++ v8::internal::RegExp::kInternalRegExpFailure); ++ ++ RegExpRunStatus status = ++ (RegExpRunStatus)IrregexpInterpreter::MatchForCallFromRuntime( ++ cx->isolate, wrappedRegExp, wrappedInput, matches->pairsRaw(), ++ matches->pairCount() * 2, startIndex); ++ ++ MOZ_ASSERT(status == RegExpRunStatus_Error || ++ status == RegExpRunStatus_Success || ++ status == RegExpRunStatus_Success_NotFound); ++ ++ return status; ++} ++ ++RegExpRunStatus Execute(JSContext* cx, MutableHandleRegExpShared re, ++ HandleLinearString input, size_t startIndex, ++ MatchPairs* matches) { ++ bool latin1 = input->hasLatin1Chars(); ++ jit::JitCode* jitCode = re->getJitCode(latin1); ++ bool isCompiled = !!jitCode; ++ ++ // Reset the Irregexp backtrack stack if it grows during execution. ++ irregexp::RegExpStackScope stackScope(cx->isolate); ++ ++ if (isCompiled) { ++ JS::AutoCheckCannotGC nogc; ++ if (latin1) { ++ return ExecuteRaw(jitCode, input->latin1Chars(nogc), input->length(), ++ startIndex, matches); ++ } ++ return ExecuteRaw(jitCode, input->twoByteChars(nogc), input->length(), ++ startIndex, matches); ++ } ++ ++ return Interpret(cx, re, input, startIndex, matches); ++} ++ ++} // namespace irregexp ++} // namespace js +diff -Nrup mozilla/js/src/irregexp/RegExpAPI.h mozilla-OK/js/src/irregexp/RegExpAPI.h +--- mozilla/js/src/irregexp/RegExpAPI.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpAPI.h 2023-02-27 08:17:58.257466033 +0300 +@@ -0,0 +1,46 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ * ++ * This Source Code Form is "Incompatible With Secondary Licenses", as ++ * defined by the Mozilla Public License, v. 2.0. ++ */ ++ ++/* This is the interface that the regexp engine exposes to SpiderMonkey. */ ++ ++#ifndef regexp_RegExpAPI_h ++#define regexp_RegExpAPI_h ++ ++#include "mozilla/MemoryReporting.h" ++ ++#include "frontend/TokenStream.h" ++#include "jscntxt.h" ++#include "jsgc.h" ++#include "vm/RegExpObject.h" ++ ++namespace js { ++namespace irregexp { ++ ++Isolate* CreateIsolate(JSContext* cx); ++void DestroyIsolate(Isolate* isolate); ++ ++size_t IsolateSizeOfIncludingThis(Isolate* isolate, ++ mozilla::MallocSizeOf mallocSizeOf); ++ ++bool CheckPatternSyntax(JSContext* cx, frontend::TokenStreamAnyChars& ts, ++ const mozilla::Range chars, ++ JS::RegExpFlags flags); ++bool CheckPatternSyntax(JSContext* cx, frontend::TokenStreamAnyChars& ts, ++ HandleAtom pattern, JS::RegExpFlags flags); ++bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re, ++ HandleLinearString input, RegExpShared::CodeKind codeKind); ++ ++RegExpRunStatus Execute(JSContext* cx, MutableHandleRegExpShared re, ++ HandleLinearString input, size_t start, ++ MatchPairs* matches); ++ ++} // namespace irregexp ++} // namespace js ++ ++#endif /* regexp_RegExpAPI_h */ +diff -Nrup mozilla/js/src/irregexp/RegExpNativeMacroAssembler.cpp mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.cpp +--- mozilla/js/src/irregexp/RegExpNativeMacroAssembler.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.cpp 2023-02-27 08:17:24.843702679 +0300 +@@ -0,0 +1,1250 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++// Copyright 2020 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#include "irregexp/imported/regexp-macro-assembler-arch.h" ++#include "irregexp/imported/regexp-stack.h" ++#include "irregexp/imported/special-case.h" ++#include "jit/Linker.h" ++#include "gc/Zone.h" ++#include "vm/MatchPairs.h" ++ ++#include "jit/MacroAssembler-inl.h" ++ ++using namespace js; ++using namespace js::irregexp; ++using namespace js::jit; ++ ++namespace v8 { ++namespace internal { ++ ++using js::MatchPairs; ++using js::jit::AbsoluteAddress; ++using js::jit::Address; ++using js::jit::AllocatableGeneralRegisterSet; ++using js::jit::Assembler; ++using js::jit::BaseIndex; ++using js::jit::CodeLocationLabel; ++using js::jit::GeneralRegisterBackwardIterator; ++using js::jit::GeneralRegisterForwardIterator; ++using js::jit::GeneralRegisterSet; ++using js::jit::Imm32; ++using js::jit::ImmPtr; ++using js::jit::ImmWord; ++using js::jit::JitCode; ++using js::jit::Linker; ++using js::jit::LiveGeneralRegisterSet; ++using js::jit::Register; ++using js::jit::Registers; ++using js::jit::StackMacroAssembler; ++ ++SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, ++ StackMacroAssembler& masm, ++ Zone* zone, Mode mode, ++ uint32_t num_capture_registers) ++ : NativeRegExpMacroAssembler(cx->isolate, zone), ++ cx_(cx), ++ masm_(masm), ++ mode_(mode), ++ num_registers_(num_capture_registers), ++ num_capture_registers_(num_capture_registers) { ++ // Each capture has a start and an end register ++ MOZ_ASSERT(num_capture_registers_ % 2 == 0); ++ ++ AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); ++ ++ temp0_ = regs.takeAny(); ++ temp1_ = regs.takeAny(); ++ temp2_ = regs.takeAny(); ++ input_end_pointer_ = regs.takeAny(); ++ current_character_ = regs.takeAny(); ++ current_position_ = regs.takeAny(); ++ backtrack_stack_pointer_ = regs.takeAny(); ++ savedRegisters_ = js::jit::SavedNonVolatileRegisters(regs); ++ ++ masm_.jump(&entry_label_); // We'll generate the entry code later ++ masm_.bind(&start_label_); // and continue from here. ++} ++ ++int SMRegExpMacroAssembler::stack_limit_slack() { ++ return RegExpStack::kStackLimitSlack; ++} ++ ++void SMRegExpMacroAssembler::AdvanceCurrentPosition(int by) { ++ if (by != 0) { ++ masm_.addPtr(Imm32(by * char_size()), current_position_); ++ } ++} ++ ++void SMRegExpMacroAssembler::AdvanceRegister(int reg, int by) { ++ MOZ_ASSERT(reg >= 0 && reg < num_registers_); ++ if (by != 0) { ++ masm_.addPtr(Imm32(by), register_location(reg)); ++ } ++} ++ ++void SMRegExpMacroAssembler::Backtrack() { ++ // Check for an interrupt. We have to restart from the beginning if we ++ // are interrupted, so we only check for urgent interrupts. ++ js::jit::Label noInterrupt; ++ masm_.branch32(Assembler::Equal, ++ AbsoluteAddress(cx_->addressOfInterruptRegExpJit()), Imm32(0), ++ &noInterrupt); ++ masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); ++ masm_.jump(&exit_label_); ++ masm_.bind(&noInterrupt); ++ ++ // Pop code location from backtrack stack and jump to location. ++ Pop(temp0_); ++ masm_.jump(temp0_); ++} ++ ++void SMRegExpMacroAssembler::Bind(Label* label) { ++ masm_.bind(label->inner()); ++ if (label->patchOffset_.bound()) { ++ AddLabelPatch(label->patchOffset_, label->pos()); ++ } ++} ++ ++// Check if current_position + cp_offset is the input start ++void SMRegExpMacroAssembler::CheckAtStartImpl(int cp_offset, Label* on_cond, ++ Assembler::Condition cond) { ++ Address addr(current_position_, cp_offset * char_size()); ++ masm_.computeEffectiveAddress(addr, temp0_); ++ ++ masm_.branchPtr(cond, inputStart(), temp0_, LabelOrBacktrack(on_cond)); ++} ++ ++void SMRegExpMacroAssembler::CheckAtStart(int cp_offset, Label* on_at_start) { ++ CheckAtStartImpl(cp_offset, on_at_start, Assembler::Equal); ++} ++ ++void SMRegExpMacroAssembler::CheckNotAtStart(int cp_offset, ++ Label* on_not_at_start) { ++ CheckAtStartImpl(cp_offset, on_not_at_start, Assembler::NotEqual); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterImpl(Imm32 c, Label* on_cond, ++ Assembler::Condition cond) { ++ masm_.branch32(cond, current_character_, c, LabelOrBacktrack(on_cond)); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacter(uint32_t c, Label* on_equal) { ++ CheckCharacterImpl(Imm32(c), on_equal, Assembler::Equal); ++} ++ ++void SMRegExpMacroAssembler::CheckNotCharacter(uint32_t c, ++ Label* on_not_equal) { ++ CheckCharacterImpl(Imm32(c), on_not_equal, Assembler::NotEqual); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterGT(uc16 c, Label* on_greater) { ++ CheckCharacterImpl(Imm32(c), on_greater, Assembler::GreaterThan); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterLT(uc16 c, Label* on_less) { ++ CheckCharacterImpl(Imm32(c), on_less, Assembler::LessThan); ++} ++ ++// Bitwise-and the current character with mask and then check for a ++// match with c. ++void SMRegExpMacroAssembler::CheckCharacterAfterAndImpl(uint32_t c, ++ uint32_t mask, ++ Label* on_cond, ++ bool is_not) { ++ if (c == 0) { ++ Assembler::Condition cond = is_not ? Assembler::NonZero : Assembler::Zero; ++ masm_.branchTest32(cond, current_character_, Imm32(mask), ++ LabelOrBacktrack(on_cond)); ++ } else { ++ Assembler::Condition cond = is_not ? Assembler::NotEqual : Assembler::Equal; ++ masm_.move32(Imm32(mask), temp0_); ++ masm_.and32(current_character_, temp0_); ++ masm_.branch32(cond, temp0_, Imm32(c), LabelOrBacktrack(on_cond)); ++ } ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, ++ Label* on_equal) { ++ CheckCharacterAfterAndImpl(c, mask, on_equal, /*is_not =*/false); ++} ++ ++void SMRegExpMacroAssembler::CheckNotCharacterAfterAnd(uint32_t c, ++ uint32_t mask, ++ Label* on_not_equal) { ++ CheckCharacterAfterAndImpl(c, mask, on_not_equal, /*is_not =*/true); ++} ++ ++// Subtract minus from the current character, then bitwise-and the ++// result with mask, then check for a match with c. ++void SMRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd( ++ uc16 c, uc16 minus, uc16 mask, Label* on_not_equal) { ++ masm_.computeEffectiveAddress(Address(current_character_, -minus), temp0_); ++ if (c == 0) { ++ masm_.branchTest32(Assembler::NonZero, temp0_, Imm32(mask), ++ LabelOrBacktrack(on_not_equal)); ++ } else { ++ masm_.and32(Imm32(mask), temp0_); ++ masm_.branch32(Assembler::NotEqual, temp0_, Imm32(c), ++ LabelOrBacktrack(on_not_equal)); ++ } ++} ++ ++// If the current position matches the position stored on top of the backtrack ++// stack, pops the backtrack stack and branches to the given label. ++void SMRegExpMacroAssembler::CheckGreedyLoop(Label* on_equal) { ++ js::jit::Label fallthrough; ++ masm_.branchPtr(Assembler::NotEqual, Address(backtrack_stack_pointer_, 0), ++ current_position_, &fallthrough); ++ masm_.addPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_); // Pop. ++ JumpOrBacktrack(on_equal); ++ masm_.bind(&fallthrough); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterInRangeImpl( ++ uc16 from, uc16 to, Label* on_cond, Assembler::Condition cond) { ++ // x is in [from,to] if unsigned(x - from) <= to - from ++ masm_.computeEffectiveAddress(Address(current_character_, -from), temp0_); ++ masm_.branch32(cond, temp0_, Imm32(to - from), LabelOrBacktrack(on_cond)); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterInRange(uc16 from, uc16 to, ++ Label* on_in_range) { ++ CheckCharacterInRangeImpl(from, to, on_in_range, Assembler::BelowOrEqual); ++} ++ ++void SMRegExpMacroAssembler::CheckCharacterNotInRange(uc16 from, uc16 to, ++ Label* on_not_in_range) { ++ CheckCharacterInRangeImpl(from, to, on_not_in_range, Assembler::Above); ++} ++ ++void SMRegExpMacroAssembler::CheckBitInTable(Handle table, ++ Label* on_bit_set) { ++ // Claim ownership of the ByteArray from the current HandleScope. ++ // ByteArrays are allocated on the C++ heap and are (eventually) ++ // owned by the RegExpShared. ++ PseudoHandle rawTable = table->takeOwnership(isolate()); ++ ++ masm_.movePtr(ImmPtr(rawTable->data()), temp0_); ++ ++ masm_.move32(Imm32(kTableMask), temp1_); ++ masm_.and32(current_character_, temp1_); ++ ++ masm_.load8ZeroExtend(BaseIndex(temp0_, temp1_, js::jit::TimesOne), temp0_); ++ masm_.branchTest32(Assembler::NonZero, temp0_, temp0_, ++ LabelOrBacktrack(on_bit_set)); ++ ++ // Transfer ownership of |rawTable| to the |tables_| vector. ++ AddTable(std::move(rawTable)); ++} ++ ++void SMRegExpMacroAssembler::CheckNotBackReferenceImpl(int start_reg, ++ bool read_backward, ++ bool unicode, ++ Label* on_no_match, ++ bool ignore_case) { ++ js::jit::Label fallthrough; ++ ++ // Captures are stored as a sequential pair of registers. ++ // Find the length of the back-referenced capture and load the ++ // capture's start index into current_character_. ++ masm_.loadPtr(register_location(start_reg), // index of start ++ current_character_); ++ masm_.loadPtr(register_location(start_reg + 1), temp0_); // index of end ++ masm_.subPtr(current_character_, temp0_); // length of capture ++ ++ // Capture registers are either both set or both cleared. ++ // If the capture length is zero, then the capture is either empty or cleared. ++ // Fall through in both cases. ++ masm_.branchPtr(Assembler::Equal, temp0_, ImmWord(0), &fallthrough); ++ ++ // Check that there are sufficient characters left in the input. ++ if (read_backward) { ++ // If start + len > current, there isn't enough room for a ++ // lookbehind backreference. ++ masm_.loadPtr(inputStart(), temp1_); ++ masm_.addPtr(temp0_, temp1_); ++ masm_.branchPtr(Assembler::GreaterThan, temp1_, current_position_, ++ LabelOrBacktrack(on_no_match)); ++ } else { ++ // current_position_ is the negative offset from the end. ++ // If current + len > 0, there isn't enough room for a backreference. ++ masm_.movePtr(current_position_, temp1_); ++ masm_.addPtr(temp0_, temp1_); ++ masm_.branchPtr(Assembler::GreaterThan, temp1_, ImmWord(0), ++ LabelOrBacktrack(on_no_match)); ++ } ++ ++ if (mode_ == UC16 && ignore_case) { ++ // We call a helper function for case-insensitive non-latin1 strings. ++ ++ // Save volatile regs. temp1_, temp2_, and current_character_ ++ // don't need to be saved. current_position_ needs to be saved ++ // even if it's non-volatile, because we modify it to use as an argument. ++ LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile()); ++ volatileRegs.addUnchecked(current_position_); ++ volatileRegs.takeUnchecked(temp1_); ++ volatileRegs.takeUnchecked(temp2_); ++ volatileRegs.takeUnchecked(current_character_); ++ masm_.PushRegsInMask(volatileRegs); ++ ++ // Parameters are ++ // Address captured - Address of captured substring's start. ++ // Address current - Address of current character position. ++ // size_t byte_length - length of capture (in bytes) ++ ++ // Compute |captured| ++ masm_.addPtr(input_end_pointer_, current_character_); ++ ++ // Compute |current| ++ masm_.addPtr(input_end_pointer_, current_position_); ++ if (read_backward) { ++ // Offset by length when matching backwards. ++ masm_.subPtr(temp0_, current_position_); ++ } ++ ++ masm_.setupUnalignedABICall(temp1_); ++ masm_.passABIArg(current_character_); ++ masm_.passABIArg(current_position_); ++ masm_.passABIArg(temp0_); ++ ++ if (unicode) { ++ uint32_t (*fun)(const char16_t*, const char16_t*, size_t) = ++ CaseInsensitiveCompareUnicode; ++ masm_.callWithABI(JS_FUNC_TO_DATA_PTR(void*, fun)); ++ } else { ++ uint32_t (*fun)(const char16_t*, const char16_t*, size_t) = ++ CaseInsensitiveCompareNonUnicode; ++ masm_.callWithABI(JS_FUNC_TO_DATA_PTR(void*, fun)); ++ } ++ masm_.storeCallInt32Result(temp1_); ++ masm_.PopRegsInMask(volatileRegs); ++ masm_.branchTest32(Assembler::Zero, temp1_, temp1_, ++ LabelOrBacktrack(on_no_match)); ++ ++ // On success, advance position by length of capture ++ if (read_backward) { ++ masm_.subPtr(temp0_, current_position_); ++ } else { ++ masm_.addPtr(temp0_, current_position_); ++ } ++ ++ masm_.bind(&fallthrough); ++ return; ++ } ++ ++ // We will be modifying current_position_. Save it in case the match fails. ++ masm_.push(current_position_); ++ ++ // Compute start of capture string ++ masm_.addPtr(input_end_pointer_, current_character_); ++ ++ // Compute start of match string ++ masm_.addPtr(input_end_pointer_, current_position_); ++ if (read_backward) { ++ // Offset by length when matching backwards. ++ masm_.subPtr(temp0_, current_position_); ++ } ++ ++ // Compute end of match string ++ masm_.addPtr(current_position_, temp0_); ++ ++ js::jit::Label success; ++ js::jit::Label fail; ++ js::jit::Label loop; ++ masm_.bind(&loop); ++ ++ // Load next character from each string. ++ if (mode_ == LATIN1) { ++ masm_.load8ZeroExtend(Address(current_character_, 0), temp1_); ++ masm_.load8ZeroExtend(Address(current_position_, 0), temp2_); ++ } else { ++ masm_.load16ZeroExtend(Address(current_character_, 0), temp1_); ++ masm_.load16ZeroExtend(Address(current_position_, 0), temp2_); ++ } ++ ++ if (ignore_case) { ++ MOZ_ASSERT(mode_ == LATIN1); ++ // Try exact match. ++ js::jit::Label loop_increment; ++ masm_.branch32(Assembler::Equal, temp1_, temp2_, &loop_increment); ++ ++ // Mismatch. Try case-insensitive match. ++ // Force the capture character to lower case (by setting bit 0x20) ++ // then check to see if it is a letter. ++ js::jit::Label convert_match; ++ masm_.or32(Imm32(0x20), temp1_); ++ ++ // Check if it is in [a,z]. ++ masm_.computeEffectiveAddress(Address(temp1_, -'a'), temp2_); ++ masm_.branch32(Assembler::BelowOrEqual, temp2_, Imm32('z' - 'a'), ++ &convert_match); ++ // Check for values in range [224,254]. ++ // Exclude 247 (U+00F7 DIVISION SIGN). ++ masm_.sub32(Imm32(224 - 'a'), temp2_); ++ masm_.branch32(Assembler::Above, temp2_, Imm32(254 - 224), &fail); ++ masm_.branch32(Assembler::Equal, temp2_, Imm32(247 - 224), &fail); ++ ++ // Capture character is lower case. Convert match character ++ // to lower case and compare. ++ masm_.bind(&convert_match); ++ masm_.load8ZeroExtend(Address(current_position_, 0), temp2_); ++ masm_.or32(Imm32(0x20), temp2_); ++ masm_.branch32(Assembler::NotEqual, temp1_, temp2_, &fail); ++ ++ masm_.bind(&loop_increment); ++ } else { ++ // Fail if characters do not match. ++ masm_.branch32(Assembler::NotEqual, temp1_, temp2_, &fail); ++ } ++ ++ // Increment pointers into match and capture strings. ++ masm_.addPtr(Imm32(char_size()), current_character_); ++ masm_.addPtr(Imm32(char_size()), current_position_); ++ ++ // Loop if we have not reached the end of the match string. ++ masm_.branchPtr(Assembler::Below, current_position_, temp0_, &loop); ++ masm_.jump(&success); ++ ++ // If we fail, restore current_position_ and branch. ++ masm_.bind(&fail); ++ masm_.pop(current_position_); ++ JumpOrBacktrack(on_no_match); ++ ++ masm_.bind(&success); ++ ++ // Drop saved value of current_position_ ++ masm_.addToStackPtr(Imm32(sizeof(uintptr_t))); ++ ++ // current_position_ is a pointer. Convert it back to an offset. ++ masm_.subPtr(input_end_pointer_, current_position_); ++ if (read_backward) { ++ // Subtract match length if we matched backward ++ masm_.addPtr(register_location(start_reg), current_position_); ++ masm_.subPtr(register_location(start_reg + 1), current_position_); ++ } ++ ++ masm_.bind(&fallthrough); ++} ++ ++// Branch if a back-reference does not match a previous capture. ++void SMRegExpMacroAssembler::CheckNotBackReference(int start_reg, ++ bool read_backward, ++ Label* on_no_match) { ++ CheckNotBackReferenceImpl(start_reg, read_backward, /*unicode = */ false, ++ on_no_match, /*ignore_case = */ false); ++} ++ ++void SMRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase( ++ int start_reg, bool read_backward, bool unicode, Label* on_no_match) { ++ CheckNotBackReferenceImpl(start_reg, read_backward, unicode, on_no_match, ++ /*ignore_case = */ true); ++} ++ ++// Checks whether the given offset from the current position is ++// inside the input string. ++void SMRegExpMacroAssembler::CheckPosition(int cp_offset, ++ Label* on_outside_input) { ++ // Note: current_position_ is a (negative) byte offset relative to ++ // the end of the input string. ++ if (cp_offset >= 0) { ++ // end + current + offset >= end ++ // <=> current + offset >= 0 ++ // <=> current >= -offset ++ masm_.branchPtr(Assembler::GreaterThanOrEqual, current_position_, ++ ImmWord(-cp_offset * char_size()), ++ LabelOrBacktrack(on_outside_input)); ++ } else { ++ // Compute offset position ++ masm_.computeEffectiveAddress( ++ Address(current_position_, cp_offset * char_size()), temp0_); ++ ++ // Compare to start of input. ++ masm_.branchPtr(Assembler::GreaterThan, inputStart(), temp0_, ++ LabelOrBacktrack(on_outside_input)); ++ } ++} ++ ++// This function attempts to generate special case code for character classes. ++// Returns true if a special case is generated. ++// Otherwise returns false and generates no code. ++bool SMRegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type, ++ Label* on_no_match) { ++ js::jit::Label* no_match = LabelOrBacktrack(on_no_match); ++ ++ // Note: throughout this function, range checks (c in [min, max]) ++ // are implemented by an unsigned (c - min) <= (max - min) check. ++ switch (type) { ++ case 's': { ++ // Match space-characters ++ if (mode_ != LATIN1) { ++ return false; ++ } ++ js::jit::Label success; ++ // One byte space characters are ' ', '\t'..'\r', and '\u00a0' (NBSP). ++ ++ // Check ' ' ++ masm_.branch32(Assembler::Equal, current_character_, Imm32(' '), ++ &success); ++ ++ // Check '\t'..'\r' ++ masm_.computeEffectiveAddress(Address(current_character_, -'\t'), temp0_); ++ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32('\r' - '\t'), ++ &success); ++ ++ // Check \u00a0. ++ masm_.branch32(Assembler::NotEqual, temp0_, Imm32(0x00a0 - '\t'), ++ no_match); ++ ++ masm_.bind(&success); ++ return true; ++ } ++ case 'S': ++ // The emitted code for generic character classes is good enough. ++ return false; ++ case 'd': ++ // Match latin1 digits ('0'-'9') ++ masm_.computeEffectiveAddress(Address(current_character_, -'0'), temp0_); ++ masm_.branch32(Assembler::Above, temp0_, Imm32('9' - '0'), no_match); ++ return true; ++ case 'D': ++ // Match anything except latin1 digits ('0'-'9') ++ masm_.computeEffectiveAddress(Address(current_character_, -'0'), temp0_); ++ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32('9' - '0'), ++ no_match); ++ return true; ++ case '.': ++ // Match non-newlines. This excludes '\n' (0x0a), '\r' (0x0d), ++ // U+2028 LINE SEPARATOR, and U+2029 PARAGRAPH SEPARATOR. ++ // See https://tc39.es/ecma262/#prod-LineTerminator ++ ++ // To test for 0x0a and 0x0d efficiently, we XOR the input with 1. ++ // This converts 0x0a to 0x0b, and 0x0d to 0x0c, allowing us to ++ // test for the contiguous range 0x0b..0x0c. ++ masm_.move32(current_character_, temp0_); ++ masm_.xor32(Imm32(0x01), temp0_); ++ masm_.sub32(Imm32(0x0b), temp0_); ++ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32(0x0c - 0x0b), ++ no_match); ++ ++ if (mode_ == UC16) { ++ // Compare original value to 0x2028 and 0x2029, using the already ++ // computed (current_char ^ 0x01 - 0x0b). I.e., check for ++ // 0x201d (0x2028 - 0x0b) or 0x201e. ++ masm_.sub32(Imm32(0x2028 - 0x0b), temp0_); ++ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32(0x2029 - 0x2028), ++ no_match); ++ } ++ return true; ++ case 'w': ++ // \w matches the set of 63 characters defined in Runtime Semantics: ++ // WordCharacters. We use a static lookup table, which is defined in ++ // regexp-macro-assembler.cc. ++ // Note: if both Unicode and IgnoreCase are true, \w matches a ++ // larger set of characters. That case is handled elsewhere. ++ if (mode_ != LATIN1) { ++ masm_.branch32(Assembler::Above, current_character_, Imm32('z'), ++ no_match); ++ } ++ static_assert( ++ arraysize(word_character_map) > unibrow::Latin1::kMaxChar, ++ "regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar"); ++ masm_.movePtr(ImmPtr(word_character_map), temp0_); ++ masm_.load8ZeroExtend( ++ BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); ++ masm_.branchTest32(Assembler::Zero, temp0_, temp0_, no_match); ++ return true; ++ case 'W': { ++ // See 'w' above. ++ js::jit::Label done; ++ if (mode_ != LATIN1) { ++ masm_.branch32(Assembler::Above, current_character_, Imm32('z'), &done); ++ } ++ static_assert( ++ arraysize(word_character_map) > unibrow::Latin1::kMaxChar, ++ "regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar"); ++ masm_.movePtr(ImmPtr(word_character_map), temp0_); ++ masm_.load8ZeroExtend( ++ BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); ++ masm_.branchTest32(Assembler::NonZero, temp0_, temp0_, no_match); ++ if (mode_ != LATIN1) { ++ masm_.bind(&done); ++ } ++ return true; ++ } ++ //////////////////////////////////////////////////////////////////////// ++ // Non-standard classes (with no syntactic shorthand) used internally // ++ //////////////////////////////////////////////////////////////////////// ++ case '*': ++ // Match any character ++ return true; ++ case 'n': ++ // Match newlines. The opposite of '.'. See '.' above. ++ masm_.move32(current_character_, temp0_); ++ masm_.xor32(Imm32(0x01), temp0_); ++ masm_.sub32(Imm32(0x0b), temp0_); ++ if (mode_ == LATIN1) { ++ masm_.branch32(Assembler::Above, temp0_, Imm32(0x0c - 0x0b), no_match); ++ } else { ++ MOZ_ASSERT(mode_ == UC16); ++ js::jit::Label done; ++ masm_.branch32(Assembler::BelowOrEqual, temp0_, Imm32(0x0c - 0x0b), ++ &done); ++ ++ // Compare original value to 0x2028 and 0x2029, using the already ++ // computed (current_char ^ 0x01 - 0x0b). I.e., check for ++ // 0x201d (0x2028 - 0x0b) or 0x201e. ++ masm_.sub32(Imm32(0x2028 - 0x0b), temp0_); ++ masm_.branch32(Assembler::Above, temp0_, Imm32(0x2029 - 0x2028), ++ no_match); ++ masm_.bind(&done); ++ } ++ return true; ++ ++ // No custom implementation ++ default: ++ return false; ++ } ++} ++ ++void SMRegExpMacroAssembler::Fail() { ++ masm_.movePtr(ImmWord(js::RegExpRunStatus_Success_NotFound), temp0_); ++ masm_.jump(&exit_label_); ++} ++ ++void SMRegExpMacroAssembler::GoTo(Label* to) { ++ masm_.jump(LabelOrBacktrack(to)); ++} ++ ++void SMRegExpMacroAssembler::IfRegisterGE(int reg, int comparand, ++ Label* if_ge) { ++ masm_.branchPtr(Assembler::GreaterThanOrEqual, register_location(reg), ++ ImmWord(comparand), LabelOrBacktrack(if_ge)); ++} ++ ++void SMRegExpMacroAssembler::IfRegisterLT(int reg, int comparand, ++ Label* if_lt) { ++ masm_.branchPtr(Assembler::LessThan, register_location(reg), ++ ImmWord(comparand), LabelOrBacktrack(if_lt)); ++} ++ ++void SMRegExpMacroAssembler::IfRegisterEqPos(int reg, Label* if_eq) { ++ masm_.branchPtr(Assembler::Equal, register_location(reg), current_position_, ++ LabelOrBacktrack(if_eq)); ++} ++ ++// This is a word-for-word identical copy of the V8 code, which is ++// duplicated in at least nine different places in V8 (one per ++// supported architecture) with no differences outside of comments and ++// formatting. It should be hoisted into the superclass. Once that is ++// done upstream, this version can be deleted. ++void SMRegExpMacroAssembler::LoadCurrentCharacterImpl(int cp_offset, ++ Label* on_end_of_input, ++ bool check_bounds, ++ int characters, ++ int eats_at_least) { ++ // It's possible to preload a small number of characters when each success ++ // path requires a large number of characters, but not the reverse. ++ MOZ_ASSERT(eats_at_least >= characters); ++ MOZ_ASSERT(cp_offset < (1 << 30)); // Be sane! (And ensure negation works) ++ ++ if (check_bounds) { ++ if (cp_offset >= 0) { ++ CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input); ++ } else { ++ CheckPosition(cp_offset, on_end_of_input); ++ } ++ } ++ LoadCurrentCharacterUnchecked(cp_offset, characters); ++} ++ ++// Load the character (or characters) at the specified offset from the ++// current position. Zero-extend to 32 bits. ++void SMRegExpMacroAssembler::LoadCurrentCharacterUnchecked(int cp_offset, ++ int characters) { ++ BaseIndex address(input_end_pointer_, current_position_, js::jit::TimesOne, ++ cp_offset * char_size()); ++ if (mode_ == LATIN1) { ++ if (characters == 4) { ++ masm_.load32(address, current_character_); ++ } else if (characters == 2) { ++ masm_.load16ZeroExtend(address, current_character_); ++ } else { ++ MOZ_ASSERT(characters == 1); ++ masm_.load8ZeroExtend(address, current_character_); ++ } ++ } else { ++ MOZ_ASSERT(mode_ == UC16); ++ if (characters == 2) { ++ masm_.load32(address, current_character_); ++ } else { ++ MOZ_ASSERT(characters == 1); ++ masm_.load16ZeroExtend(address, current_character_); ++ } ++ } ++} ++ ++void SMRegExpMacroAssembler::PopCurrentPosition() { Pop(current_position_); } ++ ++void SMRegExpMacroAssembler::PopRegister(int register_index) { ++ Pop(temp0_); ++ masm_.storePtr(temp0_, register_location(register_index)); ++} ++ ++void SMRegExpMacroAssembler::PushBacktrack(Label* label) { ++ MOZ_ASSERT(!label->is_bound()); ++ MOZ_ASSERT(!label->patchOffset_.bound()); ++ label->patchOffset_ = masm_.movWithPatch(ImmPtr(nullptr), temp0_); ++ MOZ_ASSERT(label->patchOffset_.bound()); ++ ++ Push(temp0_); ++ ++ CheckBacktrackStackLimit(); ++} ++ ++void SMRegExpMacroAssembler::PushCurrentPosition() { Push(current_position_); } ++ ++void SMRegExpMacroAssembler::PushRegister(int register_index, ++ StackCheckFlag check_stack_limit) { ++ masm_.loadPtr(register_location(register_index), temp0_); ++ Push(temp0_); ++ if (check_stack_limit) { ++ CheckBacktrackStackLimit(); ++ } ++} ++ ++void SMRegExpMacroAssembler::ReadCurrentPositionFromRegister(int reg) { ++ masm_.loadPtr(register_location(reg), current_position_); ++} ++ ++void SMRegExpMacroAssembler::WriteCurrentPositionToRegister(int reg, ++ int cp_offset) { ++ if (cp_offset == 0) { ++ masm_.storePtr(current_position_, register_location(reg)); ++ } else { ++ Address addr(current_position_, cp_offset * char_size()); ++ masm_.computeEffectiveAddress(addr, temp0_); ++ masm_.storePtr(temp0_, register_location(reg)); ++ } ++} ++ ++// Note: The backtrack stack pointer is stored in a register as an ++// offset from the stack top, not as a bare pointer, so that it is not ++// corrupted if the backtrack stack grows (and therefore moves). ++void SMRegExpMacroAssembler::ReadStackPointerFromRegister(int reg) { ++ masm_.loadPtr(register_location(reg), backtrack_stack_pointer_); ++ masm_.addPtr(backtrackStackBase(), backtrack_stack_pointer_); ++} ++void SMRegExpMacroAssembler::WriteStackPointerToRegister(int reg) { ++ masm_.movePtr(backtrack_stack_pointer_, temp0_); ++ masm_.subPtr(backtrackStackBase(), temp0_); ++ masm_.storePtr(temp0_, register_location(reg)); ++} ++ ++// When matching a regexp that is anchored at the end, this operation ++// is used to try skipping the beginning of long strings. If the ++// maximum length of a match is less than the length of the string, we ++// can skip the initial len - max_len bytes. ++void SMRegExpMacroAssembler::SetCurrentPositionFromEnd(int by) { ++ js::jit::Label after_position; ++ masm_.branchPtr(Assembler::GreaterThanOrEqual, current_position_, ++ ImmWord(-by * char_size()), &after_position); ++ masm_.movePtr(ImmWord(-by * char_size()), current_position_); ++ ++ // On RegExp code entry (where this operation is used), the character before ++ // the current position is expected to be already loaded. ++ // We have advanced the position, so it's safe to read backwards. ++ LoadCurrentCharacterUnchecked(-1, 1); ++ masm_.bind(&after_position); ++} ++ ++void SMRegExpMacroAssembler::SetRegister(int register_index, int to) { ++ MOZ_ASSERT(register_index >= num_capture_registers_); ++ masm_.storePtr(ImmWord(to), register_location(register_index)); ++} ++ ++// Returns true if a regexp match can be restarted (aka the regexp is global). ++// The return value is not used anywhere, but we implement it to be safe. ++bool SMRegExpMacroAssembler::Succeed() { ++ masm_.jump(&success_label_); ++ return global(); ++} ++ ++// Capture registers are initialized to input[-1] ++void SMRegExpMacroAssembler::ClearRegisters(int reg_from, int reg_to) { ++ MOZ_ASSERT(reg_from <= reg_to); ++ masm_.loadPtr(inputStart(), temp0_); ++ masm_.subPtr(Imm32(char_size()), temp0_); ++ for (int reg = reg_from; reg <= reg_to; reg++) { ++ masm_.storePtr(temp0_, register_location(reg)); ++ } ++} ++ ++void SMRegExpMacroAssembler::Push(Register source) { ++ MOZ_ASSERT(source != backtrack_stack_pointer_); ++ ++ masm_.subPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_); ++ masm_.storePtr(source, Address(backtrack_stack_pointer_, 0)); ++} ++ ++void SMRegExpMacroAssembler::Pop(Register target) { ++ MOZ_ASSERT(target != backtrack_stack_pointer_); ++ ++ masm_.loadPtr(Address(backtrack_stack_pointer_, 0), target); ++ masm_.addPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_); ++} ++ ++void SMRegExpMacroAssembler::JumpOrBacktrack(Label* to) { ++ if (to) { ++ masm_.jump(to->inner()); ++ } else { ++ Backtrack(); ++ } ++} ++ ++// Generate a quick inline test for backtrack stack overflow. ++// If the test fails, call an OOL handler to try growing the stack. ++void SMRegExpMacroAssembler::CheckBacktrackStackLimit() { ++ js::jit::Label no_stack_overflow; ++ masm_.branchPtr( ++ Assembler::BelowOrEqual, ++ AbsoluteAddress(isolate()->regexp_stack()->limit_address_address()), ++ backtrack_stack_pointer_, &no_stack_overflow); ++ ++ masm_.call(&stack_overflow_label_); ++ ++ // Exit with an exception if the call failed ++ masm_.branchTest32(Assembler::Zero, temp0_, temp0_, ++ &exit_with_exception_label_); ++ ++ masm_.bind(&no_stack_overflow); ++} ++ ++// This is used to sneak an OOM through the V8 layer. ++static Handle DummyCode() { ++ return Handle::fromHandleValue(JS::UndefinedHandleValue); ++} ++ ++// Finalize code. This is called last, so that we know how many ++// registers we need. ++Handle SMRegExpMacroAssembler::GetCode(Handle source) { ++ if (!cx_->compartment()->ensureJitCompartmentExists(cx_)) { ++ return DummyCode(); ++ } ++ ++ masm_.bind(&entry_label_); ++ ++ createStackFrame(); ++ initFrameAndRegs(); ++ ++ masm_.jump(&start_label_); ++ ++ successHandler(); ++ exitHandler(); ++ backtrackHandler(); ++ stackOverflowHandler(); ++ ++ Linker linker(masm_); ++ JitCode* code = linker.newCode(cx_, REGEXP_CODE); ++ if (!code) { ++ ReportOutOfMemory(cx_); ++ return DummyCode(); ++ } ++ ++ for (LabelPatch& lp : labelPatches_) { ++ Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, lp.patchOffset_), ++ ImmPtr(code->raw() + lp.labelOffset_), ++ ImmPtr(nullptr)); ++ } ++ ++ return Handle(JS::PrivateGCThingValue(code), isolate()); ++} ++ ++/* ++ * The stack will have the following structure: ++ * sp-> - FrameData ++ * - inputStart ++ * - backtrack stack base ++ * - matches ++ * - numMatches ++ * - Registers ++ * - Capture positions ++ * - Scratch registers ++ * --- frame alignment --- ++ * - Saved register area ++ * - Return address ++ */ ++void SMRegExpMacroAssembler::createStackFrame() { ++#ifdef JS_CODEGEN_ARM64 ++ // ARM64 communicates stack address via SP, but uses a pseudo-sp (PSP) for ++ // addressing. The register we use for PSP may however also be used by ++ // calling code, and it is nonvolatile, so save it. Do this as a special ++ // case first because the generic save/restore code needs the PSP to be ++ // initialized already. ++ MOZ_ASSERT(js::jit::PseudoStackPointer64.Is(masm_.GetStackPointer64())); ++ masm_.Str(js::jit::PseudoStackPointer64, ++ vixl::MemOperand(js::jit::sp, -16, vixl::PreIndex)); ++ ++ // Initialize the PSP from the SP. ++ masm_.initPseudoStackPtr(); ++#endif ++ ++ // Push non-volatile registers which might be modified by jitcode. ++ size_t pushedNonVolatileRegisters = 0; ++ for (GeneralRegisterForwardIterator iter(savedRegisters_); iter.more(); ++ ++iter) { ++ masm_.Push(*iter); ++ pushedNonVolatileRegisters++; ++ } ++ ++ // The pointer to InputOutputData is passed as the first argument. ++ // On x86 we have to load it off the stack into temp0_. ++ // On other platforms it is already in a register. ++#ifdef JS_CODEGEN_X86 ++ Address ioDataAddr(masm_.getStackPointer(), ++ (pushedNonVolatileRegisters + 1) * sizeof(void*)); ++ masm_.loadPtr(ioDataAddr, temp0_); ++#else ++ if (js::jit::IntArgReg0 != temp0_) { ++ masm_.movePtr(js::jit::IntArgReg0, temp0_); ++ } ++#endif ++ ++ // Start a new stack frame. ++ size_t frameBytes = sizeof(FrameData) + num_registers_ * sizeof(void*); ++ frameSize_ = js::jit::StackDecrementForCall(js::jit::ABIStackAlignment, ++ masm_.framePushed(), frameBytes); ++ masm_.reserveStack(frameSize_); ++ masm_.checkStackAlignment(); ++ ++ // Check if we have space on the stack. Use the *NoInterrupt stack limit to ++ // avoid failing repeatedly when the regex code is called from Ion JIT code. ++ // (See bug 1208819) ++ js::jit::Label stack_ok; ++ AbsoluteAddress limit_addr(cx_->addressOfJitStackLimitNoInterrupt()); ++ masm_.branchStackPtrRhs(Assembler::Below, limit_addr, &stack_ok); ++ ++ // There is not enough space on the stack. Exit with an exception. ++ masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); ++ masm_.jump(&exit_label_); ++ ++ masm_.bind(&stack_ok); ++} ++ ++void SMRegExpMacroAssembler::initFrameAndRegs() { ++ // At this point, an uninitialized stack frame has been created, ++ // and the address of the InputOutputData is in temp0_. ++ Register ioDataReg = temp0_; ++ ++ Register matchesReg = temp1_; ++ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, matches)), ++ matchesReg); ++ ++ // Initialize output registers ++ masm_.loadPtr(Address(matchesReg, MatchPairs::offsetOfPairs()), temp2_); ++ masm_.storePtr(temp2_, matches()); ++ masm_.load32(Address(matchesReg, MatchPairs::offsetOfPairCount()), temp2_); ++ masm_.store32(temp2_, numMatches()); ++ ++#ifdef DEBUG ++ // Bounds-check numMatches. ++ js::jit::Label enoughRegisters; ++ masm_.branchPtr(Assembler::GreaterThanOrEqual, temp2_, ++ ImmWord(num_capture_registers_ / 2), &enoughRegisters); ++ masm_.assumeUnreachable("Not enough output pairs for RegExp"); ++ masm_.bind(&enoughRegisters); ++#endif ++ ++ // Load input start pointer. ++ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, inputStart)), ++ current_position_); ++ ++ // Load input end pointer ++ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, inputEnd)), ++ input_end_pointer_); ++ ++ // Set up input position to be negative offset from string end. ++ masm_.subPtr(input_end_pointer_, current_position_); ++ ++ // Store inputStart ++ masm_.storePtr(current_position_, inputStart()); ++ ++ // Load start index ++ Register startIndexReg = temp1_; ++ masm_.loadPtr(Address(ioDataReg, offsetof(InputOutputData, startIndex)), ++ startIndexReg); ++ masm_.computeEffectiveAddress( ++ BaseIndex(current_position_, startIndexReg, factor()), current_position_); ++ ++ // Initialize current_character_. ++ // Load newline if index is at start, or previous character otherwise. ++ js::jit::Label start_regexp; ++ js::jit::Label load_previous_character; ++ masm_.branchPtr(Assembler::NotEqual, startIndexReg, ImmWord(0), ++ &load_previous_character); ++ masm_.movePtr(ImmWord('\n'), current_character_); ++ masm_.jump(&start_regexp); ++ ++ masm_.bind(&load_previous_character); ++ LoadCurrentCharacterUnchecked(-1, 1); ++ masm_.bind(&start_regexp); ++ ++ // Initialize captured registers with inputStart - 1 ++ MOZ_ASSERT(num_capture_registers_ > 0); ++ Register inputStartMinusOneReg = temp2_; ++ masm_.loadPtr(inputStart(), inputStartMinusOneReg); ++ masm_.subPtr(Imm32(char_size()), inputStartMinusOneReg); ++ if (num_capture_registers_ > 8) { ++ masm_.movePtr(ImmWord(register_offset(0)), temp1_); ++ js::jit::Label init_loop; ++ masm_.bind(&init_loop); ++ masm_.storePtr(inputStartMinusOneReg, BaseIndex(masm_.getStackPointer(), ++ temp1_, js::jit::TimesOne)); ++ masm_.addPtr(ImmWord(sizeof(void*)), temp1_); ++ masm_.branchPtr(Assembler::LessThan, temp1_, ++ ImmWord(register_offset(num_capture_registers_)), ++ &init_loop); ++ } else { ++ // Unroll the loop ++ for (int i = 0; i < num_capture_registers_; i++) { ++ masm_.storePtr(inputStartMinusOneReg, register_location(i)); ++ } ++ } ++ ++ // Initialize backtrack stack pointer ++ masm_.loadPtr(AbsoluteAddress(isolate()->top_of_regexp_stack()), ++ backtrack_stack_pointer_); ++ masm_.storePtr(backtrack_stack_pointer_, backtrackStackBase()); ++} ++ ++// Called when we find a match. May not be generated if we can ++// determine ahead of time that a regexp cannot match: for example, ++// when compiling /\u1e9e/ for latin-1 inputs. ++void SMRegExpMacroAssembler::successHandler() { ++ if (!success_label_.used()) { ++ return; ++ } ++ masm_.bind(&success_label_); ++ ++ // Copy captures to the MatchPairs pointed to by the InputOutputData. ++ // Captures are stored as positions, which are negative byte offsets ++ // from the end of the string. We must convert them to actual ++ // indices. ++ // ++ // Index: [ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][END] ++ // Pos (1-byte): [-6 ][-5 ][-4 ][-3 ][-2 ][-1 ][ 0 ] // IS = -6 ++ // Pos (2-byte): [-12][-10][-8 ][-6 ][-4 ][-2 ][ 0 ] // IS = -12 ++ // ++ // To convert a position to an index, we subtract InputStart, and ++ // divide the result by char_size. ++ Register matchesReg = temp1_; ++ masm_.loadPtr(matches(), matchesReg); ++ ++ Register inputStartReg = temp2_; ++ masm_.loadPtr(inputStart(), inputStartReg); ++ ++ for (int i = 0; i < num_capture_registers_; i++) { ++ masm_.loadPtr(register_location(i), temp0_); ++ masm_.subPtr(inputStartReg, temp0_); ++ if (mode_ == UC16) { ++ masm_.rshiftPtrArithmetic(Imm32(1), temp0_); ++ } ++ masm_.store32(temp0_, Address(matchesReg, i * sizeof(int32_t))); ++ } ++ ++ masm_.movePtr(ImmWord(js::RegExpRunStatus_Success), temp0_); ++ // This falls through to the exit handler. ++} ++ ++void SMRegExpMacroAssembler::exitHandler() { ++ masm_.bind(&exit_label_); ++ ++ if (temp0_ != js::jit::ReturnReg) { ++ masm_.movePtr(temp0_, js::jit::ReturnReg); ++ } ++ ++ masm_.freeStack(frameSize_); ++ ++ // Restore registers which were saved on entry ++ for (GeneralRegisterBackwardIterator iter(savedRegisters_); iter.more(); ++ ++iter) { ++ masm_.Pop(*iter); ++ } ++ ++#ifdef JS_CODEGEN_ARM64 ++ // Now restore the value that was in the PSP register on entry, and return. ++ ++ // Obtain the correct SP from the PSP. ++ masm_.Mov(js::jit::sp, js::jit::PseudoStackPointer64); ++ ++ // Restore the saved value of the PSP register, this value is whatever the ++ // caller had saved in it, not any actual SP value, and it must not be ++ // overwritten subsequently. ++ masm_.Ldr(js::jit::PseudoStackPointer64, ++ vixl::MemOperand(js::jit::sp, 16, vixl::PostIndex)); ++ ++ // Perform a plain Ret(), as abiret() will move SP <- PSP and that is wrong. ++ masm_.Ret(vixl::lr); ++#else ++ masm_.abiret(); ++#endif ++ ++ if (exit_with_exception_label_.used()) { ++ masm_.bind(&exit_with_exception_label_); ++ ++ // Exit with an error result to signal thrown exception ++ masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); ++ masm_.jump(&exit_label_); ++ } ++} ++ ++void SMRegExpMacroAssembler::backtrackHandler() { ++ if (!backtrack_label_.used()) { ++ return; ++ } ++ masm_.bind(&backtrack_label_); ++ Backtrack(); ++} ++ ++void SMRegExpMacroAssembler::stackOverflowHandler() { ++ if (!stack_overflow_label_.used()) { ++ return; ++ } ++ ++ // Called if the backtrack-stack limit has been hit. ++ masm_.bind(&stack_overflow_label_); ++ ++ // Load argument ++ masm_.movePtr(ImmPtr(isolate()->regexp_stack()), temp1_); ++ ++ // Save registers before calling C function ++ LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile()); ++ ++#ifdef JS_USE_LINK_REGISTER ++ masm_.pushReturnAddress(); ++#endif ++ ++ // Adjust for the return address on the stack. ++ size_t frameOffset = sizeof(void*); ++ ++ volatileRegs.takeUnchecked(temp0_); ++ volatileRegs.takeUnchecked(temp1_); ++ masm_.PushRegsInMask(volatileRegs); ++ ++ masm_.setupUnalignedABICall(temp0_); ++ masm_.passABIArg(temp1_); ++ masm_.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GrowBacktrackStack)); ++ masm_.storeCallBoolResult(temp0_); ++ ++ masm_.PopRegsInMask(volatileRegs); ++ ++ // If GrowBacktrackStack returned false, we have failed to grow the ++ // stack, and must exit with a stack-overflow exception. Do this in ++ // the caller so that the stack is adjusted by our return instruction. ++ js::jit::Label overflow_return; ++ masm_.branchTest32(Assembler::Zero, temp0_, temp0_, &overflow_return); ++ ++ // Otherwise, store the new backtrack stack base and recompute the new ++ // top of the stack. ++ Address bsbAddress(masm_.getStackPointer(), ++ offsetof(FrameData, backtrackStackBase) + frameOffset); ++ masm_.subPtr(bsbAddress, backtrack_stack_pointer_); ++ ++ masm_.loadPtr(AbsoluteAddress(isolate()->top_of_regexp_stack()), temp1_); ++ masm_.storePtr(temp1_, bsbAddress); ++ masm_.addPtr(temp1_, backtrack_stack_pointer_); ++ ++ // Resume execution in calling code. ++ masm_.bind(&overflow_return); ++ masm_.ret(); ++} ++ ++// This is only used by tracing code. ++// The return value doesn't matter. ++RegExpMacroAssembler::IrregexpImplementation ++SMRegExpMacroAssembler::Implementation() { ++ return kBytecodeImplementation; ++} ++ ++// Compare two strings in `/i` mode (ignoreCase, but not unicode). ++/*static */ ++uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareNonUnicode( ++ const char16_t* substring1, const char16_t* substring2, size_t byteLength) { ++ JS::AutoCheckCannotGC nogc; ++ ++ MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); ++ size_t length = byteLength / sizeof(char16_t); ++ ++ for (size_t i = 0; i < length; i++) { ++ char16_t c1 = substring1[i]; ++ char16_t c2 = substring2[i]; ++ if (c1 != c2) { ++#ifdef JS_HAS_INTL_API ++ // Non-unicode regexps have weird case-folding rules. ++ c1 = RegExpCaseFolding::Canonicalize(c1); ++ c2 = RegExpCaseFolding::Canonicalize(c2); ++#else ++ // If we aren't building with ICU, fall back to `/iu` mode. The only ++ // differences are in corner cases. ++ c1 = js::unicode::FoldCase(c1); ++ c2 = js::unicode::FoldCase(c2); ++#endif ++ if (c1 != c2) { ++ return 0; ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++// Compare two strings in `/iu` mode (ignoreCase and unicode). ++/*static */ ++uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUnicode( ++ const char16_t* substring1, const char16_t* substring2, size_t byteLength) { ++ JS::AutoCheckCannotGC nogc; ++ ++ MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); ++ size_t length = byteLength / sizeof(char16_t); ++ ++ for (size_t i = 0; i < length; i++) { ++ char16_t c1 = substring1[i]; ++ char16_t c2 = substring2[i]; ++ if (c1 != c2) { ++ // Unicode regexps use the common and simple case-folding ++ // mappings of the Unicode Character Database. ++ c1 = js::unicode::FoldCase(c1); ++ c2 = js::unicode::FoldCase(c2); ++ if (c1 != c2) { ++ return 0; ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++/* static */ ++bool SMRegExpMacroAssembler::GrowBacktrackStack(RegExpStack* regexp_stack) { ++ JS::AutoCheckCannotGC nogc; ++ size_t size = regexp_stack->stack_capacity(); ++ return !!regexp_stack->EnsureCapacity(size * 2); ++} ++ ++bool SMRegExpMacroAssembler::CanReadUnaligned() { ++#if defined(JS_CODEGEN_ARM) ++ return !js::jit::HasAlignmentFault(); ++#elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) ++ return false; ++#else ++ return true; ++#endif ++} ++ ++} // namespace internal ++} // namespace v8 +diff -Nrup mozilla/js/src/irregexp/RegExpNativeMacroAssembler.h mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.h +--- mozilla/js/src/irregexp/RegExpNativeMacroAssembler.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpNativeMacroAssembler.h 2023-02-27 08:17:24.844702672 +0300 +@@ -0,0 +1,297 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++// Copyright 2020 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++// This file implements the NativeRegExpMacroAssembler interface for ++// SpiderMonkey. It provides the same interface as each of V8's ++// architecture-specific implementations. ++ ++#ifndef RegexpMacroAssemblerArch_h ++#define RegexpMacroAssemblerArch_h ++ ++#include "irregexp/imported/regexp-macro-assembler.h" ++#include "jit/MacroAssembler.h" ++ ++namespace v8 { ++namespace internal { ++ ++struct FrameData { ++ // Character position at the start of the input, stored as a ++ // negative offset from the end of the string (input_end_pointer_). ++ size_t inputStart; ++ ++ // The backtrack_stack_pointer_ register points to the top of the stack. ++ // This points to the bottom of the backtrack stack. ++ void* backtrackStackBase; ++ ++ // Copy of the input MatchPairs. ++ int32_t* matches; // pointer to capture array ++ int32_t numMatches; // size of capture array ++}; ++ ++class SMRegExpMacroAssembler final : public NativeRegExpMacroAssembler { ++ public: ++ SMRegExpMacroAssembler(JSContext* cx, js::jit::StackMacroAssembler& masm, ++ Zone* zone, Mode mode, uint32_t num_capture_registers); ++ virtual ~SMRegExpMacroAssembler() {} // Nothing to do here ++ ++ virtual int stack_limit_slack(); ++ virtual IrregexpImplementation Implementation(); ++ ++ virtual bool Succeed(); ++ virtual void Fail(); ++ ++ virtual void AdvanceCurrentPosition(int by); ++ virtual void PopCurrentPosition(); ++ virtual void PushCurrentPosition(); ++ virtual void SetCurrentPositionFromEnd(int by); ++ ++ virtual void Backtrack(); ++ virtual void Bind(Label* label); ++ virtual void GoTo(Label* label); ++ virtual void PushBacktrack(Label* label); ++ ++ virtual void CheckCharacter(uint32_t c, Label* on_equal); ++ virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal); ++ virtual void CheckCharacterGT(uc16 limit, Label* on_greater); ++ virtual void CheckCharacterLT(uc16 limit, Label* on_less); ++ virtual void CheckCharacterAfterAnd(uint32_t c, uint32_t mask, ++ Label* on_equal); ++ virtual void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, ++ Label* on_not_equal); ++ virtual void CheckNotCharacterAfterMinusAnd(uc16 c, uc16 minus, uc16 mask, ++ Label* on_not_equal); ++ virtual void CheckGreedyLoop(Label* on_tos_equals_current_position); ++ virtual void CheckCharacterInRange(uc16 from, uc16 to, Label* on_in_range); ++ virtual void CheckCharacterNotInRange(uc16 from, uc16 to, ++ Label* on_not_in_range); ++ virtual void CheckAtStart(int cp_offset, Label* on_at_start); ++ virtual void CheckNotAtStart(int cp_offset, Label* on_not_at_start); ++ virtual void CheckPosition(int cp_offset, Label* on_outside_input); ++ virtual void CheckBitInTable(Handle table, Label* on_bit_set); ++ virtual bool CheckSpecialCharacterClass(uc16 type, Label* on_no_match); ++ virtual void CheckNotBackReference(int start_reg, bool read_backward, ++ Label* on_no_match); ++ virtual void CheckNotBackReferenceIgnoreCase(int start_reg, ++ bool read_backward, bool unicode, ++ Label* on_no_match); ++ ++ virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input, ++ bool check_bounds, int characters, ++ int eats_at_least); ++ ++ virtual void AdvanceRegister(int reg, int by); ++ virtual void IfRegisterGE(int reg, int comparand, Label* if_ge); ++ virtual void IfRegisterLT(int reg, int comparand, Label* if_lt); ++ virtual void IfRegisterEqPos(int reg, Label* if_eq); ++ virtual void PopRegister(int register_index); ++ virtual void PushRegister(int register_index, ++ StackCheckFlag check_stack_limit); ++ virtual void ReadCurrentPositionFromRegister(int reg); ++ virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); ++ virtual void ReadStackPointerFromRegister(int reg); ++ virtual void WriteStackPointerToRegister(int reg); ++ virtual void SetRegister(int register_index, int to); ++ virtual void ClearRegisters(int reg_from, int reg_to); ++ ++ virtual Handle GetCode(Handle source); ++ ++ virtual bool CanReadUnaligned(); ++ ++ private: ++ size_t frameSize_ = 0; ++ ++ void createStackFrame(); ++ void initFrameAndRegs(); ++ void successHandler(); ++ void exitHandler(); ++ void backtrackHandler(); ++ void stackOverflowHandler(); ++ ++ // Push a register on the backtrack stack. ++ void Push(js::jit::Register value); ++ ++ // Pop a value from the backtrack stack. ++ void Pop(js::jit::Register target); ++ ++ void CheckAtStartImpl(int cp_offset, Label* on_cond, ++ js::jit::Assembler::Condition cond); ++ void CheckCharacterImpl(js::jit::Imm32 c, Label* on_cond, ++ js::jit::Assembler::Condition cond); ++ void CheckCharacterAfterAndImpl(uint32_t c, uint32_t and_with, Label* on_cond, ++ bool negate); ++ void CheckCharacterInRangeImpl(uc16 from, uc16 to, Label* on_cond, ++ js::jit::Assembler::Condition cond); ++ void CheckNotBackReferenceImpl(int start_reg, bool read_backward, ++ bool unicode, Label* on_no_match, ++ bool ignore_case); ++ ++ void LoadCurrentCharacterUnchecked(int cp_offset, int characters); ++ ++ void JumpOrBacktrack(Label* to); ++ ++ // MacroAssembler methods that take a Label can be called with a ++ // null label, which means that we should backtrack if we would jump ++ // to that label. This is a helper to avoid writing out the same ++ // logic a dozen times. ++ inline js::jit::Label* LabelOrBacktrack(Label* to) { ++ return to ? to->inner() : &backtrack_label_; ++ } ++ ++ void CheckBacktrackStackLimit(); ++ ++ static bool GrowBacktrackStack(RegExpStack* regexp_stack); ++ ++ static uint32_t CaseInsensitiveCompareNonUnicode(const char16_t* substring1, ++ const char16_t* substring2, ++ size_t byteLength); ++ static uint32_t CaseInsensitiveCompareUnicode(const char16_t* substring1, ++ const char16_t* substring2, ++ size_t byteLength); ++ ++ inline int char_size() { return static_cast(mode_); } ++ inline js::jit::Scale factor() { ++ return mode_ == UC16 ? js::jit::TimesTwo : js::jit::TimesOne; ++ } ++ ++ js::jit::Address inputStart() { ++ return js::jit::Address(masm_.getStackPointer(), ++ offsetof(FrameData, inputStart)); ++ } ++ js::jit::Address backtrackStackBase() { ++ return js::jit::Address(masm_.getStackPointer(), ++ offsetof(FrameData, backtrackStackBase)); ++ } ++ js::jit::Address matches() { ++ return js::jit::Address(masm_.getStackPointer(), ++ offsetof(FrameData, matches)); ++ } ++ js::jit::Address numMatches() { ++ return js::jit::Address(masm_.getStackPointer(), ++ offsetof(FrameData, numMatches)); ++ } ++ ++ // The stack-pointer-relative location of a regexp register. ++ js::jit::Address register_location(int register_index) { ++ return js::jit::Address(masm_.getStackPointer(), ++ register_offset(register_index)); ++ } ++ ++ int32_t register_offset(int register_index) { ++ MOZ_ASSERT(register_index >= 0 && register_index <= kMaxRegister); ++ if (num_registers_ <= register_index) { ++ num_registers_ = register_index + 1; ++ } ++ static_assert(alignof(uintptr_t) <= alignof(FrameData), ++ "Regexp: Alignment of uintptr_t and FrameData mismatch"); ++ return sizeof(FrameData) + register_index * sizeof(uintptr_t*); ++ } ++ ++ JSContext* cx_; ++ js::jit::StackMacroAssembler& masm_; ++ ++ /* ++ * This assembler uses the following registers: ++ * ++ * - current_character_: ++ * Contains the character (or characters) currently being examined. ++ * Must be loaded using LoadCurrentCharacter before using any of the ++ * dispatch methods. After a matching pass for a global regexp, ++ * temporarily stores the index of capture start. ++ * - current_position_: ++ * Current position in input *as negative byte offset from end of string*. ++ * - input_end_pointer_: ++ * Points to byte after last character in the input. current_position_ is ++ * relative to this. ++ * - backtrack_stack_pointer_: ++ * Points to tip of the (heap-allocated) backtrack stack. The stack grows ++ * downward (like the native stack). ++ * - temp0_, temp1_, temp2_: ++ * Scratch registers. ++ * ++ * The native stack pointer is used to access arguments (InputOutputData), ++ * local variables (FrameData), and irregexp's internal virtual registers ++ * (see register_location). ++ */ ++ ++ js::jit::Register current_character_; ++ js::jit::Register current_position_; ++ js::jit::Register input_end_pointer_; ++ js::jit::Register backtrack_stack_pointer_; ++ js::jit::Register temp0_, temp1_, temp2_; ++ ++ // These labels are used in various API calls and bound (if used) in ++ // GetCode. If we abort in the middle of a compilation, as may ++ // happen if a regexp is too big, they may be used but not ++ // bound. ++ js::jit::NonAssertingLabel entry_label_; ++ js::jit::NonAssertingLabel start_label_; ++ js::jit::NonAssertingLabel backtrack_label_; ++ js::jit::NonAssertingLabel success_label_; ++ js::jit::NonAssertingLabel exit_label_; ++ js::jit::NonAssertingLabel stack_overflow_label_; ++ js::jit::NonAssertingLabel exit_with_exception_label_; ++ ++ // When we generate the code to push a backtrack label's address ++ // onto the backtrack stack, we don't know its final address. We ++ // have to patch it after linking. This is slightly delicate, as the ++ // Label itself (which is allocated on the stack) may not exist by ++ // the time we link. The approach is as follows: ++ // ++ // 1. When we push a label on the backtrack stack (PushBacktrack), ++ // we bind the label's patchOffset_ field to the offset within ++ // the code that should be overwritten. This works because each ++ // label is only pushed by a single instruction. ++ // ++ // 2. When we bind a label (Bind), we check to see if it has a ++ // bound patchOffset_. If it does, we create a LabelPatch mapping ++ // its patch offset to the offset of the label itself. ++ // ++ // 3. While linking the code, we walk the list of label patches ++ // and patch the code accordingly. ++ class LabelPatch { ++ public: ++ LabelPatch(js::jit::CodeOffset patchOffset, size_t labelOffset) ++ : patchOffset_(patchOffset), labelOffset_(labelOffset) {} ++ ++ js::jit::CodeOffset patchOffset_; ++ size_t labelOffset_ = 0; ++ }; ++ ++ js::Vector labelPatches_; ++ void AddLabelPatch(js::jit::CodeOffset patchOffset, size_t labelOffset) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ if (!labelPatches_.emplaceBack(patchOffset, labelOffset)) { ++ oomUnsafe.crash("Irregexp label patch"); ++ } ++ } ++ ++ Mode mode_; ++ int num_registers_; ++ int num_capture_registers_; ++ js::jit::LiveGeneralRegisterSet savedRegisters_; ++ ++ public: ++ using TableVector = ++ js::Vector, 4, js::SystemAllocPolicy>; ++ TableVector& tables() { return tables_; } ++ ++ private: ++ TableVector tables_; ++ void AddTable(PseudoHandle table) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ if (!tables_.append(std::move(table))) { ++ oomUnsafe.crash("Irregexp table append"); ++ } ++ } ++}; ++ ++} // namespace internal ++} // namespace v8 ++ ++#endif // RegexpMacroAssemblerArch_h +diff -Nrup mozilla/js/src/irregexp/RegExpShim.cpp mozilla-OK/js/src/irregexp/RegExpShim.cpp +--- mozilla/js/src/irregexp/RegExpShim.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpShim.cpp 2023-02-27 08:17:24.844702672 +0300 +@@ -0,0 +1,255 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++// Copyright 2019 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#include "irregexp/RegExpShim.h" ++ ++#include "mozilla/MemoryReporting.h" ++ ++#include ++ ++#include "irregexp/imported/regexp-macro-assembler.h" ++#include "irregexp/imported/regexp-stack.h" ++ ++#include "vm/NativeObject-inl.h" ++ ++#include "mozilla/Sprintf.h" // for SprintfLiteral ++ ++namespace v8 { ++namespace internal { ++ ++void PrintF(const char* format, ...) { ++ va_list arguments; ++ va_start(arguments, format); ++ vprintf(format, arguments); ++ va_end(arguments); ++} ++ ++void PrintF(FILE* out, const char* format, ...) { ++ va_list arguments; ++ va_start(arguments, format); ++ vfprintf(out, format, arguments); ++ va_end(arguments); ++} ++ ++StdoutStream::operator std::ostream&() const { return std::cerr; } ++ ++template ++std::ostream& StdoutStream::operator<<(T t) { ++ return std::cerr << t; ++} ++ ++template std::ostream& StdoutStream::operator<<(char const* c); ++ ++// Origin: ++// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/utils/ostreams.cc#L120-L169 ++// (This is a hand-simplified version.) ++// Writes the given character to the output escaping everything outside ++// of printable ASCII range. ++std::ostream& operator<<(std::ostream& os, const AsUC16& c) { ++ uc16 v = c.value; ++ bool isPrint = 0x20 < v && v <= 0x7e; ++ char buf[10]; ++ const char* format = isPrint ? "%c" : (v <= 0xFF) ? "\\x%02x" : "\\u%04x"; ++ SprintfLiteral(buf, format, v); ++ return os << buf; ++} ++std::ostream& operator<<(std::ostream& os, const AsUC32& c) { ++ int32_t v = c.value; ++ if (v <= String::kMaxUtf16CodeUnit) { ++ return os << AsUC16(v); ++ } ++ char buf[13]; ++ SprintfLiteral(buf, "\\u{%06x}", v); ++ return os << buf; ++} ++ ++HandleScope::HandleScope(Isolate* isolate) : isolate_(isolate) { ++ isolate->openHandleScope(*this); ++} ++ ++HandleScope::~HandleScope() { ++ isolate_->closeHandleScope(level_, non_gc_level_); ++} ++ ++template ++Handle::Handle(T object, Isolate* isolate) ++ : location_(isolate->getHandleLocation(object.value())) {} ++ ++template Handle::Handle(ByteArray b, Isolate* isolate); ++template Handle::Handle(const JS::Value& v, Isolate* isolate); ++template Handle::Handle(JSRegExp re, Isolate* isolate); ++template Handle::Handle(String s, Isolate* isolate); ++ ++template ++Handle::Handle(const JS::Value& value, Isolate* isolate) ++ : location_(isolate->getHandleLocation(value)) { ++ T::cast(Object(value)); // Assert that value has the correct type. ++} ++ ++JS::Value* Isolate::getHandleLocation(const JS::Value& value) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ if (!handleArena_.Append(value)) { ++ oomUnsafe.crash("Irregexp handle allocation"); ++ } ++ return &handleArena_.GetLast(); ++} ++ ++void* Isolate::allocatePseudoHandle(size_t bytes) { ++ PseudoHandle ptr; ++ ptr.reset(js_malloc(bytes)); ++ if (!ptr) { ++ return nullptr; ++ } ++ if (!uniquePtrArena_.Append(std::move(ptr))) { ++ return nullptr; ++ } ++ return uniquePtrArena_.GetLast().get(); ++} ++ ++template ++PseudoHandle Isolate::takeOwnership(void* ptr) { ++ for (auto iter = uniquePtrArena_.IterFromLast(); !iter.Done(); iter.Prev()) { ++ auto& entry = iter.Get(); ++ if (entry.get() == ptr) { ++ PseudoHandle result; ++ result.reset(static_cast(entry.release())); ++ return result; ++ } ++ } ++ MOZ_CRASH("Tried to take ownership of pseudohandle that is not in the arena"); ++} ++ ++PseudoHandle ByteArray::takeOwnership(Isolate* isolate) { ++ PseudoHandle result = ++ isolate->takeOwnership(value().toPrivate()); ++ setValue(JS::PrivateValue(nullptr)); ++ return result; ++} ++ ++void Isolate::trace(JSTracer* trc) { ++ for (auto iter = handleArena_.Iter(); !iter.Done(); iter.Next()) { ++ auto& elem = iter.Get(); ++ JS::GCPolicy::trace(trc, &elem, "Isolate handle arena"); ++ } ++} ++ ++size_t Isolate::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { ++ size_t size = mallocSizeOf(this); ++ ++ // The RegExpStack code is imported from V8, so we peek inside it to ++ // measure its memory from here. ++ size += mallocSizeOf(regexpStack_); ++ if (regexpStack_->thread_local_.owns_memory_) { ++ size += mallocSizeOf(regexpStack_->thread_local_.memory_); ++ } ++ ++ size += handleArena_.SizeOfExcludingThis(mallocSizeOf); ++ size += uniquePtrArena_.SizeOfExcludingThis(mallocSizeOf); ++ return size; ++} ++ ++/*static*/ Handle String::Flatten(Isolate* isolate, ++ Handle string) { ++ if (string->IsFlat()) { ++ return string; ++ } ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ JSLinearString* linear = string->str()->ensureLinear(isolate->cx()); ++ if (!linear) { ++ oomUnsafe.crash("Irregexp String::Flatten"); ++ } ++ return Handle(JS::StringValue(linear), isolate); ++} ++ ++// This is only used for trace messages printing the source pattern of ++// a regular expression. We have to return a unique_ptr, but we don't ++// care about the contents, so we return an empty null-terminated string. ++std::unique_ptr String::ToCString() { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ ++ std::unique_ptr ptr; ++ ptr.reset(static_cast(js_malloc(1))); ++ if (!ptr) { ++ oomUnsafe.crash("Irregexp String::ToCString"); ++ } ++ ptr[0] = '\0'; ++ ++ return ptr; ++} ++ ++bool Isolate::init() { ++ regexpStack_ = js_new(); ++ if (!regexpStack_) { ++ return false; ++ } ++ return true; ++} ++ ++Isolate::~Isolate() { ++ if (regexpStack_) { ++ js_delete(regexpStack_); ++ } ++} ++ ++byte* Isolate::top_of_regexp_stack() const { ++ return reinterpret_cast(regexpStack_->memory_top_address_address()); ++} ++ ++Handle Isolate::NewByteArray(int length, AllocationType alloc) { ++ MOZ_RELEASE_ASSERT(length >= 0); ++ ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ ++ size_t alloc_size = sizeof(uint32_t) + length; ++ ByteArrayData* data = ++ static_cast(allocatePseudoHandle(alloc_size)); ++ if (!data) { ++ oomUnsafe.crash("Irregexp NewByteArray"); ++ } ++ data->length = length; ++ ++ return Handle(JS::PrivateValue(data), this); ++} ++ ++Handle Isolate::NewFixedArray(int length) { ++ MOZ_RELEASE_ASSERT(length >= 0); ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ js::ArrayObject* array = js::NewDenseFullyAllocatedArray(cx(), length); ++ if (!array) { ++ oomUnsafe.crash("Irregexp NewFixedArray"); ++ } ++ array->ensureDenseInitializedLength(cx(), 0, length); ++ return Handle(JS::ObjectValue(*array), this); ++} ++ ++template ++Handle Isolate::InternalizeString(const Vector& str) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ JSAtom* atom = js::AtomizeChars(cx(), str.begin(), str.length()); ++ if (!atom) { ++ oomUnsafe.crash("Irregexp InternalizeString"); ++ } ++ return Handle(JS::StringValue(atom), this); ++} ++ ++template Handle Isolate::InternalizeString( ++ const Vector& str); ++template Handle Isolate::InternalizeString( ++ const Vector& str); ++ ++static_assert(JSRegExp::RegistersForCaptureCount(JSRegExp::kMaxCaptures) <= ++ RegExpMacroAssembler::kMaxRegisterCount); ++ ++bool FLAG_trace_regexp_assembler = false; ++bool FLAG_trace_regexp_bytecodes = false; ++bool FLAG_trace_regexp_parser = false; ++bool FLAG_trace_regexp_peephole_optimization = false; ++ ++} // namespace internal ++} // namespace v8 +diff -Nrup mozilla/js/src/irregexp/RegExpShim.h mozilla-OK/js/src/irregexp/RegExpShim.h +--- mozilla/js/src/irregexp/RegExpShim.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpShim.h 2023-02-27 08:17:58.257466033 +0300 +@@ -0,0 +1,1261 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++// Copyright 2019 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef RegexpShim_h ++#define RegexpShim_h ++ ++#include "mozilla/Assertions.h" ++#include "mozilla/Attributes.h" ++#include "mozilla/MathAlgorithms.h" ++#include "mozilla/Maybe.h" ++#include "mozilla/SegmentedVector.h" ++#include "mozilla/Sprintf.h" ++#include "mozilla/Types.h" ++ ++#include ++#include ++#include // needed for gcc 10 ++ ++#include "irregexp/RegExpTypes.h" ++#include "irregexp/util/FlagsShim.h" ++#include "irregexp/util/VectorShim.h" ++#include "irregexp/util/ZoneShim.h" ++#include "jit/Label.h" ++#include "jit/shared/Assembler-shared.h" ++#include "js/Value.h" ++#include "threading/ExclusiveData.h" ++#include "vm/MutexIDs.h" ++#include "vm/NativeObject.h" ++ ++// Forward declaration of classes ++namespace v8 { ++namespace internal { ++ ++class Heap; ++class Isolate; ++class RegExpMatchInfo; ++class RegExpStack; ++ ++} // namespace internal ++} // namespace v8 ++ ++#define V8_WARN_UNUSED_RESULT MOZ_MUST_USE ++#define V8_EXPORT_PRIVATE MOZ_EXPORT ++#define V8_FALLTHROUGH [[fallthrough]] ++#define V8_NODISCARD [[nodiscard]] ++ ++#define FATAL(x) MOZ_CRASH(x) ++#define UNREACHABLE() MOZ_CRASH("unreachable code") ++#define UNIMPLEMENTED() MOZ_CRASH("unimplemented code") ++#define STATIC_ASSERT(exp) static_assert(exp, #exp) ++ ++#define DCHECK MOZ_ASSERT ++#define DCHECK_EQ(lhs, rhs) MOZ_ASSERT((lhs) == (rhs)) ++#define DCHECK_NE(lhs, rhs) MOZ_ASSERT((lhs) != (rhs)) ++#define DCHECK_GT(lhs, rhs) MOZ_ASSERT((lhs) > (rhs)) ++#define DCHECK_GE(lhs, rhs) MOZ_ASSERT((lhs) >= (rhs)) ++#define DCHECK_LT(lhs, rhs) MOZ_ASSERT((lhs) < (rhs)) ++#define DCHECK_LE(lhs, rhs) MOZ_ASSERT((lhs) <= (rhs)) ++#define DCHECK_NULL(val) MOZ_ASSERT((val) == nullptr) ++#define DCHECK_NOT_NULL(val) MOZ_ASSERT((val) != nullptr) ++#define DCHECK_IMPLIES(lhs, rhs) MOZ_ASSERT_IF(lhs, rhs) ++#define CHECK MOZ_RELEASE_ASSERT ++#define CHECK_LE(lhs, rhs) MOZ_RELEASE_ASSERT((lhs) <= (rhs)) ++#define CHECK_GE(lhs, rhs) MOZ_RELEASE_ASSERT((lhs) >= (rhs)) ++#define CONSTEXPR_DCHECK MOZ_ASSERT ++ ++template ++static constexpr inline T Min(T t1, T t2) { ++ return t1 < t2 ? t1 : t2; ++} ++ ++template ++static constexpr inline T Max(T t1, T t2) { ++ return t1 > t2 ? t1 : t2; ++} ++#define MemCopy memcpy ++ ++// Origin: ++// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/macros.h#L310-L319 ++// ptrdiff_t is 't' according to the standard, but MSVC uses 'I'. ++#ifdef _MSC_VER ++# define V8PRIxPTRDIFF "Ix" ++# define V8PRIdPTRDIFF "Id" ++# define V8PRIuPTRDIFF "Iu" ++#else ++# define V8PRIxPTRDIFF "tx" ++# define V8PRIdPTRDIFF "td" ++# define V8PRIuPTRDIFF "tu" ++#endif ++ ++#define arraysize mozilla::ArrayLength ++ ++// Explicitly declare the assignment operator as deleted. ++#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete ++ ++// Explicitly declare the copy constructor and assignment operator as deleted. ++// This also deletes the implicit move constructor and implicit move assignment ++// operator, but still allows to manually define them. ++#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ ++ TypeName(const TypeName&) = delete; \ ++ DISALLOW_ASSIGN(TypeName) ++ ++// Explicitly declare all implicit constructors as deleted, namely the ++// default constructor, copy constructor and operator= functions. ++// This is especially useful for classes containing only static methods. ++#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ ++ TypeName() = delete; \ ++ DISALLOW_COPY_AND_ASSIGN(TypeName) ++ ++namespace v8 { ++ ++// Origin: ++// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/macros.h#L364-L367 ++template ++constexpr inline bool IsAligned(T value, U alignment) { ++ return (value & (alignment - 1)) == 0; ++} ++ ++using byte = uint8_t; ++using Address = uintptr_t; ++static const Address kNullAddress = 0; ++ ++// Latin1/UTF-16 constants ++// Code-point values in Unicode 4.0 are 21 bits wide. ++// Code units in UTF-16 are 16 bits wide. ++using uc16 = char16_t; ++using uc32 = uint32_t; ++ ++namespace base { ++ ++// Origin: ++// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/macros.h#L247-L258 ++// The USE(x, ...) template is used to silence C++ compiler warnings ++// issued for (yet) unused variables (typically parameters). ++// The arguments are guaranteed to be evaluated from left to right. ++struct Use { ++ template ++ Use(T&&) {} // NOLINT(runtime/explicit) ++}; ++#define USE(...) \ ++ do { \ ++ ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \ ++ (void)unused_tmp_array_for_use_macro; \ ++ } while (false) ++ ++// Origin: ++// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/base/safe_conversions.h#L35-L39 ++// saturated_cast<> is analogous to static_cast<> for numeric types, except ++// that the specified numeric conversion will saturate rather than overflow or ++// underflow. ++template ++inline Dst saturated_cast(Src value); ++ ++// This is the only specialization that is needed for regexp code. ++// Instead of pulling in dozens of lines of template goo ++// to derive it, I used the implementation from uint8_clamped in ++// ArrayBufferObject.h. ++template <> ++inline uint8_t saturated_cast(int x) { ++ return (x >= 0) ? ((x < 255) ? uint8_t(x) : 255) : 0; ++} ++ ++// Origin: ++// https://github.com/v8/v8/blob/fc088cdaccadede84886eee881e67af9db53669a/src/base/bounds.h#L14-L28 ++// Checks if value is in range [lower_limit, higher_limit] using a single ++// branch. ++template ++inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) { ++ using unsigned_T = typename std::make_unsigned::type; ++ // Use static_cast to support enum classes. ++ return static_cast(static_cast(value) - ++ static_cast(lower_limit)) <= ++ static_cast(static_cast(higher_limit) - ++ static_cast(lower_limit)); ++} ++ ++#define LAZY_INSTANCE_INITIALIZER \ ++ {} ++ ++template ++class LazyInstanceImpl { ++ public: ++ LazyInstanceImpl() : value_(js::mutexid::IrregexpLazyStatic) {} ++ ++ const T* Pointer() { ++ auto val = value_.lock(); ++ if (val->isNothing()) { ++ val->emplace(); ++ } ++ return val->ptr(); ++ } ++ ++ private: ++ js::ExclusiveData> value_; ++}; ++ ++template ++class LazyInstance { ++ public: ++ using type = LazyInstanceImpl; ++}; ++ ++namespace bits { ++ ++inline uint64_t CountTrailingZeros(uint64_t value) { ++ return mozilla::CountTrailingZeroes64(value); ++} ++ ++inline size_t RoundUpToPowerOfTwo32(size_t value) { ++ return mozilla::RoundUpPow2(value); ++} ++ ++template ++constexpr bool IsPowerOfTwo(T value) { ++ return value > 0 && (value & (value - 1)) == 0; ++} ++ ++} // namespace bits ++} // namespace base ++ ++namespace unibrow { ++ ++using uchar = unsigned int; ++ ++// Origin: ++// https://github.com/v8/v8/blob/1f1e4cdb04c75eab77adbecd5f5514ddc3eb56cf/src/strings/unicode.h#L133-L150 ++class Latin1 { ++ public: ++ static const uc16 kMaxChar = 0xff; ++ ++ // Convert the character to Latin-1 case equivalent if possible. ++ static inline uc16 TryConvertToLatin1(uc16 c) { ++ // "GREEK CAPITAL LETTER MU" case maps to "MICRO SIGN". ++ // "GREEK SMALL LETTER MU" case maps to "MICRO SIGN". ++ if (c == 0x039C || c == 0x03BC) { ++ return 0xB5; ++ } ++ // "LATIN CAPITAL LETTER Y WITH DIAERESIS" case maps to "LATIN SMALL LETTER ++ // Y WITH DIAERESIS". ++ if (c == 0x0178) { ++ return 0xFF; ++ } ++ return c; ++ } ++}; ++ ++// Origin: ++// https://github.com/v8/v8/blob/b4bfbce6f91fc2cc72178af42bb3172c5f5eaebb/src/strings/unicode.h#L99-L131 ++class Utf16 { ++ public: ++ static inline bool IsLeadSurrogate(int code) { ++ return js::unicode::IsLeadSurrogate(code); ++ } ++ static inline bool IsTrailSurrogate(int code) { ++ return js::unicode::IsTrailSurrogate(code); ++ } ++ static inline uc16 LeadSurrogate(uint32_t char_code) { ++ return js::unicode::LeadSurrogate(char_code); ++ } ++ static inline uc16 TrailSurrogate(uint32_t char_code) { ++ return js::unicode::TrailSurrogate(char_code); ++ } ++ static inline uint32_t CombineSurrogatePair(char16_t lead, char16_t trail) { ++ return js::unicode::UTF16Decode(lead, trail); ++ } ++ static const uchar kMaxNonSurrogateCharCode = 0xffff; ++}; ++ ++#ifndef V8_INTL_SUPPORT ++ ++// A cache used in case conversion. It caches the value for characters ++// that either have no mapping or map to a single character independent ++// of context. Characters that map to more than one character or that ++// map differently depending on context are always looked up. ++// Origin: ++// https://github.com/v8/v8/blob/b4bfbce6f91fc2cc72178af42bb3172c5f5eaebb/src/strings/unicode.h#L64-L88 ++template ++class Mapping { ++ public: ++ inline Mapping() = default; ++ inline int get(uchar c, uchar n, uchar* result) { ++ CacheEntry entry = entries_[c & kMask]; ++ if (entry.code_point_ == c) { ++ if (entry.offset_ == 0) { ++ return 0; ++ } else { ++ result[0] = c + entry.offset_; ++ return 1; ++ } ++ } else { ++ return CalculateValue(c, n, result); ++ } ++ } ++ ++ private: ++ int CalculateValue(uchar c, uchar n, uchar* result) { ++ bool allow_caching = true; ++ int length = T::Convert(c, n, result, &allow_caching); ++ if (allow_caching) { ++ if (length == 1) { ++ entries_[c & kMask] = CacheEntry(c, result[0] - c); ++ return 1; ++ } else { ++ entries_[c & kMask] = CacheEntry(c, 0); ++ return 0; ++ } ++ } else { ++ return length; ++ } ++ } ++ ++ struct CacheEntry { ++ inline CacheEntry() : code_point_(kNoChar), offset_(0) {} ++ inline CacheEntry(uchar code_point, signed offset) ++ : code_point_(code_point), offset_(offset) {} ++ uchar code_point_; ++ signed offset_; ++ static const int kNoChar = (1 << 21) - 1; ++ }; ++ static const int kSize = size; ++ static const int kMask = kSize - 1; ++ CacheEntry entries_[kSize]; ++}; ++ ++// Origin: ++// https://github.com/v8/v8/blob/b4bfbce6f91fc2cc72178af42bb3172c5f5eaebb/src/strings/unicode.h#L241-L252 ++struct Ecma262Canonicalize { ++ static const int kMaxWidth = 1; ++ static int Convert(uchar c, uchar n, uchar* result, bool* allow_caching_ptr); ++}; ++struct Ecma262UnCanonicalize { ++ static const int kMaxWidth = 4; ++ static int Convert(uchar c, uchar n, uchar* result, bool* allow_caching_ptr); ++}; ++struct CanonicalizationRange { ++ static const int kMaxWidth = 1; ++ static int Convert(uchar c, uchar n, uchar* result, bool* allow_caching_ptr); ++}; ++ ++#endif // !V8_INTL_SUPPORT ++ ++struct Letter { ++ static bool Is(uchar c); ++}; ++ ++} // namespace unibrow ++ ++namespace internal { ++ ++#define PRINTF_FORMAT(x, y) MOZ_FORMAT_PRINTF(x, y) ++void PRINTF_FORMAT(1, 2) PrintF(const char* format, ...); ++void PRINTF_FORMAT(2, 3) PrintF(FILE* out, const char* format, ...); ++ ++// Superclass for classes only using static method functions. ++// The subclass of AllStatic cannot be instantiated at all. ++class AllStatic { ++#ifdef DEBUG ++ public: ++ AllStatic() = delete; ++#endif ++}; ++ ++// Superclass for classes managed with new and delete. ++// In irregexp, this is only AlternativeGeneration (in regexp-compiler.cc) ++// Compare: ++// https://github.com/v8/v8/blob/7b3332844212d78ee87a9426f3a6f7f781a8fbfa/src/utils/allocation.cc#L88-L96 ++class Malloced { ++ public: ++ static void* operator new(size_t size) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ void* result = js_malloc(size); ++ if (!result) { ++ oomUnsafe.crash("Irregexp Malloced shim"); ++ } ++ return result; ++ } ++ static void operator delete(void* p) { js_free(p); } ++}; ++ ++constexpr int32_t KB = 1024; ++constexpr int32_t MB = 1024 * 1024; ++ ++#define kMaxInt JSVAL_INT_MAX ++#define kMinInt JSVAL_INT_MIN ++constexpr int kSystemPointerSize = sizeof(void*); ++ ++// The largest integer n such that n and n + 1 are both exactly ++// representable as a Number value. ES6 section 20.1.2.6 ++constexpr double kMaxSafeInteger = 9007199254740991.0; // 2^53-1 ++ ++constexpr int kBitsPerByte = 8; ++constexpr int kBitsPerByteLog2 = 3; ++constexpr int kUInt32Size = sizeof(uint32_t); ++constexpr int kInt64Size = sizeof(int64_t); ++constexpr int kUC16Size = sizeof(uc16); ++ ++inline constexpr bool IsDecimalDigit(uc32 c) { return c >= '0' && c <= '9'; } ++ ++inline bool is_uint24(int64_t val) { return (val >> 24) == 0; } ++inline bool is_int24(int64_t val) { ++ int64_t limit = int64_t(1) << 23; ++ return (-limit <= val) && (val < limit); ++} ++ ++inline bool IsIdentifierStart(uc32 c) { ++ return js::unicode::IsIdentifierStart(uint32_t(c)); ++} ++inline bool IsIdentifierPart(uc32 c) { ++ return js::unicode::IsIdentifierPart(uint32_t(c)); ++} ++ ++// Wrappers to disambiguate char16_t and uc16. ++struct AsUC16 { ++ explicit AsUC16(char16_t v) : value(v) {} ++ char16_t value; ++}; ++ ++struct AsUC32 { ++ explicit AsUC32(int32_t v) : value(v) {} ++ int32_t value; ++}; ++ ++std::ostream& operator<<(std::ostream& os, const AsUC16& c); ++std::ostream& operator<<(std::ostream& os, const AsUC32& c); ++ ++// This class is used for the output of trace-regexp-parser. V8 has ++// an elaborate implementation to ensure that the output gets to the ++// right place, even on Android. We just need something that will ++// print output (ideally to stderr, to match the rest of our tracing ++// code). This is an empty wrapper that will convert itself to ++// std::cerr when used. ++class StdoutStream { ++ public: ++ operator std::ostream&() const; ++ template ++ std::ostream& operator<<(T t); ++}; ++ ++// Reuse existing Maybe implementation ++using mozilla::Maybe; ++ ++template ++Maybe Just(const T& value) { ++ return mozilla::Some(value); ++} ++ ++template ++mozilla::Nothing Nothing() { ++ return mozilla::Nothing(); ++} ++ ++template ++using PseudoHandle = mozilla::UniquePtr; ++ ++// Compare 8bit/16bit chars to 8bit/16bit chars. ++// Used indirectly by regexp-interpreter.cc ++// Taken from: https://github.com/v8/v8/blob/master/src/utils/utils.h ++template ++inline int CompareCharsUnsigned(const lchar* lhs, const rchar* rhs, ++ size_t chars) { ++ const lchar* limit = lhs + chars; ++ if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) { ++ // memcmp compares byte-by-byte, yielding wrong results for two-byte ++ // strings on little-endian systems. ++ return memcmp(lhs, rhs, chars); ++ } ++ while (lhs < limit) { ++ int r = static_cast(*lhs) - static_cast(*rhs); ++ if (r != 0) return r; ++ ++lhs; ++ ++rhs; ++ } ++ return 0; ++} ++template ++inline int CompareChars(const lchar* lhs, const rchar* rhs, size_t chars) { ++ DCHECK_LE(sizeof(lchar), 2); ++ DCHECK_LE(sizeof(rchar), 2); ++ if (sizeof(lchar) == 1) { ++ if (sizeof(rchar) == 1) { ++ return CompareCharsUnsigned(reinterpret_cast(lhs), ++ reinterpret_cast(rhs), chars); ++ } else { ++ return CompareCharsUnsigned(reinterpret_cast(lhs), ++ reinterpret_cast(rhs), ++ chars); ++ } ++ } else { ++ if (sizeof(rchar) == 1) { ++ return CompareCharsUnsigned(reinterpret_cast(lhs), ++ reinterpret_cast(rhs), chars); ++ } else { ++ return CompareCharsUnsigned(reinterpret_cast(lhs), ++ reinterpret_cast(rhs), ++ chars); ++ } ++ } ++} ++ ++// Compare 8bit/16bit chars to 8bit/16bit chars. ++template ++inline bool CompareCharsEqualUnsigned(const lchar* lhs, const rchar* rhs, ++ size_t chars) { ++ STATIC_ASSERT(std::is_unsigned::value); ++ STATIC_ASSERT(std::is_unsigned::value); ++ if (sizeof(*lhs) == sizeof(*rhs)) { ++ // memcmp compares byte-by-byte, but for equality it doesn't matter whether ++ // two-byte char comparison is little- or big-endian. ++ return memcmp(lhs, rhs, chars * sizeof(*lhs)) == 0; ++ } ++ for (const lchar* limit = lhs + chars; lhs < limit; ++lhs, ++rhs) { ++ if (*lhs != *rhs) return false; ++ } ++ return true; ++} ++ ++template ++inline bool CompareCharsEqual(const lchar* lhs, const rchar* rhs, ++ size_t chars) { ++ using ulchar = typename std::make_unsigned::type; ++ using urchar = typename std::make_unsigned::type; ++ return CompareCharsEqualUnsigned(reinterpret_cast(lhs), ++ reinterpret_cast(rhs), chars); ++} ++ ++// Origin: ++// https://github.com/v8/v8/blob/855591a54d160303349a5f0a32fab15825c708d1/src/utils/utils.h#L40-L48 ++// Returns the value (0 .. 15) of a hexadecimal character c. ++// If c is not a legal hexadecimal character, returns a value < 0. ++// Used in regexp-parser.cc ++inline int HexValue(uc32 c) { ++ c -= '0'; ++ if (static_cast(c) <= 9) return c; ++ c = (c | 0x20) - ('a' - '0'); // detect 0x11..0x16 and 0x31..0x36. ++ if (static_cast(c) <= 5) return c + 10; ++ return -1; ++} ++ ++// V8::Object ~= JS::Value ++class Object { ++ public: ++ // The default object constructor in V8 stores a nullptr, ++ // which has its low bit clear and is interpreted as Smi(0). ++ constexpr Object() : asBits_(JS::Int32Value(0).asRawBits()) {} ++ ++ Object(const JS::Value& value) { setValue(value); } ++ ++ // Used in regexp-interpreter.cc to check the return value of ++ // isolate->stack_guard()->HandleInterrupts(). We want to handle ++ // interrupts in the caller, so we always return false from ++ // HandleInterrupts and true here. ++ inline bool IsException(Isolate*) const { ++ MOZ_ASSERT(!value().toBoolean()); ++ return true; ++ } ++ ++ JS::Value value() const { return JS::Value::fromRawBits(asBits_); } ++ ++ inline static Object cast(Object object) { return object; } ++ ++ protected: ++ void setValue(const JS::Value& val) { asBits_ = val.asRawBits(); } ++ uint64_t asBits_; ++} JS_HAZ_GC_POINTER; ++ ++class Smi : public Object { ++ public: ++ static Smi FromInt(int32_t value) { ++ Smi smi; ++ smi.setValue(JS::Int32Value(value)); ++ return smi; ++ } ++ static inline int32_t ToInt(const Object object) { ++ return object.value().toInt32(); ++ } ++}; ++ ++// V8::HeapObject ~= GC thing ++class HeapObject : public Object { ++ public: ++ inline static HeapObject cast(Object object) { ++ HeapObject h; ++ h.setValue(object.value()); ++ return h; ++ } ++}; ++ ++// A fixed-size array with Objects (aka Values) as element types. ++// Implemented using the dense elements of an ArrayObject. ++// Used for named captures. ++class FixedArray : public HeapObject { ++ public: ++ inline void set(uint32_t index, Object value) { ++ inner()->setDenseElement(index, value.value()); ++ } ++ inline static FixedArray cast(Object object) { ++ FixedArray f; ++ f.setValue(object.value()); ++ return f; ++ } ++ js::NativeObject* inner() { ++ return &value().toObject().as(); ++ } ++}; ++ ++/* ++ * Conceptually, ByteArrayData is a variable-size structure. To ++ * implement this in a C++-approved way, we allocate a struct ++ * containing the 32-bit length field, followed by additional memory ++ * for the data. To access the data, we get a pointer to the next byte ++ * after the length field and cast it to the correct type. ++ */ ++inline uint8_t* ByteArrayData::data() { ++ static_assert(alignof(uint8_t) <= alignof(ByteArrayData), ++ "The trailing data must be aligned to start immediately " ++ "after the header with no padding."); ++ ByteArrayData* immediatelyAfter = this + 1; ++ return reinterpret_cast(immediatelyAfter); ++} ++ ++// A fixed-size array of bytes. ++class ByteArray : public HeapObject { ++ ByteArrayData* inner() const { ++ return static_cast(value().toPrivate()); ++ } ++ ++ public: ++ PseudoHandle takeOwnership(Isolate* isolate); ++ byte get(uint32_t index) { ++ MOZ_ASSERT(index < length()); ++ return inner()->data()[index]; ++ } ++ void set(uint32_t index, byte val) { ++ MOZ_ASSERT(index < length()); ++ inner()->data()[index] = val; ++ } ++ uint32_t length() const { return inner()->length; } ++ byte* GetDataStartAddress() { return inner()->data(); } ++ ++ static ByteArray cast(Object object) { ++ ByteArray b; ++ b.setValue(object.value()); ++ return b; ++ } ++}; ++ ++// Like Handles in SM, V8 handles are references to marked pointers. ++// Unlike SM, where Rooted pointers are created individually on the ++// stack, the target of a V8 handle lives in an arena on the isolate ++// (~= JSContext). Whenever a Handle is created, a new "root" is ++// created at the end of the arena. ++// ++// HandleScopes are used to manage the lifetimes of these handles. A ++// HandleScope lives on the stack and stores the size of the arena at ++// the time of its creation. When the function returns and the ++// HandleScope is destroyed, the arena is truncated to its previous ++// size, clearing all roots that were created since the creation of ++// the HandleScope. ++// ++// In some cases, objects that are GC-allocated in V8 are not in SM. ++// In particular, irregexp allocates ByteArrays during code generation ++// to store lookup tables. This does not play nicely with the SM ++// macroassembler's requirement that no GC allocations take place ++// while it is on the stack. To work around this, this shim layer also ++// provides the ability to create pseudo-handles, which are not ++// managed by the GC but provide the same API to irregexp. The "root" ++// of a pseudohandle is a unique pointer living in a second arena. If ++// the allocated object should outlive the HandleScope, it must be ++// manually moved out of the arena using takeOwnership. ++ ++class MOZ_STACK_CLASS HandleScope { ++ public: ++ HandleScope(Isolate* isolate); ++ ~HandleScope(); ++ ++ private: ++ size_t level_; ++ size_t non_gc_level_; ++ Isolate* isolate_; ++ ++ friend class Isolate; ++}; ++ ++// Origin: ++// https://github.com/v8/v8/blob/5792f3587116503fc047d2f68c951c72dced08a5/src/handles/handles.h#L88-L171 ++template ++class MOZ_NONHEAP_CLASS Handle { ++ public: ++ Handle() : location_(nullptr) {} ++ Handle(T object, Isolate* isolate); ++ Handle(const JS::Value& value, Isolate* isolate); ++ ++ // Constructor for handling automatic up casting. ++ template ::value>::type> ++ inline Handle(Handle handle) : location_(handle.location_) {} ++ ++ inline bool is_null() const { return location_ == nullptr; } ++ ++ inline T operator*() const { return T::cast(Object(*location_)); }; ++ ++ // {ObjectRef} is returned by {Handle::operator->}. It should never be stored ++ // anywhere or used in any other code; no one should ever have to spell out ++ // {ObjectRef} in code. Its only purpose is to be dereferenced immediately by ++ // "operator-> chaining". Returning the address of the field is valid because ++ // this object's lifetime only ends at the end of the full statement. ++ // Origin: ++ // https://github.com/v8/v8/blob/03aaa4b3bf4cb01eee1f223b252e6869b04ab08c/src/handles/handles.h#L91-L105 ++ class ObjectRef { ++ public: ++ T* operator->() { return &object_; } ++ ++ private: ++ friend class Handle; ++ explicit ObjectRef(T object) : object_(object) {} ++ ++ T object_; ++ }; ++ inline ObjectRef operator->() const { return ObjectRef{**this}; } ++ ++ static Handle fromHandleValue(JS::HandleValue handle) { ++ return Handle(handle.address()); ++ } ++ ++ private: ++ Handle(const JS::Value* location) : location_(location) {} ++ ++ template ++ friend class Handle; ++ template ++ friend class MaybeHandle; ++ ++ const JS::Value* location_; ++}; ++ ++// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle ++// into a Handle requires checking that it does not point to nullptr. This ++// ensures nullptr checks before use. ++// ++// Also note that Handles do not provide default equality comparison or hashing ++// operators on purpose. Such operators would be misleading, because intended ++// semantics is ambiguous between Handle location and object identity. ++// Origin: ++// https://github.com/v8/v8/blob/5792f3587116503fc047d2f68c951c72dced08a5/src/handles/maybe-handles.h#L15-L78 ++template ++class MOZ_NONHEAP_CLASS MaybeHandle final { ++ public: ++ MaybeHandle() : location_(nullptr) {} ++ ++ // Constructor for handling automatic up casting from Handle. ++ // Ex. Handle can be passed when MaybeHandle is expected. ++ template ::value>::type> ++ MaybeHandle(Handle handle) : location_(handle.location_) {} ++ ++ inline Handle ToHandleChecked() const { ++ MOZ_RELEASE_ASSERT(location_); ++ return Handle(location_); ++ } ++ ++ // Convert to a Handle with a type that can be upcasted to. ++ template ++ inline bool ToHandle(Handle* out) const { ++ if (location_) { ++ *out = Handle(location_); ++ return true; ++ } else { ++ *out = Handle(); ++ return false; ++ } ++ } ++ ++ private: ++ JS::Value* location_; ++}; ++ ++// From v8/src/handles/handles-inl.h ++ ++template ++inline Handle handle(T object, Isolate* isolate) { ++ return Handle(object, isolate); ++} ++ ++// RAII Guard classes ++ ++using DisallowGarbageCollection = JS::AutoCheckCannotGC; ++ ++// V8 uses this inside DisallowGarbageCollection regions to turn ++// allocation back on before throwing a stack overflow exception or ++// handling interrupts. AutoSuppressGC is sufficient for the former ++// case, but not for the latter: handling interrupts can execute ++// arbitrary script code, and V8 jumps through some scary hoops to ++// "manually relocate unhandlified references" afterwards. To keep ++// things sane, we don't try to handle interrupts while regex code is ++// still on the stack. Instead, we return EXCEPTION and handle ++// interrupts in the caller. (See RegExpShared::execute.) ++ ++class AllowGarbageCollection { ++ public: ++ AllowGarbageCollection() {} ++}; ++ ++// Origin: ++// https://github.com/v8/v8/blob/84f3877c15bc7f8956d21614da4311337525a3c8/src/objects/string.h#L83-L474 ++class String : public HeapObject { ++ private: ++ JSString* str() const { return value().toString(); } ++ ++ public: ++ String() = default; ++ String(JSString* str) { setValue(JS::StringValue(str)); } ++ ++ operator JSString*() const { return str(); } ++ ++ // Max char codes. ++ static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar; ++ static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar; ++ static const int kMaxUtf16CodeUnit = 0xffff; ++ static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit; ++ static const uc32 kMaxCodePoint = 0x10ffff; ++ ++ MOZ_ALWAYS_INLINE int length() const { return str()->length(); } ++ bool IsFlat() { return str()->isLinear(); }; ++ ++ // Origin: ++ // https://github.com/v8/v8/blob/84f3877c15bc7f8956d21614da4311337525a3c8/src/objects/string.h#L95-L152 ++ class FlatContent { ++ public: ++ FlatContent(JSLinearString* string, const DisallowGarbageCollection& no_gc) ++ : string_(string), no_gc_(no_gc) {} ++ inline bool IsOneByte() const { return string_->hasLatin1Chars(); } ++ inline bool IsTwoByte() const { return !string_->hasLatin1Chars(); } ++ ++ Vector ToOneByteVector() const { ++ MOZ_ASSERT(IsOneByte()); ++ return Vector(string_->latin1Chars(no_gc_), ++ string_->length()); ++ } ++ Vector ToUC16Vector() const { ++ MOZ_ASSERT(IsTwoByte()); ++ return Vector(string_->twoByteChars(no_gc_), ++ string_->length()); ++ } ++ ++ private: ++ const JSLinearString* string_; ++ const JS::AutoCheckCannotGC& no_gc_; ++ }; ++ FlatContent GetFlatContent(const DisallowGarbageCollection& no_gc) { ++ MOZ_ASSERT(IsFlat()); ++ return FlatContent(&str()->asLinear(), no_gc); ++ } ++ ++ static Handle Flatten(Isolate* isolate, Handle string); ++ ++ inline static String cast(Object object) { ++ String s; ++ MOZ_ASSERT(object.value().isString()); ++ s.setValue(object.value()); ++ return s; ++ } ++ ++ inline static bool IsOneByteRepresentationUnderneath(String string) { ++ return string.str()->hasLatin1Chars(); ++ } ++ inline bool IsOneByteRepresentation() const { ++ return str()->hasLatin1Chars(); ++ } ++ ++ std::unique_ptr ToCString(); ++ ++ template ++ Vector GetCharVector(const DisallowGarbageCollection& no_gc); ++}; ++ ++template <> ++inline Vector String::GetCharVector( ++ const DisallowGarbageCollection& no_gc) { ++ String::FlatContent flat = GetFlatContent(no_gc); ++ MOZ_ASSERT(flat.IsOneByte()); ++ return flat.ToOneByteVector(); ++} ++ ++template <> ++inline Vector String::GetCharVector( ++ const DisallowGarbageCollection& no_gc) { ++ String::FlatContent flat = GetFlatContent(no_gc); ++ MOZ_ASSERT(flat.IsTwoByte()); ++ return flat.ToUC16Vector(); ++} ++ ++// A flat string reader provides random access to the contents of a ++// string independent of the character width of the string. ++class MOZ_STACK_CLASS FlatStringReader { ++ public: ++ FlatStringReader(JSContext* cx, js::HandleLinearString string) ++ : string_(string), length_(string->length()) {} ++ ++ FlatStringReader(const mozilla::Range range) ++ : string_(nullptr), range_(range), length_(range.length()) {} ++ ++ int length() { return length_; } ++ ++ inline char16_t Get(size_t index) { ++ MOZ_ASSERT(index < length_); ++ if (string_) { ++ return string_->latin1OrTwoByteChar(index); ++ } ++ return range_[index]; ++ } ++ ++ private: ++ js::HandleLinearString string_; ++ const mozilla::Range range_; ++ size_t length_; ++}; ++ ++class JSRegExp : public HeapObject { ++ public: ++ JSRegExp() : HeapObject() {} ++ JSRegExp(js::RegExpShared* re) { setValue(JS::PrivateGCThingValue(re)); } ++ ++ // ****************************************************** ++ // Methods that are called from inside the implementation ++ // ****************************************************** ++ void TierUpTick() { inner()->tierUpTick(); } ++ ++ Object Code(bool is_latin1) const { ++ return Object(JS::PrivateGCThingValue(inner()->getJitCode(is_latin1))); ++ } ++ Object Bytecode(bool is_latin1) const { ++ return Object(JS::PrivateValue(inner()->getByteCode(is_latin1))); ++ } ++ ++ // TODO: should we expose this? ++ uint32_t BacktrackLimit() const { return 0; } ++ ++ static JSRegExp cast(Object object) { ++ JSRegExp regexp; ++ js::gc::Cell* regexpShared = object.value().toGCThing(); ++ MOZ_ASSERT(regexpShared->is()); ++ regexp.setValue(JS::PrivateGCThingValue(regexpShared)); ++ return regexp; ++ } ++ ++ // Each capture (including the match itself) needs two registers. ++ static constexpr int RegistersForCaptureCount(int count) { ++ return (count + 1) * 2; ++ } ++ ++ inline int MaxRegisterCount() const { return inner()->getMaxRegisters(); } ++ ++ // ****************************** ++ // Static constants ++ // ****************************** ++ ++ // Maximum number of captures allowed. ++ static constexpr int kMaxCaptures = (1 << 15) - 1; ++ ++ // ************************************************** ++ // JSRegExp::Flags ++ // ************************************************** ++ ++ enum Flag : uint8_t { ++ kNone = JS::RegExpFlag::NoFlags, ++ kGlobal = JS::RegExpFlag::Global, ++ kIgnoreCase = JS::RegExpFlag::IgnoreCase, ++ kMultiline = JS::RegExpFlag::Multiline, ++ kSticky = JS::RegExpFlag::Sticky, ++ kUnicode = JS::RegExpFlag::Unicode, ++ kDotAll = JS::RegExpFlag::DotAll, ++ }; ++ using Flags = JS::RegExpFlags; ++ ++ static constexpr int kNoBacktrackLimit = 0; ++ ++ private: ++ js::RegExpShared* inner() const { ++ return static_cast(value().toGCThing()); ++ } ++}; ++ ++class Histogram { ++ public: ++ inline void AddSample(int sample) {} ++}; ++ ++class Counters { ++ public: ++ Histogram* regexp_backtracks() { return ®exp_backtracks_; } ++ ++ private: ++ Histogram regexp_backtracks_; ++}; ++ ++#define PROFILE(isolate, call) \ ++ do { \ ++ } while (false); ++ ++enum class AllocationType : uint8_t { ++ kYoung, // Allocate in the nursery ++ kOld, // Allocate in the tenured heap ++}; ++ ++using StackGuard = Isolate; ++using Factory = Isolate; ++ ++class Isolate { ++ public: ++ Isolate(JSContext* cx) : cx_(cx) {} ++ ~Isolate(); ++ bool init(); ++ ++ size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; ++ ++ //********** Isolate code **********// ++ RegExpStack* regexp_stack() const { return regexpStack_; } ++ byte* top_of_regexp_stack() const; ++ ++ // This is called from inside no-GC code. Instead of suppressing GC ++ // to allocate the error, we return false from Execute and call ++ // ReportOverRecursed in the caller. ++ void StackOverflow() {} ++ ++#ifndef V8_INTL_SUPPORT ++ unibrow::Mapping* jsregexp_uncanonicalize() { ++ return &jsregexp_uncanonicalize_; ++ } ++ unibrow::Mapping* ++ regexp_macro_assembler_canonicalize() { ++ return ®exp_macro_assembler_canonicalize_; ++ } ++ unibrow::Mapping* jsregexp_canonrange() { ++ return &jsregexp_canonrange_; ++ } ++ ++ private: ++ unibrow::Mapping jsregexp_uncanonicalize_; ++ unibrow::Mapping ++ regexp_macro_assembler_canonicalize_; ++ unibrow::Mapping jsregexp_canonrange_; ++#endif // !V8_INTL_SUPPORT ++ ++ public: ++ // An empty stub for telemetry we don't support ++ void IncreaseTotalRegexpCodeGenerated(Handle code) {} ++ ++ Counters* counters() { return &counters_; } ++ ++ //********** Factory code **********// ++ inline Factory* factory() { return this; } ++ ++ Handle NewByteArray( ++ int length, AllocationType allocation = AllocationType::kYoung); ++ ++ // Allocates a fixed array initialized with undefined values. ++ Handle NewFixedArray(int length); ++ ++ template ++ Handle InternalizeString(const Vector& str); ++ ++ //********** Stack guard code **********// ++ inline StackGuard* stack_guard() { return this; } ++ ++ // This is called from inside no-GC code. V8 runs the interrupt ++ // inside the no-GC code and then "manually relocates unhandlified ++ // references" afterwards. We just return false and let the caller ++ // handle interrupts. ++ Object HandleInterrupts() { return Object(JS::BooleanValue(false)); } ++ ++ JSContext* cx() const { return cx_; } ++ ++ void trace(JSTracer* trc); ++ ++ //********** Handle code **********// ++ ++ JS::Value* getHandleLocation(const JS::Value& value); ++ ++ private: ++ mozilla::SegmentedVector handleArena_; ++ mozilla::SegmentedVector, 256> uniquePtrArena_; ++ ++ void* allocatePseudoHandle(size_t bytes); ++ ++ public: ++ template ++ PseudoHandle takeOwnership(void* ptr); ++ ++ uint32_t liveHandles() const { return handleArena_.Length(); } ++ uint32_t livePseudoHandles() const { return uniquePtrArena_.Length(); } ++ ++ private: ++ void openHandleScope(HandleScope& scope) { ++ scope.level_ = handleArena_.Length(); ++ scope.non_gc_level_ = uniquePtrArena_.Length(); ++ } ++ void closeHandleScope(size_t prevLevel, size_t prevUniqueLevel) { ++ size_t currLevel = handleArena_.Length(); ++ handleArena_.PopLastN(currLevel - prevLevel); ++ ++ size_t currUniqueLevel = uniquePtrArena_.Length(); ++ uniquePtrArena_.PopLastN(currUniqueLevel - prevUniqueLevel); ++ } ++ friend class HandleScope; ++ ++ JSContext* cx_; ++ RegExpStack* regexpStack_; ++ Counters counters_; ++}; ++ ++// Origin: ++// https://github.com/v8/v8/blob/50dcf2af54ce27801a71c47c1be1d2c5e36b0dd6/src/execution/isolate.h#L1909-L1931 ++class StackLimitCheck { ++ public: ++ StackLimitCheck(Isolate* isolate) : cx_(isolate->cx()) {} ++ ++ // Use this to check for stack-overflows in C++ code. ++ bool HasOverflowed() { ++ bool overflowed = !CheckRecursionLimitDontReport(cx_); ++#ifdef JS_MORE_DETERMINISTIC ++ if (overflowed) { ++ // We don't report overrecursion here, but we throw an exception later ++ // and this still affects differential testing. Mimic ReportOverRecursed ++ // (the fuzzers check for this particular string). ++ fprintf(stderr, "ReportOverRecursed called\n"); ++ } ++#endif ++ return overflowed; ++ } ++ ++ // Use this to check for interrupt request in C++ code. ++ bool InterruptRequested() { return cx_->hasPendingInterrupt(); } ++ ++ // Use this to check for stack-overflow when entering runtime from JS code. ++ bool JsHasOverflowed() { ++ return !CheckRecursionLimitConservativeDontReport(cx_); ++ } ++ ++ private: ++ JSContext* cx_; ++}; ++ ++class Code : public HeapObject { ++ public: ++ uint8_t* raw_instruction_start() { return inner()->raw(); } ++ ++ static Code cast(Object object) { ++ Code c; ++ js::gc::Cell* jitCode = object.value().toGCThing(); ++ MOZ_ASSERT(jitCode->is()); ++ c.setValue(JS::PrivateGCThingValue(jitCode)); ++ return c; ++ } ++ js::jit::JitCode* inner() { ++ return static_cast(value().toGCThing()); ++ } ++}; ++ ++enum class MessageTemplate { kStackOverflow }; ++ ++class MessageFormatter { ++ public: ++ static const char* TemplateString(MessageTemplate index) { ++ switch (index) { ++ case MessageTemplate::kStackOverflow: ++ return "too much recursion"; ++ } ++ } ++}; ++ ++// Origin: https://github.com/v8/v8/blob/master/src/codegen/label.h ++class Label { ++ public: ++ Label() : inner_(js::jit::Label()) {} ++ ++ js::jit::Label* inner() { return &inner_; } ++ ++ void Unuse() { inner_.reset(); } ++ ++ bool is_linked() { return inner_.used(); } ++ bool is_bound() { return inner_.bound(); } ++ bool is_unused() { return !inner_.used() && !inner_.bound(); } ++ ++ int pos() { return inner_.offset(); } ++ void link_to(int pos) { inner_.use(pos); } ++ void bind_to(int pos) { inner_.bind(pos); } ++ ++ private: ++ js::jit::Label inner_; ++ js::jit::CodeOffset patchOffset_; ++ ++ friend class SMRegExpMacroAssembler; ++}; ++ ++//************************************************** ++// Constant Flags ++//************************************************** ++ ++// V8 uses this for differential fuzzing to handle stack overflows. ++// We address the same problem in StackLimitCheck::HasOverflowed. ++const bool FLAG_correctness_fuzzer_suppressions = false; ++ ++// Instead of using a flag for this, we provide an implementation of ++// CanReadUnaligned in SMRegExpMacroAssembler. ++const bool FLAG_enable_regexp_unaligned_accesses = false; ++ ++// This is used to guard a prototype implementation of sequence properties. ++// See: https://github.com/tc39/proposal-regexp-unicode-sequence-properties ++// TODO: Expose this behind a pref once it is past stage 2? ++const bool FLAG_harmony_regexp_sequence = false; ++ ++// This is only used in a helper function in regex.h that we never call. ++const bool FLAG_regexp_interpret_all = false; ++ ++// This is used to guard a prototype implementation of mode modifiers, ++// which can modify the regexp flags on the fly inside the pattern. ++// As far as I can tell, there isn't even a TC39 proposal for this. ++const bool FLAG_regexp_mode_modifiers = false; ++ ++// This is used to guard an old prototype implementation of possessive ++// quantifiers, which never got past the point of adding parser support. ++const bool FLAG_regexp_possessive_quantifier = false; ++ ++// These affect the default level of optimization. We can still turn ++// optimization off on a case-by-case basis in CompilePattern - for ++// example, if a regexp is too long - so we might as well turn these ++// flags on unconditionally. ++const bool FLAG_regexp_optimization = true; ++#if MOZ_BIG_ENDIAN ++// peephole optimization not supported on big endian ++const bool FLAG_regexp_peephole_optimization = false; ++#else ++const bool FLAG_regexp_peephole_optimization = true; ++#endif ++ ++// This is used to control whether regexps tier up from interpreted to ++// compiled. We control this with --no-native-regexp and ++// --regexp-warmup-threshold. ++const bool FLAG_regexp_tier_up = true; ++ ++//************************************************** ++// Debugging Flags ++//************************************************** ++ ++extern bool FLAG_trace_regexp_assembler; ++extern bool FLAG_trace_regexp_bytecodes; ++extern bool FLAG_trace_regexp_parser; ++extern bool FLAG_trace_regexp_peephole_optimization; ++ ++#define COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER ++ ++} // namespace internal ++} // namespace v8 ++ ++#endif // RegexpShim_h +diff -Nrup mozilla/js/src/irregexp/RegExpTypes.h mozilla-OK/js/src/irregexp/RegExpTypes.h +--- mozilla/js/src/irregexp/RegExpTypes.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/RegExpTypes.h 2023-02-27 08:17:24.846702658 +0300 +@@ -0,0 +1,64 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++// This file forward-defines Irregexp classes that need to be visible ++// to the rest of Spidermonkey and re-exports them into js::irregexp. ++ ++#ifndef regexp_RegExpTypes_h ++#define regexp_RegExpTypes_h ++ ++#include "js/UniquePtr.h" ++ ++namespace js { ++class MatchPairs; ++} ++ ++namespace v8 { ++namespace internal { ++ ++class ByteArrayData { ++ public: ++ uint32_t length; ++ uint8_t* data(); ++}; ++class Isolate; ++class RegExpStack; ++class RegExpStackScope; ++ ++struct InputOutputData { ++ const void* inputStart; ++ const void* inputEnd; ++ ++ // Index into inputStart (in chars) at which to begin matching. ++ size_t startIndex; ++ ++ js::MatchPairs* matches; ++ ++ template ++ InputOutputData(const CharT* inputStart, const CharT* inputEnd, ++ size_t startIndex, js::MatchPairs* matches) ++ : inputStart(inputStart), ++ inputEnd(inputEnd), ++ startIndex(startIndex), ++ matches(matches) {} ++}; ++ ++} // namespace internal ++} // namespace v8 ++ ++namespace js { ++namespace irregexp { ++ ++using Isolate = v8::internal::Isolate; ++using RegExpStack = v8::internal::RegExpStack; ++using RegExpStackScope = v8::internal::RegExpStackScope; ++using ByteArrayData = v8::internal::ByteArrayData; ++using ByteArray = js::UniquePtr; ++using InputOutputData = v8::internal::InputOutputData; ++ ++} // namespace irregexp ++} // namespace js ++ ++#endif // regexp_RegExpTypes_h +diff -Nrup mozilla/js/src/irregexp/import-irregexp.py mozilla-OK/js/src/irregexp/import-irregexp.py +--- mozilla/js/src/irregexp/import-irregexp.py 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/import-irregexp.py 2023-02-27 08:17:24.846702658 +0300 +@@ -0,0 +1,148 @@ ++#!/usr/bin/env python3 ++ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this file, ++# You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++# This script handles all the mechanical steps of importing irregexp from v8: ++# ++# 1. Acquire the source: either from github, or optionally from a local copy of v8. ++# 2. Copy the contents of v8/src/regexp into js/src/irregexp/imported ++# - Exclude files that we have chosen not to import. ++# 3. While doing so, update #includes: ++# - Change "src/regexp/*" to "irregexp/imported/*". ++# - Remove other v8-specific headers completely. ++# 4. Add '#include "irregexp/RegExpShim.h" in the necessary places. ++# 5. Update the IRREGEXP_VERSION file to include the correct git hash. ++# ++# Usage: ++# cd path/to/js/src/irregexp ++# ./import-irregexp.py --path path/to/v8/src/regexp ++# ++# Alternatively, without the --path argument, import-irregexp.py will ++# clone v8 from github into a temporary directory. ++# ++# After running this script, changes to the shim code may be necessary ++# to account for changes in upstream irregexp. ++ ++import os ++import re ++import subprocess ++import sys ++from pathlib import Path ++ ++ ++def get_hash(path): ++ # Get the hash for the current git revision ++ cwd = os.getcwd() ++ os.chdir(path) ++ command = ["git", "rev-parse", "HEAD"] ++ result = subprocess.check_output(command, encoding="utf-8") ++ os.chdir(cwd) ++ return result.rstrip() ++ ++ ++def copy_and_update_includes(src_path, dst_path): ++ # List of header files that need to include the shim header ++ need_shim = [ ++ "property-sequences.h", ++ "regexp-ast.h", ++ "regexp-bytecode-peephole.h", ++ "regexp-bytecodes.h", ++ "regexp-dotprinter.h", ++ "regexp-error.h", ++ "regexp.h", ++ "regexp-macro-assembler.h", ++ "regexp-stack.h", ++ "special-case.h", ++ ] ++ ++ src = open(str(src_path), "r") ++ dst = open(str(dst_path), "w") ++ ++ # 1. Rewrite includes of V8 regexp headers: ++ regexp_include = re.compile('#include "src/regexp') ++ regexp_include_new = '#include "irregexp/imported' ++ ++ # 2. Remove includes of other V8 headers ++ other_include = re.compile('#include "src/') ++ ++ # 3. If needed, add '#include "irregexp/RegExpShim.h"'. ++ # Note: We get a little fancy to ensure that header files are ++ # in alphabetic order. `need_to_add_shim` is true if we still ++ # have to add the shim header in this file. `adding_shim_now` ++ # is true if we have found a '#include "src/*' and we are just ++ # waiting to find an empty line so that we can insert the shim ++ # header in the right place. ++ need_to_add_shim = src_path.name in need_shim ++ adding_shim_now = False ++ ++ for line in src: ++ if adding_shim_now: ++ if line == "\n": ++ dst.write('#include "irregexp/RegExpShim.h"\n') ++ need_to_add_shim = False ++ adding_shim_now = False ++ ++ if regexp_include.search(line): ++ dst.write(re.sub(regexp_include, regexp_include_new, line)) ++ elif other_include.search(line): ++ if need_to_add_shim: ++ adding_shim_now = True ++ else: ++ dst.write(line) ++ ++ ++def import_from(srcdir, dstdir): ++ excluded = [ ++ "DIR_METADATA", ++ "OWNERS", ++ "regexp.cc", ++ "regexp-utils.cc", ++ "regexp-utils.h", ++ "regexp-macro-assembler-arch.h", ++ ] ++ ++ for file in srcdir.iterdir(): ++ if file.is_dir(): ++ continue ++ if str(file.name) in excluded: ++ continue ++ copy_and_update_includes(file, dstdir / "imported" / file.name) ++ ++ # Update IRREGEXP_VERSION file ++ hash = get_hash(srcdir) ++ version_file = open(str(dstdir / "IRREGEXP_VERSION"), "w") ++ version_file.write("Imported using import-irregexp.py from:\n") ++ version_file.write("https://github.com/v8/v8/tree/%s/src/regexp\n" % hash) ++ ++ ++if __name__ == "__main__": ++ import argparse ++ import tempfile ++ ++ # This script should be run from js/src/irregexp to work correctly. ++ current_path = Path(os.getcwd()) ++ expected_path = "js/src/irregexp" ++ if not current_path.match(expected_path): ++ raise RuntimeError("%s must be run from %s" % (sys.argv[0], expected_path)) ++ ++ parser = argparse.ArgumentParser(description="Import irregexp from v8") ++ parser.add_argument("-p", "--path", help="path to v8/src/regexp") ++ args = parser.parse_args() ++ ++ if args.path: ++ src_path = Path(args.path) ++ ++ if not (src_path / "regexp.h").exists(): ++ print("Usage:\n import-irregexp.py --path ") ++ sys.exit(1) ++ import_from(src_path, current_path) ++ sys.exit(0) ++ ++ with tempfile.TemporaryDirectory() as tempdir: ++ v8_git = "https://github.com/v8/v8.git" ++ clone = "git clone --depth 1 %s %s" % (v8_git, tempdir) ++ os.system(clone) ++ src_path = Path(tempdir) / "src/regexp" ++ import_from(src_path, current_path) +diff -Nrup mozilla/js/src/irregexp/moz.build mozilla-OK/js/src/irregexp/moz.build +--- mozilla/js/src/irregexp/moz.build 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/moz.build 2023-02-27 08:17:24.863702538 +0300 +@@ -0,0 +1,45 @@ ++# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++include('../js-config.mozbuild') ++include('../js-cxxflags.mozbuild') ++ ++FINAL_LIBRARY = "js" ++ ++# Includes should be relative to parent path ++LOCAL_INCLUDES += ["!..", ".."] ++ ++CXXFLAGS += ["-Wno-error=type-limits"] ++ ++SOURCES += [ ++ 'imported/regexp-ast.cc', ++ 'imported/regexp-bytecode-generator.cc', ++ 'imported/regexp-bytecode-peephole.cc', ++ 'imported/regexp-bytecodes.cc', ++ 'imported/regexp-compiler-tonode.cc', ++ 'imported/regexp-compiler.cc', ++ 'imported/regexp-dotprinter.cc', ++ 'imported/regexp-interpreter.cc', ++ 'imported/regexp-macro-assembler-tracer.cc', ++ 'imported/regexp-macro-assembler.cc', ++ 'imported/regexp-parser.cc', ++ 'imported/regexp-stack.cc', ++ 'RegExpAPI.cpp', ++ 'RegExpNativeMacroAssembler.cpp', ++ 'RegExpShim.cpp', ++ 'util/UnicodeShim.cpp' ++] ++ ++if CONFIG['ENABLE_INTL_API']: ++ CXXFLAGS += ['-DV8_INTL_SUPPORT'] ++ SOURCES += [ ++ 'imported/property-sequences.cc', ++ 'imported/special-case.cc' ++ ] ++ ++if CONFIG['_MSC_VER']: ++ # This is intended as a temporary workaround to unblock compilation ++ # on VS2015 in warnings as errors mode. ++ CXXFLAGS += ['-wd4275'] +\ No newline at end of file +diff -Nrup mozilla/js/src/irregexp/util/FlagsShim.h mozilla-OK/js/src/irregexp/util/FlagsShim.h +--- mozilla/js/src/irregexp/util/FlagsShim.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/util/FlagsShim.h 2023-02-27 08:17:24.863702538 +0300 +@@ -0,0 +1,87 @@ ++// Copyright 2014 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef V8_UTIL_FLAGS_H_ ++#define V8_UTIL_FLAGS_H_ ++ ++// Origin: ++// https://github.com/v8/v8/blob/1bafcc6b999b23ea1d394f5d267a08183e3c4e19/src/base/flags.h#L15-L90 ++ ++namespace v8 { ++namespace base { ++ ++// The Flags class provides a type-safe way of storing OR-combinations of enum ++// values. The Flags class is a template class, where T is an enum type, ++// and S is the underlying storage type (usually int). ++// ++// The traditional C++ approach for storing OR-combinations of enum values is to ++// use an int or unsigned int variable. The inconvenience with this approach is ++// that there's no type checking at all; any enum value can be OR'd with any ++// other enum value and passed on to a function that takes an int or unsigned ++// int. ++template ++class Flags final { ++ public: ++ using flag_type = T; ++ using mask_type = S; ++ ++ Flags() : mask_(0) {} ++ Flags(flag_type flag) : mask_(static_cast(flag)) {} ++ Flags(mask_type mask) : mask_(static_cast(mask)) {} ++ ++ bool operator==(flag_type flag) const { ++ return mask_ == static_cast(flag); ++ } ++ bool operator!=(flag_type flag) const { ++ return mask_ != static_cast(flag); ++ } ++ ++ Flags& operator&=(const Flags& flags) { ++ mask_ &= flags.mask_; ++ return *this; ++ } ++ Flags& operator|=(const Flags& flags) { ++ mask_ |= flags.mask_; ++ return *this; ++ } ++ Flags& operator^=(const Flags& flags) { ++ mask_ ^= flags.mask_; ++ return *this; ++ } ++ ++ Flags operator&(const Flags& flags) const { ++ return Flags(mask_ & flags.mask_); ++ } ++ Flags operator|(const Flags& flags) const { ++ return Flags(mask_ | flags.mask_); ++ } ++ Flags operator^(const Flags& flags) const { ++ return Flags(mask_ ^ flags.mask_); ++ } ++ ++ Flags& operator&=(flag_type flag) { return operator&=(Flags(flag)); } ++ Flags& operator|=(flag_type flag) { return operator|=(Flags(flag)); } ++ Flags& operator^=(flag_type flag) { return operator^=(Flags(flag)); } ++ ++ Flags operator&(flag_type flag) const { return operator&(Flags(flag)); } ++ Flags operator|(flag_type flag) const { return operator|(Flags(flag)); } ++ Flags operator^(flag_type flag) const { return operator^(Flags(flag)); } ++ ++ Flags operator~() const { return Flags(~mask_); } ++ ++ operator mask_type() const { return mask_; } ++ bool operator!() const { return !mask_; } ++ ++ Flags without(flag_type flag) { return *this & (~Flags(flag)); } ++ ++ friend size_t hash_value(const Flags& flags) { return flags.mask_; } ++ ++ private: ++ mask_type mask_; ++}; ++ ++} // namespace base ++} // namespace v8 ++ ++#endif // V8_UTIL_FLAG_H_ +diff -Nrup mozilla/js/src/irregexp/util/UnicodeShim.cpp mozilla-OK/js/src/irregexp/util/UnicodeShim.cpp +--- mozilla/js/src/irregexp/util/UnicodeShim.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/util/UnicodeShim.cpp 2023-02-27 08:17:24.865702524 +0300 +@@ -0,0 +1,1866 @@ ++// Copyright 2012 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++// ++// This file is a subset of: ++// https://github.com/v8/v8/blob/master/src/strings/unicode.cc ++ ++#include "irregexp/RegExpShim.h" ++ ++#ifdef V8_INTL_SUPPORT ++# include "unicode/uchar.h" ++#endif ++ ++namespace v8 { ++namespace unibrow { ++ ++#ifndef V8_INTL_SUPPORT ++static const int kStartBit = (1 << 30); ++static const int kChunkBits = (1 << 13); ++#endif // !V8_INTL_SUPPORT ++ ++static const uchar kSentinel = static_cast(-1); ++ ++/** ++ * \file ++ * Implementations of functions for working with Unicode. ++ */ ++ ++using int16_t = signed short; // NOLINT ++using uint16_t = unsigned short; // NOLINT ++using int32_t = int; // NOLINT ++ ++#ifndef V8_INTL_SUPPORT ++// All access to the character table should go through this function. ++template ++static inline uchar TableGet(const int32_t* table, int index) { ++ return table[D * index]; ++} ++ ++static inline uchar GetEntry(int32_t entry) { return entry & (kStartBit - 1); } ++ ++static inline bool IsStart(int32_t entry) { return (entry & kStartBit) != 0; } ++ ++/** ++ * Look up a character in the Unicode table using a mix of binary and ++ * interpolation search. For a uniformly distributed array ++ * interpolation search beats binary search by a wide margin. However, ++ * in this case interpolation search degenerates because of some very ++ * high values in the lower end of the table so this function uses a ++ * combination. The average number of steps to look up the information ++ * about a character is around 10, slightly higher if there is no ++ * information available about the character. ++ */ ++static bool LookupPredicate(const int32_t* table, uint16_t size, uchar chr) { ++ static const int kEntryDist = 1; ++ uint16_t value = chr & (kChunkBits - 1); ++ unsigned int low = 0; ++ unsigned int high = size - 1; ++ while (high != low) { ++ unsigned int mid = low + ((high - low) >> 1); ++ uchar current_value = GetEntry(TableGet(table, mid)); ++ // If we've found an entry less than or equal to this one, and the ++ // next one is not also less than this one, we've arrived. ++ if ((current_value <= value) && ++ (mid + 1 == size || ++ GetEntry(TableGet(table, mid + 1)) > value)) { ++ low = mid; ++ break; ++ } else if (current_value < value) { ++ low = mid + 1; ++ } else if (current_value > value) { ++ // If we've just checked the bottom-most value and it's not ++ // the one we're looking for, we're done. ++ if (mid == 0) break; ++ high = mid - 1; ++ } ++ } ++ int32_t field = TableGet(table, low); ++ uchar entry = GetEntry(field); ++ bool is_start = IsStart(field); ++ return (entry == value) || (entry < value && is_start); ++} ++#endif // !V8_INTL_SUPPORT ++ ++template ++struct MultiCharacterSpecialCase { ++ static const uchar kEndOfEncoding = kSentinel; ++ uchar chars[kW]; ++}; ++ ++#ifndef V8_INTL_SUPPORT ++// Look up the mapping for the given character in the specified table, ++// which is of the specified length and uses the specified special case ++// mapping for multi-char mappings. The next parameter is the character ++// following the one to map. The result will be written in to the result ++// buffer and the number of characters written will be returned. Finally, ++// if the allow_caching_ptr is non-null then false will be stored in ++// it if the result contains multiple characters or depends on the ++// context. ++// If ranges are linear, a match between a start and end point is ++// offset by the distance between the match and the start. Otherwise ++// the result is the same as for the start point on the entire range. ++template ++static int LookupMapping(const int32_t* table, uint16_t size, ++ const MultiCharacterSpecialCase* multi_chars, ++ uchar chr, uchar next, uchar* result, ++ bool* allow_caching_ptr) { ++ static const int kEntryDist = 2; ++ uint16_t key = chr & (kChunkBits - 1); ++ uint16_t chunk_start = chr - key; ++ unsigned int low = 0; ++ unsigned int high = size - 1; ++ while (high != low) { ++ unsigned int mid = low + ((high - low) >> 1); ++ uchar current_value = GetEntry(TableGet(table, mid)); ++ // If we've found an entry less than or equal to this one, and the next one ++ // is not also less than this one, we've arrived. ++ if ((current_value <= key) && ++ (mid + 1 == size || ++ GetEntry(TableGet(table, mid + 1)) > key)) { ++ low = mid; ++ break; ++ } else if (current_value < key) { ++ low = mid + 1; ++ } else if (current_value > key) { ++ // If we've just checked the bottom-most value and it's not ++ // the one we're looking for, we're done. ++ if (mid == 0) break; ++ high = mid - 1; ++ } ++ } ++ int32_t field = TableGet(table, low); ++ uchar entry = GetEntry(field); ++ bool is_start = IsStart(field); ++ bool found = (entry == key) || (entry < key && is_start); ++ if (found) { ++ int32_t value = table[2 * low + 1]; ++ if (value == 0) { ++ // 0 means not present ++ return 0; ++ } else if ((value & 3) == 0) { ++ // Low bits 0 means a constant offset from the given character. ++ if (ranges_are_linear) { ++ result[0] = chr + (value >> 2); ++ } else { ++ result[0] = entry + chunk_start + (value >> 2); ++ } ++ return 1; ++ } else if ((value & 3) == 1) { ++ // Low bits 1 means a special case mapping ++ if (allow_caching_ptr) *allow_caching_ptr = false; ++ const MultiCharacterSpecialCase& mapping = multi_chars[value >> 2]; ++ int length = 0; ++ for (length = 0; length < kW; length++) { ++ uchar mapped = mapping.chars[length]; ++ if (mapped == MultiCharacterSpecialCase::kEndOfEncoding) break; ++ if (ranges_are_linear) { ++ result[length] = mapped + (key - entry); ++ } else { ++ result[length] = mapped; ++ } ++ } ++ return length; ++ } else { ++ // Low bits 2 means a really really special case ++ if (allow_caching_ptr) *allow_caching_ptr = false; ++ // The cases of this switch are defined in unicode.py in the ++ // really_special_cases mapping. ++ switch (value >> 2) { ++ case 1: ++ // Really special case 1: upper case sigma. This letter ++ // converts to two different lower case sigmas depending on ++ // whether or not it occurs at the end of a word. ++ if (next != 0 && Letter::Is(next)) { ++ result[0] = 0x03C3; ++ } else { ++ result[0] = 0x03C2; ++ } ++ return 1; ++ default: ++ return 0; ++ } ++ return -1; ++ } ++ } else { ++ return 0; ++ } ++} ++#endif // !V8_INTL_SUPPORT ++ ++// Letter: point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl'] ++#ifdef V8_INTL_SUPPORT ++bool Letter::Is(uchar c) { return static_cast(u_isalpha(c)); } ++#else ++static const uint16_t kLetterTable0Size = 431; ++static const int32_t kLetterTable0[431] = { ++ 1073741889, 90, 1073741921, 122, ++ 170, 181, 186, 1073742016, // NOLINT ++ 214, 1073742040, 246, 1073742072, ++ 705, 1073742534, 721, 1073742560, // NOLINT ++ 740, 748, 750, 1073742704, ++ 884, 1073742710, 887, 1073742714, // NOLINT ++ 893, 895, 902, 1073742728, ++ 906, 908, 1073742734, 929, // NOLINT ++ 1073742755, 1013, 1073742839, 1153, ++ 1073742986, 1327, 1073743153, 1366, // NOLINT ++ 1369, 1073743201, 1415, 1073743312, ++ 1514, 1073743344, 1522, 1073743392, // NOLINT ++ 1610, 1073743470, 1647, 1073743473, ++ 1747, 1749, 1073743589, 1766, // NOLINT ++ 1073743598, 1775, 1073743610, 1788, ++ 1791, 1808, 1073743634, 1839, // NOLINT ++ 1073743693, 1957, 1969, 1073743818, ++ 2026, 1073743860, 2037, 2042, // NOLINT ++ 1073743872, 2069, 2074, 2084, ++ 2088, 1073743936, 2136, 1073744032, // NOLINT ++ 2226, 1073744132, 2361, 2365, ++ 2384, 1073744216, 2401, 1073744241, // NOLINT ++ 2432, 1073744261, 2444, 1073744271, ++ 2448, 1073744275, 2472, 1073744298, // NOLINT ++ 2480, 2482, 1073744310, 2489, ++ 2493, 2510, 1073744348, 2525, // NOLINT ++ 1073744351, 2529, 1073744368, 2545, ++ 1073744389, 2570, 1073744399, 2576, // NOLINT ++ 1073744403, 2600, 1073744426, 2608, ++ 1073744434, 2611, 1073744437, 2614, // NOLINT ++ 1073744440, 2617, 1073744473, 2652, ++ 2654, 1073744498, 2676, 1073744517, // NOLINT ++ 2701, 1073744527, 2705, 1073744531, ++ 2728, 1073744554, 2736, 1073744562, // NOLINT ++ 2739, 1073744565, 2745, 2749, ++ 2768, 1073744608, 2785, 1073744645, // NOLINT ++ 2828, 1073744655, 2832, 1073744659, ++ 2856, 1073744682, 2864, 1073744690, // NOLINT ++ 2867, 1073744693, 2873, 2877, ++ 1073744732, 2909, 1073744735, 2913, // NOLINT ++ 2929, 2947, 1073744773, 2954, ++ 1073744782, 2960, 1073744786, 2965, // NOLINT ++ 1073744793, 2970, 2972, 1073744798, ++ 2975, 1073744803, 2980, 1073744808, // NOLINT ++ 2986, 1073744814, 3001, 3024, ++ 1073744901, 3084, 1073744910, 3088, // NOLINT ++ 1073744914, 3112, 1073744938, 3129, ++ 3133, 1073744984, 3161, 1073744992, // NOLINT ++ 3169, 1073745029, 3212, 1073745038, ++ 3216, 1073745042, 3240, 1073745066, // NOLINT ++ 3251, 1073745077, 3257, 3261, ++ 3294, 1073745120, 3297, 1073745137, // NOLINT ++ 3314, 1073745157, 3340, 1073745166, ++ 3344, 1073745170, 3386, 3389, // NOLINT ++ 3406, 1073745248, 3425, 1073745274, ++ 3455, 1073745285, 3478, 1073745306, // NOLINT ++ 3505, 1073745331, 3515, 3517, ++ 1073745344, 3526, 1073745409, 3632, // NOLINT ++ 1073745458, 3635, 1073745472, 3654, ++ 1073745537, 3714, 3716, 1073745543, // NOLINT ++ 3720, 3722, 3725, 1073745556, ++ 3735, 1073745561, 3743, 1073745569, // NOLINT ++ 3747, 3749, 3751, 1073745578, ++ 3755, 1073745581, 3760, 1073745586, // NOLINT ++ 3763, 3773, 1073745600, 3780, ++ 3782, 1073745628, 3807, 3840, // NOLINT ++ 1073745728, 3911, 1073745737, 3948, ++ 1073745800, 3980, 1073745920, 4138, // NOLINT ++ 4159, 1073746000, 4181, 1073746010, ++ 4189, 4193, 1073746021, 4198, // NOLINT ++ 1073746030, 4208, 1073746037, 4225, ++ 4238, 1073746080, 4293, 4295, // NOLINT ++ 4301, 1073746128, 4346, 1073746172, ++ 4680, 1073746506, 4685, 1073746512, // NOLINT ++ 4694, 4696, 1073746522, 4701, ++ 1073746528, 4744, 1073746570, 4749, // NOLINT ++ 1073746576, 4784, 1073746610, 4789, ++ 1073746616, 4798, 4800, 1073746626, // NOLINT ++ 4805, 1073746632, 4822, 1073746648, ++ 4880, 1073746706, 4885, 1073746712, // NOLINT ++ 4954, 1073746816, 5007, 1073746848, ++ 5108, 1073746945, 5740, 1073747567, // NOLINT ++ 5759, 1073747585, 5786, 1073747616, ++ 5866, 1073747694, 5880, 1073747712, // NOLINT ++ 5900, 1073747726, 5905, 1073747744, ++ 5937, 1073747776, 5969, 1073747808, // NOLINT ++ 5996, 1073747822, 6000, 1073747840, ++ 6067, 6103, 6108, 1073748000, // NOLINT ++ 6263, 1073748096, 6312, 6314, ++ 1073748144, 6389, 1073748224, 6430, // NOLINT ++ 1073748304, 6509, 1073748336, 6516, ++ 1073748352, 6571, 1073748417, 6599, // NOLINT ++ 1073748480, 6678, 1073748512, 6740, ++ 6823, 1073748741, 6963, 1073748805, // NOLINT ++ 6987, 1073748867, 7072, 1073748910, ++ 7087, 1073748922, 7141, 1073748992, // NOLINT ++ 7203, 1073749069, 7247, 1073749082, ++ 7293, 1073749225, 7404, 1073749230, // NOLINT ++ 7409, 1073749237, 7414, 1073749248, ++ 7615, 1073749504, 7957, 1073749784, // NOLINT ++ 7965, 1073749792, 8005, 1073749832, ++ 8013, 1073749840, 8023, 8025, // NOLINT ++ 8027, 8029, 1073749855, 8061, ++ 1073749888, 8116, 1073749942, 8124, // NOLINT ++ 8126, 1073749954, 8132, 1073749958, ++ 8140, 1073749968, 8147, 1073749974, // NOLINT ++ 8155, 1073749984, 8172, 1073750002, ++ 8180, 1073750006, 8188}; // NOLINT ++static const uint16_t kLetterTable1Size = 87; ++static const int32_t kLetterTable1[87] = { ++ 113, 127, 1073741968, 156, ++ 258, 263, 1073742090, 275, // NOLINT ++ 277, 1073742105, 285, 292, ++ 294, 296, 1073742122, 301, // NOLINT ++ 1073742127, 313, 1073742140, 319, ++ 1073742149, 329, 334, 1073742176, // NOLINT ++ 392, 1073744896, 3118, 1073744944, ++ 3166, 1073744992, 3300, 1073745131, // NOLINT ++ 3310, 1073745138, 3315, 1073745152, ++ 3365, 3367, 3373, 1073745200, // NOLINT ++ 3431, 3439, 1073745280, 3478, ++ 1073745312, 3494, 1073745320, 3502, // NOLINT ++ 1073745328, 3510, 1073745336, 3518, ++ 1073745344, 3526, 1073745352, 3534, // NOLINT ++ 1073745360, 3542, 1073745368, 3550, ++ 3631, 1073745925, 4103, 1073745953, // NOLINT ++ 4137, 1073745969, 4149, 1073745976, ++ 4156, 1073745985, 4246, 1073746077, // NOLINT ++ 4255, 1073746081, 4346, 1073746172, ++ 4351, 1073746181, 4397, 1073746225, // NOLINT ++ 4494, 1073746336, 4538, 1073746416, ++ 4607, 1073746944, 8191}; // NOLINT ++static const uint16_t kLetterTable2Size = 4; ++static const int32_t kLetterTable2[4] = {1073741824, 3509, 1073745408, ++ 8191}; // NOLINT ++static const uint16_t kLetterTable3Size = 2; ++static const int32_t kLetterTable3[2] = {1073741824, 8191}; // NOLINT ++static const uint16_t kLetterTable4Size = 2; ++static const int32_t kLetterTable4[2] = {1073741824, 8140}; // NOLINT ++static const uint16_t kLetterTable5Size = 100; ++static const int32_t kLetterTable5[100] = { ++ 1073741824, 1164, 1073743056, 1277, ++ 1073743104, 1548, 1073743376, 1567, // NOLINT ++ 1073743402, 1579, 1073743424, 1646, ++ 1073743487, 1693, 1073743520, 1775, // NOLINT ++ 1073743639, 1823, 1073743650, 1928, ++ 1073743755, 1934, 1073743760, 1965, // NOLINT ++ 1073743792, 1969, 1073743863, 2049, ++ 1073743875, 2053, 1073743879, 2058, // NOLINT ++ 1073743884, 2082, 1073743936, 2163, ++ 1073744002, 2227, 1073744114, 2295, // NOLINT ++ 2299, 1073744138, 2341, 1073744176, ++ 2374, 1073744224, 2428, 1073744260, // NOLINT ++ 2482, 2511, 1073744352, 2532, ++ 1073744358, 2543, 1073744378, 2558, // NOLINT ++ 1073744384, 2600, 1073744448, 2626, ++ 1073744452, 2635, 1073744480, 2678, // NOLINT ++ 2682, 1073744510, 2735, 2737, ++ 1073744565, 2742, 1073744569, 2749, // NOLINT ++ 2752, 2754, 1073744603, 2781, ++ 1073744608, 2794, 1073744626, 2804, // NOLINT ++ 1073744641, 2822, 1073744649, 2830, ++ 1073744657, 2838, 1073744672, 2854, // NOLINT ++ 1073744680, 2862, 1073744688, 2906, ++ 1073744732, 2911, 1073744740, 2917, // NOLINT ++ 1073744832, 3042, 1073744896, 8191}; // NOLINT ++static const uint16_t kLetterTable6Size = 6; ++static const int32_t kLetterTable6[6] = {1073741824, 6051, 1073747888, 6086, ++ 1073747915, 6139}; // NOLINT ++static const uint16_t kLetterTable7Size = 48; ++static const int32_t kLetterTable7[48] = { ++ 1073748224, 6765, 1073748592, 6873, ++ 1073748736, 6918, 1073748755, 6935, // NOLINT ++ 6941, 1073748767, 6952, 1073748778, ++ 6966, 1073748792, 6972, 6974, // NOLINT ++ 1073748800, 6977, 1073748803, 6980, ++ 1073748806, 7089, 1073748947, 7485, // NOLINT ++ 1073749328, 7567, 1073749394, 7623, ++ 1073749488, 7675, 1073749616, 7796, // NOLINT ++ 1073749622, 7932, 1073749793, 7994, ++ 1073749825, 8026, 1073749862, 8126, // NOLINT ++ 1073749954, 8135, 1073749962, 8143, ++ 1073749970, 8151, 1073749978, 8156}; // NOLINT ++bool Letter::Is(uchar c) { ++ int chunk_index = c >> 13; ++ switch (chunk_index) { ++ case 0: ++ return LookupPredicate(kLetterTable0, kLetterTable0Size, c); ++ case 1: ++ return LookupPredicate(kLetterTable1, kLetterTable1Size, c); ++ case 2: ++ return LookupPredicate(kLetterTable2, kLetterTable2Size, c); ++ case 3: ++ return LookupPredicate(kLetterTable3, kLetterTable3Size, c); ++ case 4: ++ return LookupPredicate(kLetterTable4, kLetterTable4Size, c); ++ case 5: ++ return LookupPredicate(kLetterTable5, kLetterTable5Size, c); ++ case 6: ++ return LookupPredicate(kLetterTable6, kLetterTable6Size, c); ++ case 7: ++ return LookupPredicate(kLetterTable7, kLetterTable7Size, c); ++ default: ++ return false; ++ } ++} ++#endif ++ ++#ifndef V8_INTL_SUPPORT ++ ++static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings0[1] = ++ { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262CanonicalizeTable0Size = 498; // NOLINT ++static const int32_t kEcma262CanonicalizeTable0[996] = { ++ 1073741921, -128, 122, -128, 181, 2972, ++ 1073742048, -128, 246, -128, 1073742072, -128, ++ 254, -128, 255, 484, // NOLINT ++ 257, -4, 259, -4, 261, -4, ++ 263, -4, 265, -4, 267, -4, ++ 269, -4, 271, -4, // NOLINT ++ 273, -4, 275, -4, 277, -4, ++ 279, -4, 281, -4, 283, -4, ++ 285, -4, 287, -4, // NOLINT ++ 289, -4, 291, -4, 293, -4, ++ 295, -4, 297, -4, 299, -4, ++ 301, -4, 303, -4, // NOLINT ++ 307, -4, 309, -4, 311, -4, ++ 314, -4, 316, -4, 318, -4, ++ 320, -4, 322, -4, // NOLINT ++ 324, -4, 326, -4, 328, -4, ++ 331, -4, 333, -4, 335, -4, ++ 337, -4, 339, -4, // NOLINT ++ 341, -4, 343, -4, 345, -4, ++ 347, -4, 349, -4, 351, -4, ++ 353, -4, 355, -4, // NOLINT ++ 357, -4, 359, -4, 361, -4, ++ 363, -4, 365, -4, 367, -4, ++ 369, -4, 371, -4, // NOLINT ++ 373, -4, 375, -4, 378, -4, ++ 380, -4, 382, -4, 384, 780, ++ 387, -4, 389, -4, // NOLINT ++ 392, -4, 396, -4, 402, -4, ++ 405, 388, 409, -4, 410, 652, ++ 414, 520, 417, -4, // NOLINT ++ 419, -4, 421, -4, 424, -4, ++ 429, -4, 432, -4, 436, -4, ++ 438, -4, 441, -4, // NOLINT ++ 445, -4, 447, 224, 453, -4, ++ 454, -8, 456, -4, 457, -8, ++ 459, -4, 460, -8, // NOLINT ++ 462, -4, 464, -4, 466, -4, ++ 468, -4, 470, -4, 472, -4, ++ 474, -4, 476, -4, // NOLINT ++ 477, -316, 479, -4, 481, -4, ++ 483, -4, 485, -4, 487, -4, ++ 489, -4, 491, -4, // NOLINT ++ 493, -4, 495, -4, 498, -4, ++ 499, -8, 501, -4, 505, -4, ++ 507, -4, 509, -4, // NOLINT ++ 511, -4, 513, -4, 515, -4, ++ 517, -4, 519, -4, 521, -4, ++ 523, -4, 525, -4, // NOLINT ++ 527, -4, 529, -4, 531, -4, ++ 533, -4, 535, -4, 537, -4, ++ 539, -4, 541, -4, // NOLINT ++ 543, -4, 547, -4, 549, -4, ++ 551, -4, 553, -4, 555, -4, ++ 557, -4, 559, -4, // NOLINT ++ 561, -4, 563, -4, 572, -4, ++ 1073742399, 43260, 576, 43260, 578, -4, ++ 583, -4, 585, -4, // NOLINT ++ 587, -4, 589, -4, 591, -4, ++ 592, 43132, 593, 43120, 594, 43128, ++ 595, -840, 596, -824, // NOLINT ++ 1073742422, -820, 599, -820, 601, -808, ++ 603, -812, 604, 169276, 608, -820, ++ 609, 169260, 611, -828, // NOLINT ++ 613, 169120, 614, 169232, 616, -836, ++ 617, -844, 619, 42972, 620, 169220, ++ 623, -844, 625, 42996, // NOLINT ++ 626, -852, 629, -856, 637, 42908, ++ 640, -872, 643, -872, 647, 169128, ++ 648, -872, 649, -276, // NOLINT ++ 1073742474, -868, 651, -868, 652, -284, ++ 658, -876, 670, 169032, 837, 336, ++ 881, -4, 883, -4, // NOLINT ++ 887, -4, 1073742715, 520, 893, 520, ++ 940, -152, 1073742765, -148, 943, -148, ++ 1073742769, -128, 961, -128, // NOLINT ++ 962, -124, 1073742787, -128, 971, -128, ++ 972, -256, 1073742797, -252, 974, -252, ++ 976, -248, 977, -228, // NOLINT ++ 981, -188, 982, -216, 983, -32, ++ 985, -4, 987, -4, 989, -4, ++ 991, -4, 993, -4, // NOLINT ++ 995, -4, 997, -4, 999, -4, ++ 1001, -4, 1003, -4, 1005, -4, ++ 1007, -4, 1008, -344, // NOLINT ++ 1009, -320, 1010, 28, 1011, -464, ++ 1013, -384, 1016, -4, 1019, -4, ++ 1073742896, -128, 1103, -128, // NOLINT ++ 1073742928, -320, 1119, -320, 1121, -4, ++ 1123, -4, 1125, -4, 1127, -4, ++ 1129, -4, 1131, -4, // NOLINT ++ 1133, -4, 1135, -4, 1137, -4, ++ 1139, -4, 1141, -4, 1143, -4, ++ 1145, -4, 1147, -4, // NOLINT ++ 1149, -4, 1151, -4, 1153, -4, ++ 1163, -4, 1165, -4, 1167, -4, ++ 1169, -4, 1171, -4, // NOLINT ++ 1173, -4, 1175, -4, 1177, -4, ++ 1179, -4, 1181, -4, 1183, -4, ++ 1185, -4, 1187, -4, // NOLINT ++ 1189, -4, 1191, -4, 1193, -4, ++ 1195, -4, 1197, -4, 1199, -4, ++ 1201, -4, 1203, -4, // NOLINT ++ 1205, -4, 1207, -4, 1209, -4, ++ 1211, -4, 1213, -4, 1215, -4, ++ 1218, -4, 1220, -4, // NOLINT ++ 1222, -4, 1224, -4, 1226, -4, ++ 1228, -4, 1230, -4, 1231, -60, ++ 1233, -4, 1235, -4, // NOLINT ++ 1237, -4, 1239, -4, 1241, -4, ++ 1243, -4, 1245, -4, 1247, -4, ++ 1249, -4, 1251, -4, // NOLINT ++ 1253, -4, 1255, -4, 1257, -4, ++ 1259, -4, 1261, -4, 1263, -4, ++ 1265, -4, 1267, -4, // NOLINT ++ 1269, -4, 1271, -4, 1273, -4, ++ 1275, -4, 1277, -4, 1279, -4, ++ 1281, -4, 1283, -4, // NOLINT ++ 1285, -4, 1287, -4, 1289, -4, ++ 1291, -4, 1293, -4, 1295, -4, ++ 1297, -4, 1299, -4, // NOLINT ++ 1301, -4, 1303, -4, 1305, -4, ++ 1307, -4, 1309, -4, 1311, -4, ++ 1313, -4, 1315, -4, // NOLINT ++ 1317, -4, 1319, -4, 1321, -4, ++ 1323, -4, 1325, -4, 1327, -4, ++ 1073743201, -192, 1414, -192, // NOLINT ++ 7545, 141328, 7549, 15256, 7681, -4, ++ 7683, -4, 7685, -4, 7687, -4, ++ 7689, -4, 7691, -4, // NOLINT ++ 7693, -4, 7695, -4, 7697, -4, ++ 7699, -4, 7701, -4, 7703, -4, ++ 7705, -4, 7707, -4, // NOLINT ++ 7709, -4, 7711, -4, 7713, -4, ++ 7715, -4, 7717, -4, 7719, -4, ++ 7721, -4, 7723, -4, // NOLINT ++ 7725, -4, 7727, -4, 7729, -4, ++ 7731, -4, 7733, -4, 7735, -4, ++ 7737, -4, 7739, -4, // NOLINT ++ 7741, -4, 7743, -4, 7745, -4, ++ 7747, -4, 7749, -4, 7751, -4, ++ 7753, -4, 7755, -4, // NOLINT ++ 7757, -4, 7759, -4, 7761, -4, ++ 7763, -4, 7765, -4, 7767, -4, ++ 7769, -4, 7771, -4, // NOLINT ++ 7773, -4, 7775, -4, 7777, -4, ++ 7779, -4, 7781, -4, 7783, -4, ++ 7785, -4, 7787, -4, // NOLINT ++ 7789, -4, 7791, -4, 7793, -4, ++ 7795, -4, 7797, -4, 7799, -4, ++ 7801, -4, 7803, -4, // NOLINT ++ 7805, -4, 7807, -4, 7809, -4, ++ 7811, -4, 7813, -4, 7815, -4, ++ 7817, -4, 7819, -4, // NOLINT ++ 7821, -4, 7823, -4, 7825, -4, ++ 7827, -4, 7829, -4, 7835, -236, ++ 7841, -4, 7843, -4, // NOLINT ++ 7845, -4, 7847, -4, 7849, -4, ++ 7851, -4, 7853, -4, 7855, -4, ++ 7857, -4, 7859, -4, // NOLINT ++ 7861, -4, 7863, -4, 7865, -4, ++ 7867, -4, 7869, -4, 7871, -4, ++ 7873, -4, 7875, -4, // NOLINT ++ 7877, -4, 7879, -4, 7881, -4, ++ 7883, -4, 7885, -4, 7887, -4, ++ 7889, -4, 7891, -4, // NOLINT ++ 7893, -4, 7895, -4, 7897, -4, ++ 7899, -4, 7901, -4, 7903, -4, ++ 7905, -4, 7907, -4, // NOLINT ++ 7909, -4, 7911, -4, 7913, -4, ++ 7915, -4, 7917, -4, 7919, -4, ++ 7921, -4, 7923, -4, // NOLINT ++ 7925, -4, 7927, -4, 7929, -4, ++ 7931, -4, 7933, -4, 7935, -4, ++ 1073749760, 32, 7943, 32, // NOLINT ++ 1073749776, 32, 7957, 32, 1073749792, 32, ++ 7975, 32, 1073749808, 32, 7991, 32, ++ 1073749824, 32, 8005, 32, // NOLINT ++ 8017, 32, 8019, 32, 8021, 32, ++ 8023, 32, 1073749856, 32, 8039, 32, ++ 1073749872, 296, 8049, 296, // NOLINT ++ 1073749874, 344, 8053, 344, 1073749878, 400, ++ 8055, 400, 1073749880, 512, 8057, 512, ++ 1073749882, 448, 8059, 448, // NOLINT ++ 1073749884, 504, 8061, 504, 1073749936, 32, ++ 8113, 32, 8126, -28820, 1073749968, 32, ++ 8145, 32, 1073749984, 32, // NOLINT ++ 8161, 32, 8165, 28}; // NOLINT ++static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings1[1] = ++ { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262CanonicalizeTable1Size = 73; // NOLINT ++static const int32_t kEcma262CanonicalizeTable1[146] = { ++ 334, -112, 1073742192, -64, 383, -64, ++ 388, -4, 1073743056, -104, 1257, -104, ++ 1073744944, -192, 3166, -192, // NOLINT ++ 3169, -4, 3173, -43180, 3174, -43168, ++ 3176, -4, 3178, -4, 3180, -4, ++ 3187, -4, 3190, -4, // NOLINT ++ 3201, -4, 3203, -4, 3205, -4, ++ 3207, -4, 3209, -4, 3211, -4, ++ 3213, -4, 3215, -4, // NOLINT ++ 3217, -4, 3219, -4, 3221, -4, ++ 3223, -4, 3225, -4, 3227, -4, ++ 3229, -4, 3231, -4, // NOLINT ++ 3233, -4, 3235, -4, 3237, -4, ++ 3239, -4, 3241, -4, 3243, -4, ++ 3245, -4, 3247, -4, // NOLINT ++ 3249, -4, 3251, -4, 3253, -4, ++ 3255, -4, 3257, -4, 3259, -4, ++ 3261, -4, 3263, -4, // NOLINT ++ 3265, -4, 3267, -4, 3269, -4, ++ 3271, -4, 3273, -4, 3275, -4, ++ 3277, -4, 3279, -4, // NOLINT ++ 3281, -4, 3283, -4, 3285, -4, ++ 3287, -4, 3289, -4, 3291, -4, ++ 3293, -4, 3295, -4, // NOLINT ++ 3297, -4, 3299, -4, 3308, -4, ++ 3310, -4, 3315, -4, 1073745152, -29056, ++ 3365, -29056, 3367, -29056, // NOLINT ++ 3373, -29056}; // NOLINT ++static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings5[1] = ++ { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262CanonicalizeTable5Size = 95; // NOLINT ++static const int32_t kEcma262CanonicalizeTable5[190] = ++ { ++ 1601, -4, 1603, -4, 1605, -4, 1607, -4, ++ 1609, -4, 1611, -4, 1613, -4, 1615, -4, // NOLINT ++ 1617, -4, 1619, -4, 1621, -4, 1623, -4, ++ 1625, -4, 1627, -4, 1629, -4, 1631, -4, // NOLINT ++ 1633, -4, 1635, -4, 1637, -4, 1639, -4, ++ 1641, -4, 1643, -4, 1645, -4, 1665, -4, // NOLINT ++ 1667, -4, 1669, -4, 1671, -4, 1673, -4, ++ 1675, -4, 1677, -4, 1679, -4, 1681, -4, // NOLINT ++ 1683, -4, 1685, -4, 1687, -4, 1689, -4, ++ 1691, -4, 1827, -4, 1829, -4, 1831, -4, // NOLINT ++ 1833, -4, 1835, -4, 1837, -4, 1839, -4, ++ 1843, -4, 1845, -4, 1847, -4, 1849, -4, // NOLINT ++ 1851, -4, 1853, -4, 1855, -4, 1857, -4, ++ 1859, -4, 1861, -4, 1863, -4, 1865, -4, // NOLINT ++ 1867, -4, 1869, -4, 1871, -4, 1873, -4, ++ 1875, -4, 1877, -4, 1879, -4, 1881, -4, // NOLINT ++ 1883, -4, 1885, -4, 1887, -4, 1889, -4, ++ 1891, -4, 1893, -4, 1895, -4, 1897, -4, // NOLINT ++ 1899, -4, 1901, -4, 1903, -4, 1914, -4, ++ 1916, -4, 1919, -4, 1921, -4, 1923, -4, // NOLINT ++ 1925, -4, 1927, -4, 1932, -4, 1937, -4, ++ 1939, -4, 1943, -4, 1945, -4, 1947, -4, // NOLINT ++ 1949, -4, 1951, -4, 1953, -4, 1955, -4, ++ 1957, -4, 1959, -4, 1961, -4}; // NOLINT ++static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings7[1] = ++ { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262CanonicalizeTable7Size = 2; // NOLINT ++static const int32_t kEcma262CanonicalizeTable7[4] = {1073749825, -128, 8026, ++ -128}; // NOLINT ++int Ecma262Canonicalize::Convert(uchar c, uchar n, uchar* result, ++ bool* allow_caching_ptr) { ++ int chunk_index = c >> 13; ++ switch (chunk_index) { ++ case 0: ++ return LookupMapping( ++ kEcma262CanonicalizeTable0, kEcma262CanonicalizeTable0Size, ++ kEcma262CanonicalizeMultiStrings0, c, n, result, allow_caching_ptr); ++ case 1: ++ return LookupMapping( ++ kEcma262CanonicalizeTable1, kEcma262CanonicalizeTable1Size, ++ kEcma262CanonicalizeMultiStrings1, c, n, result, allow_caching_ptr); ++ case 5: ++ return LookupMapping( ++ kEcma262CanonicalizeTable5, kEcma262CanonicalizeTable5Size, ++ kEcma262CanonicalizeMultiStrings5, c, n, result, allow_caching_ptr); ++ case 7: ++ return LookupMapping( ++ kEcma262CanonicalizeTable7, kEcma262CanonicalizeTable7Size, ++ kEcma262CanonicalizeMultiStrings7, c, n, result, allow_caching_ptr); ++ default: ++ return 0; ++ } ++} ++ ++static const MultiCharacterSpecialCase<4> ++ kEcma262UnCanonicalizeMultiStrings0[507] = { // NOLINT ++ {{65, 97, kSentinel}}, ++ {{90, 122, kSentinel}}, ++ {{181, 924, 956, kSentinel}}, ++ {{192, 224, kSentinel}}, // NOLINT ++ {{214, 246, kSentinel}}, ++ {{216, 248, kSentinel}}, ++ {{222, 254, kSentinel}}, ++ {{255, 376, kSentinel}}, // NOLINT ++ {{256, 257, kSentinel}}, ++ {{258, 259, kSentinel}}, ++ {{260, 261, kSentinel}}, ++ {{262, 263, kSentinel}}, // NOLINT ++ {{264, 265, kSentinel}}, ++ {{266, 267, kSentinel}}, ++ {{268, 269, kSentinel}}, ++ {{270, 271, kSentinel}}, // NOLINT ++ {{272, 273, kSentinel}}, ++ {{274, 275, kSentinel}}, ++ {{276, 277, kSentinel}}, ++ {{278, 279, kSentinel}}, // NOLINT ++ {{280, 281, kSentinel}}, ++ {{282, 283, kSentinel}}, ++ {{284, 285, kSentinel}}, ++ {{286, 287, kSentinel}}, // NOLINT ++ {{288, 289, kSentinel}}, ++ {{290, 291, kSentinel}}, ++ {{292, 293, kSentinel}}, ++ {{294, 295, kSentinel}}, // NOLINT ++ {{296, 297, kSentinel}}, ++ {{298, 299, kSentinel}}, ++ {{300, 301, kSentinel}}, ++ {{302, 303, kSentinel}}, // NOLINT ++ {{306, 307, kSentinel}}, ++ {{308, 309, kSentinel}}, ++ {{310, 311, kSentinel}}, ++ {{313, 314, kSentinel}}, // NOLINT ++ {{315, 316, kSentinel}}, ++ {{317, 318, kSentinel}}, ++ {{319, 320, kSentinel}}, ++ {{321, 322, kSentinel}}, // NOLINT ++ {{323, 324, kSentinel}}, ++ {{325, 326, kSentinel}}, ++ {{327, 328, kSentinel}}, ++ {{330, 331, kSentinel}}, // NOLINT ++ {{332, 333, kSentinel}}, ++ {{334, 335, kSentinel}}, ++ {{336, 337, kSentinel}}, ++ {{338, 339, kSentinel}}, // NOLINT ++ {{340, 341, kSentinel}}, ++ {{342, 343, kSentinel}}, ++ {{344, 345, kSentinel}}, ++ {{346, 347, kSentinel}}, // NOLINT ++ {{348, 349, kSentinel}}, ++ {{350, 351, kSentinel}}, ++ {{352, 353, kSentinel}}, ++ {{354, 355, kSentinel}}, // NOLINT ++ {{356, 357, kSentinel}}, ++ {{358, 359, kSentinel}}, ++ {{360, 361, kSentinel}}, ++ {{362, 363, kSentinel}}, // NOLINT ++ {{364, 365, kSentinel}}, ++ {{366, 367, kSentinel}}, ++ {{368, 369, kSentinel}}, ++ {{370, 371, kSentinel}}, // NOLINT ++ {{372, 373, kSentinel}}, ++ {{374, 375, kSentinel}}, ++ {{377, 378, kSentinel}}, ++ {{379, 380, kSentinel}}, // NOLINT ++ {{381, 382, kSentinel}}, ++ {{384, 579, kSentinel}}, ++ {{385, 595, kSentinel}}, ++ {{386, 387, kSentinel}}, // NOLINT ++ {{388, 389, kSentinel}}, ++ {{390, 596, kSentinel}}, ++ {{391, 392, kSentinel}}, ++ {{393, 598, kSentinel}}, // NOLINT ++ {{394, 599, kSentinel}}, ++ {{395, 396, kSentinel}}, ++ {{398, 477, kSentinel}}, ++ {{399, 601, kSentinel}}, // NOLINT ++ {{400, 603, kSentinel}}, ++ {{401, 402, kSentinel}}, ++ {{403, 608, kSentinel}}, ++ {{404, 611, kSentinel}}, // NOLINT ++ {{405, 502, kSentinel}}, ++ {{406, 617, kSentinel}}, ++ {{407, 616, kSentinel}}, ++ {{408, 409, kSentinel}}, // NOLINT ++ {{410, 573, kSentinel}}, ++ {{412, 623, kSentinel}}, ++ {{413, 626, kSentinel}}, ++ {{414, 544, kSentinel}}, // NOLINT ++ {{415, 629, kSentinel}}, ++ {{416, 417, kSentinel}}, ++ {{418, 419, kSentinel}}, ++ {{420, 421, kSentinel}}, // NOLINT ++ {{422, 640, kSentinel}}, ++ {{423, 424, kSentinel}}, ++ {{425, 643, kSentinel}}, ++ {{428, 429, kSentinel}}, // NOLINT ++ {{430, 648, kSentinel}}, ++ {{431, 432, kSentinel}}, ++ {{433, 650, kSentinel}}, ++ {{434, 651, kSentinel}}, // NOLINT ++ {{435, 436, kSentinel}}, ++ {{437, 438, kSentinel}}, ++ {{439, 658, kSentinel}}, ++ {{440, 441, kSentinel}}, // NOLINT ++ {{444, 445, kSentinel}}, ++ {{447, 503, kSentinel}}, ++ {{452, 453, 454, kSentinel}}, ++ {{455, 456, 457, kSentinel}}, // NOLINT ++ {{458, 459, 460, kSentinel}}, ++ {{461, 462, kSentinel}}, ++ {{463, 464, kSentinel}}, ++ {{465, 466, kSentinel}}, // NOLINT ++ {{467, 468, kSentinel}}, ++ {{469, 470, kSentinel}}, ++ {{471, 472, kSentinel}}, ++ {{473, 474, kSentinel}}, // NOLINT ++ {{475, 476, kSentinel}}, ++ {{478, 479, kSentinel}}, ++ {{480, 481, kSentinel}}, ++ {{482, 483, kSentinel}}, // NOLINT ++ {{484, 485, kSentinel}}, ++ {{486, 487, kSentinel}}, ++ {{488, 489, kSentinel}}, ++ {{490, 491, kSentinel}}, // NOLINT ++ {{492, 493, kSentinel}}, ++ {{494, 495, kSentinel}}, ++ {{497, 498, 499, kSentinel}}, ++ {{500, 501, kSentinel}}, // NOLINT ++ {{504, 505, kSentinel}}, ++ {{506, 507, kSentinel}}, ++ {{508, 509, kSentinel}}, ++ {{510, 511, kSentinel}}, // NOLINT ++ {{512, 513, kSentinel}}, ++ {{514, 515, kSentinel}}, ++ {{516, 517, kSentinel}}, ++ {{518, 519, kSentinel}}, // NOLINT ++ {{520, 521, kSentinel}}, ++ {{522, 523, kSentinel}}, ++ {{524, 525, kSentinel}}, ++ {{526, 527, kSentinel}}, // NOLINT ++ {{528, 529, kSentinel}}, ++ {{530, 531, kSentinel}}, ++ {{532, 533, kSentinel}}, ++ {{534, 535, kSentinel}}, // NOLINT ++ {{536, 537, kSentinel}}, ++ {{538, 539, kSentinel}}, ++ {{540, 541, kSentinel}}, ++ {{542, 543, kSentinel}}, // NOLINT ++ {{546, 547, kSentinel}}, ++ {{548, 549, kSentinel}}, ++ {{550, 551, kSentinel}}, ++ {{552, 553, kSentinel}}, // NOLINT ++ {{554, 555, kSentinel}}, ++ {{556, 557, kSentinel}}, ++ {{558, 559, kSentinel}}, ++ {{560, 561, kSentinel}}, // NOLINT ++ {{562, 563, kSentinel}}, ++ {{570, 11365, kSentinel}}, ++ {{571, 572, kSentinel}}, ++ {{574, 11366, kSentinel}}, // NOLINT ++ {{575, 11390, kSentinel}}, ++ {{576, 11391, kSentinel}}, ++ {{577, 578, kSentinel}}, ++ {{580, 649, kSentinel}}, // NOLINT ++ {{581, 652, kSentinel}}, ++ {{582, 583, kSentinel}}, ++ {{584, 585, kSentinel}}, ++ {{586, 587, kSentinel}}, // NOLINT ++ {{588, 589, kSentinel}}, ++ {{590, 591, kSentinel}}, ++ {{592, 11375, kSentinel}}, ++ {{593, 11373, kSentinel}}, // NOLINT ++ {{594, 11376, kSentinel}}, ++ {{604, 42923, kSentinel}}, ++ {{609, 42924, kSentinel}}, ++ {{613, 42893, kSentinel}}, // NOLINT ++ {{614, 42922, kSentinel}}, ++ {{619, 11362, kSentinel}}, ++ {{620, 42925, kSentinel}}, ++ {{625, 11374, kSentinel}}, // NOLINT ++ {{637, 11364, kSentinel}}, ++ {{647, 42929, kSentinel}}, ++ {{670, 42928, kSentinel}}, ++ {{837, 921, 953, 8126}}, // NOLINT ++ {{880, 881, kSentinel}}, ++ {{882, 883, kSentinel}}, ++ {{886, 887, kSentinel}}, ++ {{891, 1021, kSentinel}}, // NOLINT ++ {{893, 1023, kSentinel}}, ++ {{895, 1011, kSentinel}}, ++ {{902, 940, kSentinel}}, ++ {{904, 941, kSentinel}}, // NOLINT ++ {{906, 943, kSentinel}}, ++ {{908, 972, kSentinel}}, ++ {{910, 973, kSentinel}}, ++ {{911, 974, kSentinel}}, // NOLINT ++ {{913, 945, kSentinel}}, ++ {{914, 946, 976, kSentinel}}, ++ {{915, 947, kSentinel}}, ++ {{916, 948, kSentinel}}, // NOLINT ++ {{917, 949, 1013, kSentinel}}, ++ {{918, 950, kSentinel}}, ++ {{919, 951, kSentinel}}, ++ {{920, 952, 977, kSentinel}}, // NOLINT ++ {{922, 954, 1008, kSentinel}}, ++ {{923, 955, kSentinel}}, ++ {{925, 957, kSentinel}}, ++ {{927, 959, kSentinel}}, // NOLINT ++ {{928, 960, 982, kSentinel}}, ++ {{929, 961, 1009, kSentinel}}, ++ {{931, 962, 963, kSentinel}}, ++ {{932, 964, kSentinel}}, // NOLINT ++ {{933, 965, kSentinel}}, ++ {{934, 966, 981, kSentinel}}, ++ {{935, 967, kSentinel}}, ++ {{939, 971, kSentinel}}, // NOLINT ++ {{975, 983, kSentinel}}, ++ {{984, 985, kSentinel}}, ++ {{986, 987, kSentinel}}, ++ {{988, 989, kSentinel}}, // NOLINT ++ {{990, 991, kSentinel}}, ++ {{992, 993, kSentinel}}, ++ {{994, 995, kSentinel}}, ++ {{996, 997, kSentinel}}, // NOLINT ++ {{998, 999, kSentinel}}, ++ {{1000, 1001, kSentinel}}, ++ {{1002, 1003, kSentinel}}, ++ {{1004, 1005, kSentinel}}, // NOLINT ++ {{1006, 1007, kSentinel}}, ++ {{1010, 1017, kSentinel}}, ++ {{1015, 1016, kSentinel}}, ++ {{1018, 1019, kSentinel}}, // NOLINT ++ {{1024, 1104, kSentinel}}, ++ {{1039, 1119, kSentinel}}, ++ {{1040, 1072, kSentinel}}, ++ {{1071, 1103, kSentinel}}, // NOLINT ++ {{1120, 1121, kSentinel}}, ++ {{1122, 1123, kSentinel}}, ++ {{1124, 1125, kSentinel}}, ++ {{1126, 1127, kSentinel}}, // NOLINT ++ {{1128, 1129, kSentinel}}, ++ {{1130, 1131, kSentinel}}, ++ {{1132, 1133, kSentinel}}, ++ {{1134, 1135, kSentinel}}, // NOLINT ++ {{1136, 1137, kSentinel}}, ++ {{1138, 1139, kSentinel}}, ++ {{1140, 1141, kSentinel}}, ++ {{1142, 1143, kSentinel}}, // NOLINT ++ {{1144, 1145, kSentinel}}, ++ {{1146, 1147, kSentinel}}, ++ {{1148, 1149, kSentinel}}, ++ {{1150, 1151, kSentinel}}, // NOLINT ++ {{1152, 1153, kSentinel}}, ++ {{1162, 1163, kSentinel}}, ++ {{1164, 1165, kSentinel}}, ++ {{1166, 1167, kSentinel}}, // NOLINT ++ {{1168, 1169, kSentinel}}, ++ {{1170, 1171, kSentinel}}, ++ {{1172, 1173, kSentinel}}, ++ {{1174, 1175, kSentinel}}, // NOLINT ++ {{1176, 1177, kSentinel}}, ++ {{1178, 1179, kSentinel}}, ++ {{1180, 1181, kSentinel}}, ++ {{1182, 1183, kSentinel}}, // NOLINT ++ {{1184, 1185, kSentinel}}, ++ {{1186, 1187, kSentinel}}, ++ {{1188, 1189, kSentinel}}, ++ {{1190, 1191, kSentinel}}, // NOLINT ++ {{1192, 1193, kSentinel}}, ++ {{1194, 1195, kSentinel}}, ++ {{1196, 1197, kSentinel}}, ++ {{1198, 1199, kSentinel}}, // NOLINT ++ {{1200, 1201, kSentinel}}, ++ {{1202, 1203, kSentinel}}, ++ {{1204, 1205, kSentinel}}, ++ {{1206, 1207, kSentinel}}, // NOLINT ++ {{1208, 1209, kSentinel}}, ++ {{1210, 1211, kSentinel}}, ++ {{1212, 1213, kSentinel}}, ++ {{1214, 1215, kSentinel}}, // NOLINT ++ {{1216, 1231, kSentinel}}, ++ {{1217, 1218, kSentinel}}, ++ {{1219, 1220, kSentinel}}, ++ {{1221, 1222, kSentinel}}, // NOLINT ++ {{1223, 1224, kSentinel}}, ++ {{1225, 1226, kSentinel}}, ++ {{1227, 1228, kSentinel}}, ++ {{1229, 1230, kSentinel}}, // NOLINT ++ {{1232, 1233, kSentinel}}, ++ {{1234, 1235, kSentinel}}, ++ {{1236, 1237, kSentinel}}, ++ {{1238, 1239, kSentinel}}, // NOLINT ++ {{1240, 1241, kSentinel}}, ++ {{1242, 1243, kSentinel}}, ++ {{1244, 1245, kSentinel}}, ++ {{1246, 1247, kSentinel}}, // NOLINT ++ {{1248, 1249, kSentinel}}, ++ {{1250, 1251, kSentinel}}, ++ {{1252, 1253, kSentinel}}, ++ {{1254, 1255, kSentinel}}, // NOLINT ++ {{1256, 1257, kSentinel}}, ++ {{1258, 1259, kSentinel}}, ++ {{1260, 1261, kSentinel}}, ++ {{1262, 1263, kSentinel}}, // NOLINT ++ {{1264, 1265, kSentinel}}, ++ {{1266, 1267, kSentinel}}, ++ {{1268, 1269, kSentinel}}, ++ {{1270, 1271, kSentinel}}, // NOLINT ++ {{1272, 1273, kSentinel}}, ++ {{1274, 1275, kSentinel}}, ++ {{1276, 1277, kSentinel}}, ++ {{1278, 1279, kSentinel}}, // NOLINT ++ {{1280, 1281, kSentinel}}, ++ {{1282, 1283, kSentinel}}, ++ {{1284, 1285, kSentinel}}, ++ {{1286, 1287, kSentinel}}, // NOLINT ++ {{1288, 1289, kSentinel}}, ++ {{1290, 1291, kSentinel}}, ++ {{1292, 1293, kSentinel}}, ++ {{1294, 1295, kSentinel}}, // NOLINT ++ {{1296, 1297, kSentinel}}, ++ {{1298, 1299, kSentinel}}, ++ {{1300, 1301, kSentinel}}, ++ {{1302, 1303, kSentinel}}, // NOLINT ++ {{1304, 1305, kSentinel}}, ++ {{1306, 1307, kSentinel}}, ++ {{1308, 1309, kSentinel}}, ++ {{1310, 1311, kSentinel}}, // NOLINT ++ {{1312, 1313, kSentinel}}, ++ {{1314, 1315, kSentinel}}, ++ {{1316, 1317, kSentinel}}, ++ {{1318, 1319, kSentinel}}, // NOLINT ++ {{1320, 1321, kSentinel}}, ++ {{1322, 1323, kSentinel}}, ++ {{1324, 1325, kSentinel}}, ++ {{1326, 1327, kSentinel}}, // NOLINT ++ {{1329, 1377, kSentinel}}, ++ {{1366, 1414, kSentinel}}, ++ {{4256, 11520, kSentinel}}, ++ {{4293, 11557, kSentinel}}, // NOLINT ++ {{4295, 11559, kSentinel}}, ++ {{4301, 11565, kSentinel}}, ++ {{7545, 42877, kSentinel}}, ++ {{7549, 11363, kSentinel}}, // NOLINT ++ {{7680, 7681, kSentinel}}, ++ {{7682, 7683, kSentinel}}, ++ {{7684, 7685, kSentinel}}, ++ {{7686, 7687, kSentinel}}, // NOLINT ++ {{7688, 7689, kSentinel}}, ++ {{7690, 7691, kSentinel}}, ++ {{7692, 7693, kSentinel}}, ++ {{7694, 7695, kSentinel}}, // NOLINT ++ {{7696, 7697, kSentinel}}, ++ {{7698, 7699, kSentinel}}, ++ {{7700, 7701, kSentinel}}, ++ {{7702, 7703, kSentinel}}, // NOLINT ++ {{7704, 7705, kSentinel}}, ++ {{7706, 7707, kSentinel}}, ++ {{7708, 7709, kSentinel}}, ++ {{7710, 7711, kSentinel}}, // NOLINT ++ {{7712, 7713, kSentinel}}, ++ {{7714, 7715, kSentinel}}, ++ {{7716, 7717, kSentinel}}, ++ {{7718, 7719, kSentinel}}, // NOLINT ++ {{7720, 7721, kSentinel}}, ++ {{7722, 7723, kSentinel}}, ++ {{7724, 7725, kSentinel}}, ++ {{7726, 7727, kSentinel}}, // NOLINT ++ {{7728, 7729, kSentinel}}, ++ {{7730, 7731, kSentinel}}, ++ {{7732, 7733, kSentinel}}, ++ {{7734, 7735, kSentinel}}, // NOLINT ++ {{7736, 7737, kSentinel}}, ++ {{7738, 7739, kSentinel}}, ++ {{7740, 7741, kSentinel}}, ++ {{7742, 7743, kSentinel}}, // NOLINT ++ {{7744, 7745, kSentinel}}, ++ {{7746, 7747, kSentinel}}, ++ {{7748, 7749, kSentinel}}, ++ {{7750, 7751, kSentinel}}, // NOLINT ++ {{7752, 7753, kSentinel}}, ++ {{7754, 7755, kSentinel}}, ++ {{7756, 7757, kSentinel}}, ++ {{7758, 7759, kSentinel}}, // NOLINT ++ {{7760, 7761, kSentinel}}, ++ {{7762, 7763, kSentinel}}, ++ {{7764, 7765, kSentinel}}, ++ {{7766, 7767, kSentinel}}, // NOLINT ++ {{7768, 7769, kSentinel}}, ++ {{7770, 7771, kSentinel}}, ++ {{7772, 7773, kSentinel}}, ++ {{7774, 7775, kSentinel}}, // NOLINT ++ {{7776, 7777, 7835, kSentinel}}, ++ {{7778, 7779, kSentinel}}, ++ {{7780, 7781, kSentinel}}, ++ {{7782, 7783, kSentinel}}, // NOLINT ++ {{7784, 7785, kSentinel}}, ++ {{7786, 7787, kSentinel}}, ++ {{7788, 7789, kSentinel}}, ++ {{7790, 7791, kSentinel}}, // NOLINT ++ {{7792, 7793, kSentinel}}, ++ {{7794, 7795, kSentinel}}, ++ {{7796, 7797, kSentinel}}, ++ {{7798, 7799, kSentinel}}, // NOLINT ++ {{7800, 7801, kSentinel}}, ++ {{7802, 7803, kSentinel}}, ++ {{7804, 7805, kSentinel}}, ++ {{7806, 7807, kSentinel}}, // NOLINT ++ {{7808, 7809, kSentinel}}, ++ {{7810, 7811, kSentinel}}, ++ {{7812, 7813, kSentinel}}, ++ {{7814, 7815, kSentinel}}, // NOLINT ++ {{7816, 7817, kSentinel}}, ++ {{7818, 7819, kSentinel}}, ++ {{7820, 7821, kSentinel}}, ++ {{7822, 7823, kSentinel}}, // NOLINT ++ {{7824, 7825, kSentinel}}, ++ {{7826, 7827, kSentinel}}, ++ {{7828, 7829, kSentinel}}, ++ {{7840, 7841, kSentinel}}, // NOLINT ++ {{7842, 7843, kSentinel}}, ++ {{7844, 7845, kSentinel}}, ++ {{7846, 7847, kSentinel}}, ++ {{7848, 7849, kSentinel}}, // NOLINT ++ {{7850, 7851, kSentinel}}, ++ {{7852, 7853, kSentinel}}, ++ {{7854, 7855, kSentinel}}, ++ {{7856, 7857, kSentinel}}, // NOLINT ++ {{7858, 7859, kSentinel}}, ++ {{7860, 7861, kSentinel}}, ++ {{7862, 7863, kSentinel}}, ++ {{7864, 7865, kSentinel}}, // NOLINT ++ {{7866, 7867, kSentinel}}, ++ {{7868, 7869, kSentinel}}, ++ {{7870, 7871, kSentinel}}, ++ {{7872, 7873, kSentinel}}, // NOLINT ++ {{7874, 7875, kSentinel}}, ++ {{7876, 7877, kSentinel}}, ++ {{7878, 7879, kSentinel}}, ++ {{7880, 7881, kSentinel}}, // NOLINT ++ {{7882, 7883, kSentinel}}, ++ {{7884, 7885, kSentinel}}, ++ {{7886, 7887, kSentinel}}, ++ {{7888, 7889, kSentinel}}, // NOLINT ++ {{7890, 7891, kSentinel}}, ++ {{7892, 7893, kSentinel}}, ++ {{7894, 7895, kSentinel}}, ++ {{7896, 7897, kSentinel}}, // NOLINT ++ {{7898, 7899, kSentinel}}, ++ {{7900, 7901, kSentinel}}, ++ {{7902, 7903, kSentinel}}, ++ {{7904, 7905, kSentinel}}, // NOLINT ++ {{7906, 7907, kSentinel}}, ++ {{7908, 7909, kSentinel}}, ++ {{7910, 7911, kSentinel}}, ++ {{7912, 7913, kSentinel}}, // NOLINT ++ {{7914, 7915, kSentinel}}, ++ {{7916, 7917, kSentinel}}, ++ {{7918, 7919, kSentinel}}, ++ {{7920, 7921, kSentinel}}, // NOLINT ++ {{7922, 7923, kSentinel}}, ++ {{7924, 7925, kSentinel}}, ++ {{7926, 7927, kSentinel}}, ++ {{7928, 7929, kSentinel}}, // NOLINT ++ {{7930, 7931, kSentinel}}, ++ {{7932, 7933, kSentinel}}, ++ {{7934, 7935, kSentinel}}, ++ {{7936, 7944, kSentinel}}, // NOLINT ++ {{7943, 7951, kSentinel}}, ++ {{7952, 7960, kSentinel}}, ++ {{7957, 7965, kSentinel}}, ++ {{7968, 7976, kSentinel}}, // NOLINT ++ {{7975, 7983, kSentinel}}, ++ {{7984, 7992, kSentinel}}, ++ {{7991, 7999, kSentinel}}, ++ {{8000, 8008, kSentinel}}, // NOLINT ++ {{8005, 8013, kSentinel}}, ++ {{8017, 8025, kSentinel}}, ++ {{8019, 8027, kSentinel}}, ++ {{8021, 8029, kSentinel}}, // NOLINT ++ {{8023, 8031, kSentinel}}, ++ {{8032, 8040, kSentinel}}, ++ {{8039, 8047, kSentinel}}, ++ {{8048, 8122, kSentinel}}, // NOLINT ++ {{8049, 8123, kSentinel}}, ++ {{8050, 8136, kSentinel}}, ++ {{8053, 8139, kSentinel}}, ++ {{8054, 8154, kSentinel}}, // NOLINT ++ {{8055, 8155, kSentinel}}, ++ {{8056, 8184, kSentinel}}, ++ {{8057, 8185, kSentinel}}, ++ {{8058, 8170, kSentinel}}, // NOLINT ++ {{8059, 8171, kSentinel}}, ++ {{8060, 8186, kSentinel}}, ++ {{8061, 8187, kSentinel}}, ++ {{8112, 8120, kSentinel}}, // NOLINT ++ {{8113, 8121, kSentinel}}, ++ {{8144, 8152, kSentinel}}, ++ {{8145, 8153, kSentinel}}, ++ {{8160, 8168, kSentinel}}, // NOLINT ++ {{8161, 8169, kSentinel}}, ++ {{8165, 8172, kSentinel}}, ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262UnCanonicalizeTable0Size = 1005; // NOLINT ++static const int32_t kEcma262UnCanonicalizeTable0[2010] = { ++ 1073741889, 1, 90, 5, 1073741921, 1, ++ 122, 5, 181, 9, 1073742016, 13, ++ 214, 17, 1073742040, 21, // NOLINT ++ 222, 25, 1073742048, 13, 246, 17, ++ 1073742072, 21, 254, 25, 255, 29, ++ 256, 33, 257, 33, // NOLINT ++ 258, 37, 259, 37, 260, 41, ++ 261, 41, 262, 45, 263, 45, ++ 264, 49, 265, 49, // NOLINT ++ 266, 53, 267, 53, 268, 57, ++ 269, 57, 270, 61, 271, 61, ++ 272, 65, 273, 65, // NOLINT ++ 274, 69, 275, 69, 276, 73, ++ 277, 73, 278, 77, 279, 77, ++ 280, 81, 281, 81, // NOLINT ++ 282, 85, 283, 85, 284, 89, ++ 285, 89, 286, 93, 287, 93, ++ 288, 97, 289, 97, // NOLINT ++ 290, 101, 291, 101, 292, 105, ++ 293, 105, 294, 109, 295, 109, ++ 296, 113, 297, 113, // NOLINT ++ 298, 117, 299, 117, 300, 121, ++ 301, 121, 302, 125, 303, 125, ++ 306, 129, 307, 129, // NOLINT ++ 308, 133, 309, 133, 310, 137, ++ 311, 137, 313, 141, 314, 141, ++ 315, 145, 316, 145, // NOLINT ++ 317, 149, 318, 149, 319, 153, ++ 320, 153, 321, 157, 322, 157, ++ 323, 161, 324, 161, // NOLINT ++ 325, 165, 326, 165, 327, 169, ++ 328, 169, 330, 173, 331, 173, ++ 332, 177, 333, 177, // NOLINT ++ 334, 181, 335, 181, 336, 185, ++ 337, 185, 338, 189, 339, 189, ++ 340, 193, 341, 193, // NOLINT ++ 342, 197, 343, 197, 344, 201, ++ 345, 201, 346, 205, 347, 205, ++ 348, 209, 349, 209, // NOLINT ++ 350, 213, 351, 213, 352, 217, ++ 353, 217, 354, 221, 355, 221, ++ 356, 225, 357, 225, // NOLINT ++ 358, 229, 359, 229, 360, 233, ++ 361, 233, 362, 237, 363, 237, ++ 364, 241, 365, 241, // NOLINT ++ 366, 245, 367, 245, 368, 249, ++ 369, 249, 370, 253, 371, 253, ++ 372, 257, 373, 257, // NOLINT ++ 374, 261, 375, 261, 376, 29, ++ 377, 265, 378, 265, 379, 269, ++ 380, 269, 381, 273, // NOLINT ++ 382, 273, 384, 277, 385, 281, ++ 386, 285, 387, 285, 388, 289, ++ 389, 289, 390, 293, // NOLINT ++ 391, 297, 392, 297, 1073742217, 301, ++ 394, 305, 395, 309, 396, 309, ++ 398, 313, 399, 317, // NOLINT ++ 400, 321, 401, 325, 402, 325, ++ 403, 329, 404, 333, 405, 337, ++ 406, 341, 407, 345, // NOLINT ++ 408, 349, 409, 349, 410, 353, ++ 412, 357, 413, 361, 414, 365, ++ 415, 369, 416, 373, // NOLINT ++ 417, 373, 418, 377, 419, 377, ++ 420, 381, 421, 381, 422, 385, ++ 423, 389, 424, 389, // NOLINT ++ 425, 393, 428, 397, 429, 397, ++ 430, 401, 431, 405, 432, 405, ++ 1073742257, 409, 434, 413, // NOLINT ++ 435, 417, 436, 417, 437, 421, ++ 438, 421, 439, 425, 440, 429, ++ 441, 429, 444, 433, // NOLINT ++ 445, 433, 447, 437, 452, 441, ++ 453, 441, 454, 441, 455, 445, ++ 456, 445, 457, 445, // NOLINT ++ 458, 449, 459, 449, 460, 449, ++ 461, 453, 462, 453, 463, 457, ++ 464, 457, 465, 461, // NOLINT ++ 466, 461, 467, 465, 468, 465, ++ 469, 469, 470, 469, 471, 473, ++ 472, 473, 473, 477, // NOLINT ++ 474, 477, 475, 481, 476, 481, ++ 477, 313, 478, 485, 479, 485, ++ 480, 489, 481, 489, // NOLINT ++ 482, 493, 483, 493, 484, 497, ++ 485, 497, 486, 501, 487, 501, ++ 488, 505, 489, 505, // NOLINT ++ 490, 509, 491, 509, 492, 513, ++ 493, 513, 494, 517, 495, 517, ++ 497, 521, 498, 521, // NOLINT ++ 499, 521, 500, 525, 501, 525, ++ 502, 337, 503, 437, 504, 529, ++ 505, 529, 506, 533, // NOLINT ++ 507, 533, 508, 537, 509, 537, ++ 510, 541, 511, 541, 512, 545, ++ 513, 545, 514, 549, // NOLINT ++ 515, 549, 516, 553, 517, 553, ++ 518, 557, 519, 557, 520, 561, ++ 521, 561, 522, 565, // NOLINT ++ 523, 565, 524, 569, 525, 569, ++ 526, 573, 527, 573, 528, 577, ++ 529, 577, 530, 581, // NOLINT ++ 531, 581, 532, 585, 533, 585, ++ 534, 589, 535, 589, 536, 593, ++ 537, 593, 538, 597, // NOLINT ++ 539, 597, 540, 601, 541, 601, ++ 542, 605, 543, 605, 544, 365, ++ 546, 609, 547, 609, // NOLINT ++ 548, 613, 549, 613, 550, 617, ++ 551, 617, 552, 621, 553, 621, ++ 554, 625, 555, 625, // NOLINT ++ 556, 629, 557, 629, 558, 633, ++ 559, 633, 560, 637, 561, 637, ++ 562, 641, 563, 641, // NOLINT ++ 570, 645, 571, 649, 572, 649, ++ 573, 353, 574, 653, 1073742399, 657, ++ 576, 661, 577, 665, // NOLINT ++ 578, 665, 579, 277, 580, 669, ++ 581, 673, 582, 677, 583, 677, ++ 584, 681, 585, 681, // NOLINT ++ 586, 685, 587, 685, 588, 689, ++ 589, 689, 590, 693, 591, 693, ++ 592, 697, 593, 701, // NOLINT ++ 594, 705, 595, 281, 596, 293, ++ 1073742422, 301, 599, 305, 601, 317, ++ 603, 321, 604, 709, // NOLINT ++ 608, 329, 609, 713, 611, 333, ++ 613, 717, 614, 721, 616, 345, ++ 617, 341, 619, 725, // NOLINT ++ 620, 729, 623, 357, 625, 733, ++ 626, 361, 629, 369, 637, 737, ++ 640, 385, 643, 393, // NOLINT ++ 647, 741, 648, 401, 649, 669, ++ 1073742474, 409, 651, 413, 652, 673, ++ 658, 425, 670, 745, // NOLINT ++ 837, 749, 880, 753, 881, 753, ++ 882, 757, 883, 757, 886, 761, ++ 887, 761, 1073742715, 765, // NOLINT ++ 893, 769, 895, 773, 902, 777, ++ 1073742728, 781, 906, 785, 908, 789, ++ 1073742734, 793, 911, 797, // NOLINT ++ 913, 801, 914, 805, 1073742739, 809, ++ 916, 813, 917, 817, 1073742742, 821, ++ 919, 825, 920, 829, // NOLINT ++ 921, 749, 922, 833, 923, 837, ++ 924, 9, 1073742749, 841, 927, 845, ++ 928, 849, 929, 853, // NOLINT ++ 931, 857, 1073742756, 861, 933, 865, ++ 934, 869, 1073742759, 873, 939, 877, ++ 940, 777, 1073742765, 781, // NOLINT ++ 943, 785, 945, 801, 946, 805, ++ 1073742771, 809, 948, 813, 949, 817, ++ 1073742774, 821, 951, 825, // NOLINT ++ 952, 829, 953, 749, 954, 833, ++ 955, 837, 956, 9, 1073742781, 841, ++ 959, 845, 960, 849, // NOLINT ++ 961, 853, 962, 857, 963, 857, ++ 1073742788, 861, 965, 865, 966, 869, ++ 1073742791, 873, 971, 877, // NOLINT ++ 972, 789, 1073742797, 793, 974, 797, ++ 975, 881, 976, 805, 977, 829, ++ 981, 869, 982, 849, // NOLINT ++ 983, 881, 984, 885, 985, 885, ++ 986, 889, 987, 889, 988, 893, ++ 989, 893, 990, 897, // NOLINT ++ 991, 897, 992, 901, 993, 901, ++ 994, 905, 995, 905, 996, 909, ++ 997, 909, 998, 913, // NOLINT ++ 999, 913, 1000, 917, 1001, 917, ++ 1002, 921, 1003, 921, 1004, 925, ++ 1005, 925, 1006, 929, // NOLINT ++ 1007, 929, 1008, 833, 1009, 853, ++ 1010, 933, 1011, 773, 1013, 817, ++ 1015, 937, 1016, 937, // NOLINT ++ 1017, 933, 1018, 941, 1019, 941, ++ 1073742845, 765, 1023, 769, 1073742848, 945, ++ 1039, 949, 1073742864, 953, // NOLINT ++ 1071, 957, 1073742896, 953, 1103, 957, ++ 1073742928, 945, 1119, 949, 1120, 961, ++ 1121, 961, 1122, 965, // NOLINT ++ 1123, 965, 1124, 969, 1125, 969, ++ 1126, 973, 1127, 973, 1128, 977, ++ 1129, 977, 1130, 981, // NOLINT ++ 1131, 981, 1132, 985, 1133, 985, ++ 1134, 989, 1135, 989, 1136, 993, ++ 1137, 993, 1138, 997, // NOLINT ++ 1139, 997, 1140, 1001, 1141, 1001, ++ 1142, 1005, 1143, 1005, 1144, 1009, ++ 1145, 1009, 1146, 1013, // NOLINT ++ 1147, 1013, 1148, 1017, 1149, 1017, ++ 1150, 1021, 1151, 1021, 1152, 1025, ++ 1153, 1025, 1162, 1029, // NOLINT ++ 1163, 1029, 1164, 1033, 1165, 1033, ++ 1166, 1037, 1167, 1037, 1168, 1041, ++ 1169, 1041, 1170, 1045, // NOLINT ++ 1171, 1045, 1172, 1049, 1173, 1049, ++ 1174, 1053, 1175, 1053, 1176, 1057, ++ 1177, 1057, 1178, 1061, // NOLINT ++ 1179, 1061, 1180, 1065, 1181, 1065, ++ 1182, 1069, 1183, 1069, 1184, 1073, ++ 1185, 1073, 1186, 1077, // NOLINT ++ 1187, 1077, 1188, 1081, 1189, 1081, ++ 1190, 1085, 1191, 1085, 1192, 1089, ++ 1193, 1089, 1194, 1093, // NOLINT ++ 1195, 1093, 1196, 1097, 1197, 1097, ++ 1198, 1101, 1199, 1101, 1200, 1105, ++ 1201, 1105, 1202, 1109, // NOLINT ++ 1203, 1109, 1204, 1113, 1205, 1113, ++ 1206, 1117, 1207, 1117, 1208, 1121, ++ 1209, 1121, 1210, 1125, // NOLINT ++ 1211, 1125, 1212, 1129, 1213, 1129, ++ 1214, 1133, 1215, 1133, 1216, 1137, ++ 1217, 1141, 1218, 1141, // NOLINT ++ 1219, 1145, 1220, 1145, 1221, 1149, ++ 1222, 1149, 1223, 1153, 1224, 1153, ++ 1225, 1157, 1226, 1157, // NOLINT ++ 1227, 1161, 1228, 1161, 1229, 1165, ++ 1230, 1165, 1231, 1137, 1232, 1169, ++ 1233, 1169, 1234, 1173, // NOLINT ++ 1235, 1173, 1236, 1177, 1237, 1177, ++ 1238, 1181, 1239, 1181, 1240, 1185, ++ 1241, 1185, 1242, 1189, // NOLINT ++ 1243, 1189, 1244, 1193, 1245, 1193, ++ 1246, 1197, 1247, 1197, 1248, 1201, ++ 1249, 1201, 1250, 1205, // NOLINT ++ 1251, 1205, 1252, 1209, 1253, 1209, ++ 1254, 1213, 1255, 1213, 1256, 1217, ++ 1257, 1217, 1258, 1221, // NOLINT ++ 1259, 1221, 1260, 1225, 1261, 1225, ++ 1262, 1229, 1263, 1229, 1264, 1233, ++ 1265, 1233, 1266, 1237, // NOLINT ++ 1267, 1237, 1268, 1241, 1269, 1241, ++ 1270, 1245, 1271, 1245, 1272, 1249, ++ 1273, 1249, 1274, 1253, // NOLINT ++ 1275, 1253, 1276, 1257, 1277, 1257, ++ 1278, 1261, 1279, 1261, 1280, 1265, ++ 1281, 1265, 1282, 1269, // NOLINT ++ 1283, 1269, 1284, 1273, 1285, 1273, ++ 1286, 1277, 1287, 1277, 1288, 1281, ++ 1289, 1281, 1290, 1285, // NOLINT ++ 1291, 1285, 1292, 1289, 1293, 1289, ++ 1294, 1293, 1295, 1293, 1296, 1297, ++ 1297, 1297, 1298, 1301, // NOLINT ++ 1299, 1301, 1300, 1305, 1301, 1305, ++ 1302, 1309, 1303, 1309, 1304, 1313, ++ 1305, 1313, 1306, 1317, // NOLINT ++ 1307, 1317, 1308, 1321, 1309, 1321, ++ 1310, 1325, 1311, 1325, 1312, 1329, ++ 1313, 1329, 1314, 1333, // NOLINT ++ 1315, 1333, 1316, 1337, 1317, 1337, ++ 1318, 1341, 1319, 1341, 1320, 1345, ++ 1321, 1345, 1322, 1349, // NOLINT ++ 1323, 1349, 1324, 1353, 1325, 1353, ++ 1326, 1357, 1327, 1357, 1073743153, 1361, ++ 1366, 1365, 1073743201, 1361, // NOLINT ++ 1414, 1365, 1073746080, 1369, 4293, 1373, ++ 4295, 1377, 4301, 1381, 7545, 1385, ++ 7549, 1389, 7680, 1393, // NOLINT ++ 7681, 1393, 7682, 1397, 7683, 1397, ++ 7684, 1401, 7685, 1401, 7686, 1405, ++ 7687, 1405, 7688, 1409, // NOLINT ++ 7689, 1409, 7690, 1413, 7691, 1413, ++ 7692, 1417, 7693, 1417, 7694, 1421, ++ 7695, 1421, 7696, 1425, // NOLINT ++ 7697, 1425, 7698, 1429, 7699, 1429, ++ 7700, 1433, 7701, 1433, 7702, 1437, ++ 7703, 1437, 7704, 1441, // NOLINT ++ 7705, 1441, 7706, 1445, 7707, 1445, ++ 7708, 1449, 7709, 1449, 7710, 1453, ++ 7711, 1453, 7712, 1457, // NOLINT ++ 7713, 1457, 7714, 1461, 7715, 1461, ++ 7716, 1465, 7717, 1465, 7718, 1469, ++ 7719, 1469, 7720, 1473, // NOLINT ++ 7721, 1473, 7722, 1477, 7723, 1477, ++ 7724, 1481, 7725, 1481, 7726, 1485, ++ 7727, 1485, 7728, 1489, // NOLINT ++ 7729, 1489, 7730, 1493, 7731, 1493, ++ 7732, 1497, 7733, 1497, 7734, 1501, ++ 7735, 1501, 7736, 1505, // NOLINT ++ 7737, 1505, 7738, 1509, 7739, 1509, ++ 7740, 1513, 7741, 1513, 7742, 1517, ++ 7743, 1517, 7744, 1521, // NOLINT ++ 7745, 1521, 7746, 1525, 7747, 1525, ++ 7748, 1529, 7749, 1529, 7750, 1533, ++ 7751, 1533, 7752, 1537, // NOLINT ++ 7753, 1537, 7754, 1541, 7755, 1541, ++ 7756, 1545, 7757, 1545, 7758, 1549, ++ 7759, 1549, 7760, 1553, // NOLINT ++ 7761, 1553, 7762, 1557, 7763, 1557, ++ 7764, 1561, 7765, 1561, 7766, 1565, ++ 7767, 1565, 7768, 1569, // NOLINT ++ 7769, 1569, 7770, 1573, 7771, 1573, ++ 7772, 1577, 7773, 1577, 7774, 1581, ++ 7775, 1581, 7776, 1585, // NOLINT ++ 7777, 1585, 7778, 1589, 7779, 1589, ++ 7780, 1593, 7781, 1593, 7782, 1597, ++ 7783, 1597, 7784, 1601, // NOLINT ++ 7785, 1601, 7786, 1605, 7787, 1605, ++ 7788, 1609, 7789, 1609, 7790, 1613, ++ 7791, 1613, 7792, 1617, // NOLINT ++ 7793, 1617, 7794, 1621, 7795, 1621, ++ 7796, 1625, 7797, 1625, 7798, 1629, ++ 7799, 1629, 7800, 1633, // NOLINT ++ 7801, 1633, 7802, 1637, 7803, 1637, ++ 7804, 1641, 7805, 1641, 7806, 1645, ++ 7807, 1645, 7808, 1649, // NOLINT ++ 7809, 1649, 7810, 1653, 7811, 1653, ++ 7812, 1657, 7813, 1657, 7814, 1661, ++ 7815, 1661, 7816, 1665, // NOLINT ++ 7817, 1665, 7818, 1669, 7819, 1669, ++ 7820, 1673, 7821, 1673, 7822, 1677, ++ 7823, 1677, 7824, 1681, // NOLINT ++ 7825, 1681, 7826, 1685, 7827, 1685, ++ 7828, 1689, 7829, 1689, 7835, 1585, ++ 7840, 1693, 7841, 1693, // NOLINT ++ 7842, 1697, 7843, 1697, 7844, 1701, ++ 7845, 1701, 7846, 1705, 7847, 1705, ++ 7848, 1709, 7849, 1709, // NOLINT ++ 7850, 1713, 7851, 1713, 7852, 1717, ++ 7853, 1717, 7854, 1721, 7855, 1721, ++ 7856, 1725, 7857, 1725, // NOLINT ++ 7858, 1729, 7859, 1729, 7860, 1733, ++ 7861, 1733, 7862, 1737, 7863, 1737, ++ 7864, 1741, 7865, 1741, // NOLINT ++ 7866, 1745, 7867, 1745, 7868, 1749, ++ 7869, 1749, 7870, 1753, 7871, 1753, ++ 7872, 1757, 7873, 1757, // NOLINT ++ 7874, 1761, 7875, 1761, 7876, 1765, ++ 7877, 1765, 7878, 1769, 7879, 1769, ++ 7880, 1773, 7881, 1773, // NOLINT ++ 7882, 1777, 7883, 1777, 7884, 1781, ++ 7885, 1781, 7886, 1785, 7887, 1785, ++ 7888, 1789, 7889, 1789, // NOLINT ++ 7890, 1793, 7891, 1793, 7892, 1797, ++ 7893, 1797, 7894, 1801, 7895, 1801, ++ 7896, 1805, 7897, 1805, // NOLINT ++ 7898, 1809, 7899, 1809, 7900, 1813, ++ 7901, 1813, 7902, 1817, 7903, 1817, ++ 7904, 1821, 7905, 1821, // NOLINT ++ 7906, 1825, 7907, 1825, 7908, 1829, ++ 7909, 1829, 7910, 1833, 7911, 1833, ++ 7912, 1837, 7913, 1837, // NOLINT ++ 7914, 1841, 7915, 1841, 7916, 1845, ++ 7917, 1845, 7918, 1849, 7919, 1849, ++ 7920, 1853, 7921, 1853, // NOLINT ++ 7922, 1857, 7923, 1857, 7924, 1861, ++ 7925, 1861, 7926, 1865, 7927, 1865, ++ 7928, 1869, 7929, 1869, // NOLINT ++ 7930, 1873, 7931, 1873, 7932, 1877, ++ 7933, 1877, 7934, 1881, 7935, 1881, ++ 1073749760, 1885, 7943, 1889, // NOLINT ++ 1073749768, 1885, 7951, 1889, 1073749776, 1893, ++ 7957, 1897, 1073749784, 1893, 7965, 1897, ++ 1073749792, 1901, 7975, 1905, // NOLINT ++ 1073749800, 1901, 7983, 1905, 1073749808, 1909, ++ 7991, 1913, 1073749816, 1909, 7999, 1913, ++ 1073749824, 1917, 8005, 1921, // NOLINT ++ 1073749832, 1917, 8013, 1921, 8017, 1925, ++ 8019, 1929, 8021, 1933, 8023, 1937, ++ 8025, 1925, 8027, 1929, // NOLINT ++ 8029, 1933, 8031, 1937, 1073749856, 1941, ++ 8039, 1945, 1073749864, 1941, 8047, 1945, ++ 1073749872, 1949, 8049, 1953, // NOLINT ++ 1073749874, 1957, 8053, 1961, 1073749878, 1965, ++ 8055, 1969, 1073749880, 1973, 8057, 1977, ++ 1073749882, 1981, 8059, 1985, // NOLINT ++ 1073749884, 1989, 8061, 1993, 1073749936, 1997, ++ 8113, 2001, 1073749944, 1997, 8121, 2001, ++ 1073749946, 1949, 8123, 1953, // NOLINT ++ 8126, 749, 1073749960, 1957, 8139, 1961, ++ 1073749968, 2005, 8145, 2009, 1073749976, 2005, ++ 8153, 2009, 1073749978, 1965, // NOLINT ++ 8155, 1969, 1073749984, 2013, 8161, 2017, ++ 8165, 2021, 1073749992, 2013, 8169, 2017, ++ 1073749994, 1981, 8171, 1985, // NOLINT ++ 8172, 2021, 1073750008, 1973, 8185, 1977, ++ 1073750010, 1989, 8187, 1993}; // NOLINT ++static const MultiCharacterSpecialCase<2> ++ kEcma262UnCanonicalizeMultiStrings1[83] = { // NOLINT ++ {{8498, 8526}}, {{8544, 8560}}, {{8559, 8575}}, ++ {{8579, 8580}}, // NOLINT ++ {{9398, 9424}}, {{9423, 9449}}, {{11264, 11312}}, ++ {{11310, 11358}}, // NOLINT ++ {{11360, 11361}}, {{619, 11362}}, {{7549, 11363}}, ++ {{637, 11364}}, // NOLINT ++ {{570, 11365}}, {{574, 11366}}, {{11367, 11368}}, ++ {{11369, 11370}}, // NOLINT ++ {{11371, 11372}}, {{593, 11373}}, {{625, 11374}}, ++ {{592, 11375}}, // NOLINT ++ {{594, 11376}}, {{11378, 11379}}, {{11381, 11382}}, ++ {{575, 11390}}, // NOLINT ++ {{576, 11391}}, {{11392, 11393}}, {{11394, 11395}}, ++ {{11396, 11397}}, // NOLINT ++ {{11398, 11399}}, {{11400, 11401}}, {{11402, 11403}}, ++ {{11404, 11405}}, // NOLINT ++ {{11406, 11407}}, {{11408, 11409}}, {{11410, 11411}}, ++ {{11412, 11413}}, // NOLINT ++ {{11414, 11415}}, {{11416, 11417}}, {{11418, 11419}}, ++ {{11420, 11421}}, // NOLINT ++ {{11422, 11423}}, {{11424, 11425}}, {{11426, 11427}}, ++ {{11428, 11429}}, // NOLINT ++ {{11430, 11431}}, {{11432, 11433}}, {{11434, 11435}}, ++ {{11436, 11437}}, // NOLINT ++ {{11438, 11439}}, {{11440, 11441}}, {{11442, 11443}}, ++ {{11444, 11445}}, // NOLINT ++ {{11446, 11447}}, {{11448, 11449}}, {{11450, 11451}}, ++ {{11452, 11453}}, // NOLINT ++ {{11454, 11455}}, {{11456, 11457}}, {{11458, 11459}}, ++ {{11460, 11461}}, // NOLINT ++ {{11462, 11463}}, {{11464, 11465}}, {{11466, 11467}}, ++ {{11468, 11469}}, // NOLINT ++ {{11470, 11471}}, {{11472, 11473}}, {{11474, 11475}}, ++ {{11476, 11477}}, // NOLINT ++ {{11478, 11479}}, {{11480, 11481}}, {{11482, 11483}}, ++ {{11484, 11485}}, // NOLINT ++ {{11486, 11487}}, {{11488, 11489}}, {{11490, 11491}}, ++ {{11499, 11500}}, // NOLINT ++ {{11501, 11502}}, {{11506, 11507}}, {{4256, 11520}}, ++ {{4293, 11557}}, // NOLINT ++ {{4295, 11559}}, {{4301, 11565}}, {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262UnCanonicalizeTable1Size = 149; // NOLINT ++static const int32_t kEcma262UnCanonicalizeTable1[298] = { ++ 306, 1, 334, 1, 1073742176, 5, 367, 9, ++ 1073742192, 5, 383, 9, 387, 13, 388, 13, // NOLINT ++ 1073743030, 17, 1231, 21, 1073743056, 17, 1257, 21, ++ 1073744896, 25, 3118, 29, 1073744944, 25, 3166, 29, // NOLINT ++ 3168, 33, 3169, 33, 3170, 37, 3171, 41, ++ 3172, 45, 3173, 49, 3174, 53, 3175, 57, // NOLINT ++ 3176, 57, 3177, 61, 3178, 61, 3179, 65, ++ 3180, 65, 3181, 69, 3182, 73, 3183, 77, // NOLINT ++ 3184, 81, 3186, 85, 3187, 85, 3189, 89, ++ 3190, 89, 1073745022, 93, 3199, 97, 3200, 101, // NOLINT ++ 3201, 101, 3202, 105, 3203, 105, 3204, 109, ++ 3205, 109, 3206, 113, 3207, 113, 3208, 117, // NOLINT ++ 3209, 117, 3210, 121, 3211, 121, 3212, 125, ++ 3213, 125, 3214, 129, 3215, 129, 3216, 133, // NOLINT ++ 3217, 133, 3218, 137, 3219, 137, 3220, 141, ++ 3221, 141, 3222, 145, 3223, 145, 3224, 149, // NOLINT ++ 3225, 149, 3226, 153, 3227, 153, 3228, 157, ++ 3229, 157, 3230, 161, 3231, 161, 3232, 165, // NOLINT ++ 3233, 165, 3234, 169, 3235, 169, 3236, 173, ++ 3237, 173, 3238, 177, 3239, 177, 3240, 181, // NOLINT ++ 3241, 181, 3242, 185, 3243, 185, 3244, 189, ++ 3245, 189, 3246, 193, 3247, 193, 3248, 197, // NOLINT ++ 3249, 197, 3250, 201, 3251, 201, 3252, 205, ++ 3253, 205, 3254, 209, 3255, 209, 3256, 213, // NOLINT ++ 3257, 213, 3258, 217, 3259, 217, 3260, 221, ++ 3261, 221, 3262, 225, 3263, 225, 3264, 229, // NOLINT ++ 3265, 229, 3266, 233, 3267, 233, 3268, 237, ++ 3269, 237, 3270, 241, 3271, 241, 3272, 245, // NOLINT ++ 3273, 245, 3274, 249, 3275, 249, 3276, 253, ++ 3277, 253, 3278, 257, 3279, 257, 3280, 261, // NOLINT ++ 3281, 261, 3282, 265, 3283, 265, 3284, 269, ++ 3285, 269, 3286, 273, 3287, 273, 3288, 277, // NOLINT ++ 3289, 277, 3290, 281, 3291, 281, 3292, 285, ++ 3293, 285, 3294, 289, 3295, 289, 3296, 293, // NOLINT ++ 3297, 293, 3298, 297, 3299, 297, 3307, 301, ++ 3308, 301, 3309, 305, 3310, 305, 3314, 309, // NOLINT ++ 3315, 309, 1073745152, 313, 3365, 317, 3367, 321, ++ 3373, 325}; // NOLINT ++static const MultiCharacterSpecialCase<2> ++ kEcma262UnCanonicalizeMultiStrings5[104] = { // NOLINT ++ {{42560, 42561}}, {{42562, 42563}}, ++ {{42564, 42565}}, {{42566, 42567}}, // NOLINT ++ {{42568, 42569}}, {{42570, 42571}}, ++ {{42572, 42573}}, {{42574, 42575}}, // NOLINT ++ {{42576, 42577}}, {{42578, 42579}}, ++ {{42580, 42581}}, {{42582, 42583}}, // NOLINT ++ {{42584, 42585}}, {{42586, 42587}}, ++ {{42588, 42589}}, {{42590, 42591}}, // NOLINT ++ {{42592, 42593}}, {{42594, 42595}}, ++ {{42596, 42597}}, {{42598, 42599}}, // NOLINT ++ {{42600, 42601}}, {{42602, 42603}}, ++ {{42604, 42605}}, {{42624, 42625}}, // NOLINT ++ {{42626, 42627}}, {{42628, 42629}}, ++ {{42630, 42631}}, {{42632, 42633}}, // NOLINT ++ {{42634, 42635}}, {{42636, 42637}}, ++ {{42638, 42639}}, {{42640, 42641}}, // NOLINT ++ {{42642, 42643}}, {{42644, 42645}}, ++ {{42646, 42647}}, {{42648, 42649}}, // NOLINT ++ {{42650, 42651}}, {{42786, 42787}}, ++ {{42788, 42789}}, {{42790, 42791}}, // NOLINT ++ {{42792, 42793}}, {{42794, 42795}}, ++ {{42796, 42797}}, {{42798, 42799}}, // NOLINT ++ {{42802, 42803}}, {{42804, 42805}}, ++ {{42806, 42807}}, {{42808, 42809}}, // NOLINT ++ {{42810, 42811}}, {{42812, 42813}}, ++ {{42814, 42815}}, {{42816, 42817}}, // NOLINT ++ {{42818, 42819}}, {{42820, 42821}}, ++ {{42822, 42823}}, {{42824, 42825}}, // NOLINT ++ {{42826, 42827}}, {{42828, 42829}}, ++ {{42830, 42831}}, {{42832, 42833}}, // NOLINT ++ {{42834, 42835}}, {{42836, 42837}}, ++ {{42838, 42839}}, {{42840, 42841}}, // NOLINT ++ {{42842, 42843}}, {{42844, 42845}}, ++ {{42846, 42847}}, {{42848, 42849}}, // NOLINT ++ {{42850, 42851}}, {{42852, 42853}}, ++ {{42854, 42855}}, {{42856, 42857}}, // NOLINT ++ {{42858, 42859}}, {{42860, 42861}}, ++ {{42862, 42863}}, {{42873, 42874}}, // NOLINT ++ {{42875, 42876}}, {{7545, 42877}}, ++ {{42878, 42879}}, {{42880, 42881}}, // NOLINT ++ {{42882, 42883}}, {{42884, 42885}}, ++ {{42886, 42887}}, {{42891, 42892}}, // NOLINT ++ {{613, 42893}}, {{42896, 42897}}, ++ {{42898, 42899}}, {{42902, 42903}}, // NOLINT ++ {{42904, 42905}}, {{42906, 42907}}, ++ {{42908, 42909}}, {{42910, 42911}}, // NOLINT ++ {{42912, 42913}}, {{42914, 42915}}, ++ {{42916, 42917}}, {{42918, 42919}}, // NOLINT ++ {{42920, 42921}}, {{614, 42922}}, ++ {{604, 42923}}, {{609, 42924}}, // NOLINT ++ {{620, 42925}}, {{670, 42928}}, ++ {{647, 42929}}, {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262UnCanonicalizeTable5Size = 198; // NOLINT ++static const int32_t ++ kEcma262UnCanonicalizeTable5[396] = ++ {1600, 1, 1601, 1, 1602, 5, 1603, 5, ++ 1604, 9, 1605, 9, 1606, 13, 1607, 13, // NOLINT ++ 1608, 17, 1609, 17, 1610, 21, 1611, 21, ++ 1612, 25, 1613, 25, 1614, 29, 1615, 29, // NOLINT ++ 1616, 33, 1617, 33, 1618, 37, 1619, 37, ++ 1620, 41, 1621, 41, 1622, 45, 1623, 45, // NOLINT ++ 1624, 49, 1625, 49, 1626, 53, 1627, 53, ++ 1628, 57, 1629, 57, 1630, 61, 1631, 61, // NOLINT ++ 1632, 65, 1633, 65, 1634, 69, 1635, 69, ++ 1636, 73, 1637, 73, 1638, 77, 1639, 77, // NOLINT ++ 1640, 81, 1641, 81, 1642, 85, 1643, 85, ++ 1644, 89, 1645, 89, 1664, 93, 1665, 93, // NOLINT ++ 1666, 97, 1667, 97, 1668, 101, 1669, 101, ++ 1670, 105, 1671, 105, 1672, 109, 1673, 109, // NOLINT ++ 1674, 113, 1675, 113, 1676, 117, 1677, 117, ++ 1678, 121, 1679, 121, 1680, 125, 1681, 125, // NOLINT ++ 1682, 129, 1683, 129, 1684, 133, 1685, 133, ++ 1686, 137, 1687, 137, 1688, 141, 1689, 141, // NOLINT ++ 1690, 145, 1691, 145, 1826, 149, 1827, 149, ++ 1828, 153, 1829, 153, 1830, 157, 1831, 157, // NOLINT ++ 1832, 161, 1833, 161, 1834, 165, 1835, 165, ++ 1836, 169, 1837, 169, 1838, 173, 1839, 173, // NOLINT ++ 1842, 177, 1843, 177, 1844, 181, 1845, 181, ++ 1846, 185, 1847, 185, 1848, 189, 1849, 189, // NOLINT ++ 1850, 193, 1851, 193, 1852, 197, 1853, 197, ++ 1854, 201, 1855, 201, 1856, 205, 1857, 205, // NOLINT ++ 1858, 209, 1859, 209, 1860, 213, 1861, 213, ++ 1862, 217, 1863, 217, 1864, 221, 1865, 221, // NOLINT ++ 1866, 225, 1867, 225, 1868, 229, 1869, 229, ++ 1870, 233, 1871, 233, 1872, 237, 1873, 237, // NOLINT ++ 1874, 241, 1875, 241, 1876, 245, 1877, 245, ++ 1878, 249, 1879, 249, 1880, 253, 1881, 253, // NOLINT ++ 1882, 257, 1883, 257, 1884, 261, 1885, 261, ++ 1886, 265, 1887, 265, 1888, 269, 1889, 269, // NOLINT ++ 1890, 273, 1891, 273, 1892, 277, 1893, 277, ++ 1894, 281, 1895, 281, 1896, 285, 1897, 285, // NOLINT ++ 1898, 289, 1899, 289, 1900, 293, 1901, 293, ++ 1902, 297, 1903, 297, 1913, 301, 1914, 301, // NOLINT ++ 1915, 305, 1916, 305, 1917, 309, 1918, 313, ++ 1919, 313, 1920, 317, 1921, 317, 1922, 321, // NOLINT ++ 1923, 321, 1924, 325, 1925, 325, 1926, 329, ++ 1927, 329, 1931, 333, 1932, 333, 1933, 337, // NOLINT ++ 1936, 341, 1937, 341, 1938, 345, 1939, 345, ++ 1942, 349, 1943, 349, 1944, 353, 1945, 353, // NOLINT ++ 1946, 357, 1947, 357, 1948, 361, 1949, 361, ++ 1950, 365, 1951, 365, 1952, 369, 1953, 369, // NOLINT ++ 1954, 373, 1955, 373, 1956, 377, 1957, 377, ++ 1958, 381, 1959, 381, 1960, 385, 1961, 385, // NOLINT ++ 1962, 389, 1963, 393, 1964, 397, 1965, 401, ++ 1968, 405, 1969, 409}; // NOLINT ++static const MultiCharacterSpecialCase<2> ++ kEcma262UnCanonicalizeMultiStrings7[3] = { // NOLINT ++ {{65313, 65345}}, ++ {{65338, 65370}}, ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kEcma262UnCanonicalizeTable7Size = 4; // NOLINT ++static const int32_t kEcma262UnCanonicalizeTable7[8] = { ++ 1073749793, 1, 7994, 5, 1073749825, 1, 8026, 5}; // NOLINT ++int Ecma262UnCanonicalize::Convert(uchar c, uchar n, uchar* result, ++ bool* allow_caching_ptr) { ++ int chunk_index = c >> 13; ++ switch (chunk_index) { ++ case 0: ++ return LookupMapping( ++ kEcma262UnCanonicalizeTable0, kEcma262UnCanonicalizeTable0Size, ++ kEcma262UnCanonicalizeMultiStrings0, c, n, result, allow_caching_ptr); ++ case 1: ++ return LookupMapping( ++ kEcma262UnCanonicalizeTable1, kEcma262UnCanonicalizeTable1Size, ++ kEcma262UnCanonicalizeMultiStrings1, c, n, result, allow_caching_ptr); ++ case 5: ++ return LookupMapping( ++ kEcma262UnCanonicalizeTable5, kEcma262UnCanonicalizeTable5Size, ++ kEcma262UnCanonicalizeMultiStrings5, c, n, result, allow_caching_ptr); ++ case 7: ++ return LookupMapping( ++ kEcma262UnCanonicalizeTable7, kEcma262UnCanonicalizeTable7Size, ++ kEcma262UnCanonicalizeMultiStrings7, c, n, result, allow_caching_ptr); ++ default: ++ return 0; ++ } ++} ++ ++static const MultiCharacterSpecialCase<1> ++ kCanonicalizationRangeMultiStrings0[1] = { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kCanonicalizationRangeTable0Size = 70; // NOLINT ++static const int32_t kCanonicalizationRangeTable0[140] = { ++ 1073741889, 100, 90, 0, 1073741921, 100, 122, 0, ++ 1073742016, 88, 214, 0, 1073742040, 24, 222, 0, // NOLINT ++ 1073742048, 88, 246, 0, 1073742072, 24, 254, 0, ++ 1073742715, 8, 893, 0, 1073742728, 8, 906, 0, // NOLINT ++ 1073742749, 8, 927, 0, 1073742759, 16, 939, 0, ++ 1073742765, 8, 943, 0, 1073742781, 8, 959, 0, // NOLINT ++ 1073742791, 16, 971, 0, 1073742845, 8, 1023, 0, ++ 1073742848, 60, 1039, 0, 1073742864, 124, 1071, 0, // NOLINT ++ 1073742896, 124, 1103, 0, 1073742928, 60, 1119, 0, ++ 1073743153, 148, 1366, 0, 1073743201, 148, 1414, 0, // NOLINT ++ 1073746080, 148, 4293, 0, 1073749760, 28, 7943, 0, ++ 1073749768, 28, 7951, 0, 1073749776, 20, 7957, 0, // NOLINT ++ 1073749784, 20, 7965, 0, 1073749792, 28, 7975, 0, ++ 1073749800, 28, 7983, 0, 1073749808, 28, 7991, 0, // NOLINT ++ 1073749816, 28, 7999, 0, 1073749824, 20, 8005, 0, ++ 1073749832, 20, 8013, 0, 1073749856, 28, 8039, 0, // NOLINT ++ 1073749864, 28, 8047, 0, 1073749874, 12, 8053, 0, ++ 1073749960, 12, 8139, 0}; // NOLINT ++static const MultiCharacterSpecialCase<1> ++ kCanonicalizationRangeMultiStrings1[1] = { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kCanonicalizationRangeTable1Size = 14; // NOLINT ++static const int32_t kCanonicalizationRangeTable1[28] = { ++ 1073742176, 60, 367, 0, 1073742192, 60, 383, 0, ++ 1073743030, 100, 1231, 0, 1073743056, 100, 1257, 0, // NOLINT ++ 1073744896, 184, 3118, 0, 1073744944, 184, 3166, 0, ++ 1073745152, 148, 3365, 0}; // NOLINT ++static const MultiCharacterSpecialCase<1> ++ kCanonicalizationRangeMultiStrings7[1] = { // NOLINT ++ {{kSentinel}}}; // NOLINT ++static const uint16_t kCanonicalizationRangeTable7Size = 4; // NOLINT ++static const int32_t kCanonicalizationRangeTable7[8] = { ++ 1073749793, 100, 7994, 0, 1073749825, 100, 8026, 0}; // NOLINT ++int CanonicalizationRange::Convert(uchar c, uchar n, uchar* result, ++ bool* allow_caching_ptr) { ++ int chunk_index = c >> 13; ++ switch (chunk_index) { ++ case 0: ++ return LookupMapping( ++ kCanonicalizationRangeTable0, kCanonicalizationRangeTable0Size, ++ kCanonicalizationRangeMultiStrings0, c, n, result, allow_caching_ptr); ++ case 1: ++ return LookupMapping( ++ kCanonicalizationRangeTable1, kCanonicalizationRangeTable1Size, ++ kCanonicalizationRangeMultiStrings1, c, n, result, allow_caching_ptr); ++ case 7: ++ return LookupMapping( ++ kCanonicalizationRangeTable7, kCanonicalizationRangeTable7Size, ++ kCanonicalizationRangeMultiStrings7, c, n, result, allow_caching_ptr); ++ default: ++ return 0; ++ } ++} ++ ++#endif // !V8_INTL_SUPPORT ++ ++} // namespace unibrow ++} // namespace v8 +diff -Nrup mozilla/js/src/irregexp/util/VectorShim.h mozilla-OK/js/src/irregexp/util/VectorShim.h +--- mozilla/js/src/irregexp/util/VectorShim.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/util/VectorShim.h 2023-02-27 08:17:58.258466026 +0300 +@@ -0,0 +1,215 @@ ++// Copyright 2014 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef V8_UTIL_VECTOR_H_ ++#define V8_UTIL_VECTOR_H_ ++ ++#include ++#include ++#include ++#include ++ ++#include "jsalloc.h" ++#include "js/Utility.h" ++#include "js/Vector.h" ++ ++namespace v8 { ++namespace internal { ++ ++////////////////////////////////////////////////// ++ ++// Adapted from: ++// https://github.com/v8/v8/blob/5f69bbc233c2d1baf149faf869a7901603929914/src/utils/allocation.h#L36-L58 ++ ++template ++T* NewArray(size_t size) { ++ static_assert(std::is_pod::value, ""); ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ T* result = static_cast(js_malloc(size * sizeof(T))); ++ if (!result) { ++ oomUnsafe.crash("Irregexp NewArray"); ++ } ++ return result; ++} ++ ++template ++void DeleteArray(T* array) { ++ js_free(array); ++} ++ ++////////////////////////////////////////////////// ++ ++// A non-resizable vector containing a pointer and a length. ++// The Vector may or may not own the pointer, depending on context. ++// Origin: ++// https://github.com/v8/v8/blob/5f69bbc233c2d1baf149faf869a7901603929914/src/utils/vector.h#L20-L134 ++ ++template ++class Vector { ++ public: ++ Vector() : start_(nullptr), length_(0) {} ++ ++ Vector(T* data, size_t length) : start_(data), length_(length) { ++ MOZ_ASSERT_IF(length != 0, data != nullptr); ++ } ++ ++ static Vector New(size_t length) { ++ return Vector(NewArray(length), length); ++ } ++ ++ // Returns a vector using the same backing storage as this one, ++ // spanning from and including 'from', to but not including 'to'. ++ Vector SubVector(size_t from, size_t to) const { ++ MOZ_ASSERT(from <= to); ++ MOZ_ASSERT(to <= length_); ++ return Vector(begin() + from, to - from); ++ } ++ ++ // Returns the length of the vector. Only use this if you really need an ++ // integer return value. Use {size()} otherwise. ++ int length() const { ++ MOZ_ASSERT(length_ <= static_cast(std::numeric_limits::max())); ++ return static_cast(length_); ++ } ++ ++ // Returns the length of the vector as a size_t. ++ constexpr size_t size() const { return length_; } ++ ++ // Returns whether or not the vector is empty. ++ constexpr bool empty() const { return length_ == 0; } ++ ++ // Access individual vector elements - checks bounds in debug mode. ++ T& operator[](size_t index) const { ++ MOZ_ASSERT(index < length_); ++ return start_[index]; ++ } ++ ++ const T& at(size_t index) const { return operator[](index); } ++ ++ T& first() { return start_[0]; } ++ ++ T& last() { ++ MOZ_ASSERT(length_ > 0); ++ return start_[length_ - 1]; ++ } ++ ++ // Returns a pointer to the start of the data in the vector. ++ constexpr T* begin() const { return start_; } ++ ++ // Returns a pointer past the end of the data in the vector. ++ constexpr T* end() const { return start_ + length_; } ++ ++ // Returns a clone of this vector with a new backing store. ++ Vector Clone() const { ++ T* result = NewArray(length_); ++ for (size_t i = 0; i < length_; i++) result[i] = start_[i]; ++ return Vector(result, length_); ++ } ++ ++ void Truncate(size_t length) { ++ MOZ_ASSERT(length <= length_); ++ length_ = length; ++ } ++ ++ // Releases the array underlying this vector. Once disposed the ++ // vector is empty. ++ void Dispose() { ++ DeleteArray(start_); ++ start_ = nullptr; ++ length_ = 0; ++ } ++ ++ Vector operator+(size_t offset) { ++ MOZ_ASSERT(offset <= length_); ++ return Vector(start_ + offset, length_ - offset); ++ } ++ ++ Vector operator+=(size_t offset) { ++ MOZ_ASSERT(offset <= length_); ++ start_ += offset; ++ length_ -= offset; ++ return *this; ++ } ++ ++ // Implicit conversion from Vector to Vector. ++ inline operator Vector() const { ++ return Vector::cast(*this); ++ } ++ ++ template ++ static constexpr Vector cast(Vector input) { ++ return Vector(reinterpret_cast(input.begin()), ++ input.length() * sizeof(S) / sizeof(T)); ++ } ++ ++ bool operator==(const Vector other) const { ++ if (length_ != other.length_) return false; ++ if (start_ == other.start_) return true; ++ for (size_t i = 0; i < length_; ++i) { ++ if (start_[i] != other.start_[i]) { ++ return false; ++ } ++ } ++ return true; ++ } ++ ++ private: ++ T* start_; ++ size_t length_; ++}; ++ ++// The resulting vector does not contain a null-termination byte. If you want ++// the null byte, use ArrayVector("foo"). ++inline Vector CStrVector(const char* data) { ++ return Vector(data, strlen(data)); ++} ++ ++} // namespace internal ++ ++namespace base { ++ ++// SmallVector uses inline storage first, and reallocates when full. ++// It is basically equivalent to js::Vector, and is implemented ++// as a thin wrapper. ++// V8's implementation: ++// https://github.com/v8/v8/blob/master/src/base/small-vector.h ++template ++class SmallVector { ++ public: ++ SmallVector() = default; ++ SmallVector(size_t size) { resize_no_init(size); } ++ ++ inline bool empty() const { return inner_.empty(); } ++ inline const T& back() const { return inner_.back(); } ++ inline void pop_back() { inner_.popBack(); }; ++ template ++ inline void emplace_back(Args&&... args) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ if (!inner_.emplaceBack(args...)) { ++ oomUnsafe.crash("Irregexp SmallVector emplace_back"); ++ } ++ }; ++ inline size_t size() const { return inner_.length(); } ++ inline const T& at(size_t index) const { return inner_[index]; } ++ T* data() { return inner_.begin(); } ++ ++ T& operator[](size_t index) { return inner_[index]; } ++ const T& operator[](size_t index) const { return inner_[index]; } ++ ++ void resize_no_init(size_t new_size) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ if (!inner_.resizeUninitialized(new_size)) { ++ oomUnsafe.crash("Irregexp SmallVector resize"); ++ } ++ } ++ ++ private: ++ js::Vector inner_; ++}; ++ ++} // namespace base ++ ++} // namespace v8 ++ ++#endif // V8_UTIL_VECTOR_H_ +diff -Nrup mozilla/js/src/irregexp/util/ZoneShim.h mozilla-OK/js/src/irregexp/util/ZoneShim.h +--- mozilla/js/src/irregexp/util/ZoneShim.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/irregexp/util/ZoneShim.h 2023-02-27 08:17:24.866702517 +0300 +@@ -0,0 +1,376 @@ ++// Copyright 2019 the V8 project authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef V8_UTIL_ZONE_H_ ++#define V8_UTIL_ZONE_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "ds/LifoAlloc.h" ++#include "ds/Sort.h" ++#include "irregexp/util/VectorShim.h" ++ ++namespace v8 { ++namespace internal { ++ ++// V8::Zone ~= LifoAlloc ++class Zone { ++ public: ++ Zone(js::LifoAlloc& alloc) : lifoAlloc_(alloc) {} ++ ++ template ++ T* New(Args&&... args) { ++ js::LifoAlloc::AutoFallibleScope fallible(&lifoAlloc_); ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ void* memory = lifoAlloc_.alloc(sizeof(T)); ++ if (!memory) { ++ oomUnsafe.crash("Irregexp Zone::New"); ++ } ++ return new (memory) T(std::forward(args)...); ++ } ++ ++ // Allocates uninitialized memory for 'length' number of T instances. ++ template ++ T* NewArray(size_t length) { ++ js::LifoAlloc::AutoFallibleScope fallible(&lifoAlloc_); ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ void* memory = lifoAlloc_.alloc(length * sizeof(T)); ++ if (!memory) { ++ oomUnsafe.crash("Irregexp Zone::New"); ++ } ++ return static_cast(memory); ++ } ++ ++ void DeleteAll() { lifoAlloc_.freeAll(); } ++ ++ // Returns true if the total memory allocated exceeds a threshold. ++ static const size_t kExcessLimit = 256 * 1024 * 1024; ++ bool excess_allocation() const { ++ return lifoAlloc_.computedSizeOfExcludingThis() > kExcessLimit; ++ } ++ ++ private: ++ js::LifoAlloc& lifoAlloc_; ++}; ++ ++// Superclass for classes allocated in a Zone. ++// Based on: https://github.com/v8/v8/blob/master/src/zone/zone.h ++class ZoneObject { ++ public: ++ // new (zone) SomeObject(...) was the old pattern. ++ // Delete the constructor to avoid using it accidentally. ++ void* operator new(size_t size, Zone* zone) = delete; ++ ++ // Allow non-allocating placement new ++ void* operator new(size_t size, void* ptr) { return ptr; } ++ ++ // Ideally, the delete operator should be private instead of ++ // public, but unfortunately the compiler sometimes synthesizes ++ // (unused) destructors for classes derived from ZoneObject, which ++ // require the operator to be visible. MSVC requires the delete ++ // operator to be public. ++ ++ // ZoneObjects should never be deleted individually; use ++ // Zone::DeleteAll() to delete all zone objects in one go. ++ void operator delete(void*, size_t) { MOZ_CRASH("unreachable"); } ++ void operator delete(void* pointer, Zone* zone) { MOZ_CRASH("unreachable"); } ++}; ++ ++// ZoneLists are growable lists with constant-time access to the ++// elements. The list itself and all its elements are allocated in the ++// Zone. ZoneLists cannot be deleted individually; you can delete all ++// objects in the Zone by calling Zone::DeleteAll(). ++// Used throughout irregexp. ++// Based on: https://github.com/v8/v8/blob/master/src/zone/zone-list.h ++template ++class ZoneList final : public ZoneObject { ++ public: ++ // Construct a new ZoneList with the given capacity; the length is ++ // always zero. The capacity must be non-negative. ++ ZoneList(int capacity, Zone* zone) : capacity_(capacity) { ++ data_ = (capacity_ > 0) ? zone->NewArray(capacity_) : nullptr; ++ } ++ // Construct a new ZoneList by copying the elements of the given ZoneList. ++ ZoneList(const ZoneList& other, Zone* zone) ++ : ZoneList(other.length(), zone) { ++ AddAll(other, zone); ++ } ++ ++ // Returns a reference to the element at index i. This reference is not safe ++ // to use after operations that can change the list's backing store ++ // (e.g. Add). ++ inline T& operator[](int i) const { ++ MOZ_ASSERT(i >= 0); ++ MOZ_ASSERT(static_cast(i) < static_cast(length_)); ++ return data_[i]; ++ } ++ inline T& at(int i) const { return operator[](i); } ++ inline T& last() const { return at(length_ - 1); } ++ inline T& first() const { return at(0); } ++ ++ using iterator = T*; ++ inline iterator begin() const { return &data_[0]; } ++ inline iterator end() const { return &data_[length_]; } ++ ++ inline bool is_empty() const { return length_ == 0; } ++ inline int length() const { return length_; } ++ inline int capacity() const { return capacity_; } ++ ++ Vector ToVector() const { return Vector(data_, length_); } ++ Vector ToVector(int start, int length) const { ++ return Vector(data_ + start, std::min(length_ - start, length)); ++ } ++ ++ Vector ToConstVector() const { ++ return Vector(data_, length_); ++ } ++ ++ // Adds a copy of the given 'element' to the end of the list, ++ // expanding the list if necessary. ++ void Add(const T& element, Zone* zone) { ++ if (length_ < capacity_) { ++ data_[length_++] = element; ++ } else { ++ ZoneList::ResizeAdd(element, zone); ++ } ++ } ++ // Add all the elements from the argument list to this list. ++ void AddAll(const ZoneList& other, Zone* zone) { ++ AddAll(other.ToVector(), zone); ++ } ++ // Add all the elements from the vector to this list. ++ void AddAll(const Vector& other, Zone* zone) { ++ int result_length = length_ + other.length(); ++ if (capacity_ < result_length) { ++ Resize(result_length, zone); ++ } ++ if (std::is_fundamental()) { ++ memcpy(data_ + length_, other.begin(), sizeof(*data_) * other.length()); ++ } else { ++ for (int i = 0; i < other.length(); i++) { ++ data_[length_ + i] = other.at(i); ++ } ++ } ++ length_ = result_length; ++ } ++ ++ // Overwrites the element at the specific index. ++ void Set(int index, const T& element) { ++ MOZ_ASSERT(index >= 0 && index <= length_); ++ data_[index] = element; ++ } ++ ++ // Removes the i'th element without deleting it even if T is a ++ // pointer type; moves all elements above i "down". Returns the ++ // removed element. This function's complexity is linear in the ++ // size of the list. ++ T Remove(int i) { ++ T element = at(i); ++ length_--; ++ while (i < length_) { ++ data_[i] = data_[i + 1]; ++ i++; ++ } ++ return element; ++ } ++ ++ // Removes the last element without deleting it even if T is a ++ // pointer type. Returns the removed element. ++ inline T RemoveLast() { return Remove(length_ - 1); } ++ ++ // Clears the list by freeing the storage memory. If you want to keep the ++ // memory, use Rewind(0) instead. Be aware, that even if T is a ++ // pointer type, clearing the list doesn't delete the entries. ++ inline void Clear() { ++ data_ = nullptr; ++ capacity_ = 0; ++ length_ = 0; ++ } ++ ++ // Drops all but the first 'pos' elements from the list. ++ inline void Rewind(int pos) { ++ MOZ_ASSERT(0 <= pos && pos <= length_); ++ length_ = pos; ++ } ++ ++ inline bool Contains(const T& elm) const { ++ for (int i = 0; i < length_; i++) { ++ if (data_[i] == elm) return true; ++ } ++ return false; ++ } ++ ++ template ++ void StableSort(CompareFunction cmp, size_t start, size_t length) { ++ js::AutoEnterOOMUnsafeRegion oomUnsafe; ++ T* scratch = static_cast(js_malloc(length * sizeof(T))); ++ if (!scratch) { ++ oomUnsafe.crash("Irregexp stable sort scratch space"); ++ } ++ auto comparator = [cmp](const T& a, const T& b, bool* lessOrEqual) { ++ *lessOrEqual = cmp(&a, &b) <= 0; ++ return true; ++ }; ++ MOZ_ALWAYS_TRUE( ++ js::MergeSort(begin() + start, length, scratch, comparator)); ++ js_free(scratch); ++ } ++ ++ void operator delete(void* pointer) { MOZ_CRASH("unreachable"); } ++ void operator delete(void* pointer, Zone* zone) { MOZ_CRASH("unreachable"); } ++ ++ private: ++ T* data_ = nullptr; ++ int capacity_ = 0; ++ int length_ = 0; ++ ++ // Increase the capacity of a full list, and add an element. ++ // List must be full already. ++ void ResizeAdd(const T& element, Zone* zone) { ++ MOZ_ASSERT(length_ >= capacity_); ++ // Grow the list capacity by 100%, but make sure to let it grow ++ // even when the capacity is zero (possible initial case). ++ int new_capacity = 1 + 2 * capacity_; ++ // Since the element reference could be an element of the list, copy ++ // it out of the old backing storage before resizing. ++ T temp = element; ++ Resize(new_capacity, zone); ++ data_[length_++] = temp; ++ } ++ ++ // Resize the list. ++ void Resize(int new_capacity, Zone* zone) { ++ MOZ_ASSERT(length_ <= new_capacity); ++ static_assert(std::is_trivially_copyable::value); ++ T* new_data = zone->NewArray(new_capacity); ++ if (length_ > 0) { ++ memcpy(new_data, data_, length_ * sizeof(T)); ++ } ++ data_ = new_data; ++ capacity_ = new_capacity; ++ } ++ ++ ZoneList& operator=(const ZoneList&) = delete; ++ ZoneList() = delete; ++ ZoneList(const ZoneList&) = delete; ++}; ++ ++// Based on: https://github.com/v8/v8/blob/master/src/zone/zone-allocator.h ++template ++class ZoneAllocator { ++ public: ++ using pointer = T*; ++ using const_pointer = const T*; ++ using reference = T&; ++ using const_reference = const T&; ++ using value_type = T; ++ using size_type = size_t; ++ using difference_type = ptrdiff_t; ++ template ++ struct rebind { ++ using other = ZoneAllocator; ++ }; ++ ++ explicit ZoneAllocator(Zone* zone) : zone_(zone) {} ++ template ++ ZoneAllocator(const ZoneAllocator& other) ++ : ZoneAllocator(other.zone_) {} ++ template ++ friend class ZoneAllocator; ++ ++ T* allocate(size_t n) { return zone_->NewArray(n); } ++ void deallocate(T* p, size_t) {} // noop for zones ++ ++ bool operator==(ZoneAllocator const& other) const { ++ return zone_ == other.zone_; ++ } ++ bool operator!=(ZoneAllocator const& other) const { ++ return zone_ != other.zone_; ++ } ++ ++ private: ++ Zone* zone_; ++}; ++ ++// Zone wrappers for std containers: ++// Origin: ++// https://github.com/v8/v8/blob/5e514a969376dc63517d575b062758efd36cd757/src/zone/zone-containers.h#L25-L169 ++ ++// A wrapper subclass for std::vector to make it easy to construct one ++// that uses a zone allocator. ++// Used throughout irregexp ++template ++class ZoneVector : public std::vector> { ++ public: ++ ZoneVector(Zone* zone) ++ : std::vector>(ZoneAllocator(zone)) {} ++ ++ // Constructs a new vector and fills it with the contents of the range ++ // [first, last). ++ template ++ ZoneVector(Iter first, Iter last, Zone* zone) ++ : std::vector>(first, last, ZoneAllocator(zone)) {} ++}; ++ ++// A wrapper subclass for std::list to make it easy to construct one ++// that uses a zone allocator. ++// Used in regexp-bytecode-peephole.cc ++template ++class ZoneLinkedList : public std::list> { ++ public: ++ // Constructs an empty list. ++ explicit ZoneLinkedList(Zone* zone) ++ : std::list>(ZoneAllocator(zone)) {} ++}; ++ ++// A wrapper subclass for std::set to make it easy to construct one that uses ++// a zone allocator. ++// Used in regexp-parser.cc ++template > ++class ZoneSet : public std::set> { ++ public: ++ // Constructs an empty set. ++ explicit ZoneSet(Zone* zone) ++ : std::set>(Compare(), ++ ZoneAllocator(zone)) {} ++}; ++ ++// A wrapper subclass for std::map to make it easy to construct one that uses ++// a zone allocator. ++// Used in regexp-bytecode-peephole.cc ++template > ++class ZoneMap ++ : public std::map>> { ++ public: ++ // Constructs an empty map. ++ explicit ZoneMap(Zone* zone) ++ : std::map>>( ++ Compare(), ZoneAllocator>(zone)) {} ++}; ++ ++// A wrapper subclass for std::unordered_map to make it easy to construct one ++// that uses a zone allocator. ++// Used in regexp-bytecode-peephole.cc ++template , ++ typename KeyEqual = std::equal_to> ++class ZoneUnorderedMap ++ : public std::unordered_map>> { ++ public: ++ // Constructs an empty map. ++ explicit ZoneUnorderedMap(Zone* zone, size_t bucket_count = 100) ++ : std::unordered_map>>( ++ bucket_count, Hash(), KeyEqual(), ++ ZoneAllocator>(zone)) {} ++}; ++ ++} // namespace internal ++} // namespace v8 ++ ++#endif // V8_UTIL_FLAG_H_ +diff -Nrup mozilla/js/src/jit/BaselineIC.cpp mozilla-OK/js/src/jit/BaselineIC.cpp +--- mozilla/js/src/jit/BaselineIC.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/BaselineIC.cpp 2023-02-27 07:46:51.297696313 +0300 +@@ -2119,6 +2119,11 @@ GetTemplateObjectForNative(JSContext* cx + return !!res; + } + ++ if (native == js::intrinsic_NewRegExpStringIterator) { ++ res.set(NewRegExpStringIteratorObject(cx, TenuredObject)); ++ return !!res; ++ } ++ + if (JitSupportsSimd() && GetTemplateObjectForSimd(cx, target, res)) + return !!res; + +diff -Nrup mozilla/js/src/jit/CodeGenerator.cpp mozilla-OK/js/src/jit/CodeGenerator.cpp +--- mozilla/js/src/jit/CodeGenerator.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/CodeGenerator.cpp 2023-02-27 08:15:51.417364380 +0300 +@@ -26,7 +26,7 @@ + #include "builtin/SelfHostingDefines.h" + #include "builtin/TypedObject.h" + #include "gc/Nursery.h" +-#include "irregexp/NativeRegExpMacroAssembler.h" ++#include "irregexp/RegExpTypes.h" + #include "jit/AtomicOperations.h" + #include "jit/BaselineCompiler.h" + #include "jit/IonBuilder.h" +@@ -41,6 +41,7 @@ + #include "jit/RangeAnalysis.h" + #include "jit/SharedICHelpers.h" + #include "jit/StackSlotAllocator.h" ++#include "js/RegExpFlags.h" + #include "vm/AsyncFunction.h" + #include "vm/AsyncIteration.h" + #include "vm/MatchPairs.h" +@@ -1206,243 +1207,314 @@ CodeGenerator::visitRegExp(LRegExp* lir) + masm.bind(ool->rejoin()); + } + ++static const size_t InputOutputDataSize = sizeof(irregexp::InputOutputData); ++ + // Amount of space to reserve on the stack when executing RegExps inline. +-static const size_t RegExpReservedStack = sizeof(irregexp::InputOutputData) ++static const size_t RegExpReservedStack = InputOutputDataSize + + sizeof(MatchPairs) + + RegExpObject::MaxPairCount * sizeof(MatchPair); + + static size_t + RegExpPairsVectorStartOffset(size_t inputOutputDataStartOffset) + { +- return inputOutputDataStartOffset + sizeof(irregexp::InputOutputData) + sizeof(MatchPairs); ++ return inputOutputDataStartOffset + InputOutputDataSize + sizeof(MatchPairs); + } + + static Address + RegExpPairCountAddress(MacroAssembler& masm, size_t inputOutputDataStartOffset) + { + return Address(masm.getStackPointer(), inputOutputDataStartOffset +- + sizeof(irregexp::InputOutputData) ++ + InputOutputDataSize + + MatchPairs::offsetOfPairCount()); + } + ++// When the unicode flag is set, if lastIndex points to a trail ++// surrogate, we should step back to the corresponding lead surrogate. ++// See ExecuteRegExp in builtin/RegExp.cpp for more detail. ++static void ++StepBackToLeadSurrogate(MacroAssembler& masm, ++ Register regexpShared, ++ Register input, ++ Register lastIndex, ++ Register temp1, ++ Register temp2) ++{ ++ Label done; ++ ++ // If the unicode flag is not set, there is nothing to do. ++ masm.branchTest32(Assembler::Zero, ++ Address(regexpShared, RegExpShared::offsetOfFlags()), ++ Imm32(int32_t(JS::RegExpFlag::Unicode)), ++ &done); ++ ++ // If the input is latin1, there can't be any surrogates. ++ masm.branchLatin1String(input, &done); ++ ++ // Check if |lastIndex > 0 && lastIndex < input->length()|. ++ // lastIndex should already have no sign here. ++ masm.branchTest32(Assembler::Zero, lastIndex, lastIndex, &done); ++ masm.loadStringLength(input, temp1); ++ masm.branch32(Assembler::AboveOrEqual, lastIndex, temp1, &done); ++ ++ Register charsReg = temp1; ++ masm.loadStringChars(input, charsReg); ++ ++ // Check if input[lastIndex] is trail surrogate. ++ masm.computeEffectiveAddress(BaseIndex(charsReg, lastIndex, TimesTwo), temp2); ++ masm.load16ZeroExtend(Address(temp2, 0), temp2); ++ ++ masm.branch32(Assembler::Below, temp2, Imm32(unicode::TrailSurrogateMin), &done); ++ masm.branch32(Assembler::Above, temp2, Imm32(unicode::TrailSurrogateMax), &done); ++ ++ // Check if input[lastIndex-1] is lead surrogate. ++ masm.move32(lastIndex, temp2); ++ masm.sub32(Imm32(1), temp2); ++ masm.computeEffectiveAddress(BaseIndex(charsReg, temp2, TimesTwo), temp2); ++ masm.load16ZeroExtend(Address(temp2, 0), temp2); ++ ++ masm.branch32(Assembler::Below, temp2, Imm32(unicode::LeadSurrogateMin), &done); ++ masm.branch32(Assembler::Above, temp2, Imm32(unicode::LeadSurrogateMax), &done); ++ ++ // Move lastIndex back to lead surrogate. ++ masm.subPtr(Imm32(1), lastIndex); ++ ++ masm.bind(&done); ++} ++ ++static void ++UpdateRegExpStatics(MacroAssembler& masm, ++ Register regexp, ++ Register input, ++ Register lastIndex, ++ Register staticsReg, ++ Register temp1, ++ Register temp2, ++ // bool stringsCanBeInNursery, ++ LiveGeneralRegisterSet& volatileRegs) ++{ ++ Address pendingInputAddress(staticsReg, RegExpStatics::offsetOfPendingInput()); ++ Address matchesInputAddress(staticsReg, RegExpStatics::offsetOfMatchesInput()); ++ Address lazySourceAddress(staticsReg, RegExpStatics::offsetOfLazySource()); ++ Address lazyIndexAddress(staticsReg, RegExpStatics::offsetOfLazyIndex()); ++ ++ masm.guardedCallPreBarrier(pendingInputAddress, MIRType::String); ++ masm.guardedCallPreBarrier(matchesInputAddress, MIRType::String); ++ masm.guardedCallPreBarrier(lazySourceAddress, MIRType::String); ++ ++ masm.storePtr(input, pendingInputAddress); ++ masm.storePtr(input, matchesInputAddress); ++ masm.storePtr(lastIndex, Address(staticsReg, RegExpStatics::offsetOfLazyIndex())); ++ masm.store32(Imm32(1), Address(staticsReg, RegExpStatics::offsetOfPendingLazyEvaluation())); ++ ++ masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), ++ temp1); ++ masm.loadPtr(Address(temp1, RegExpShared::offsetOfSource()), temp2); ++ masm.storePtr(temp2, lazySourceAddress); ++ masm.load32(Address(temp1, RegExpShared::offsetOfFlags()), temp2); ++ masm.store32(temp2, Address(staticsReg, RegExpStatics::offsetOfLazyFlags())); ++} ++ + // Prepare an InputOutputData and optional MatchPairs which space has been + // allocated for on the stack, and try to execute a RegExp on a string input. +-// If the RegExp was successfully executed and matched the input, fallthrough, +-// otherwise jump to notFound or failure. ++// If the RegExp was successfully executed and matched the input, fallthrough. ++// Otherwise, jump to notFound or failure. + static bool +-PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Register input, ++PrepareAndExecuteRegExp(JSContext* cx, ++ MacroAssembler& masm, ++ Register regexp, ++ Register input, + Register lastIndex, +- Register temp1, Register temp2, Register temp3, ++ Register temp1, ++ Register temp2, ++ Register temp3, + size_t inputOutputDataStartOffset, +- RegExpShared::CompilationMode mode, +- Label* notFound, Label* failure) +-{ +- size_t matchPairsStartOffset = inputOutputDataStartOffset + sizeof(irregexp::InputOutputData); +- size_t pairsVectorStartOffset = RegExpPairsVectorStartOffset(inputOutputDataStartOffset); ++ // bool stringsCanBeInNursery, ++ Label* notFound, ++ Label* failure) ++{ ++ using irregexp::InputOutputData; ++ ++ size_t ioOffset = inputOutputDataStartOffset; ++ size_t matchPairsOffset = ioOffset + sizeof(InputOutputData); ++ size_t pairsArrayOffset = matchPairsOffset + sizeof(MatchPairs); + + Address inputStartAddress(masm.getStackPointer(), +- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, inputStart)); ++ ioOffset + offsetof(InputOutputData, inputStart)); + Address inputEndAddress(masm.getStackPointer(), +- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, inputEnd)); +- Address matchesPointerAddress(masm.getStackPointer(), +- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, matches)); ++ ioOffset + offsetof(InputOutputData, inputEnd)); + Address startIndexAddress(masm.getStackPointer(), +- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, startIndex)); +- Address endIndexAddress(masm.getStackPointer(), +- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, endIndex)); +- Address matchResultAddress(masm.getStackPointer(), +- inputOutputDataStartOffset + offsetof(irregexp::InputOutputData, result)); ++ ioOffset + offsetof(InputOutputData, startIndex)); ++ Address matchesAddress(masm.getStackPointer(), ioOffset + offsetof(InputOutputData, matches)); + +- Address pairCountAddress = RegExpPairCountAddress(masm, inputOutputDataStartOffset); ++ Address matchPairsAddress(masm.getStackPointer(), matchPairsOffset); ++ Address pairCountAddress(masm.getStackPointer(), ++ matchPairsOffset + MatchPairs::offsetOfPairCount()); + Address pairsPointerAddress(masm.getStackPointer(), +- matchPairsStartOffset + MatchPairs::offsetOfPairs()); ++ matchPairsOffset + MatchPairs::offsetOfPairs()); + +- Address pairsVectorAddress(masm.getStackPointer(), pairsVectorStartOffset); ++ Address pairsArrayAddress(masm.getStackPointer(), pairsArrayOffset); + +- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); +- if (!res) +- return false; +-#ifdef JS_USE_LINK_REGISTER +- if (mode != RegExpShared::MatchOnly) +- masm.pushReturnAddress(); +-#endif +- if (mode == RegExpShared::Normal) { +- // First, fill in a skeletal MatchPairs instance on the stack. This will be +- // passed to the OOL stub in the caller if we aren't able to execute the +- // RegExp inline, and that stub needs to be able to determine whether the +- // execution finished successfully. +- masm.store32(Imm32(1), pairCountAddress); +- masm.store32(Imm32(-1), pairsVectorAddress); +- masm.computeEffectiveAddress(pairsVectorAddress, temp1); +- masm.storePtr(temp1, pairsPointerAddress); +- } ++ // First, fill in a skeletal MatchPairs instance on the stack. This will be ++ // passed to the OOL stub in the caller if we aren't able to execute the ++ // RegExp inline, and that stub needs to be able to determine whether the ++ // execution finished successfully. ++ ++ // Initialize MatchPairs::pairCount to 1. The correct value can only ++ // be determined after loading the RegExpShared. If the RegExpShared ++ // has Kind::Atom, this is the correct pairCount. ++ masm.store32(Imm32(1), pairCountAddress); ++ ++ // Initialize MatchPairs::pairs pointer ++ masm.store32(Imm32(-1), pairsArrayAddress); ++ masm.computeEffectiveAddress(pairsArrayAddress, temp1); ++ masm.storePtr(temp1, pairsPointerAddress); + + // Check for a linear input string. + masm.branchIfRopeOrExternal(input, temp1, failure); + +- // Get the RegExpShared for the RegExp. +- masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), temp1); +- masm.branchPtr(Assembler::Equal, temp1, ImmWord(0), failure); ++ // Load the RegExpShared. ++ Register regexpReg = temp1; + +- // ES6 21.2.2.2 step 2. +- // See RegExp.cpp ExecuteRegExp for more detail. ++ // Get the RegExpShared for the RegExp. ++ masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), ++ regexpReg); ++ masm.branchPtr(Assembler::Equal, regexpReg, ImmWord(0), failure); ++ ++ // Handle Atom matches ++ Label notAtom, checkSuccess; ++ masm.branchPtr(Assembler::Equal, ++ Address(regexpReg, RegExpShared::offsetOfPatternAtom()), ++ ImmWord(0), ¬Atom); + { +- Label done; +- +- masm.branchTest32(Assembler::Zero, Address(temp1, RegExpShared::offsetOfFlags()), +- Imm32(UnicodeFlag), &done); +- +- // If input is latin1, there should not be surrogate pair. +- masm.branchLatin1String(input, &done); +- +- // Check if |lastIndex > 0 && lastIndex < input->length()|. +- // lastIndex should already have no sign here. +- masm.branchTest32(Assembler::Zero, lastIndex, lastIndex, &done); +- masm.loadStringLength(input, temp2); +- masm.branch32(Assembler::AboveOrEqual, lastIndex, temp2, &done); +- +- // Check if input[lastIndex] is trail surrogate. +- masm.loadStringChars(input, temp2); +- masm.computeEffectiveAddress(BaseIndex(temp2, lastIndex, TimesTwo), temp3); +- masm.load16ZeroExtend(Address(temp3, 0), temp3); +- +- masm.branch32(Assembler::Below, temp3, Imm32(unicode::TrailSurrogateMin), &done); +- masm.branch32(Assembler::Above, temp3, Imm32(unicode::TrailSurrogateMax), &done); +- +- // Check if input[lastIndex-1] is lead surrogate. +- masm.move32(lastIndex, temp3); +- masm.sub32(Imm32(1), temp3); +- masm.computeEffectiveAddress(BaseIndex(temp2, temp3, TimesTwo), temp3); +- masm.load16ZeroExtend(Address(temp3, 0), temp3); +- +- masm.branch32(Assembler::Below, temp3, Imm32(unicode::LeadSurrogateMin), &done); +- masm.branch32(Assembler::Above, temp3, Imm32(unicode::LeadSurrogateMax), &done); +- +- // Move lastIndex to lead surrogate. +- masm.subPtr(Imm32(1), lastIndex); +- +- masm.bind(&done); +- } +- +- if (mode == RegExpShared::Normal) { +- // Don't handle RegExps with excessive parens. +- masm.load32(Address(temp1, RegExpShared::offsetOfParenCount()), temp2); +- masm.branch32(Assembler::AboveOrEqual, temp2, Imm32(RegExpObject::MaxPairCount), failure); +- +- // Fill in the paren count in the MatchPairs on the stack. +- masm.add32(Imm32(1), temp2); +- masm.store32(temp2, pairCountAddress); +- } +- +- // Load the code pointer for the type of input string we have, and compute +- // the input start/end pointers in the InputOutputData. +- Register codePointer = temp1; ++ LiveGeneralRegisterSet regsToSave(GeneralRegisterSet::Volatile()); ++ regsToSave.takeUnchecked(temp1); ++ regsToSave.takeUnchecked(temp2); ++ regsToSave.takeUnchecked(temp3); ++ ++ masm.computeEffectiveAddress(matchPairsAddress, temp3); ++ ++ masm.PushRegsInMask(regsToSave); ++ masm.setupUnalignedABICall(temp2); ++ masm.passABIArg(regexpReg); ++ masm.passABIArg(input); ++ masm.passABIArg(lastIndex); ++ masm.passABIArg(temp3); ++ masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ExecuteRegExpAtomRaw)); ++ masm.storeCallInt32Result(temp1); ++ masm.PopRegsInMask(regsToSave); ++ ++ masm.jump(&checkSuccess); ++ } ++ masm.bind(¬Atom); ++ ++ // Don't handle regexps with too many capture pairs. ++ masm.load32(Address(regexpReg, RegExpShared::offsetOfPairCount()), temp2); ++ masm.branch32(Assembler::Above, temp2, Imm32(RegExpObject::MaxPairCount), failure); ++ ++ // Fill in the pair count in the MatchPairs on the stack. ++ masm.store32(temp2, pairCountAddress); ++ ++ // Update lastIndex if necessary. ++ StepBackToLeadSurrogate(masm, regexpReg, input, lastIndex, temp2, temp3); ++ ++ // Load code pointer and length of input (in bytes). ++ // Store the input start in the InputOutputData. ++ Register codePointer = temp1; // Note: temp1 was previously regexpReg. ++ Register byteLength = temp3; + { ++ Label isLatin1, done; + masm.loadStringChars(input, temp2); + masm.storePtr(temp2, inputStartAddress); +- masm.loadStringLength(input, temp3); ++ masm.loadStringLength(input, byteLength); + +- Label isLatin1, done; + masm.branchLatin1String(input, &isLatin1); +- { +- masm.lshiftPtr(Imm32(1), temp3); +- masm.loadPtr(Address(temp1, RegExpShared::offsetOfTwoByteJitCode(mode)), +- codePointer); +- } ++ ++ // Two-byte input ++ masm.loadPtr(Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 =*/false)), ++ codePointer); ++ masm.lshiftPtr(Imm32(1), byteLength); + masm.jump(&done); +- { +- masm.bind(&isLatin1); +- masm.loadPtr(Address(temp1, RegExpShared::offsetOfLatin1JitCode(mode)), +- codePointer); +- } ++ ++ // Latin1 input ++ masm.bind(&isLatin1); ++ masm.loadPtr(Address(regexpReg, RegExpShared::offsetOfJitCode(/*latin1 = */ true)), ++ codePointer); ++ + masm.bind(&done); + +- masm.addPtr(temp3, temp2); ++ // Store end pointer ++ masm.addPtr(byteLength, temp2); + masm.storePtr(temp2, inputEndAddress); + } + +- // Check the RegExpShared has been compiled for this type of input. ++ // Guard that the RegExpShared has been compiled for this type of input. ++ // If it has not been compiled, we fall back to the OOL case, which will ++ // do a VM call into the interpreter. ++ // TODO: add an interpreter trampoline? + masm.branchPtr(Assembler::Equal, codePointer, ImmWord(0), failure); + masm.loadPtr(Address(codePointer, JitCode::offsetOfCode()), codePointer); + +- // Finish filling in the InputOutputData instance on the stack. +- if (mode == RegExpShared::Normal) { +- masm.computeEffectiveAddress(Address(masm.getStackPointer(), matchPairsStartOffset), temp2); +- masm.storePtr(temp2, matchesPointerAddress); +- } else { +- // Use InputOutputData.endIndex itself for output. +- masm.computeEffectiveAddress(endIndexAddress, temp2); +- masm.storePtr(temp2, endIndexAddress); +- } ++ // Finish filling in the InputOutputData instance on the stack ++ masm.computeEffectiveAddress(matchPairsAddress, temp2); ++ masm.storePtr(temp2, matchesAddress); + masm.storePtr(lastIndex, startIndexAddress); +- masm.store32(Imm32(0), matchResultAddress); + + // Save any volatile inputs. + LiveGeneralRegisterSet volatileRegs; +- if (lastIndex.volatile_()) ++ if (lastIndex.volatile_()) { + volatileRegs.add(lastIndex); +- if (input.volatile_()) ++ } ++ if (input.volatile_()) { + volatileRegs.add(input); +- if (regexp.volatile_()) ++ } ++ if (regexp.volatile_()) { + volatileRegs.add(regexp); ++ } + + #ifdef JS_TRACE_LOGGING + if (TraceLogTextIdEnabled(TraceLogger_IrregexpExecute)) { +- masm.push(temp1); +- masm.loadTraceLogger(temp1); +- masm.tracelogStartId(temp1, TraceLogger_IrregexpExecute); +- masm.pop(temp1); ++ masm.loadTraceLogger(temp2); ++ masm.tracelogStartId(temp2, TraceLogger_IrregexpExecute); + } + #endif + + // Execute the RegExp. +- masm.computeEffectiveAddress(Address(masm.getStackPointer(), inputOutputDataStartOffset), temp2); ++ masm.computeEffectiveAddress(Address(masm.getStackPointer(), inputOutputDataStartOffset), ++ temp2); + masm.PushRegsInMask(volatileRegs); + masm.setupUnalignedABICall(temp3); + masm.passABIArg(temp2); + masm.callWithABI(codePointer); ++ masm.storeCallInt32Result(temp1); + masm.PopRegsInMask(volatileRegs); + + #ifdef JS_TRACE_LOGGING + if (TraceLogTextIdEnabled(TraceLogger_IrregexpExecute)) { +- masm.loadTraceLogger(temp1); +- masm.tracelogStopId(temp1, TraceLogger_IrregexpExecute); ++ masm.loadTraceLogger(temp2); ++ masm.tracelogStopId(temp2, TraceLogger_IrregexpExecute); + } + #endif + + Label success; +- masm.branch32(Assembler::Equal, matchResultAddress, +- Imm32(RegExpRunStatus_Success_NotFound), notFound); +- masm.branch32(Assembler::Equal, matchResultAddress, +- Imm32(RegExpRunStatus_Error), failure); ++ masm.bind(&checkSuccess); ++ masm.branch32(Assembler::Equal, temp1, Imm32(RegExpRunStatus_Success_NotFound), notFound); ++ masm.branch32(Assembler::Equal, temp1, Imm32(RegExpRunStatus_Error), failure); + + // Lazily update the RegExpStatics. +- masm.movePtr(ImmPtr(res), temp1); +- +- Address pendingInputAddress(temp1, RegExpStatics::offsetOfPendingInput()); +- Address matchesInputAddress(temp1, RegExpStatics::offsetOfMatchesInput()); +- Address lazySourceAddress(temp1, RegExpStatics::offsetOfLazySource()); +- Address lazyIndexAddress(temp1, RegExpStatics::offsetOfLazyIndex()); +- +- masm.guardedCallPreBarrier(pendingInputAddress, MIRType::String); +- masm.guardedCallPreBarrier(matchesInputAddress, MIRType::String); +- masm.guardedCallPreBarrier(lazySourceAddress, MIRType::String); +- +- masm.storePtr(input, pendingInputAddress); +- masm.storePtr(input, matchesInputAddress); +- masm.storePtr(lastIndex, Address(temp1, RegExpStatics::offsetOfLazyIndex())); +- masm.store32(Imm32(1), Address(temp1, RegExpStatics::offsetOfPendingLazyEvaluation())); +- +- masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), temp2); +- masm.loadPtr(Address(temp2, RegExpShared::offsetOfSource()), temp3); +- masm.storePtr(temp3, lazySourceAddress); +- masm.load32(Address(temp2, RegExpShared::offsetOfFlags()), temp3); +- masm.store32(temp3, Address(temp1, RegExpStatics::offsetOfLazyFlags())); +- +- if (mode == RegExpShared::MatchOnly) { +- // endIndex is passed via temp3. +- masm.load32(endIndexAddress, temp3); ++ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); ++ if (!res) { ++ return false; + } ++ masm.movePtr(ImmPtr(res), temp1); ++ UpdateRegExpStatics(masm, ++ regexp, ++ input, ++ lastIndex, ++ temp1, ++ temp2, ++ temp3, ++ // stringsCanBeInNursery, ++ volatileRegs); + + return true; + } +@@ -1728,17 +1800,31 @@ JitCompartment::generateRegExpMatcherStu + + MacroAssembler masm(cx); + ++#ifdef JS_USE_LINK_REGISTER ++ masm.pushReturnAddress(); ++#endif ++ + // The InputOutputData is placed above the return address on the stack. + size_t inputOutputDataStartOffset = sizeof(void*); + + Label notFound, oolEntry; + if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, + temp1, temp2, temp5, inputOutputDataStartOffset, +- RegExpShared::Normal, ¬Found, &oolEntry)) ++ ¬Found, &oolEntry)) + { + return nullptr; + } + ++ // If a regexp has named captures, fall back to the OOL stub, which ++ // will end up calling CreateRegExpMatchResults. ++ Register shared = temp2; ++ masm.loadPtr(Address(regexp, NativeObject::getFixedSlotOffset(RegExpObject::PRIVATE_SLOT)), ++ shared); ++ masm.branchPtr(Assembler::NotEqual, ++ Address(shared, RegExpShared::offsetOfGroupsTemplate()), ++ ImmWord(0), ++ &oolEntry); ++ + // Construct the result. + Register object = temp1; + Label matchResultFallback, matchResultJoin; +@@ -1749,6 +1835,7 @@ JitCompartment::generateRegExpMatcherStu + masm.loadPtr(Address(object, NativeObject::offsetOfSlots()), temp2); + masm.storeValue(templateObject->getSlot(0), Address(temp2, 0)); + masm.storeValue(templateObject->getSlot(1), Address(temp2, sizeof(Value))); ++ masm.storeValue(templateObject->getSlot(2), Address(temp2, 2 * sizeof(Value))); + + size_t elementsOffset = NativeObject::offsetOfFixedElements(); + +@@ -1958,7 +2045,7 @@ CodeGenerator::visitOutOfLineRegExpMatch + Register temp = regs.takeAny(); + + masm.computeEffectiveAddress(Address(masm.getStackPointer(), +- sizeof(irregexp::InputOutputData)), temp); ++ InputOutputDataSize), temp); + + pushArg(temp); + pushArg(lastIndex); +@@ -2029,13 +2116,17 @@ JitCompartment::generateRegExpSearcherSt + + MacroAssembler masm(cx); + ++#ifdef JS_USE_LINK_REGISTER ++ masm.pushReturnAddress(); ++#endif ++ + // The InputOutputData is placed above the return address on the stack. + size_t inputOutputDataStartOffset = sizeof(void*); + + Label notFound, oolEntry; + if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, + temp1, temp2, temp3, inputOutputDataStartOffset, +- RegExpShared::Normal, ¬Found, &oolEntry)) ++ ¬Found, &oolEntry)) + { + return nullptr; + } +@@ -2115,7 +2206,7 @@ CodeGenerator::visitOutOfLineRegExpSearc + Register temp = regs.takeAny(); + + masm.computeEffectiveAddress(Address(masm.getStackPointer(), +- sizeof(irregexp::InputOutputData)), temp); ++ InputOutputDataSize), temp); + + pushArg(temp); + pushArg(lastIndex); +@@ -2181,20 +2272,29 @@ JitCompartment::generateRegExpTesterStub + Register temp2 = regs.takeAny(); + Register temp3 = regs.takeAny(); + +- masm.reserveStack(sizeof(irregexp::InputOutputData)); ++ masm.reserveStack(RegExpReservedStack); + + Label notFound, oolEntry; + if (!PrepareAndExecuteRegExp(cx, masm, regexp, input, lastIndex, + temp1, temp2, temp3, 0, +- RegExpShared::MatchOnly, ¬Found, &oolEntry)) ++ ¬Found, &oolEntry)) + { + return nullptr; + } + + Label done; + +- // temp3 contains endIndex. +- masm.move32(temp3, result); ++ // In visitRegExpMatcher and visitRegExpSearcher, we reserve stack space ++ // before calling the stub. For RegExpTester we call the stub before reserving ++ // stack space, so the offset of the InputOutputData is 0. ++ size_t inputOutputDataStartOffset = 0; ++ ++ size_t pairsVectorStartOffset = RegExpPairsVectorStartOffset(inputOutputDataStartOffset); ++ Address matchPairLimit(masm.getStackPointer(), ++ pairsVectorStartOffset + offsetof(MatchPair, limit)); ++ ++ // RegExpTester returns the end index of the match to update lastIndex. ++ masm.load32(matchPairLimit, result); + masm.jump(&done); + + masm.bind(¬Found); +@@ -2205,7 +2305,7 @@ JitCompartment::generateRegExpTesterStub + masm.move32(Imm32(RegExpTesterResultFailed), result); + + masm.bind(&done); +- masm.freeStack(sizeof(irregexp::InputOutputData)); ++ masm.freeStack(RegExpReservedStack); + masm.ret(); + + Linker linker(masm); +@@ -5769,6 +5869,12 @@ typedef StringIteratorObject* (*NewStrin + static const VMFunction NewStringIteratorObjectInfo = + FunctionInfo(NewStringIteratorObject, "NewStringIteratorObject"); + ++typedef RegExpStringIteratorObject* (*NewRegExpStringIteratorObjectFn)(JSContext*, NewObjectKind); ++ ++static const VMFunction NewRegExpStringIteratorObjectInfo = ++ FunctionInfo(NewRegExpStringIteratorObject, ++ "NewRegExpStringIteratorObject"); ++ + void + CodeGenerator::visitNewIterator(LNewIterator* lir) + { +@@ -5788,6 +5894,12 @@ CodeGenerator::visitNewIterator(LNewIter + ArgList(Imm32(GenericObject)), + StoreRegisterTo(objReg)); + break; ++ case MNewIterator::RegExpStringIterator: ++ ool = oolCallVM(NewRegExpStringIteratorObjectInfo, ++ lir, ++ ArgList(Imm32(GenericObject)), ++ StoreRegisterTo(objReg)); ++ break; + default: + MOZ_CRASH("unexpected iterator type"); + } +diff -Nrup mozilla/js/src/jit/InlinableNatives.h mozilla-OK/js/src/jit/InlinableNatives.h +--- mozilla/js/src/jit/InlinableNatives.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/InlinableNatives.h 2023-02-27 07:51:30.110719460 +0300 +@@ -136,6 +136,7 @@ + _(IntrinsicGuardToMapIterator) \ + _(IntrinsicGuardToSetIterator) \ + _(IntrinsicGuardToStringIterator) \ ++ _(IntrinsicGuardToRegExpStringIterator) \ + \ + _(IntrinsicGuardToMapObject) \ + _(IntrinsicGetNextMapEntryForIterator) \ +@@ -145,6 +146,7 @@ + \ + _(IntrinsicNewArrayIterator) \ + _(IntrinsicNewStringIterator) \ ++ _(IntrinsicNewRegExpStringIterator) \ + \ + _(IntrinsicGuardToArrayBuffer) \ + _(IntrinsicArrayBufferByteLength) \ +diff -Nrup mozilla/js/src/jit/JitOptions.cpp mozilla-OK/js/src/jit/JitOptions.cpp +--- mozilla/js/src/jit/JitOptions.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/JitOptions.cpp 2023-02-27 07:59:24.240357852 +0300 +@@ -159,6 +159,10 @@ DefaultJitOptions::DefaultJitOptions() + // are compiled with the baseline compiler. + SET_DEFAULT(baselineWarmUpThreshold, 10); + ++ // How many invocations are needed before regexps are compiled to ++ // native code. ++ SET_DEFAULT(regexpWarmUpThreshold, 10); ++ + // Number of exception bailouts (resuming into catch/finally block) before + // we invalidate and forbid Ion compilation. + SET_DEFAULT(exceptionBailoutThreshold, 10); +@@ -275,6 +279,7 @@ DefaultJitOptions::setEagerCompilation() + { + eagerCompilation = true; + baselineWarmUpThreshold = 0; ++ regexpWarmUpThreshold = 0; + forcedDefaultIonWarmUpThreshold.reset(); + forcedDefaultIonWarmUpThreshold.emplace(0); + forcedDefaultIonSmallFunctionWarmUpThreshold.reset(); +diff -Nrup mozilla/js/src/jit/JitOptions.h mozilla-OK/js/src/jit/JitOptions.h +--- mozilla/js/src/jit/JitOptions.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/JitOptions.h 2023-02-27 07:59:24.240357852 +0300 +@@ -78,6 +78,7 @@ struct DefaultJitOptions + bool ionInterruptWithoutSignals; + bool simulatorAlwaysInterrupt; + uint32_t baselineWarmUpThreshold; ++ uint32_t regexpWarmUpThreshold; + uint32_t exceptionBailoutThreshold; + uint32_t frequentBailoutThreshold; + uint32_t maxStackArgs; +diff -Nrup mozilla/js/src/jit/MCallOptimize.cpp mozilla-OK/js/src/jit/MCallOptimize.cpp +--- mozilla/js/src/jit/MCallOptimize.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/MCallOptimize.cpp 2023-02-27 07:53:42.120783508 +0300 +@@ -26,6 +26,7 @@ + #include "jit/Lowering.h" + #include "jit/MIR.h" + #include "jit/MIRGraph.h" ++#include "js/RegExpFlags.h" + #include "vm/ArgumentsObject.h" + #include "vm/ArrayBufferObject.h" + #include "vm/ProxyObject.h" +@@ -44,6 +45,8 @@ using mozilla::ArrayLength; + using mozilla::AssertedCast; + + using JS::DoubleNaNValue; ++using JS::RegExpFlag; ++using JS::RegExpFlags; + using JS::TrackedOutcome; + using JS::TrackedStrategy; + using JS::TrackedTypeSite; +@@ -226,6 +229,8 @@ IonBuilder::inlineNativeCall(CallInfo& c + return inlineRegExpInstanceOptimizable(callInfo); + case InlinableNative::GetFirstDollarIndex: + return inlineGetFirstDollarIndex(callInfo); ++ case InlinableNative::IntrinsicNewRegExpStringIterator: ++ return inlineNewIterator(callInfo, MNewIterator::RegExpStringIterator); + + // String natives. + case InlinableNative::String: +@@ -330,6 +335,8 @@ IonBuilder::inlineNativeCall(CallInfo& c + return inlineGuardToClass(callInfo, &SetIteratorObject::class_); + case InlinableNative::IntrinsicGuardToStringIterator: + return inlineGuardToClass(callInfo, &StringIteratorObject::class_); ++ case InlinableNative::IntrinsicGuardToRegExpStringIterator: ++ return inlineHasClass(callInfo, &RegExpStringIteratorObject::class_); + case InlinableNative::IntrinsicObjectHasPrototype: + return inlineObjectHasPrototype(callInfo); + case InlinableNative::IntrinsicFinishBoundFunctionInit: +@@ -434,7 +441,7 @@ IonBuilder::inlineNativeGetter(CallInfo& + } + + // Try to optimize RegExp getters. +- RegExpFlag mask = NoFlags; ++ RegExpFlags mask = RegExpFlag::NoFlags; + if (RegExpObject::isOriginalFlagGetter(native, &mask)) { + const Class* clasp = thisTypes->getKnownClass(constraints()); + if (clasp != &RegExpObject::class_) +@@ -443,7 +450,7 @@ IonBuilder::inlineNativeGetter(CallInfo& + MLoadFixedSlot* flags = MLoadFixedSlot::New(alloc(), thisArg, RegExpObject::flagsSlot()); + current->add(flags); + flags->setResultType(MIRType::Int32); +- MConstant* maskConst = MConstant::New(alloc(), Int32Value(mask)); ++ MConstant* maskConst = MConstant::New(alloc(), Int32Value(mask.value())); + current->add(maskConst); + MBitAnd* maskedFlag = MBitAnd::New(alloc(), flags, maskConst); + maskedFlag->setInt32Specialization(); +@@ -1034,6 +1041,10 @@ IonBuilder::inlineNewIterator(CallInfo& + templateObject = inspector->getTemplateObjectForNative(pc, js::intrinsic_NewStringIterator); + MOZ_ASSERT_IF(templateObject, templateObject->is()); + break; ++ case MNewIterator::RegExpStringIterator: ++ templateObject = inspector->getTemplateObjectForNative(pc, js::intrinsic_NewRegExpStringIterator); ++ MOZ_ASSERT_IF(templateObject, templateObject->is()); ++ break; + } + + if (!templateObject) +diff -Nrup mozilla/js/src/jit/MIR.h mozilla-OK/js/src/jit/MIR.h +--- mozilla/js/src/jit/MIR.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/MIR.h 2023-02-27 07:46:51.306696250 +0300 +@@ -3608,6 +3608,7 @@ class MNewIterator + enum Type { + ArrayIterator, + StringIterator, ++ RegExpStringIterator, + }; + + private: +diff -Nrup mozilla/js/src/jit/MacroAssembler.h mozilla-OK/js/src/jit/MacroAssembler.h +--- mozilla/js/src/jit/MacroAssembler.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/MacroAssembler.h 2023-02-27 08:17:58.259466019 +0300 +@@ -2252,6 +2252,20 @@ class MacroAssembler : public MacroAssem + inline void assertStackAlignment(uint32_t alignment, int32_t offset = 0); + }; + ++// StackMacroAssembler checks no GC will happen while it's on the stack. ++class MOZ_RAII StackMacroAssembler : public MacroAssembler ++{ ++ JS::AutoCheckCannotGC nogc; ++ ++ public: ++ StackMacroAssembler() ++ : MacroAssembler() ++ {} ++ explicit StackMacroAssembler(JSContext* cx) ++ : MacroAssembler(cx) ++ {} ++}; ++ + //{{{ check_macroassembler_style + inline uint32_t + MacroAssembler::framePushed() const +diff -Nrup mozilla/js/src/jit/Recover.cpp mozilla-OK/js/src/jit/Recover.cpp +--- mozilla/js/src/jit/Recover.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/Recover.cpp 2023-02-27 07:46:51.307696243 +0300 +@@ -1396,6 +1396,9 @@ RNewIterator::recover(JSContext* cx, Sna + case MNewIterator::StringIterator: + resultObject = NewStringIteratorObject(cx); + break; ++ case MNewIterator::RegExpStringIterator: ++ resultObject = NewRegExpStringIteratorObject(cx); ++ break; + } + + if (!resultObject) +diff -Nrup mozilla/js/src/jit/VMFunctions.h mozilla-OK/js/src/jit/VMFunctions.h +--- mozilla/js/src/jit/VMFunctions.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/VMFunctions.h 2023-02-27 07:46:51.307696243 +0300 +@@ -323,6 +323,7 @@ template <> struct TypeToDataType struct TypeToDataType { static const DataType result = Type_Object; }; + template <> struct TypeToDataType { static const DataType result = Type_Object; }; + template <> struct TypeToDataType { static const DataType result = Type_Object; }; ++template <> struct TypeToDataType{ static const DataType result = Type_Object; }; + template <> struct TypeToDataType { static const DataType result = Type_Object; }; + template <> struct TypeToDataType { static const DataType result = Type_Object; }; + template <> struct TypeToDataType { static const DataType result = Type_Handle; }; +diff -Nrup mozilla/js/src/jit/arm64/Assembler-arm64.h mozilla-OK/js/src/jit/arm64/Assembler-arm64.h +--- mozilla/js/src/jit/arm64/Assembler-arm64.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit/arm64/Assembler-arm64.h 2023-02-27 07:59:24.241357845 +0300 +@@ -71,9 +71,6 @@ static constexpr Register PseudoStackPoi + static constexpr ARMRegister PseudoStackPointer64 = { Registers::x28, 64 }; + static constexpr ARMRegister PseudoStackPointer32 = { Registers::x28, 32 }; + +-// StackPointer for use by irregexp. +-static constexpr Register RegExpStackPointer = PseudoStackPointer; +- + static constexpr Register IntArgReg0 { Registers::x0 }; + static constexpr Register IntArgReg1 { Registers::x1 }; + static constexpr Register IntArgReg2 { Registers::x2 }; +diff -Nrup mozilla/js/src/jit-test/lib/regexp_parse.js mozilla-OK/js/src/jit-test/lib/regexp_parse.js +--- mozilla/js/src/jit-test/lib/regexp_parse.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/lib/regexp_parse.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,205 +0,0 @@ +-load(libdir + "asserts.js"); +- +-// helper functions +- +-function Disjunction(alternatives) { +- return{ +- type: "Disjunction", +- alternatives: alternatives +- }; +-} +- +-function Alternative(nodes) { +- return { +- type: "Alternative", +- nodes: nodes +- }; +-} +- +-function Empty() { +- return { +- type: "Empty" +- }; +-} +- +-function Text(elements) { +- return { +- type: "Text", +- elements: elements +- }; +-} +- +-function Assertion(type) { +- return { +- type: "Assertion", +- assertion_type: type +- }; +-} +- +-function Atom(data) { +- return { +- type: "Atom", +- data: data +- }; +-} +- +-const kInfinity = 0x7FFFFFFF; +-function Quantifier(min, max, type, body) { +- return { +- type: "Quantifier", +- min: min, +- max: max, +- quantifier_type: type, +- body: body +- }; +-} +- +-function Lookahead(body) { +- return { +- type: "Lookahead", +- is_positive: true, +- body: body +- }; +-} +- +-function NegativeLookahead(body) { +- return { +- type: "Lookahead", +- is_positive: false, +- body: body +- }; +-} +- +-function BackReference(index) { +- return { +- type: "BackReference", +- index: index +- }; +-} +- +-function CharacterClass(ranges) { +- return { +- type: "CharacterClass", +- is_negated: false, +- ranges: ranges.map(([from, to]) => ({ from ,to })) +- }; +-} +- +-function NegativeCharacterClass(ranges) { +- return { +- type: "CharacterClass", +- is_negated: true, +- ranges: ranges.map(([from, to]) => ({ from ,to })) +- }; +-} +- +-function Capture(index, body) { +- return { +- type: "Capture", +- index: index, +- body: body +- }; +-} +- +-function AllSurrogateAndCharacterClass(ranges) { +- return Disjunction([ +- CharacterClass(ranges), +- Alternative([ +- CharacterClass([["\uD800", "\uDBFF"]]), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- CharacterClass([["\uDC00", "\uDFFF"]]) +- ]), +- Text([ +- CharacterClass([["\uD800", "\uDBFF"]]), +- CharacterClass([["\uDC00", "\uDFFF"]]) +- ]) +- ]); +-} +- +-// testing functions +- +-var all_flags = [ +- "", +- "i", +- "m", +- "u", +- "im", +- "iu", +- "mu", +- "imu", +-]; +- +-var no_unicode_flags = [ +- "", +- "i", +- "m", +- "im", +-]; +- +-var unicode_flags = [ +- "u", +- "iu", +- "mu", +- "imu", +-]; +- +-var no_multiline_flags = [ +- "", +- "i", +- "u", +- "iu", +-]; +- +-var multiline_flags = [ +- "m", +- "im", +- "mu", +- "imu", +-]; +- +-function test_flags(pattern, flags, match_only, expected) { +- for (var flag of flags) { +- assertDeepEq(parseRegExp(pattern, flag, match_only), expected); +- } +-} +- +-function make_mix(tree) { +- if (tree.type == "Atom") { +- return Atom("X" + tree.data + "Y"); +- } +- if (tree.type == "CharacterClass") { +- return Text([ +- Atom("X"), +- tree, +- Atom("Y") +- ]); +- } +- if (tree.type == "Alternative") { +- return Alternative([ +- Atom("X"), +- ...tree.nodes, +- Atom("Y") +- ]); +- } +- return Alternative([ +- Atom("X"), +- tree, +- Atom("Y") +- ]); +-} +- +-function test_mix(pattern, flags, expected) { +- test_flags(pattern, flags, false, expected); +- test_flags("X" + pattern + "Y", flags, false, make_mix(expected)); +-} +- +-function test(pattern, flags, expected) { +- test_flags(pattern, flags, false, expected); +-} +- +-function test_match_only(pattern, flags, expected) { +- test_flags(pattern, flags, true, expected); +-} +diff -Nrup mozilla/js/src/jit-test/tests/regexp/bug1640479.js mozilla-OK/js/src/jit-test/tests/regexp/bug1640479.js +--- mozilla/js/src/jit-test/tests/regexp/bug1640479.js 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp/bug1640479.js 2023-02-27 07:42:31.742537430 +0300 +@@ -0,0 +1,15 @@ ++// |jit-test| skip-if: !('oomTest' in this) ++ ++var failures = 0; ++var i = 0; ++ ++function foo() { ++ var e; ++ var r = RegExp("(?<_" + (i++) + "a>)"); ++ try { e = r.exec("a"); } catch {} ++ e = r.exec("a"); ++ if (e.groups === undefined) failures++; ++} ++ ++oomTest(foo); ++assertEq(failures, 0); +diff -Nrup mozilla/js/src/jit-test/tests/regexp/huge-02.js mozilla-OK/js/src/jit-test/tests/regexp/huge-02.js +--- mozilla/js/src/jit-test/tests/regexp/huge-02.js 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp/huge-02.js 2023-02-27 07:41:37.928919229 +0300 +@@ -0,0 +1,13 @@ ++var interestingCaptureNums = [(1 << 14), ++ (1 << 15) - 1, ++ (1 << 15), ++ (1 << 15) + 1, ++ (1 << 16)] ++ ++for (let i of interestingCaptureNums) { ++ print(i); ++ try { ++ var source = Array(i).join("(") + "a" + Array(i).join(")"); ++ RegExp(source).exec("a"); ++ } catch {} ++} +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Assertion.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Assertion.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Assertion.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Assertion.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,20 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("^", no_multiline_flags, +- Assertion("START_OF_INPUT")); +-test_mix("^", multiline_flags, +- Assertion("START_OF_LINE")); +- +-test_mix("$", no_multiline_flags, +- Assertion("END_OF_INPUT")); +-test_mix("$", multiline_flags, +- Assertion("END_OF_LINE")); +- +-test_mix("\\b", all_flags, +- Assertion("BOUNDARY")); +- +-test_mix("\\B", all_flags, +- Assertion("NON_BOUNDARY")); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,54 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("a", all_flags, +- Atom("a")); +-test_mix("abc\u3042\u3044\u3046", all_flags, +- Atom("abc\u3042\u3044\u3046")); +- +-// raw brace +- +-test("{", no_unicode_flags, +- Atom("{")); +-test("{a", no_unicode_flags, +- Atom("{a")); +-test("a{b", no_unicode_flags, +- Atom("a{b")); +- +-test("}", no_unicode_flags, +- Atom("}")); +-test("}a", no_unicode_flags, +- Atom("}a")); +-test("a}b", no_unicode_flags, +- Atom("a}b")); +- +-// raw surrogate pair +- +-test("X\uD83D\uDC38Y", unicode_flags, +- Text([ +- Atom("X"), +- Atom("\uD83D\uDC38"), +- Atom("Y") +- ])); +- +-test("X\uD83DY", unicode_flags, +- Alternative([ +- Atom("X"), +- Alternative([ +- Atom("\uD83D"), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]), +- Atom("Y") +- ])); +- +-test("X\uDC38Y", unicode_flags, +- Alternative([ +- Atom("X"), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- Atom("\uDC38"), +- ]), +- Atom("Y") +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,115 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("\\d", all_flags, +- CharacterClass([["0", "9"]])); +- +-test_mix("\\D", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "/"], +- [":", "\uFFFF"] +- ])); +-test_mix("\\D", unicode_flags, +- AllSurrogateAndCharacterClass([ +- ["\u0000", "/"], +- [":", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +- +-test_mix("\\s", all_flags, +- CharacterClass([ +- ["\t", "\r"], +- [" ", " "], +- ["\u00A0", "\u00A0"], +- ["\u1680", "\u1680"], +- ["\u2000", "\u200A"], +- ["\u2028", "\u2029"], +- ["\u202F", "\u202F"], +- ["\u205F", "\u205F"], +- ["\u3000", "\u3000"], +- ["\uFEFF", "\uFEFF"] +- ])); +-test_mix("\\S", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "\u0008"], +- ["\u000E", "\u001F"], +- ["!", "\u009F"], +- ["\u00A1", "\u167F"], +- ["\u1681", "\u1FFF"], +- ["\u200B", "\u2027"], +- ["\u202A", "\u202E"], +- ["\u2030", "\u205E"], +- ["\u2060", "\u2FFF"], +- ["\u3001", "\uFEFE"], +- ["\uFF00", "\uFFFF"] +- ])); +-test_mix("\\S", unicode_flags, +- AllSurrogateAndCharacterClass([ +- ["\u0000", "\u0008"], +- ["\u000E", "\u001F"], +- ["!", "\u009F"], +- ["\u00A1", "\u167F"], +- ["\u1681", "\u1FFF"], +- ["\u200B", "\u2027"], +- ["\u202A", "\u202E"], +- ["\u2030", "\u205E"], +- ["\u2060", "\u2FFF"], +- ["\u3001", "\uD7FF"], +- ["\uE000", "\uFEFE"], +- ["\uFF00", "\uFFFF"] +- ])); +- +-test_mix("\\w", no_unicode_flags, +- CharacterClass([ +- ["0", "9"], +- ["A", "Z"], +- ["_", "_"], +- ["a", "z"] +- ])); +-test_mix("\\w", ["u", "mu"], +- CharacterClass([ +- ["0", "9"], +- ["A", "Z"], +- ["_", "_"], +- ["a", "z"] +- ])); +-test_mix("\\w", ["iu", "imu"], +- CharacterClass([ +- ["0", "9"], +- ["A", "Z"], +- ["_", "_"], +- ["a", "z"], +- ["\u017F", "\u017F"], +- ["\u212A", "\u212A"] +- ])); +- +-test_mix("\\W", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "/"], +- [":", "@"], +- ["[", "^"], +- ["`", "`"], +- ["{", "\uFFFF"] +- ])); +-test_mix("\\W", ["u", "mu"], +- AllSurrogateAndCharacterClass([ +- ["\u0000", "/"], +- [":", "@"], +- ["[", "^"], +- ["`", "`"], +- ["{", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +-test_mix("\\W", ["iu", "imu"], +- AllSurrogateAndCharacterClass([ +- ["\u0000", "/"], +- [":", "@"], +- ["[", "^"], +- ["`", "`"], +- ["{", "\u017E"], +- ["\u0180", "\u2129"], +- ["\u212B", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,19 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("\\f", all_flags, +- Atom("\u000c")); +- +-test_mix("\\n", all_flags, +- Atom("\u000a")); +- +-test_mix("\\r", all_flags, +- Atom("\u000d")); +- +-test_mix("\\t", all_flags, +- Atom("\u0009")); +- +-test_mix("\\v", all_flags, +- Atom("\u000b")); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,13 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("\\ca", all_flags, +- Atom("\u0001")); +-test_mix("\\cz", all_flags, +- Atom("\u001a")); +-test_mix("\\cA", all_flags, +- Atom("\u0001")); +-test_mix("\\cZ", all_flags, +- Atom("\u001a")); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,87 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-// LegacyOctalEscapeSequence +- +-test_mix("\\1", no_unicode_flags, +- Atom("\u0001")); +-test_mix("\\2", no_unicode_flags, +- Atom("\u0002")); +-test_mix("\\3", no_unicode_flags, +- Atom("\u0003")); +-test_mix("\\4", no_unicode_flags, +- Atom("\u0004")); +-test_mix("\\5", no_unicode_flags, +- Atom("\u0005")); +-test_mix("\\6", no_unicode_flags, +- Atom("\u0006")); +-test_mix("\\7", no_unicode_flags, +- Atom("\u0007")); +-test_mix("\\8", no_unicode_flags, +- Atom("8")); +-test_mix("\\9", no_unicode_flags, +- Atom("9")); +- +-test_mix("\\10", no_unicode_flags, +- Atom("\u0008")); +-test_mix("\\11", no_unicode_flags, +- Atom("\u0009")); +- +-test_mix("\\189", no_unicode_flags, +- Atom("\u{0001}89")); +-test_mix("\\1089", no_unicode_flags, +- Atom("\u{0008}89")); +-test_mix("\\10189", no_unicode_flags, +- Atom("A89")); +-test_mix("\\101189", no_unicode_flags, +- Atom("A189")); +- +-// BackReference +- +-test_mix("()\\1", no_unicode_flags, +- Alternative([ +- Capture(1, Empty()), +- BackReference(1) +- ])); +-test_mix("()\\1", unicode_flags, +- Alternative([ +- Capture(1, Empty()), +- Alternative([ +- BackReference(1), +- Assertion("NOT_IN_SURROGATE_PAIR") +- ]) +- ])); +- +-test_mix("()()()()()()()()()()\\10", no_unicode_flags, +- Alternative([ +- Capture(1, Empty()), +- Capture(2, Empty()), +- Capture(3, Empty()), +- Capture(4, Empty()), +- Capture(5, Empty()), +- Capture(6, Empty()), +- Capture(7, Empty()), +- Capture(8, Empty()), +- Capture(9, Empty()), +- Capture(10, Empty()), +- BackReference(10) +- ])); +-test_mix("()()()()()()()()()()\\10", unicode_flags, +- Alternative([ +- Capture(1, Empty()), +- Capture(2, Empty()), +- Capture(3, Empty()), +- Capture(4, Empty()), +- Capture(5, Empty()), +- Capture(6, Empty()), +- Capture(7, Empty()), +- Capture(8, Empty()), +- Capture(9, Empty()), +- Capture(10, Empty()), +- Alternative([ +- BackReference(10), +- Assertion("NOT_IN_SURROGATE_PAIR") +- ]) +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,19 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("\\x00", all_flags, +- Atom("\u0000")); +-test_mix("\\xFF", all_flags, +- Atom("\u00FF")); +- +-test_mix("\\x0", no_unicode_flags, +- Atom("x0")); +-test_mix("\\x000", all_flags, +- Atom("\u{0000}0")); +- +-test_mix("\\xG", no_unicode_flags, +- Atom("xG")); +-test_mix("\\x0G", no_unicode_flags, +- Atom("x0G")); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,55 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-// SyntaxCharacter +- +-test("\\^", all_flags, +- Atom("^")); +-test("\\$", all_flags, +- Atom("$")); +-test("\\\\", all_flags, +- Atom("\\")); +-test("\\.", all_flags, +- Atom(".")); +-test("\\*", all_flags, +- Atom("*")); +-test("\\+", all_flags, +- Atom("+")); +-test("\\?", all_flags, +- Atom("?")); +-test("\\(", all_flags, +- Atom("(")); +-test("\\)", all_flags, +- Atom(")")); +-test("\\[", all_flags, +- Atom("[")); +-test("\\]", all_flags, +- Atom("]")); +-test("\\{", all_flags, +- Atom("{")); +-test("\\}", all_flags, +- Atom("}")); +-test("\\|", all_flags, +- Atom("|")); +- +-// Slash +- +-test("\\/", all_flags, +- Atom("/")); +- +-// SourceCharacter +- +-test("\\P", no_unicode_flags, +- Atom("P")); +- +-test("\\uX", no_unicode_flags, +- Atom("uX")); +- +-test("\\u{0000}", no_unicode_flags, +- Quantifier(0, 0, "GREEDY", Atom("u"))); +- +-test("\\c_", no_unicode_flags, +- Atom("\\c_")); +- +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_Null.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_Null.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_Null.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_Null.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,7 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("\\0", all_flags, +- Atom("\u0000")); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,108 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-// LeadSurrogate TrailSurrogate +- +-test("\\uD83D\\uDC38", all_flags, +- Atom("\uD83D\uDC38")); +-test("X\\uD83D\\uDC38Y", no_unicode_flags, +- Atom("X\uD83D\uDC38Y")); +-test("X\\uD83D\\uDC38Y", unicode_flags, +- Text([ +- Atom("X"), +- Atom("\uD83D\uDC38"), +- Atom("Y") +- ])); +- +-// LeadSurrogate +- +-test_mix("\\uD83D", no_unicode_flags, +- Atom("\uD83D")); +-test("\\uD83D", unicode_flags, +- Alternative([ +- Atom("\uD83D"), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ])); +-test("X\\uD83DY", unicode_flags, +- Alternative([ +- Atom("X"), +- Alternative([ +- Atom("\uD83D"), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]), +- Atom("Y") +- ])); +- +-// TrailSurrogate +- +-test_mix("\\uDC38", no_unicode_flags, +- Atom("\uDC38")); +-test("\\uDC38", unicode_flags, +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- Atom("\uDC38"), +- ])); +-test("X\\uDC38Y", unicode_flags, +- Alternative([ +- Atom("X"), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- Atom("\uDC38"), +- ]), +- Atom("Y") +- ])); +- +-// NonSurrogate / Hex4Digits +- +-test_mix("\\u0000", all_flags, +- Atom("\u0000")); +-test_mix("\\uFFFF", all_flags, +- Atom("\uFFFF")); +- +-// braced HexDigits +- +-test_mix("\\u{0000}", unicode_flags, +- Atom("\u0000")); +-test_mix("\\u{FFFF}", unicode_flags, +- Atom("\uFFFF")); +- +-test("\\u{1F438}", unicode_flags, +- Atom("\uD83D\uDC38")); +-test("X\\u{1F438}Y", unicode_flags, +- Text([ +- Atom("X"), +- Atom("\uD83D\uDC38"), +- Atom("Y") +- ])); +- +-test("\\u{D83D}", unicode_flags, +- Alternative([ +- Atom("\uD83D"), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ])); +-test("X\\u{D83D}Y", unicode_flags, +- Alternative([ +- Atom("X"), +- Alternative([ +- Atom("\uD83D"), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]), +- Atom("Y") +- ])); +- +-test("\\u{DC38}", unicode_flags, +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- Atom("\uDC38"), +- ])); +-test("X\\u{DC38}Y", unicode_flags, +- Alternative([ +- Atom("X"), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- Atom("\uDC38"), +- ]), +- Atom("Y") +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Capture.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Capture.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Capture.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Capture.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,21 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("()", all_flags, +- Capture(1, Empty())); +- +-test("(a)", all_flags, +- Capture(1, Atom("a"))); +- +-test("((a()b))c(d)", all_flags, +- Alternative([ +- Capture(1, Capture(2, Alternative([ +- Atom("a"), +- Capture(3, Empty()), +- Atom("b") +- ]))), +- Atom("c"), +- Capture(4, Atom("d")) +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,74 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("[]", all_flags, +- NegativeCharacterClass([ +- ["\u0000", "\uFFFF"] +- ])); +- +-test("[a]", all_flags, +- CharacterClass([ +- ["a", "a"] +- ])); +- +-test("[abc\u3042\u3044\u3046]", all_flags, +- CharacterClass([ +- ["a", "a"], +- ["b", "b"], +- ["c", "c"], +- ["\u3042", "\u3042"], +- ["\u3044", "\u3044"], +- ["\u3046", "\u3046"], +- ])); +- +-test("[a-c\u3042-\u3046]", all_flags, +- CharacterClass([ +- ["a", "c"], +- ["\u3042", "\u3046"] +- ])); +- +-test("[-]", all_flags, +- CharacterClass([ +- ["-", "-"] +- ])); +- +-// raw surrogate pair +- +-test("[X\uD83D\uDC38Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"], +- ]), +- Atom("\uD83D\uDC38") +- ])); +- +-test("[X\uD83DY]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"] +- ]), +- Alternative([ +- CharacterClass([ +- ["\uD83D", "\uD83D"] +- ]), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]) +- ])); +- +-test("[X\uDC38Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"] +- ]), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- CharacterClass([ +- ["\uDC38", "\uDC38"] +- ]) +- ]) +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,115 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("[\\d]", all_flags, +- CharacterClass([["0", "9"]])); +- +-test("[\\D]", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "/"], +- [":", "\uFFFF"] +- ])); +-test("[\\D]", unicode_flags, +- AllSurrogateAndCharacterClass([ +- ["\u0000", "/"], +- [":", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +- +-test("[\\s]", all_flags, +- CharacterClass([ +- ["\t", "\r"], +- [" ", " "], +- ["\u00A0", "\u00A0"], +- ["\u1680", "\u1680"], +- ["\u2000", "\u200A"], +- ["\u2028", "\u2029"], +- ["\u202F", "\u202F"], +- ["\u205F", "\u205F"], +- ["\u3000", "\u3000"], +- ["\uFEFF", "\uFEFF"] +- ])); +-test("[\\S]", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "\u0008"], +- ["\u000E", "\u001F"], +- ["!", "\u009F"], +- ["\u00A1", "\u167F"], +- ["\u1681", "\u1FFF"], +- ["\u200B", "\u2027"], +- ["\u202A", "\u202E"], +- ["\u2030", "\u205E"], +- ["\u2060", "\u2FFF"], +- ["\u3001", "\uFEFE"], +- ["\uFF00", "\uFFFF"] +- ])); +-test("[\\S]", unicode_flags, +- AllSurrogateAndCharacterClass([ +- ["\u0000", "\u0008"], +- ["\u000E", "\u001F"], +- ["!", "\u009F"], +- ["\u00A1", "\u167F"], +- ["\u1681", "\u1FFF"], +- ["\u200B", "\u2027"], +- ["\u202A", "\u202E"], +- ["\u2030", "\u205E"], +- ["\u2060", "\u2FFF"], +- ["\u3001", "\uD7FF"], +- ["\uE000", "\uFEFE"], +- ["\uFF00", "\uFFFF"] +- ])); +- +-test("[\\w]", no_unicode_flags, +- CharacterClass([ +- ["0", "9"], +- ["A", "Z"], +- ["_", "_"], +- ["a", "z"] +- ])); +-test("[\\w]", ["u", "mu"], +- CharacterClass([ +- ["0", "9"], +- ["A", "Z"], +- ["_", "_"], +- ["a", "z"] +- ])); +-test("[\\w]", ["iu", "imu"], +- CharacterClass([ +- ["0", "9"], +- ["A", "Z"], +- ["_", "_"], +- ["a", "z"], +- ["\u017F", "\u017F"], +- ["\u212A", "\u212A"] +- ])); +- +-test("[\\W]", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "/"], +- [":", "@"], +- ["[", "^"], +- ["`", "`"], +- ["{", "\uFFFF"] +- ])); +-test("[\\W]", ["u", "mu"], +- AllSurrogateAndCharacterClass([ +- ["\u0000", "/"], +- [":", "@"], +- ["[", "^"], +- ["`", "`"], +- ["{", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +-test("[\\W]", ["iu", "imu"], +- AllSurrogateAndCharacterClass([ +- ["\u0000", "/"], +- [":", "@"], +- ["[", "^"], +- ["`", "`"], +- ["{", "\u017E"], +- ["\u0180", "\u2129"], +- ["\u212B", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,13 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("[\b]", all_flags, +- CharacterClass([ +- ["\u0008", "\u0008"] +- ])); +-test("[\-]", all_flags, +- CharacterClass([ +- ["-", "-"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,29 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("[\\f]", all_flags, +- CharacterClass([ +- ["\u000c", "\u000c"] +- ])); +- +-test("[\\n]", all_flags, +- CharacterClass([ +- ["\u000a", "\u000a"] +- ])); +- +-test("[\\r]", all_flags, +- CharacterClass([ +- ["\u000d", "\u000d"] +- ])); +- +-test("[\\t]", all_flags, +- CharacterClass([ +- ["\u0009", "\u0009"] +- ])); +- +-test("[\\v]", all_flags, +- CharacterClass([ +- ["\u000b", "\u000b"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,35 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("[\\ca]", all_flags, +- CharacterClass([ +- ["\u0001", "\u0001"] +- ])); +-test("[\\cz]", all_flags, +- CharacterClass([ +- ["\u001a", "\u001a"] +- ])); +-test("[\\cA]", all_flags, +- CharacterClass([ +- ["\u0001", "\u0001"] +- ])); +-test("[\\cZ]", all_flags, +- CharacterClass([ +- ["\u001a", "\u001a"] +- ])); +- +-// Invalid +- +-test("[\\c]", no_unicode_flags, +- CharacterClass([ +- ["\\", "\\"], +- ["c", "c"] +- ])); +-test("[\\c=]", no_unicode_flags, +- CharacterClass([ +- ["\\", "\\"], +- ["c", "c"], +- ["=", "="] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,39 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("[\\x00]", all_flags, +- CharacterClass([ +- ["\u0000", "\u0000"] +- ])); +-test("[\\xff]", all_flags, +- CharacterClass([ +- ["\u00FF", "\u00FF"] +- ])); +- +-// Invalid +- +-test("[\\x]", no_unicode_flags, +- CharacterClass([ +- ["x", "x"] +- ])); +- +-test("[\\xG]", no_unicode_flags, +- CharacterClass([ +- ["x", "x"], +- ["G", "G"] +- ])); +- +-test("[\\x0]", no_unicode_flags, +- CharacterClass([ +- ["x", "x"], +- ["0", "0"] +- ])); +- +-test("[\\x0G]", no_unicode_flags, +- CharacterClass([ +- ["x", "x"], +- ["0", "0"], +- ["G", "G"], +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,9 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("[\\0]", all_flags, +- CharacterClass([ +- ["\u0000", "\u0000"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js +--- mozilla/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,162 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-// LeadSurrogate TrailSurrogate +- +-test("[X\\uD83D\\uDC38Y]", no_unicode_flags, +- CharacterClass([ +- ["X", "X"], +- ["\uD83D", "\uD83D"], +- ["\uDC38", "\uDC38"], +- ["Y", "Y"] +- ])); +-test("[X\\uD83D\\uDC38Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"], +- ]), +- Atom("\uD83D\uDC38") +- ])); +- +-// LeadSurrogate +- +-test("[X\\uD83DY]", no_unicode_flags, +- CharacterClass([ +- ["X", "X"], +- ["\uD83D", "\uD83D"], +- ["Y", "Y"] +- ])); +-test("[X\\uD83DY]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"] +- ]), +- Alternative([ +- CharacterClass([ +- ["\uD83D", "\uD83D"] +- ]), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]) +- ])); +- +-// TrailSurrogate +- +-test("[X\\uDC38Y]", no_unicode_flags, +- CharacterClass([ +- ["X", "X"], +- ["\uDC38", "\uDC38"], +- ["Y", "Y"] +- ])); +-test("[X\\uDC38Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"] +- ]), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- CharacterClass([ +- ["\uDC38", "\uDC38"] +- ]) +- ]) +- ])); +- +-// NonSurrogate / Hex4Digits +- +-test("[X\\u0000Y]", all_flags, +- CharacterClass([ +- ["X", "X"], +- ["\u0000", "\u0000"], +- ["Y", "Y"] +- ])); +-test("[X\\uFFFFY]", all_flags, +- CharacterClass([ +- ["X", "X"], +- ["\uFFFF", "\uFFFF"], +- ["Y", "Y"] +- ])); +- +-// braced HexDigits +- +-test("[X\\u{0000}Y]", unicode_flags, +- CharacterClass([ +- ["X", "X"], +- ["\u0000", "\u0000"], +- ["Y", "Y"] +- ])); +-test("[X\\uFFFFY]", unicode_flags, +- CharacterClass([ +- ["X", "X"], +- ["\uFFFF", "\uFFFF"], +- ["Y", "Y"] +- ])); +- +-test("[X\\u{1F438}Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"], +- ]), +- Atom("\uD83D\uDC38") +- ])); +- +-test("[X\\u{D83D}Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"] +- ]), +- Alternative([ +- CharacterClass([ +- ["\uD83D", "\uD83D"] +- ]), +- NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]])) +- ]) +- ])); +-test("[X\\u{DC38}Y]", unicode_flags, +- Disjunction([ +- CharacterClass([ +- ["X", "X"], +- ["Y", "Y"] +- ]), +- Alternative([ +- Assertion("NOT_AFTER_LEAD_SURROGATE"), +- CharacterClass([ +- ["\uDC38", "\uDC38"] +- ]) +- ]) +- ])); +- +-// Invalid +- +-test("[\\u]", no_unicode_flags, +- CharacterClass([ +- ["u", "u"] +- ])); +- +-test("[\\uG]", no_unicode_flags, +- CharacterClass([ +- ["u", "u"], +- ["G", "G"] +- ])); +- +-test("[\\uD83]", no_unicode_flags, +- CharacterClass([ +- ["u", "u"], +- ["D", "D"], +- ["8", "8"], +- ["3", "3"] +- ])); +- +-test("[\\uD83G]", no_unicode_flags, +- CharacterClass([ +- ["u", "u"], +- ["D", "D"], +- ["8", "8"], +- ["3", "3"], +- ["G", "G"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Disjunction.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Disjunction.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Disjunction.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Disjunction.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,42 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("a|\u3042", all_flags, +- Disjunction([ +- Atom("a"), +- Atom("\u3042") +- ])); +- +-test("a|\u3042|abc", all_flags, +- Disjunction([ +- Atom("a"), +- Atom("\u3042"), +- Atom("abc") +- ])); +- +-test("|", all_flags, +- Disjunction([ +- Empty(), +- Empty() +- ])); +- +-test("||", all_flags, +- Disjunction([ +- Empty(), +- Empty(), +- Empty() +- ])); +- +-test("abc|", all_flags, +- Disjunction([ +- Atom("abc"), +- Empty() +- ])); +- +-test("|abc", all_flags, +- Disjunction([ +- Empty(), +- Atom("abc") +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Empty.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Empty.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Empty.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Empty.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,7 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("", all_flags, +- Empty()); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Everything.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Everything.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Everything.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Everything.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,21 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix(".", no_unicode_flags, +- CharacterClass([ +- ["\u0000", "\u0009"], +- ["\u000b", "\u000c"], +- ["\u000e", "\u2027"], +- ["\u202A", "\uFFFF"] +- ])); +- +-test_mix(".", unicode_flags, +- AllSurrogateAndCharacterClass([ +- ["\u0000", "\u0009"], +- ["\u000b", "\u000c"], +- ["\u000e", "\u2027"], +- ["\u202A", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Group.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Group.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Group.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Group.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,15 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test("(?:)", all_flags, +- Empty()); +-test("(?:a)", all_flags, +- Atom("a")); +-test("X(?:a)Y", all_flags, +- Text([ +- Atom("X"), +- Atom("a"), +- Atom("Y") +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Lookahead.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Lookahead.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Lookahead.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Lookahead.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,31 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("(?=abc)", all_flags, +- Lookahead(Atom("abc"))); +- +-test_mix("(?!abc)", all_flags, +- NegativeLookahead(Atom("abc"))); +- +-test_mix("(?=abc)+", no_unicode_flags, +- Lookahead(Atom("abc"))); +- +-// Lookahead becomes Empty because max_match of Lookahead is 0 and the min vaue +-// of Quantifier is also 0. +-test("(?=abc)*", no_unicode_flags, +- Empty()); +-test("X(?=abc)*Y", no_unicode_flags, +- Alternative([ +- Atom("X"), +- Atom("Y"), +- ])); +- +-test("(?=abc)?", no_unicode_flags, +- Empty()); +-test("X(?=abc)?Y", no_unicode_flags, +- Alternative([ +- Atom("X"), +- Atom("Y"), +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/MatchOnly.js mozilla-OK/js/src/jit-test/tests/regexp_parse/MatchOnly.js +--- mozilla/js/src/jit-test/tests/regexp_parse/MatchOnly.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/MatchOnly.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,35 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-// Leading and trailing .* are ignored if match_only==true. +- +-test_match_only(".*abc", all_flags, +- Atom("abc")); +-test_match_only("abc.*", all_flags, +- Atom("abc")); +- +-test_match_only(".*?abc", no_unicode_flags, +- Alternative([ +- Quantifier(0, kInfinity, "NON_GREEDY", +- CharacterClass([ +- ["\u0000", "\u0009"], +- ["\u000b", "\u000c"], +- ["\u000e", "\u2027"], +- ["\u202A", "\uFFFF"] +- ])), +- Atom("abc") +- ])); +-test_match_only(".*?abc", unicode_flags, +- Alternative([ +- Quantifier(0, kInfinity, "NON_GREEDY", +- AllSurrogateAndCharacterClass([ +- ["\u0000", "\u0009"], +- ["\u000b", "\u000c"], +- ["\u000e", "\u2027"], +- ["\u202A", "\uD7FF"], +- ["\uE000", "\uFFFF"] +- ])), +- Atom("abc") +- ])); +diff -Nrup mozilla/js/src/jit-test/tests/regexp_parse/Quantifier.js mozilla-OK/js/src/jit-test/tests/regexp_parse/Quantifier.js +--- mozilla/js/src/jit-test/tests/regexp_parse/Quantifier.js 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jit-test/tests/regexp_parse/Quantifier.js 1970-01-01 03:00:00.000000000 +0300 +@@ -1,58 +0,0 @@ +-if (typeof parseRegExp === 'undefined') +- quit(); +- +-load(libdir + "regexp_parse.js"); +- +-test_mix("a*", all_flags, +- Quantifier(0, kInfinity, "GREEDY", Atom("a"))); +-test_mix("a*?", all_flags, +- Quantifier(0, kInfinity, "NON_GREEDY", Atom("a"))); +- +-test_mix("a+", all_flags, +- Quantifier(1, kInfinity, "GREEDY", Atom("a"))); +-test_mix("a+?", all_flags, +- Quantifier(1, kInfinity, "NON_GREEDY", Atom("a"))); +- +-test_mix("a?", all_flags, +- Quantifier(0, 1, "GREEDY", Atom("a"))); +-test_mix("a??", all_flags, +- Quantifier(0, 1, "NON_GREEDY", Atom("a"))); +- +-test_mix("a{3}", all_flags, +- Quantifier(3, 3, "GREEDY", Atom("a"))); +-test_mix("a{3}?", all_flags, +- Quantifier(3, 3, "NON_GREEDY", Atom("a"))); +- +-test_mix("a{3,}", all_flags, +- Quantifier(3, kInfinity, "GREEDY", Atom("a"))); +-test_mix("a{3,}?", all_flags, +- Quantifier(3, kInfinity, "NON_GREEDY", Atom("a"))); +- +-test_mix("a{3,5}", all_flags, +- Quantifier(3, 5, "GREEDY", Atom("a"))); +-test_mix("a{3,5}?", all_flags, +- Quantifier(3, 5, "NON_GREEDY", Atom("a"))); +- +-// Surrogate Pair and Quantifier +- +-test("\\uD83D\\uDC38+", no_unicode_flags, +- Alternative([ +- Atom("\uD83D"), +- Quantifier(1, kInfinity, "GREEDY", Atom("\uDC38")) +- ])); +-test("\\uD83D\\uDC38+", unicode_flags, +- Quantifier(1, kInfinity, "GREEDY", Atom("\uD83D\uDC38"))); +- +-// Invalid +- +-test_mix("a{", no_unicode_flags, +- Atom("a{")); +-test_mix("a{1", no_unicode_flags, +- Atom("a{1")); +-test_mix("a{1,", no_unicode_flags, +- Atom("a{1,")); +-test_mix("a{1,2", no_unicode_flags, +- Atom("a{1,2")); +- +-test_mix("a{,", no_unicode_flags, +- Atom("a{,")); +diff -Nrup mozilla/js/src/js.msg mozilla-OK/js/src/js.msg +--- mozilla/js/src/js.msg 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/js.msg 2023-02-27 07:59:24.264357678 +0300 +@@ -495,7 +495,6 @@ MSG_DEF(JSMSG_INVALID_TIME_ZONE, 1 + MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") + + // RegExp +-MSG_DEF(JSMSG_BACK_REF_OUT_OF_RANGE, 0, JSEXN_SYNTAXERR, "back reference out of range in regular expression") + MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") + MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") + MSG_DEF(JSMSG_EXEC_NOT_OBJORNULL, 0, JSEXN_TYPEERR, "RegExp exec method should return object or null") +@@ -508,12 +507,19 @@ MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 0 + MSG_DEF(JSMSG_NOTHING_TO_REPEAT, 0, JSEXN_SYNTAXERR, "nothing to repeat") + MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER, 0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.") + MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class escape cannot be used in class range in regular expression") +-MSG_DEF(JSMSG_RAW_BRACE_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") +-MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") ++MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEXP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") + MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") + MSG_DEF(JSMSG_UNICODE_OVERFLOW, 1, JSEXN_SYNTAXERR, "Unicode codepoint must not be greater than 0x10FFFF in {0}") + MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") + MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") ++MSG_DEF(JSMSG_INVALID_PROPERTY_NAME, 0, JSEXN_SYNTAXERR, "invalid property name in regular expression") ++MSG_DEF(JSMSG_INVALID_CLASS_PROPERTY_NAME, 0, JSEXN_SYNTAXERR, "invalid class property name in regular expression") ++MSG_DEF(JSMSG_INCOMPLETE_QUANTIFIER, 0, JSEXN_SYNTAXERR, "incomplete quantifier in regular expression") ++MSG_DEF(JSMSG_INVALID_QUANTIFIER, 0, JSEXN_SYNTAXERR, "invalid quantifier in regular expression") ++MSG_DEF(JSMSG_INVALID_CAPTURE_NAME, 0, JSEXN_SYNTAXERR, "invalid capture group name in regular expression") ++MSG_DEF(JSMSG_DUPLICATE_CAPTURE_NAME, 0, JSEXN_SYNTAXERR, "duplicate capture group name in regular expression") ++MSG_DEF(JSMSG_INVALID_NAMED_REF, 0, JSEXN_SYNTAXERR, "invalid named reference in regular expression") ++MSG_DEF(JSMSG_INVALID_NAMED_CAPTURE_REF, 0, JSEXN_SYNTAXERR, "invalid named capture reference in regular expression") + + // Self-hosting + MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 0, JSEXN_ERR, "internal error getting the default locale") +diff -Nrup mozilla/js/src/jsapi-tests/testRegExp.cpp mozilla-OK/js/src/jsapi-tests/testRegExp.cpp +--- mozilla/js/src/jsapi-tests/testRegExp.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsapi-tests/testRegExp.cpp 2023-02-27 07:04:13.337911810 +0300 +@@ -2,6 +2,8 @@ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + ++#include "js/RegExp.h" ++#include "js/RegExpFlags.h" + #include "jsapi-tests/tests.h" + + BEGIN_TEST(testObjectIsRegExp) +@@ -12,12 +14,12 @@ BEGIN_TEST(testObjectIsRegExp) + + EVAL("new Object", &val); + JS::RootedObject obj(cx, val.toObjectOrNull()); +- CHECK(JS_ObjectIsRegExp(cx, obj, &isRegExp)); ++ CHECK(JS::ObjectIsRegExp(cx, obj, &isRegExp)); + CHECK(!isRegExp); + + EVAL("/foopy/", &val); + obj = val.toObjectOrNull(); +- CHECK(JS_ObjectIsRegExp(cx, obj, &isRegExp)); ++ CHECK(JS::ObjectIsRegExp(cx, obj, &isRegExp)); + CHECK(isRegExp); + + return true; +@@ -31,15 +33,16 @@ BEGIN_TEST(testGetRegExpFlags) + + EVAL("/foopy/", &val); + obj = val.toObjectOrNull(); +- CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), 0u); ++ CHECK_EQUAL(JS::GetRegExpFlags(cx, obj), JS::RegExpFlags(JS::RegExpFlag::NoFlags)); + + EVAL("/foopy/g", &val); + obj = val.toObjectOrNull(); +- CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), JSREG_GLOB); ++ CHECK_EQUAL(JS::GetRegExpFlags(cx, obj), JS::RegExpFlags(JS::RegExpFlag::Global)); + + EVAL("/foopy/gi", &val); + obj = val.toObjectOrNull(); +- CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), (JSREG_FOLD | JSREG_GLOB)); ++ CHECK_EQUAL(JS::GetRegExpFlags(cx, obj), ++ JS::RegExpFlags(JS::RegExpFlag::Global | JS::RegExpFlag::IgnoreCase)); + + return true; + } +@@ -52,7 +55,8 @@ BEGIN_TEST(testGetRegExpSource) + + EVAL("/foopy/", &val); + obj = val.toObjectOrNull(); +- JSString* source = JS_GetRegExpSource(cx, obj); ++ JSString* source = JS::GetRegExpSource(cx, obj); ++ CHECK(source); + CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(source), "foopy")); + + return true; +diff -Nrup mozilla/js/src/jsapi-tests/tests.h mozilla-OK/js/src/jsapi-tests/tests.h +--- mozilla/js/src/jsapi-tests/tests.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsapi-tests/tests.h 2023-02-27 07:45:54.690097673 +0300 +@@ -19,6 +19,7 @@ + #include "jscntxt.h" + #include "jsgc.h" + ++#include "js/RegExpFlags.h" + #include "js/Vector.h" + + /* Note: Aborts on OOM. */ +@@ -150,6 +151,30 @@ class JSAPITest + return JSAPITestString(v ? "true" : "false"); + } + ++ JSAPITestString toSource(JS::RegExpFlags flags) ++ { ++ JSAPITestString str; ++ if (flags.global()) { ++ str += "g"; ++ } ++ if (flags.ignoreCase()) { ++ str += "i"; ++ } ++ if (flags.multiline()) { ++ str += "m"; ++ } ++ if (flags.dotAll()) { ++ str += "s"; ++ } ++ if (flags.unicode()) { ++ str += "u"; ++ } ++ if (flags.sticky()) { ++ str += "y"; ++ } ++ return str; ++ } ++ + JSAPITestString toSource(JSAtom* v) { + JS::RootedValue val(cx, JS::StringValue((JSString*)v)); + return jsvalToSource(val); +diff -Nrup mozilla/js/src/jsapi.cpp mozilla-OK/js/src/jsapi.cpp +--- mozilla/js/src/jsapi.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsapi.cpp 2023-02-27 07:03:29.867223740 +0300 +@@ -44,7 +44,6 @@ + #include "builtin/Eval.h" + #include "builtin/MapObject.h" + #include "builtin/Promise.h" +-#include "builtin/RegExp.h" + #include "builtin/Stream.h" + #include "builtin/SymbolObject.h" + #ifdef ENABLE_SIMD +@@ -76,7 +75,6 @@ + #include "vm/ErrorObject.h" + #include "vm/HelperThreads.h" + #include "vm/Interpreter.h" +-#include "vm/RegExpStatics.h" + #include "vm/Runtime.h" + #include "vm/SavedStacks.h" + #include "vm/SelfHosting.h" +@@ -6620,138 +6618,6 @@ JS_ObjectIsDate(JSContext* cx, HandleObj + } + + /************************************************************************/ +- +-/* +- * Regular Expressions. +- */ +-JS_PUBLIC_API(JSObject*) +-JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- +- ScopedJSFreePtr chars(InflateString(cx, bytes, length)); +- if (!chars) +- return nullptr; +- +- return RegExpObject::create(cx, chars.get(), length, RegExpFlag(flags), cx->tempLifoAlloc(), +- GenericObject); +-} +- +-JS_PUBLIC_API(JSObject*) +-JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- +- return RegExpObject::create(cx, chars, length, RegExpFlag(flags), cx->tempLifoAlloc(), +- GenericObject); +-} +- +-JS_PUBLIC_API(bool) +-JS_SetRegExpInput(JSContext* cx, HandleObject obj, HandleString input) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- assertSameCompartment(cx, input); +- +- Handle global = obj.as(); +- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); +- if (!res) +- return false; +- +- res->reset(input); +- return true; +-} +- +-JS_PUBLIC_API(bool) +-JS_ClearRegExpStatics(JSContext* cx, HandleObject obj) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- MOZ_ASSERT(obj); +- +- Handle global = obj.as(); +- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); +- if (!res) +- return false; +- +- res->clear(); +- return true; +-} +- +-JS_PUBLIC_API(bool) +-JS_ExecuteRegExp(JSContext* cx, HandleObject obj, HandleObject reobj, char16_t* chars, +- size_t length, size_t* indexp, bool test, MutableHandleValue rval) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- +- Handle global = obj.as(); +- RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); +- if (!res) +- return false; +- +- RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); +- if (!input) +- return false; +- +- return ExecuteRegExpLegacy(cx, res, reobj.as(), input, indexp, test, rval); +-} +- +-JS_PUBLIC_API(bool) +-JS_ExecuteRegExpNoStatics(JSContext* cx, HandleObject obj, char16_t* chars, size_t length, +- size_t* indexp, bool test, MutableHandleValue rval) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- +- RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); +- if (!input) +- return false; +- +- return ExecuteRegExpLegacy(cx, nullptr, obj.as(), input, indexp, test, +- rval); +-} +- +-JS_PUBLIC_API(bool) +-JS_ObjectIsRegExp(JSContext* cx, HandleObject obj, bool* isRegExp) +-{ +- assertSameCompartment(cx, obj); +- +- ESClass cls; +- if (!GetBuiltinClass(cx, obj, &cls)) +- return false; +- +- *isRegExp = cls == ESClass::RegExp; +- return true; +-} +- +-JS_PUBLIC_API(unsigned) +-JS_GetRegExpFlags(JSContext* cx, HandleObject obj) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- +- RegExpShared* shared = RegExpToShared(cx, obj); +- if (!shared) +- return false; +- return shared->getFlags(); +-} +- +-JS_PUBLIC_API(JSString*) +-JS_GetRegExpSource(JSContext* cx, HandleObject obj) +-{ +- AssertHeapIsIdle(); +- CHECK_REQUEST(cx); +- +- RegExpShared* shared = RegExpToShared(cx, obj); +- if (!shared) +- return nullptr; +- return shared->getSource(); +-} +- +-/************************************************************************/ + + JS_PUBLIC_API(bool) + JS_SetDefaultLocale(JSRuntime* rt, const char* locale) +diff -Nrup mozilla/js/src/jsapi.h mozilla-OK/js/src/jsapi.h +--- mozilla/js/src/jsapi.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsapi.h 2023-02-27 07:46:51.309696229 +0300 +@@ -5024,7 +5024,8 @@ GetSymbolDescription(HandleSymbol symbol + macro(toPrimitive) \ + macro(toStringTag) \ + macro(unscopables) \ +- macro(asyncIterator) ++ macro(asyncIterator) \ ++ macro(matchAll) + + enum class SymbolCode : uint32_t { + // There is one SymbolCode for each well-known symbol. +@@ -5634,56 +5635,6 @@ JS_ObjectIsDate(JSContext* cx, JS::Handl + + /************************************************************************/ + +-/* +- * Regular Expressions. +- */ +-#define JSREG_FOLD 0x01u /* fold uppercase to lowercase */ +-#define JSREG_GLOB 0x02u /* global exec, creates array of matches */ +-#define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */ +-#define JSREG_STICKY 0x08u /* only match starting at lastIndex */ +-#define JSREG_UNICODE 0x10u /* unicode */ +- +-extern JS_PUBLIC_API(JSObject*) +-JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags); +- +-extern JS_PUBLIC_API(JSObject*) +-JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags); +- +-extern JS_PUBLIC_API(bool) +-JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input); +- +-extern JS_PUBLIC_API(bool) +-JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj); +- +-extern JS_PUBLIC_API(bool) +-JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj, +- char16_t* chars, size_t length, size_t* indexp, bool test, +- JS::MutableHandleValue rval); +- +-/* RegExp interface for clients without a global object. */ +- +-extern JS_PUBLIC_API(bool) +-JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length, +- size_t* indexp, bool test, JS::MutableHandleValue rval); +- +-/** +- * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp +- * object or a wrapper around one, otherwise returns false on failure. +- * +- * This method returns true with |*isRegExp == false| when passed a proxy whose +- * target is a RegExp, or when passed a revoked proxy. +- */ +-extern JS_PUBLIC_API(bool) +-JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp); +- +-extern JS_PUBLIC_API(unsigned) +-JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj); +- +-extern JS_PUBLIC_API(JSString*) +-JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj); +- +-/************************************************************************/ +- + extern JS_PUBLIC_API(bool) + JS_IsExceptionPending(JSContext* cx); + +diff -Nrup mozilla/js/src/jscntxt.cpp mozilla-OK/js/src/jscntxt.cpp +--- mozilla/js/src/jscntxt.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jscntxt.cpp 2023-02-27 08:16:03.036282094 +0300 +@@ -45,6 +45,7 @@ + + #include "gc/FreeOp.h" + #include "gc/Marking.h" ++#include "irregexp/RegExpAPI.h" + #include "jit/Ion.h" + #include "jit/PcScriptCache.h" + #include "js/CharacterEncoding.h" +@@ -117,9 +118,6 @@ JSContext::init(ContextKind kind) + threadNative_ = (size_t)pthread_self(); + #endif + +- if (!regexpStack.ref().init()) +- return false; +- + if (!fx.initInstance()) + return false; + +@@ -133,6 +131,11 @@ JSContext::init(ContextKind kind) + return false; + } + ++ isolate = irregexp::CreateIsolate(this); ++ if (!isolate) { ++ return false; ++ } ++ + // Set the ContextKind last, so that ProtectedData checks will allow us to + // initialize this context before it becomes the runtime's active context. + kind_ = kind; +@@ -1354,6 +1357,10 @@ JSContext::~JSContext() + DestroyTraceLogger(traceLogger); + #endif + ++ if (isolate) { ++ irregexp::DestroyIsolate(isolate.ref()); ++ } ++ + MOZ_ASSERT(TlsContext.get() == this); + TlsContext.set(nullptr); + } +@@ -1485,15 +1492,15 @@ JSContext::updateJITEnabled() + jitIsBroken = IsJITBrokenHere(); + } + +-size_t +-JSContext::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const +-{ +- /* +- * There are other JSContext members that could be measured; the following +- * ones have been found by DMD to be worth measuring. More stuff may be +- * added later. +- */ +- return cycleDetectorVector().sizeOfExcludingThis(mallocSizeOf); ++size_t JSContext::sizeOfExcludingThis( ++ mozilla::MallocSizeOf mallocSizeOf) const { ++ /* ++ * There are other JSContext members that could be measured; the following ++ * ones have been found by DMD to be worth measuring. More stuff may be ++ * added later. ++ */ ++ return cycleDetectorVector().sizeOfExcludingThis(mallocSizeOf) + ++ irregexp::IsolateSizeOfIncludingThis(isolate, mallocSizeOf); + } + + void +diff -Nrup mozilla/js/src/jscntxt.h mozilla-OK/js/src/jscntxt.h +--- mozilla/js/src/jscntxt.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jscntxt.h 2023-02-27 07:59:24.265357671 +0300 +@@ -11,6 +11,7 @@ + + #include "mozilla/MemoryReporting.h" + ++#include "irregexp/RegExpTypes.h" + #include "js/CharacterEncoding.h" + #include "js/GCVector.h" + #include "js/Result.h" +@@ -338,8 +339,8 @@ struct JSContext : public JS::RootingCon + */ + js::ThreadLocalData jitActivation; + +- // Information about the heap allocated backtrack stack used by RegExp JIT code. +- js::ThreadLocalData regexpStack; ++ // Shim for V8 interfaces used by irregexp code ++ js::ThreadLocalData isolate; + + /* + * Points to the most recent activation running on the thread. +diff -Nrup mozilla/js/src/jsgc.cpp mozilla-OK/js/src/jsgc.cpp +--- mozilla/js/src/jsgc.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsgc.cpp 2023-02-27 07:42:19.263625981 +0300 +@@ -2769,7 +2769,8 @@ static const AllocKinds UpdatePhaseMisc + AllocKind::OBJECT_GROUP, + AllocKind::STRING, + AllocKind::JITCODE, +- AllocKind::SCOPE ++ AllocKind::SCOPE, ++ AllocKind::REGEXP_SHARED + }; + + static const AllocKinds UpdatePhaseObjects { +diff -Nrup mozilla/js/src/jsiter.cpp mozilla-OK/js/src/jsiter.cpp +--- mozilla/js/src/jsiter.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsiter.cpp 2023-02-27 07:46:51.310696222 +0300 +@@ -23,6 +23,7 @@ + #include "jstypes.h" + #include "jsutil.h" + ++#include "builtin/SelfHostingDefines.h" + #include "ds/Sort.h" + #include "gc/FreeOp.h" + #include "gc/Marking.h" +@@ -1175,6 +1176,78 @@ js::NewStringIteratorObject(JSContext* c + return NewObjectWithGivenProto(cx, proto, newKind); + } + ++static const Class RegExpStringIteratorPrototypeClass = { ++ "RegExp String Iterator", 0 ++}; ++ ++enum { ++ // The regular expression used for iteration. May hold the original RegExp ++ // object when it is reused instead of a new RegExp object. ++ RegExpStringIteratorSlotRegExp, ++ ++ // The String value being iterated upon. ++ RegExpStringIteratorSlotString, ++ ++ // The source string of the original RegExp object. Used to validate we can ++ // reuse the original RegExp object for matching. ++ RegExpStringIteratorSlotSource, ++ ++ // The flags of the original RegExp object. ++ RegExpStringIteratorSlotFlags, ++ ++ // When non-negative, this slot holds the current lastIndex position when ++ // reusing the original RegExp object for matching. When set to |-1|, the ++ // iterator has finished. When set to any other negative value, the ++ // iterator is not yet exhausted and we're not on the fast path and we're ++ // not reusing the input RegExp object. ++ RegExpStringIteratorSlotLastIndex, ++ ++ RegExpStringIteratorSlotCount ++}; ++ ++static_assert(RegExpStringIteratorSlotRegExp == ++ REGEXP_STRING_ITERATOR_REGEXP_SLOT, ++ "RegExpStringIteratorSlotRegExp must match self-hosting define " ++ "for regexp slot."); ++static_assert(RegExpStringIteratorSlotString == ++ REGEXP_STRING_ITERATOR_STRING_SLOT, ++ "RegExpStringIteratorSlotString must match self-hosting define " ++ "for string slot."); ++static_assert(RegExpStringIteratorSlotSource == ++ REGEXP_STRING_ITERATOR_SOURCE_SLOT, ++ "RegExpStringIteratorSlotString must match self-hosting define " ++ "for source slot."); ++static_assert(RegExpStringIteratorSlotFlags == ++ REGEXP_STRING_ITERATOR_FLAGS_SLOT, ++ "RegExpStringIteratorSlotFlags must match self-hosting define " ++ "for flags slot."); ++static_assert(RegExpStringIteratorSlotLastIndex == ++ REGEXP_STRING_ITERATOR_LASTINDEX_SLOT, ++ "RegExpStringIteratorSlotLastIndex must match self-hosting " ++ "define for lastIndex slot."); ++ ++const Class RegExpStringIteratorObject::class_ = { ++ "RegExp String Iterator", ++ JSCLASS_HAS_RESERVED_SLOTS(RegExpStringIteratorSlotCount) ++}; ++ ++static const JSFunctionSpec regexp_string_iterator_methods[] = { ++ JS_SELF_HOSTED_FN("next", "RegExpStringIteratorNext", 0, 0), ++ JS_FS_END ++}; ++ ++RegExpStringIteratorObject* js::NewRegExpStringIteratorObject( ++ JSContext* cx, NewObjectKind newKind) { ++ RootedObject proto(cx, GlobalObject::getOrCreateRegExpStringIteratorPrototype( ++ cx, cx->global())); ++ if (!proto) { ++ return nullptr; ++ } ++ ++ return NewObjectWithGivenProto(cx, proto, ++ newKind); ++} ++ + JSObject* + js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp) + { +@@ -1516,3 +1589,29 @@ GlobalObject::initStringIteratorProto(JS + global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto)); + return true; + } ++ ++/* static */ bool ++GlobalObject::initRegExpStringIteratorProto(JSContext* cx, Handle global) ++{ ++ if (global->getReservedSlot(REGEXP_STRING_ITERATOR_PROTO).isObject()) { ++ return true; ++ } ++ ++ RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global)); ++ if (!iteratorProto) { ++ return false; ++ } ++ ++ const Class* cls = &RegExpStringIteratorPrototypeClass; ++ RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls, ++ iteratorProto)); ++ if (!proto || ++ !DefinePropertiesAndFunctions(cx, proto, nullptr, regexp_string_iterator_methods) || ++ !DefineToStringTag(cx, proto, cx->names().RegExpStringIterator)) ++ { ++ return false; ++ } ++ ++ global->setReservedSlot(REGEXP_STRING_ITERATOR_PROTO, ObjectValue(*proto)); ++ return true; ++} +diff -Nrup mozilla/js/src/jsiter.h mozilla-OK/js/src/jsiter.h +--- mozilla/js/src/jsiter.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsiter.h 2023-02-27 07:46:51.310696222 +0300 +@@ -157,6 +157,15 @@ class StringIteratorObject : public JSOb + StringIteratorObject* + NewStringIteratorObject(JSContext* cx, NewObjectKind newKind = GenericObject); + ++class RegExpStringIteratorObject : public NativeObject ++{ ++ public: ++ static const Class class_; ++}; ++ ++RegExpStringIteratorObject* ++NewRegExpStringIteratorObject(JSContext* cx, NewObjectKind newKind = GenericObject); ++ + JSObject* + GetIterator(JSContext* cx, HandleObject obj, unsigned flags); + +diff -Nrup mozilla/js/src/jsstr.cpp mozilla-OK/js/src/jsstr.cpp +--- mozilla/js/src/jsstr.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/jsstr.cpp 2023-02-27 07:46:51.312696208 +0300 +@@ -3599,6 +3599,7 @@ static const JSFunctionSpec string_metho + + /* Perl-ish methods (search is actually Python-esque). */ + JS_SELF_HOSTED_FN("match", "String_match", 1,0), ++ JS_SELF_HOSTED_FN("matchAll", "String_matchAll", 1,0), + JS_SELF_HOSTED_FN("search", "String_search", 1,0), + JS_SELF_HOSTED_FN("replace", "String_replace", 2,0), + JS_SELF_HOSTED_FN("replaceAll", "String_replaceAll", 2, 0), +diff -Nrup mozilla/js/src/moz.build mozilla-OK/js/src/moz.build +--- mozilla/js/src/moz.build 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/moz.build 2023-02-27 08:20:09.802534344 +0300 +@@ -145,6 +145,8 @@ EXPORTS.js += [ + '../public/Proxy.h', + '../public/Realm.h', + '../public/RefCounted.h', ++ '../public/RegExp.h', ++ '../public/RegExpFlags.h', + '../public/RequiredDefines.h', + '../public/Result.h', + '../public/RootingAPI.h', +@@ -169,6 +171,10 @@ EXPORTS.js += [ + '../public/WeakMapPtr.h', + ] + ++SOURCES += [ ++ 'util/Text.cpp', ++] ++ + UNIFIED_SOURCES += [ + 'builtin/AtomicsObject.cpp', + 'builtin/DataViewObject.cpp', +@@ -198,14 +204,6 @@ UNIFIED_SOURCES += [ + 'devtools/sharkctl.cpp', + 'ds/Bitmap.cpp', + 'ds/LifoAlloc.cpp', +- 'irregexp/NativeRegExpMacroAssembler.cpp', +- 'irregexp/RegExpAST.cpp', +- 'irregexp/RegExpCharacters.cpp', +- 'irregexp/RegExpEngine.cpp', +- 'irregexp/RegExpInterpreter.cpp', +- 'irregexp/RegExpMacroAssembler.cpp', +- 'irregexp/RegExpParser.cpp', +- 'irregexp/RegExpStack.cpp', + 'jsalloc.cpp', + 'jsapi.cpp', + 'jsarray.cpp', +@@ -382,13 +380,39 @@ else: + 'perf/pm_stub.cpp' + ] + ++SOURCES += [ ++ 'irregexp/imported/regexp-ast.cc', ++ 'irregexp/imported/regexp-bytecode-generator.cc', ++ 'irregexp/imported/regexp-bytecode-peephole.cc', ++ 'irregexp/imported/regexp-bytecodes.cc', ++ 'irregexp/imported/regexp-compiler-tonode.cc', ++ 'irregexp/imported/regexp-compiler.cc', ++ 'irregexp/imported/regexp-dotprinter.cc', ++ 'irregexp/imported/regexp-interpreter.cc', ++ 'irregexp/imported/regexp-macro-assembler-tracer.cc', ++ 'irregexp/imported/regexp-macro-assembler.cc', ++ 'irregexp/imported/regexp-parser.cc', ++ 'irregexp/imported/regexp-stack.cc', ++ 'irregexp/RegExpAPI.cpp', ++ 'irregexp/RegExpNativeMacroAssembler.cpp', ++ 'irregexp/RegExpShim.cpp', ++ 'irregexp/util/UnicodeShim.cpp' ++] ++ ++if CONFIG['ENABLE_INTL_API']: ++ CXXFLAGS += ['-DV8_INTL_SUPPORT'] ++ SOURCES += [ ++ 'irregexp/imported/property-sequences.cc', ++ 'irregexp/imported/special-case.cc' ++ ] ++ + DIRS += [ + 'build', + 'frontend', + 'gc', + 'jit', + 'wasm', +-] + (['new-regexp'] if CONFIG['ENABLE_NEW_REGEXP'] else []) ++] + + FINAL_LIBRARY = 'js' + +diff -Nrup mozilla/js/src/moz.build.later mozilla-OK/js/src/moz.build.later +--- mozilla/js/src/moz.build.later 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/moz.build.later 2023-02-27 07:59:24.266357664 +0300 +@@ -0,0 +1,10 @@ ++--- js/src/moz.build +++++ js/src/moz.build ++@@ -114,6 +114,7 @@ ++ 'frontend', ++ 'gc', ++ 'jit', +++ 'irregexp', ++ 'perf', ++ 'proxy', ++ 'threading', +diff -Nrup mozilla/js/src/shell/js.cpp mozilla-OK/js/src/shell/js.cpp +--- mozilla/js/src/shell/js.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/shell/js.cpp 2023-02-27 07:59:40.449242945 +0300 +@@ -8188,6 +8188,11 @@ SetContextOptions(JSContext* cx, const O + if (warmUpThreshold >= 0) + jit::JitOptions.baselineWarmUpThreshold = warmUpThreshold; + ++ warmUpThreshold = op.getIntOption("regexp-warmup-threshold"); ++ if (warmUpThreshold >= 0) { ++ jit::JitOptions.regexpWarmUpThreshold = warmUpThreshold; ++ } ++ + if (op.getBoolOption("baseline-eager")) + jit::JitOptions.baselineWarmUpThreshold = 0; + +@@ -8511,6 +8516,11 @@ main(int argc, char** argv, char** envp) + || !op.addBoolOption('\0', "test-wasm-await-tier2", "Forcibly activate tiering and block " + "instantiation on completion of tier2") + || !op.addBoolOption('\0', "no-native-regexp", "Disable native regexp compilation") ++ || !op.addIntOption( ++ '\0', "regexp-warmup-threshold", "COUNT", ++ "Wait for COUNT invocations before compiling regexps to native code " ++ "(default 10)", ++ -1) + || !op.addBoolOption('\0', "no-unboxed-objects", "Disable creating unboxed plain objects") + || !op.addBoolOption('\0', "wasm-test-mode", "Enable wasm testing mode, creating synthetic " + "objects for non-canonical NaNs and i64 returned from wasm.") +diff -Nrup mozilla/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js mozilla-OK/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js +--- mozilla/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js 2023-02-27 08:15:57.814319072 +0300 +@@ -0,0 +1,12 @@ ++// Bug 1667094. ++ ++var obj = { ++ exec() { ++ return function(){}; ++ } ++}; ++ ++assertEq(RegExp.prototype.test.call(obj, ""), true); ++ ++if (typeof reportCompare === "function") ++ reportCompare(true, true); +diff -Nrup mozilla/js/src/tests/non262/extensions/bad-regexp-data-clone.js mozilla-OK/js/src/tests/non262/extensions/bad-regexp-data-clone.js +--- mozilla/js/src/tests/non262/extensions/bad-regexp-data-clone.js 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/tests/non262/extensions/bad-regexp-data-clone.js 2023-02-27 07:24:02.493415875 +0300 +@@ -0,0 +1,20 @@ ++// |reftest| skip-if(!xulRuntime.shell) ++// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++// Any copyright is dedicated to the Public Domain. ++// http://creativecommons.org/licenses/publicdomain/ ++ ++let data = new Uint8Array([ ++ 104,97,108,101,6,0,255,255,95,98, ++ 0,0,0,0,0,104,97,108,101,9,0,255, ++ 255,95,98,115,0,0,0,0,0,0,65,0,0, ++ 0,0,0,0,0,0,0,0,0,0,0,0,0 ++]); ++let cloneBuffer = serialize(null); ++cloneBuffer.clonebuffer = data.buffer; ++ ++// One of the bytes above encodes a JS::RegExpFlags, but that byte contains bits ++// outside of JS::RegExpFlag::AllFlags and so will trigger an error. ++assertThrowsInstanceOf(() => deserialize(cloneBuffer), InternalError); ++ ++if (typeof reportCompare === "function") ++ reportCompare(0, 0, 'ok'); +diff -Nrup mozilla/js/src/util/Text.cpp mozilla-OK/js/src/util/Text.cpp +--- mozilla/js/src/util/Text.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/util/Text.cpp 2023-02-27 07:24:43.173125915 +0300 +@@ -0,0 +1,37 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * vim: set ts=8 sts=2 et sw=2 tw=80: ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include "util/Text.h" ++ ++#include "mozilla/Assertions.h" ++#include "vm/Unicode.h" ++ ++using namespace JS; ++using namespace js; ++ ++size_t ++js::unicode::CountCodePoints(const char16_t* begin, const char16_t* end) ++{ ++ MOZ_ASSERT(begin <= end); ++ ++ size_t count = 0; ++ ++ const char16_t* ptr = begin; ++ while (ptr < end) { ++ count++; ++ ++ if (!IsLeadSurrogate(*ptr++)) { ++ continue; ++ } ++ ++ if (ptr < end && IsTrailSurrogate(*ptr)) { ++ ptr++; ++ } ++ } ++ MOZ_ASSERT(ptr == end, "should have consumed the full range"); ++ ++ return count; ++} +diff -Nrup mozilla/js/src/util/Text.h mozilla-OK/js/src/util/Text.h +--- mozilla/js/src/util/Text.h 1970-01-01 03:00:00.000000000 +0300 ++++ mozilla-OK/js/src/util/Text.h 2023-02-27 07:24:43.173125915 +0300 +@@ -0,0 +1,27 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- ++ * vim: set ts=8 sts=2 et sw=2 tw=80: ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#ifndef util_Text_h ++#define util_Text_h ++ ++#include ++ ++namespace js { ++ ++namespace unicode { ++/** ++ * Count the number of code points in [begin, end]. ++ * ++ * Every sequence of 16-bit units is considered valid. Lone surrogates are ++ * treated as if they represented a code point of the same value. ++ */ ++extern size_t ++CountCodePoints(const char16_t* begin, const char16_t* end); ++} // namespace unicode ++ ++} // namespace js ++ ++#endif // util_Text_h +diff -Nrup mozilla/js/src/vm/CommonPropertyNames.h mozilla-OK/js/src/vm/CommonPropertyNames.h +--- mozilla/js/src/vm/CommonPropertyNames.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/CommonPropertyNames.h 2023-02-27 07:46:51.312696208 +0300 +@@ -104,6 +104,7 @@ + macro(displayURL, displayURL, "displayURL") \ + macro(do, do_, "do") \ + macro(done, done, "done") \ ++ macro(dotAll, dotAll, "dotAll") \ + macro(dotGenerator, dotGenerator, ".generator") \ + macro(dotThis, dotThis, ".this") \ + macro(each, each, "each") \ +@@ -170,6 +171,7 @@ + macro(global, global, "global") \ + macro(globalThis, globalThis, "globalThis") \ + macro(group, group, "group") \ ++ macro(groups, groups, "groups") \ + macro(Handle, Handle, "Handle") \ + macro(has, has, "has") \ + macro(hasOwn, hasOwn, "hasOwn") \ +@@ -348,6 +350,7 @@ + macro(ReadableStreamTee, ReadableStreamTee, "ReadableStreamTee") \ + macro(reason, reason, "reason") \ + macro(RegExpFlagsGetter, RegExpFlagsGetter, "RegExpFlagsGetter") \ ++ macro(RegExpStringIterator, RegExpStringIterator, "RegExp String Iterator") \ + macro(Reify, Reify, "Reify") \ + macro(reject, reject, "reject") \ + macro(rejected, rejected, "rejected") \ +diff -Nrup mozilla/js/src/vm/GlobalObject.cpp mozilla-OK/js/src/vm/GlobalObject.cpp +--- mozilla/js/src/vm/GlobalObject.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/GlobalObject.cpp 2023-02-27 07:46:51.312696208 +0300 +@@ -488,63 +488,30 @@ GlobalObject::initSelfHostingBuiltins(JS + return false; + } + +- RootedValue std_isConcatSpreadable(cx); +- std_isConcatSpreadable.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::isConcatSpreadable)); +- if (!JS_DefineProperty(cx, global, "std_isConcatSpreadable", std_isConcatSpreadable, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { +- return false; +- } +- +- // Define a top-level property 'std_iterator' with the name of the method +- // used by for-of loops to create an iterator. +- RootedValue std_iterator(cx); +- std_iterator.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::iterator)); +- if (!JS_DefineProperty(cx, global, "std_iterator", std_iterator, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { +- return false; +- } +- +- RootedValue std_match(cx); +- std_match.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::match)); +- if (!JS_DefineProperty(cx, global, "std_match", std_match, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { +- return false; +- } +- +- RootedValue std_replace(cx); +- std_replace.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::replace)); +- if (!JS_DefineProperty(cx, global, "std_replace", std_replace, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { +- return false; +- } +- +- RootedValue std_search(cx); +- std_search.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::search)); +- if (!JS_DefineProperty(cx, global, "std_search", std_search, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { +- return false; +- } +- +- RootedValue std_species(cx); +- std_species.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::species)); +- if (!JS_DefineProperty(cx, global, "std_species", std_species, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { +- return false; +- } +- +- RootedValue std_split(cx); +- std_split.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::split)); +- if (!JS_DefineProperty(cx, global, "std_split", std_split, +- JSPROP_PERMANENT | JSPROP_READONLY)) +- { ++ struct SymbolAndName { ++ JS::SymbolCode code; ++ const char* name; ++ }; ++ ++ SymbolAndName wellKnownSymbols[] = { ++ {JS::SymbolCode::isConcatSpreadable, "std_isConcatSpreadable"}, ++ {JS::SymbolCode::iterator, "std_iterator"}, ++ {JS::SymbolCode::match, "std_match"}, ++ {JS::SymbolCode::matchAll, "std_matchAll"}, ++ {JS::SymbolCode::replace, "std_replace"}, ++ {JS::SymbolCode::search, "std_search"}, ++ {JS::SymbolCode::species, "std_species"}, ++ {JS::SymbolCode::split, "std_split"}, ++ }; ++ ++ RootedValue symVal(cx); ++ for (const auto& sym : wellKnownSymbols) { ++ symVal.setSymbol(cx->wellKnownSymbols().get(sym.code)); ++ if (!JS_DefineProperty(cx, global, sym.name, symVal, ++ JSPROP_PERMANENT | JSPROP_READONLY)) { + return false; + } ++ } + + return InitBareBuiltinCtor(cx, global, JSProto_Array) && + InitBareBuiltinCtor(cx, global, JSProto_TypedArray) && +diff -Nrup mozilla/js/src/vm/GlobalObject.h mozilla-OK/js/src/vm/GlobalObject.h +--- mozilla/js/src/vm/GlobalObject.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/GlobalObject.h 2023-02-27 07:46:51.313696201 +0300 +@@ -77,6 +77,7 @@ class GlobalObject : public NativeObject + ITERATOR_PROTO, + ARRAY_ITERATOR_PROTO, + STRING_ITERATOR_PROTO, ++ REGEXP_STRING_ITERATOR_PROTO, + GENERATOR_OBJECT_PROTO, + GENERATOR_FUNCTION_PROTO, + GENERATOR_FUNCTION, +@@ -580,6 +581,12 @@ class GlobalObject : public NativeObject + } + + static NativeObject* ++ getOrCreateRegExpStringIteratorPrototype(JSContext* cx, Handle global) { ++ return MaybeNativeObject(getOrCreateObject(cx, global, REGEXP_STRING_ITERATOR_PROTO, ++ initRegExpStringIteratorProto)); ++ } ++ ++ static NativeObject* + getOrCreateGeneratorObjectPrototype(JSContext* cx, Handle global) + { + return MaybeNativeObject(getOrCreateObject(cx, global, GENERATOR_OBJECT_PROTO, +@@ -765,6 +772,7 @@ class GlobalObject : public NativeObject + static bool initIteratorProto(JSContext* cx, Handle global); + static bool initArrayIteratorProto(JSContext* cx, Handle global); + static bool initStringIteratorProto(JSContext* cx, Handle global); ++ static bool initRegExpStringIteratorProto(JSContext* cx, Handle global); + + // Implemented in vm/GeneratorObject.cpp. + static bool initGenerators(JSContext* cx, Handle global); +diff -Nrup mozilla/js/src/vm/MatchPairs.h mozilla-OK/js/src/vm/MatchPairs.h +--- mozilla/js/src/vm/MatchPairs.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/MatchPairs.h 2023-02-27 08:15:51.417364380 +0300 +@@ -79,6 +79,7 @@ class MatchPairs + bool initArrayFrom(MatchPairs& copyFrom); + void forgetArray() { pairs_ = nullptr; } + ++ public: + void checkAgainst(size_t inputLength) { + #ifdef DEBUG + for (size_t i = 0; i < pairCount_; i++) { +@@ -91,7 +92,6 @@ class MatchPairs + #endif + } + +- public: + /* Querying functions in the style of RegExpStatics. */ + bool empty() const { return pairCount_ == 0; } + size_t pairCount() const { MOZ_ASSERT(pairCount_ > 0); return pairCount_; } +diff -Nrup mozilla/js/src/vm/MutexIDs.h mozilla-OK/js/src/vm/MutexIDs.h +--- mozilla/js/src/vm/MutexIDs.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/MutexIDs.h 2023-02-27 07:41:32.322958998 +0300 +@@ -50,6 +50,7 @@ + _(WasmStreamStatus, 500) \ + \ + _(IcuTimeZoneStateMutex, 600) \ ++ _(IrregexpLazyStatic, 600) \ + _(ThreadId, 600) \ + _(WasmCodeSegmentMap, 600) \ + _(TraceLoggerGraphState, 600) \ +diff -Nrup mozilla/js/src/vm/RegExpObject.cpp mozilla-OK/js/src/vm/RegExpObject.cpp +--- mozilla/js/src/vm/RegExpObject.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/RegExpObject.cpp 2023-02-27 08:16:08.336244561 +0300 +@@ -16,11 +16,9 @@ + #endif + + #include "builtin/RegExp.h" ++#include "builtin/SelfHostingDefines.h" + #include "frontend/TokenStream.h" +-#ifdef DEBUG +-#include "irregexp/RegExpBytecode.h" +-#endif +-#include "irregexp/RegExpParser.h" ++#include "irregexp/RegExpAPI.h" + #include "vm/MatchPairs.h" + #include "vm/RegExpStatics.h" + #include "vm/StringBuffer.h" +@@ -35,21 +33,33 @@ + #include "vm/NativeObject-inl.h" + #include "vm/Shape-inl.h" + ++#include "js/RegExp.h" ++#include "js/RegExpFlags.h" ++ + using namespace js; + + using mozilla::ArrayLength; + using mozilla::DebugOnly; + using mozilla::Maybe; + using mozilla::PodCopy; ++using JS::RegExpFlag; ++using JS::RegExpFlags; + using js::frontend::TokenStream; + + using JS::AutoCheckCannotGC; + +-JS_STATIC_ASSERT(IgnoreCaseFlag == JSREG_FOLD); +-JS_STATIC_ASSERT(GlobalFlag == JSREG_GLOB); +-JS_STATIC_ASSERT(MultilineFlag == JSREG_MULTILINE); +-JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY); +-JS_STATIC_ASSERT(UnicodeFlag == JSREG_UNICODE); ++static_assert(RegExpFlag::Global == REGEXP_GLOBAL_FLAG, ++ "self-hosted JS and /g flag bits must agree"); ++static_assert(RegExpFlag::IgnoreCase == REGEXP_IGNORECASE_FLAG, ++ "self-hosted JS and /i flag bits must agree"); ++static_assert(RegExpFlag::Multiline == REGEXP_MULTILINE_FLAG, ++ "self-hosted JS and /m flag bits must agree"); ++static_assert(RegExpFlag::DotAll == REGEXP_DOTALL_FLAG, ++ "self-hosted JS and /s flag bits must agree"); ++static_assert(RegExpFlag::Unicode == REGEXP_UNICODE_FLAG, ++ "self-hosted JS and /u flag bits must agree"); ++static_assert(RegExpFlag::Sticky == REGEXP_STICKY_FLAG, ++ "self-hosted JS and /y flag bits must agree"); + + RegExpObject* + js::RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto /* = nullptr */) +@@ -126,26 +136,30 @@ RegExpObject::getShared(JSContext* cx, H + } + + /* static */ bool +-RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlag* mask) ++RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlags* mask) + { + if (native == regexp_global) { +- *mask = GlobalFlag; ++ *mask = RegExpFlag::Global; + return true; + } + if (native == regexp_ignoreCase) { +- *mask = IgnoreCaseFlag; ++ *mask = RegExpFlag::IgnoreCase; + return true; + } + if (native == regexp_multiline) { +- *mask = MultilineFlag; ++ *mask = RegExpFlag::Multiline; + return true; + } + if (native == regexp_sticky) { +- *mask = StickyFlag; ++ *mask = RegExpFlag::Sticky; + return true; + } + if (native == regexp_unicode) { +- *mask = UnicodeFlag; ++ *mask = RegExpFlag::Unicode; ++ return true; ++ } ++ if (native == regexp_dotAll) { ++ *mask = RegExpFlag::DotAll; + return true; + } + +@@ -227,7 +241,7 @@ const Class RegExpObject::protoClass_ = + + template + RegExpObject* +-RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, ++RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlags flags, + frontend::TokenStreamAnyChars& tokenStream, LifoAlloc& alloc, + NewObjectKind newKind) + { +@@ -242,13 +256,13 @@ RegExpObject::create(JSContext* cx, cons + } + + template RegExpObject* +-RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags, ++RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlags flags, + frontend::TokenStreamAnyChars& tokenStream, LifoAlloc& alloc, + NewObjectKind newKind); + + template + RegExpObject* +-RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, ++RegExpObject::create(JSContext* cx, const CharT* chars, size_t length, RegExpFlags flags, + LifoAlloc& alloc, NewObjectKind newKind) + { + static_assert(mozilla::IsSame::value, +@@ -262,17 +276,17 @@ RegExpObject::create(JSContext* cx, cons + } + + template RegExpObject* +-RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags, ++RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlags flags, + LifoAlloc& alloc, NewObjectKind newKind); + + RegExpObject* +-RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags, ++RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlags flags, + frontend::TokenStreamAnyChars& tokenStream, + LifoAlloc& alloc, NewObjectKind newKind) + { +- if (!irregexp::ParsePatternSyntax(tokenStream, alloc, source, flags & UnicodeFlag)) ++ if (!irregexp::CheckPatternSyntax(cx, tokenStream, source, flags)) { + return nullptr; +- ++ } + Rooted regexp(cx, RegExpAlloc(cx, newKind)); + if (!regexp) + return nullptr; +@@ -283,15 +297,15 @@ RegExpObject::create(JSContext* cx, Hand + } + + RegExpObject* +-RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags, LifoAlloc& alloc, ++RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlags flags, LifoAlloc& alloc, + NewObjectKind newKind) + { + CompileOptions dummyOptions(cx); + TokenStream dummyTokenStream(cx, dummyOptions, (const char16_t*) nullptr, 0, nullptr); + +- if (!irregexp::ParsePatternSyntax(dummyTokenStream, alloc, source, flags & UnicodeFlag)) ++ if (!irregexp::CheckPatternSyntax(cx, dummyTokenStream, source, flags)) { + return nullptr; +- ++ } + Rooted regexp(cx, RegExpAlloc(cx, newKind)); + if (!regexp) + return nullptr; +@@ -327,7 +341,7 @@ RegExpObject::assignInitialShape(JSConte + } + + void +-RegExpObject::initIgnoringLastIndex(JSAtom* source, RegExpFlag flags) ++RegExpObject::initIgnoringLastIndex(JSAtom* source, RegExpFlags flags) + { + // If this is a re-initialization with an existing RegExpShared, 'flags' + // may not match getShared()->flags, so forget the RegExpShared. +@@ -338,7 +352,7 @@ RegExpObject::initIgnoringLastIndex(JSAt + } + + void +-RegExpObject::initAndZeroLastIndex(JSAtom* source, RegExpFlag flags, JSContext* cx) ++RegExpObject::initAndZeroLastIndex(JSAtom* source, RegExpFlags flags, JSContext* cx) + { + initIgnoringLastIndex(source, flags); + zeroLastIndex(cx); +@@ -527,406 +541,12 @@ RegExpObject::toString(JSContext* cx) co + return nullptr; + if (sticky() && !sb.append('y')) + return nullptr; ++ if (dotAll() && !sb.append('s')) ++ return nullptr; + + return sb.finishString(); + } + +-#ifdef DEBUG +-/* static */ bool +-RegExpShared::dumpBytecode(JSContext* cx, MutableHandleRegExpShared re, bool match_only, +- HandleLinearString input) +-{ +- CompilationMode mode = match_only ? MatchOnly : Normal; +- if (!RegExpShared::compileIfNecessary(cx, re, input, mode, ForceByteCode)) +- return false; +- +- const uint8_t* byteCode = re->compilation(mode, input->hasLatin1Chars()).byteCode; +- const uint8_t* pc = byteCode; +- +- auto Load32Aligned = [](const uint8_t* pc) -> int32_t { +- MOZ_ASSERT((reinterpret_cast(pc) & 3) == 0); +- return *reinterpret_cast(pc); +- }; +- +- auto Load16Aligned = [](const uint8_t* pc) -> int32_t { +- MOZ_ASSERT((reinterpret_cast(pc) & 1) == 0); +- return *reinterpret_cast(pc); +- }; +- +- int32_t numRegisters = Load32Aligned(pc); +- fprintf(stderr, "numRegisters: %d\n", numRegisters); +- pc += 4; +- +- fprintf(stderr, "loc op\n"); +- fprintf(stderr, "----- --\n"); +- +- auto DumpLower = [](const char* text) { +- while (*text) { +- fprintf(stderr, "%c", unicode::ToLowerCase(*text)); +- text++; +- } +- }; +- +-#define BYTECODE(NAME) \ +- case irregexp::BC_##NAME: \ +- DumpLower(#NAME); +-#define ADVANCE(NAME) \ +- fprintf(stderr, "\n"); \ +- pc += irregexp::BC_##NAME##_LENGTH; \ +- maxPc = js::Max(maxPc, pc); \ +- break; +-#define STOP(NAME) \ +- fprintf(stderr, "\n"); \ +- pc += irregexp::BC_##NAME##_LENGTH; \ +- break; +-#define JUMP(NAME, OFFSET) \ +- fprintf(stderr, "\n"); \ +- maxPc = js::Max(maxPc, byteCode + OFFSET); \ +- pc += irregexp::BC_##NAME##_LENGTH; \ +- break; +-#define BRANCH(NAME, OFFSET) \ +- fprintf(stderr, "\n"); \ +- pc += irregexp::BC_##NAME##_LENGTH; \ +- maxPc = js::Max(maxPc, js::Max(pc, byteCode + OFFSET)); \ +- break; +- +- // Bytecode has no end marker, we need to calculate the bytecode length by +- // tracing jumps and branches. +- const uint8_t* maxPc = pc; +- while (pc <= maxPc) { +- fprintf(stderr, "%05d: ", int32_t(pc - byteCode)); +- int32_t insn = Load32Aligned(pc); +- switch (insn & irregexp::BYTECODE_MASK) { +- BYTECODE(BREAK) { +- STOP(BREAK); +- } +- BYTECODE(PUSH_CP) { +- ADVANCE(PUSH_CP); +- } +- BYTECODE(PUSH_BT) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d", +- offset); +- // Pushed value is used by POP_BT for jumping. +- // Resolve maxPc here. +- BRANCH(PUSH_BT, offset); +- } +- BYTECODE(PUSH_REGISTER) { +- fprintf(stderr, " reg[%d]", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(PUSH_REGISTER); +- } +- BYTECODE(SET_REGISTER) { +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4)); +- ADVANCE(SET_REGISTER); +- } +- BYTECODE(ADVANCE_REGISTER) { +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4)); +- ADVANCE(ADVANCE_REGISTER); +- } +- BYTECODE(SET_REGISTER_TO_CP) { +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4)); +- ADVANCE(SET_REGISTER_TO_CP); +- } +- BYTECODE(SET_CP_TO_REGISTER) { +- fprintf(stderr, " reg[%d]", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(SET_CP_TO_REGISTER); +- } +- BYTECODE(SET_REGISTER_TO_SP) { +- fprintf(stderr, " reg[%d]", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(SET_REGISTER_TO_SP); +- } +- BYTECODE(SET_SP_TO_REGISTER) { +- fprintf(stderr, " reg[%d]", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(SET_SP_TO_REGISTER); +- } +- BYTECODE(POP_CP) { +- ADVANCE(POP_CP); +- } +- BYTECODE(POP_BT) { +- // Jump is already resolved in PUSH_BT. +- STOP(POP_BT); +- } +- BYTECODE(POP_REGISTER) { +- fprintf(stderr, " reg[%d]", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(POP_REGISTER); +- } +- BYTECODE(FAIL) { +- ADVANCE(FAIL); +- } +- BYTECODE(SUCCEED) { +- ADVANCE(SUCCEED); +- } +- BYTECODE(ADVANCE_CP) { +- fprintf(stderr, " %d", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(ADVANCE_CP); +- } +- BYTECODE(GOTO) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d", +- offset); +- JUMP(GOTO, offset); +- } +- BYTECODE(ADVANCE_CP_AND_GOTO) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- JUMP(ADVANCE_CP_AND_GOTO, offset); +- } +- BYTECODE(CHECK_GREEDY) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d", +- offset); +- BRANCH(CHECK_GREEDY, offset); +- } +- BYTECODE(LOAD_CURRENT_CHAR) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(LOAD_CURRENT_CHAR, offset); +- } +- BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) { +- fprintf(stderr, " %d", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(LOAD_CURRENT_CHAR_UNCHECKED); +- } +- BYTECODE(LOAD_2_CURRENT_CHARS) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(LOAD_2_CURRENT_CHARS, offset); +- } +- BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) { +- fprintf(stderr, " %d", +- insn >> irregexp::BYTECODE_SHIFT); +- ADVANCE(LOAD_2_CURRENT_CHARS_UNCHECKED); +- } +- BYTECODE(LOAD_4_CURRENT_CHARS) { +- ADVANCE(LOAD_4_CURRENT_CHARS); +- } +- BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) { +- ADVANCE(LOAD_4_CURRENT_CHARS_UNCHECKED); +- } +- BYTECODE(CHECK_4_CHARS) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d", +- Load32Aligned(pc + 4), +- offset); +- BRANCH(CHECK_4_CHARS, offset); +- } +- BYTECODE(CHECK_CHAR) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_CHAR, offset); +- } +- BYTECODE(CHECK_NOT_4_CHARS) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d", +- Load32Aligned(pc + 4), +- offset); +- BRANCH(CHECK_NOT_4_CHARS, offset); +- } +- BYTECODE(CHECK_NOT_CHAR) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_NOT_CHAR, offset); +- } +- BYTECODE(AND_CHECK_4_CHARS) { +- int32_t offset = Load32Aligned(pc + 12); +- fprintf(stderr, " %d, %d, %d", +- Load32Aligned(pc + 4), +- Load32Aligned(pc + 8), +- offset); +- BRANCH(AND_CHECK_4_CHARS, offset); +- } +- BYTECODE(AND_CHECK_CHAR) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4), +- offset); +- BRANCH(AND_CHECK_CHAR, offset); +- } +- BYTECODE(AND_CHECK_NOT_4_CHARS) { +- int32_t offset = Load32Aligned(pc + 12); +- fprintf(stderr, " %d, %d, %d", +- Load32Aligned(pc + 4), +- Load32Aligned(pc + 8), +- offset); +- BRANCH(AND_CHECK_NOT_4_CHARS, offset); +- } +- BYTECODE(AND_CHECK_NOT_CHAR) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4), +- offset); +- BRANCH(AND_CHECK_NOT_CHAR, offset); +- } +- BYTECODE(MINUS_AND_CHECK_NOT_CHAR) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d, %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load16Aligned(pc + 4), +- Load16Aligned(pc + 6), +- offset); +- BRANCH(MINUS_AND_CHECK_NOT_CHAR, offset); +- } +- BYTECODE(CHECK_CHAR_IN_RANGE) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d, %d", +- Load16Aligned(pc + 4), +- Load16Aligned(pc + 6), +- offset); +- BRANCH(CHECK_CHAR_IN_RANGE, offset); +- } +- BYTECODE(CHECK_CHAR_NOT_IN_RANGE) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " %d, %d, %d", +- Load16Aligned(pc + 4), +- Load16Aligned(pc + 6), +- offset); +- BRANCH(CHECK_CHAR_NOT_IN_RANGE, offset); +- } +- BYTECODE(CHECK_BIT_IN_TABLE) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, " +- "%02x %02x %02x %02x %02x %02x %02x %02x " +- "%02x %02x %02x %02x %02x %02x %02x %02x", +- offset, +- pc[8], pc[9], pc[10], pc[11], +- pc[12], pc[13], pc[14], pc[15], +- pc[16], pc[17], pc[18], pc[19], +- pc[20], pc[21], pc[22], pc[23]); +- BRANCH(CHECK_BIT_IN_TABLE, offset); +- } +- BYTECODE(CHECK_LT) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_LT, offset); +- } +- BYTECODE(CHECK_GT) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_GT, offset); +- } +- BYTECODE(CHECK_REGISTER_LT) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " reg[%d], %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4), +- offset); +- BRANCH(CHECK_REGISTER_LT, offset); +- } +- BYTECODE(CHECK_REGISTER_GE) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " reg[%d], %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4), +- offset); +- BRANCH(CHECK_REGISTER_GE, offset); +- } +- BYTECODE(CHECK_REGISTER_EQ_POS) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_REGISTER_EQ_POS, offset); +- } +- BYTECODE(CHECK_NOT_REGS_EQUAL) { +- int32_t offset = Load32Aligned(pc + 8); +- fprintf(stderr, " reg[%d], %d, %d", +- insn >> irregexp::BYTECODE_SHIFT, +- Load32Aligned(pc + 4), +- offset); +- BRANCH(CHECK_NOT_REGS_EQUAL, offset); +- } +- BYTECODE(CHECK_NOT_BACK_REF) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_NOT_BACK_REF, offset); +- } +- BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_NOT_BACK_REF_NO_CASE, offset); +- } +- BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_UNICODE) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " reg[%d], %d", +- insn >> irregexp::BYTECODE_SHIFT, +- offset); +- BRANCH(CHECK_NOT_BACK_REF_NO_CASE_UNICODE, offset); +- } +- BYTECODE(CHECK_AT_START) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d", +- offset); +- BRANCH(CHECK_AT_START, offset); +- } +- BYTECODE(CHECK_NOT_AT_START) { +- int32_t offset = Load32Aligned(pc + 4); +- fprintf(stderr, " %d", +- offset); +- BRANCH(CHECK_NOT_AT_START, offset); +- } +- BYTECODE(SET_CURRENT_POSITION_FROM_END) { +- fprintf(stderr, " %u", +- static_cast(insn) >> irregexp::BYTECODE_SHIFT); +- ADVANCE(SET_CURRENT_POSITION_FROM_END); +- } +- default: +- MOZ_CRASH("Bad bytecode"); +- } +- } +- +-#undef BYTECODE +-#undef ADVANCE +-#undef STOP +-#undef JUMP +-#undef BRANCH +- +- return true; +-} +- +-/* static */ bool +-RegExpObject::dumpBytecode(JSContext* cx, Handle regexp, +- bool match_only, HandleLinearString input) +-{ +- RootedRegExpShared shared(cx, getShared(cx, regexp)); +- if (!shared) +- return false; +- +- return RegExpShared::dumpBytecode(cx, &shared, match_only, input); +-} +-#endif +- + template + static MOZ_ALWAYS_INLINE bool + IsRegExpMetaChar(CharT ch) +@@ -971,8 +591,10 @@ js::StringHasRegExpMetaChars(JSLinearStr + + /* RegExpShared */ + +-RegExpShared::RegExpShared(JSAtom* source, RegExpFlag flags) +- : source(source), flags(flags), canStringMatch(false), parenCount(0) ++RegExpShared::RegExpShared(JSAtom* source, RegExpFlags flags) ++ : source(source) ++ , flags(flags) ++ , pairCount_(0) + {} + + void +@@ -983,8 +605,14 @@ RegExpShared::traceChildren(JSTracer* tr + discardJitCode(); + + TraceNullableEdge(trc, &source, "RegExpShared source"); +- for (auto& comp : compilationArray) +- TraceNullableEdge(trc, &comp.jitCode, "RegExpShared code"); ++ if (kind() == RegExpShared::Kind::Atom) { ++ TraceNullableEdge(trc, &patternAtom_, "RegExpShared pattern atom"); ++ } else { ++ for (auto& comp : compilationArray) { ++ TraceNullableEdge(trc, &comp.jitCode, "RegExpShared code"); ++ } ++ TraceNullableEdge(trc, &groupsTemplate_, "RegExpShared groups template"); ++ } + } + + void +@@ -997,219 +625,287 @@ RegExpShared::discardJitCode() + tables.clearAndFree(); + } + ++ + void + RegExpShared::finalize(FreeOp* fop) + { +- for (auto& comp : compilationArray) +- js_free(comp.byteCode); ++ for (auto& comp : compilationArray) { ++ if (comp.byteCode) { ++ js_free(comp.byteCode); ++ } ++ } ++ if (namedCaptureIndices_) { ++ js_free(namedCaptureIndices_); ++ } + tables.~JitCodeTables(); + } + +-/* static */ bool +-RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input, +- CompilationMode mode, ForceByteCodeEnum force) +-{ +- TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx); +- AutoTraceLog logCompile(logger, TraceLogger_IrregexpCompile); +- +- RootedAtom pattern(cx, re->source); +- return compile(cx, re, pattern, input, mode, force); +-} +- +-/* static */ bool +-RegExpShared::compile(JSContext* cx, MutableHandleRegExpShared re, HandleAtom pattern, +- HandleLinearString input, CompilationMode mode, ForceByteCodeEnum force) +-{ +- if (!re->ignoreCase() && !StringHasRegExpMetaChars(pattern)) +- re->canStringMatch = true; +- +- CompileOptions options(cx); +- frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); +- +- LifoAllocScope scope(&cx->tempLifoAlloc()); +- +- /* Parse the pattern. */ +- irregexp::RegExpCompileData data; +- if (!irregexp::ParsePattern(dummyTokenStream, cx->tempLifoAlloc(), pattern, +- re->multiline(), mode == MatchOnly, re->unicode(), +- re->ignoreCase(), re->global(), re->sticky(), &data)) +- { +- return false; ++/* static */ ++bool ++RegExpShared::compileIfNecessary(JSContext* cx, ++ MutableHandleRegExpShared re, ++ HandleLinearString input, ++ RegExpShared::CodeKind codeKind) ++{ ++ if (codeKind == RegExpShared::CodeKind::Any) { ++ // We start by interpreting regexps, then compile them once they are ++ // sufficiently hot. For very long input strings, we tier up eagerly. ++ codeKind = RegExpShared::CodeKind::Bytecode; ++ if (re->markedForTierUp(cx) || input->length() > 1000) { ++ codeKind = RegExpShared::CodeKind::Jitcode; + } ++ } + +- re->parenCount = data.capture_count; +- +- JitCodeTables tables; +- irregexp::RegExpCode code = irregexp::CompilePattern(cx, re, &data, input, +- false /* global() */, +- re->ignoreCase(), +- input->hasLatin1Chars(), +- mode == MatchOnly, +- force == ForceByteCode, +- re->sticky(), +- re->unicode(), +- tables); +- if (code.empty()) +- return false; ++ // Fall back to bytecode if native codegen is not available. ++ if (!IsNativeRegExpEnabled(cx) && codeKind == RegExpShared::CodeKind::Jitcode) { ++ codeKind = RegExpShared::CodeKind::Bytecode; ++ } + +- MOZ_ASSERT(!code.jitCode || !code.byteCode); +- MOZ_ASSERT_IF(force == ForceByteCode, code.byteCode); ++ bool needsCompile = false; ++ if (re->kind() == RegExpShared::Kind::Unparsed) { ++ needsCompile = true; ++ } + +- RegExpCompilation& compilation = re->compilation(mode, input->hasLatin1Chars()); +- if (code.jitCode) { +- // First copy the tables. GC can purge the tables if the RegExpShared +- // has no JIT code, so it's important to do this right before setting +- // compilation.jitCode (to ensure no purging happens between adding the +- // tables and setting the JIT code). +- for (size_t i = 0; i < tables.length(); i++) { +- if (!re->addTable(Move(tables[i]))) +- return false; +- } +- compilation.jitCode = code.jitCode; +- } else if (code.byteCode) { +- MOZ_ASSERT(tables.empty(), "RegExpInterpreter does not use data tables"); +- compilation.byteCode = code.byteCode; ++ if (re->kind() == RegExpShared::Kind::RegExp) { ++ if (!re->isCompiled(input->hasLatin1Chars(), codeKind)) { ++ needsCompile = true; + } ++ } + +- return true; +-} +- +-/* static */ bool +-RegExpShared::compileIfNecessary(JSContext* cx, MutableHandleRegExpShared re, +- HandleLinearString input, CompilationMode mode, +- ForceByteCodeEnum force) +-{ +- if (re->isCompiled(mode, input->hasLatin1Chars(), force)) +- return true; +- return compile(cx, re, input, mode, force); ++ if (needsCompile) { ++ return irregexp::CompilePattern(cx, re, input, codeKind); ++ } ++ return true; + } + +-/* static */ RegExpRunStatus +-RegExpShared::execute(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input, +- size_t start, MatchPairs* matches, size_t* endIndex) ++/* static */ ++RegExpRunStatus ++RegExpShared::execute(JSContext* cx, ++ MutableHandleRegExpShared re, ++ HandleLinearString input, ++ size_t start, ++ MatchPairs* matches) + { +- MOZ_ASSERT_IF(matches, !endIndex); +- MOZ_ASSERT_IF(!matches, endIndex); +- TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx); ++ MOZ_ASSERT(matches); + +- CompilationMode mode = matches ? Normal : MatchOnly; ++ // TODO: Add tracelogger support + + /* Compile the code at point-of-use. */ +- if (!compileIfNecessary(cx, re, input, mode, DontForceByteCode)) ++ if (!compileIfNecessary(cx, re, input, RegExpShared::CodeKind::Any)) { + return RegExpRunStatus_Error; ++ } + + /* + * Ensure sufficient memory for output vector. + * No need to initialize it. The RegExp engine fills them in on a match. + */ +- if (matches && !matches->allocOrExpandArray(re->pairCount())) { ++ if (!matches->allocOrExpandArray(re->pairCount())) { + ReportOutOfMemory(cx); + return RegExpRunStatus_Error; + } + +- size_t length = input->length(); ++ if (re->kind() == RegExpShared::Kind::Atom) { ++ return RegExpShared::executeAtom(re, input, start, matches); ++ } + +- // Reset the Irregexp backtrack stack if it grows during execution. +- irregexp::RegExpStackScope stackScope(cx); ++ /* ++ * Ensure sufficient memory for output vector. ++ * No need to initialize it. The RegExp engine fills them in on a match. ++ */ ++ if (!matches->allocOrExpandArray(re->pairCount())) { ++ ReportOutOfMemory(cx); ++ return RegExpRunStatus_Error; ++ } ++ ++ uint32_t interruptRetries = 0; ++ const uint32_t maxInterruptRetries = 4; ++ do { ++ RegExpRunStatus result = irregexp::Execute(cx, re, input, start, matches); + +- if (re->canStringMatch) { +- MOZ_ASSERT(re->pairCount() == 1); +- size_t sourceLength = re->source->length(); +- if (re->sticky()) { +- // First part checks size_t overflow. +- if (sourceLength + start < sourceLength || sourceLength + start > length) +- return RegExpRunStatus_Success_NotFound; +- if (!HasSubstringAt(input, re->source, start)) +- return RegExpRunStatus_Success_NotFound; +- +- if (matches) { +- (*matches)[0].start = start; +- (*matches)[0].limit = start + sourceLength; +- +- matches->checkAgainst(length); +- } else if (endIndex) { +- *endIndex = start + sourceLength; ++ if (result == RegExpRunStatus_Error) { ++ /* Execute can return RegExpRunStatus_Error: ++ * ++ * 1. If the native stack overflowed ++ * 2. If the backtrack stack overflowed ++ * 3. If an interrupt was requested during execution. ++ * ++ * In the first two cases, we want to throw an error. In the ++ * third case, we want to handle the interrupt and try again. ++ * We cap the number of times we will retry. ++ */ ++ if (cx->hasPendingInterrupt()) { ++ if (!CheckForInterrupt(cx)) { ++ return RegExpRunStatus_Error; ++ } ++ if (interruptRetries++ < maxInterruptRetries) { ++ // The initial execution may have been interpreted, or the ++ // interrupt may have triggered a GC that discarded jitcode. ++ // To maximize the chance of succeeding before being ++ // interrupted again, we want to ensure we are compiled. ++ if (!compileIfNecessary(cx, re, input, ++ RegExpShared::CodeKind::Jitcode)) { ++ return RegExpRunStatus_Error; ++ } ++ continue; + } +- return RegExpRunStatus_Success; ++ } ++ // If we have run out of retries, this regexp takes too long to ++ // execute. ++ ReportOverRecursed(cx); ++ return RegExpRunStatus_Error; + } + +- int res = StringFindPattern(input, re->source, start); +- if (res == -1) +- return RegExpRunStatus_Success_NotFound; ++ MOZ_ASSERT(result == RegExpRunStatus_Success || ++ result == RegExpRunStatus_Success_NotFound); + +- if (matches) { +- (*matches)[0].start = res; +- (*matches)[0].limit = res + sourceLength; +- +- matches->checkAgainst(length); +- } else if (endIndex) { +- *endIndex = res + sourceLength; +- } +- return RegExpRunStatus_Success; ++ return result; ++ } while (true); ++ ++ MOZ_CRASH("Unreachable"); ++} ++ ++void RegExpShared::useAtomMatch(HandleAtom pattern) { ++ MOZ_ASSERT(kind() == RegExpShared::Kind::Unparsed); ++ kind_ = RegExpShared::Kind::Atom; ++ patternAtom_ = pattern; ++ pairCount_ = 1; ++} ++ ++void RegExpShared::useRegExpMatch(size_t pairCount) { ++ MOZ_ASSERT(kind() == RegExpShared::Kind::Unparsed); ++ kind_ = RegExpShared::Kind::RegExp; ++ pairCount_ = pairCount; ++ ticks_ = jit::JitOptions.regexpWarmUpThreshold; ++} ++ ++/* static */ ++bool ++RegExpShared::initializeNamedCaptures(JSContext* cx, ++ HandleRegExpShared re, ++ HandleNativeObject namedCaptures) ++{ ++ MOZ_ASSERT(!re->groupsTemplate_); ++ MOZ_ASSERT(!re->namedCaptureIndices_); ++ ++ // The irregexp parser returns named capture information in the form ++ // of an ArrayObject, where even elements store the capture name and ++ // odd elements store the corresponding capture index. We create a ++ // template object with a property for each capture name, and store ++ // the capture indices as a heap-allocated array. ++ MOZ_ASSERT(namedCaptures->getDenseInitializedLength() % 2 == 0); ++ uint32_t numNamedCaptures = namedCaptures->getDenseInitializedLength() / 2; ++ ++ // Create a plain template object. ++ RootedPlainObject templateObject(cx, NewObjectWithGivenProto(cx, nullptr, TenuredObject)); ++ if (!templateObject) { ++ return false; + } + +- do { +- jit::JitCode* code = re->compilation(mode, input->hasLatin1Chars()).jitCode; +- if (!code) +- break; ++ // Create a new group for the template. ++ Rooted proto(cx, templateObject->taggedProto()); ++ ObjectGroup* group = ++ ObjectGroupCompartment::makeGroup(cx, templateObject->getClass(), proto); ++ if (!group) { ++ return false; ++ } ++ templateObject->setGroup(group); + +- RegExpRunStatus result; +- { +- AutoTraceLog logJIT(logger, TraceLogger_IrregexpExecute); +- AutoCheckCannotGC nogc; +- if (input->hasLatin1Chars()) { +- const Latin1Char* chars = input->latin1Chars(nogc); +- result = irregexp::ExecuteCode(cx, code, chars, start, length, matches, endIndex); +- } else { +- const char16_t* chars = input->twoByteChars(nogc); +- result = irregexp::ExecuteCode(cx, code, chars, start, length, matches, endIndex); +- } ++ // Initialize the properties of the template. ++ RootedId id(cx); ++ RootedValue dummyString(cx, StringValue(cx->runtime()->emptyString)); ++ for (uint32_t i = 0; i < numNamedCaptures; i++) { ++ JSString* name = namedCaptures->getDenseElement(i * 2).toString(); ++ id = NameToId(name->asAtom().asPropertyName()); ++ if (!NativeDefineProperty( ++ cx, templateObject, id, dummyString, nullptr, nullptr, JSPROP_ENUMERATE)) { ++ return false; + } ++ AddTypePropertyId(cx, templateObject, id, UndefinedValue()); ++ } + +- if (result == RegExpRunStatus_Error) { +- // An 'Error' result is returned if a stack overflow guard or +- // interrupt guard failed. If CheckOverRecursed doesn't throw, break +- // out and retry the regexp in the bytecode interpreter, which can +- // execute while tolerating future interrupts. Otherwise, if we keep +- // getting interrupted we will never finish executing the regexp. +- if (!jit::CheckOverRecursed(cx)) +- return RegExpRunStatus_Error; +- break; +- } ++ // Allocate the capture index array. ++ uint32_t arraySize = numNamedCaptures * sizeof(uint32_t); ++ uint32_t* captureIndices = static_cast(js_malloc(arraySize)); ++ if (!captureIndices) { ++ ReportOutOfMemory(cx); ++ return false; ++ } + +- if (result == RegExpRunStatus_Success_NotFound) +- return RegExpRunStatus_Success_NotFound; ++ // Populate the capture index array ++ for (uint32_t i = 0; i < numNamedCaptures; i++) { ++ captureIndices[i] = namedCaptures->getDenseElement(i * 2 + 1).toInt32(); ++ } + +- MOZ_ASSERT(result == RegExpRunStatus_Success); ++ re->numNamedCaptures_ = numNamedCaptures; ++ re->groupsTemplate_ = templateObject; ++ re->namedCaptureIndices_ = captureIndices; ++ // js::AddCellMemory(re, arraySize, MemoryUse::RegExpSharedNamedCaptureData); ++ return true; ++} + +- if (matches) +- matches->checkAgainst(length); +- return RegExpRunStatus_Success; +- } while (false); ++void RegExpShared::tierUpTick() { ++ MOZ_ASSERT(kind() == RegExpShared::Kind::RegExp); ++ if (ticks_ > 0) { ++ ticks_--; ++ } ++} + +- // Compile bytecode for the RegExp if necessary. +- if (!compileIfNecessary(cx, re, input, mode, ForceByteCode)) +- return RegExpRunStatus_Error; ++bool RegExpShared::markedForTierUp(JSContext* cx) const { ++ if (!IsNativeRegExpEnabled(cx)) { ++ return false; ++ } ++ if (kind() != RegExpShared::Kind::RegExp) { ++ return false; ++ } ++ return ticks_ == 0; ++} + +- uint8_t* byteCode = re->compilation(mode, input->hasLatin1Chars()).byteCode; +- AutoTraceLog logInterpreter(logger, TraceLogger_IrregexpExecute); ++/* static */ ++RegExpRunStatus ExecuteAtomImpl(RegExpShared* re, JSLinearString* input, ++ size_t start, MatchPairs* matches) ++{ ++ MOZ_ASSERT(re->pairCount() == 1); ++ size_t length = input->length(); ++ size_t searchLength = re->patternAtom()->length(); + +- AutoStableStringChars inputChars(cx); +- if (!inputChars.init(cx, input)) +- return RegExpRunStatus_Error; ++ if (re->sticky()) { ++ // First part checks size_t overflow. ++ if (searchLength + start < searchLength || searchLength + start > length) { ++ return RegExpRunStatus_Success_NotFound; ++ } ++ if (!HasSubstringAt(input, re->patternAtom(), start)) { ++ return RegExpRunStatus_Success_NotFound; ++ } + +- RegExpRunStatus result; +- if (inputChars.isLatin1()) { +- const Latin1Char* chars = inputChars.latin1Range().begin().get(); +- result = irregexp::InterpretCode(cx, byteCode, chars, start, length, matches, endIndex); +- } else { +- const char16_t* chars = inputChars.twoByteRange().begin().get(); +- result = irregexp::InterpretCode(cx, byteCode, chars, start, length, matches, endIndex); ++ (*matches)[0].start = start; ++ (*matches)[0].limit = start + searchLength; ++ matches->checkAgainst(input->length()); ++ return RegExpRunStatus_Success; ++ } ++ ++ int res = StringFindPattern(input, re->patternAtom(), start); ++ if (res == -1) { ++ return RegExpRunStatus_Success_NotFound; + } + +- if (result == RegExpRunStatus_Success && matches) +- matches->checkAgainst(length); +- return result; ++ (*matches)[0].start = res; ++ (*matches)[0].limit = res + searchLength; ++ matches->checkAgainst(input->length()); ++ return RegExpRunStatus_Success; ++} ++ ++RegExpRunStatus js::ExecuteRegExpAtomRaw(RegExpShared* re, ++ JSLinearString* input, size_t start, ++ MatchPairs* matchPairs) { ++ JS::AutoCheckCannotGC nogc; ++ return ExecuteAtomImpl(re, input, start, matchPairs); ++} ++ ++/* static */ ++RegExpRunStatus RegExpShared::executeAtom(MutableHandleRegExpShared re, ++ HandleLinearString input, ++ size_t start, MatchPairs* matches) { ++ return ExecuteAtomImpl(re, input, start, matches); + } + + size_t +@@ -1246,14 +942,16 @@ RegExpCompartment::createMatchResultTemp + /* Create template array object */ + RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount, + nullptr, TenuredObject)); +- if (!templateObject) +- return matchResultTemplateObject_; // = nullptr ++ if (!templateObject) { ++ return nullptr; ++ } + + // Create a new group for the template. + Rooted proto(cx, templateObject->taggedProto()); + ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, templateObject->getClass(), proto); +- if (!group) +- return matchResultTemplateObject_; // = nullptr ++ if (!group) { ++ return nullptr; ++ } + templateObject->setGroup(group); + + /* Set dummy index property */ +@@ -1261,23 +959,36 @@ RegExpCompartment::createMatchResultTemp + if (!NativeDefineProperty(cx, templateObject, cx->names().index, index, nullptr, nullptr, + JSPROP_ENUMERATE)) + { +- return matchResultTemplateObject_; // = nullptr ++ return nullptr; + } + + /* Set dummy input property */ + RootedValue inputVal(cx, StringValue(cx->runtime()->emptyString)); +- if (!NativeDefineProperty(cx, templateObject, cx->names().input, inputVal, nullptr, nullptr, +- JSPROP_ENUMERATE)) +- { +- return matchResultTemplateObject_; // = nullptr ++ if (!NativeDefineProperty( ++ cx, templateObject, cx->names().input, inputVal, nullptr, nullptr, JSPROP_ENUMERATE)) { ++ return nullptr; + } + ++ /* Set dummy groups property */ ++ RootedValue groupsVal(cx, UndefinedValue()); ++ if (!NativeDefineProperty( ++ cx, templateObject, cx->names().groups, groupsVal, nullptr, nullptr, JSPROP_ENUMERATE)) { ++ return nullptr; ++ } ++ AddTypePropertyId(cx, templateObject, NameToId(cx->names().groups), TypeSet::AnyObjectType()); ++ + // Make sure that the properties are in the right slots. +- DebugOnly shape = templateObject->lastProperty(); +- MOZ_ASSERT(shape->previous()->slot() == 0 && +- shape->previous()->propidRef() == NameToId(cx->names().index)); +- MOZ_ASSERT(shape->slot() == 1 && +- shape->propidRef() == NameToId(cx->names().input)); ++#ifdef DEBUG ++ Shape* groupsShape = templateObject->lastProperty(); ++ MOZ_ASSERT(groupsShape->slot() == 0 && ++ groupsShape->propidRef() == NameToId(cx->names().groups)); ++ Shape* inputShape = groupsShape->previous().get(); ++ MOZ_ASSERT(inputShape->slot() == 1 && ++ inputShape->propidRef() == NameToId(cx->names().input)); ++ Shape* indexShape = inputShape->previous().get(); ++ MOZ_ASSERT(indexShape->slot() == 2 && ++ indexShape->propidRef() == NameToId(cx->names().index)); ++#endif + + // Make sure type information reflects the indexed properties which might + // be added. +@@ -1321,7 +1032,7 @@ RegExpCompartment::sweep() + } + + RegExpShared* +-RegExpZone::get(JSContext* cx, HandleAtom source, RegExpFlag flags) ++RegExpZone::get(JSContext* cx, HandleAtom source, RegExpFlags flags) + { + DependentAddPtr p(cx, set_, Key(source, flags)); + if (p) +@@ -1344,7 +1055,7 @@ RegExpZone::get(JSContext* cx, HandleAto + RegExpShared* + RegExpZone::get(JSContext* cx, HandleAtom atom, JSString* opt) + { +- RegExpFlag flags = RegExpFlag(0); ++ RegExpFlags flags = RegExpFlag::NoFlags; + if (opt && !ParseRegExpFlags(cx, opt, &flags)) + return nullptr; + +@@ -1388,27 +1099,30 @@ js::CloneRegExpObject(JSContext* cx, Han + + template + static bool +-ParseRegExpFlags(const CharT* chars, size_t length, RegExpFlag* flagsOut, char16_t* invalidFlag) ++ParseRegExpFlags(const CharT* chars, size_t length, RegExpFlags* flagsOut, char16_t* invalidFlag) + { +- *flagsOut = RegExpFlag(0); ++ *flagsOut = RegExpFlag::NoFlags; + + for (size_t i = 0; i < length; i++) { +- RegExpFlag flag; ++ uint8_t flag; + switch (chars[i]) { + case 'i': +- flag = IgnoreCaseFlag; ++ flag = RegExpFlag::IgnoreCase; + break; + case 'g': +- flag = GlobalFlag; ++ flag = RegExpFlag::Global; + break; + case 'm': +- flag = MultilineFlag; ++ flag = RegExpFlag::Multiline; + break; + case 'y': +- flag = StickyFlag; ++ flag = RegExpFlag::Sticky; + break; + case 'u': +- flag = UnicodeFlag; ++ flag = RegExpFlag::Unicode; ++ break; ++ case 's': ++ flag = RegExpFlag::DotAll; + break; + default: + *invalidFlag = chars[i]; +@@ -1418,14 +1132,14 @@ ParseRegExpFlags(const CharT* chars, siz + *invalidFlag = chars[i]; + return false; + } +- *flagsOut = RegExpFlag(*flagsOut | flag); ++ *flagsOut = RegExpFlags(*flagsOut | flag); + } + + return true; + } + + bool +-js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut) ++js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlags* flagsOut) + { + JSLinearString* linear = flagStr->ensureLinear(cx); + if (!linear) +@@ -1445,7 +1159,7 @@ js::ParseRegExpFlags(JSContext* cx, JSSt + + if (!ok) { + TwoByteChars range(&invalidFlag, 1); +- UniqueChars utf8(JS::CharsToNewUTF8CharsZ(nullptr, range).c_str()); ++ UniqueChars utf8(JS::CharsToNewUTF8CharsZ(cx, range).c_str()); + if (!utf8) + return false; + JS_ReportErrorFlagsAndNumberUTF8(cx, JSREPORT_ERROR, GetErrorMessage, nullptr, +@@ -1463,18 +1177,18 @@ js::XDRScriptRegExpObject(XDRState + /* NB: Keep this in sync with CloneScriptRegExpObject. */ + + RootedAtom source(xdr->cx()); +- uint32_t flagsword = 0; ++ uint8_t flags = 0; + + if (mode == XDR_ENCODE) { + MOZ_ASSERT(objp); + RegExpObject& reobj = *objp; + source = reobj.getSource(); +- flagsword = reobj.getFlags(); ++ flags = reobj.getFlags().value(); + } +- if (!XDRAtom(xdr, &source) || !xdr->codeUint32(&flagsword)) ++ if (!XDRAtom(xdr, &source) || !xdr->codeUint8(&flags)) + return false; + if (mode == XDR_DECODE) { +- RegExpObject* reobj = RegExpObject::create(xdr->cx(), source, RegExpFlag(flagsword), ++ RegExpObject* reobj = RegExpObject::create(xdr->cx(), source, RegExpFlags(flags), + xdr->lifoAlloc(), TenuredObject); + if (!reobj) + return false; +@@ -1513,3 +1227,162 @@ JS::ubi::Concrete::size(mo + return js::gc::Arena::thingSize(gc::AllocKind::REGEXP_SHARED) + + get().sizeOfExcludingThis(mallocSizeOf); + } ++ ++/* ++ * Public API functions for Regular Expressions. ++ */ ++JS_PUBLIC_API(JSObject*) ++JS::NewRegExpObject(JSContext* cx, const char* bytes, size_t length, RegExpFlags flags) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ ScopedJSFreePtr chars(InflateString(cx, bytes, length)); ++ if (!chars) ++ return nullptr; ++ ++ return RegExpObject::create(cx, chars.get(), length, flags, cx->tempLifoAlloc(), ++ GenericObject); ++} ++ ++JS_PUBLIC_API(JSObject*) ++JS::NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, RegExpFlags flags) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ return RegExpObject::create(cx, chars, length, flags, cx->tempLifoAlloc(), ++ GenericObject); ++} ++ ++JS_PUBLIC_API(bool) ++JS::SetRegExpInput(JSContext* cx, HandleObject obj, HandleString input) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ assertSameCompartment(cx, input); ++ ++ Handle global = obj.as(); ++ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); ++ if (!res) ++ return false; ++ ++ res->reset(input); ++ return true; ++} ++ ++JS_PUBLIC_API(bool) ++JS::ClearRegExpStatics(JSContext* cx, HandleObject obj) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ MOZ_ASSERT(obj); ++ ++ Handle global = obj.as(); ++ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); ++ if (!res) ++ return false; ++ ++ res->clear(); ++ return true; ++} ++ ++JS_PUBLIC_API(bool) ++JS::ExecuteRegExp(JSContext* cx, HandleObject obj, HandleObject reobj, char16_t* chars, ++ size_t length, size_t* indexp, bool test, MutableHandleValue rval) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ Handle global = obj.as(); ++ RegExpStatics* res = GlobalObject::getRegExpStatics(cx, global); ++ if (!res) ++ return false; ++ ++ RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); ++ if (!input) ++ return false; ++ ++ return ExecuteRegExpLegacy(cx, res, reobj.as(), input, indexp, test, rval); ++} ++ ++JS_PUBLIC_API(bool) ++JS::ExecuteRegExpNoStatics(JSContext* cx, HandleObject obj, char16_t* chars, size_t length, ++ size_t* indexp, bool test, MutableHandleValue rval) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ RootedLinearString input(cx, NewStringCopyN(cx, chars, length)); ++ if (!input) ++ return false; ++ ++ return ExecuteRegExpLegacy(cx, nullptr, obj.as(), input, indexp, test, ++ rval); ++} ++ ++JS_PUBLIC_API(bool) ++JS::ObjectIsRegExp(JSContext* cx, HandleObject obj, bool* isRegExp) ++{ ++ assertSameCompartment(cx, obj); ++ ++ ESClass cls; ++ if (!GetBuiltinClass(cx, obj, &cls)) ++ return false; ++ ++ *isRegExp = cls == ESClass::RegExp; ++ return true; ++} ++ ++JS_PUBLIC_API(RegExpFlags) ++JS::GetRegExpFlags(JSContext* cx, HandleObject obj) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ RegExpShared* shared = RegExpToShared(cx, obj); ++ if (!shared) ++ return RegExpFlag::NoFlags; ++ return shared->getFlags(); ++} ++ ++JS_PUBLIC_API(JSString*) ++JS::GetRegExpSource(JSContext* cx, HandleObject obj) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ RegExpShared* shared = RegExpToShared(cx, obj); ++ if (!shared) ++ return nullptr; ++ return shared->getSource(); ++} ++ ++JS_PUBLIC_API(bool) ++JS::CheckRegExpSyntax(JSContext* cx, ++ const char16_t* chars, ++ size_t length, ++ RegExpFlags flags, ++ MutableHandleValue error) ++{ ++ AssertHeapIsIdle(); ++ CHECK_REQUEST(cx); ++ ++ CompileOptions options(cx); ++ frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr); ++ ++ mozilla::Range source(chars, length); ++ bool success = irregexp::CheckPatternSyntax(cx, dummyTokenStream, source, flags); ++ error.set(UndefinedValue()); ++ if (!success) { ++ // We can fail because of OOM or over-recursion even if the syntax is valid. ++ if (cx->isThrowingOutOfMemory() || cx->isThrowingOverRecursed()) { ++ return false; ++ } ++ if (!cx->getPendingException(error)) { ++ return false; ++ } ++ cx->clearPendingException(); ++ } ++ return true; ++} +diff -Nrup mozilla/js/src/vm/RegExpObject.h mozilla-OK/js/src/vm/RegExpObject.h +--- mozilla/js/src/vm/RegExpObject.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/RegExpObject.h 2023-02-27 08:10:08.165795466 +0300 +@@ -17,6 +17,7 @@ + #include "builtin/SelfHostingDefines.h" + #include "gc/Marking.h" + #include "js/GCHashTable.h" ++#include "js/RegExpFlags.h" + #include "proxy/Proxy.h" + #include "vm/ArrayObject.h" + #include "vm/RegExpShared.h" +@@ -73,20 +74,20 @@ class RegExpObject : public NativeObject + + template + static RegExpObject* +- create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, LifoAlloc& alloc, ++ create(JSContext* cx, const CharT* chars, size_t length, JS::RegExpFlags flags, LifoAlloc& alloc, + NewObjectKind newKind); + + template + static RegExpObject* +- create(JSContext* cx, const CharT* chars, size_t length, RegExpFlag flags, ++ create(JSContext* cx, const CharT* chars, size_t length, JS::RegExpFlags flags, + frontend::TokenStreamAnyChars& ts, LifoAlloc& alloc, NewObjectKind kind); + + static RegExpObject* +- create(JSContext* cx, HandleAtom atom, RegExpFlag flags, LifoAlloc& alloc, ++ create(JSContext* cx, HandleAtom atom, JS::RegExpFlags flags, LifoAlloc& alloc, + NewObjectKind newKind); + + static RegExpObject* +- create(JSContext* cx, HandleAtom atom, RegExpFlag flags, frontend::TokenStreamAnyChars& ts, ++ create(JSContext* cx, HandleAtom atom, JS::RegExpFlags flags, frontend::TokenStreamAnyChars& ts, + LifoAlloc& alloc, NewObjectKind newKind); + + /* +@@ -135,25 +136,28 @@ class RegExpObject : public NativeObject + + static unsigned flagsSlot() { return FLAGS_SLOT; } + +- RegExpFlag getFlags() const { +- return RegExpFlag(getFixedSlot(FLAGS_SLOT).toInt32()); +- } +- void setFlags(RegExpFlag flags) { +- setSlot(FLAGS_SLOT, Int32Value(flags)); +- } ++ JS::RegExpFlags getFlags() const ++ { ++ return JS::RegExpFlags(getFixedSlot(FLAGS_SLOT).toInt32()); ++ } ++ void setFlags(JS::RegExpFlags flags) { setFixedSlot(FLAGS_SLOT, Int32Value(flags.value())); }; ++ ++ bool global() const { return getFlags().global(); } ++ bool ignoreCase() const { return getFlags().ignoreCase(); } ++ bool multiline() const { return getFlags().multiline(); } ++ bool dotAll() const { return getFlags().dotAll(); } ++ bool unicode() const { return getFlags().unicode(); } ++ bool sticky() const { return getFlags().sticky(); } + +- bool ignoreCase() const { return getFlags() & IgnoreCaseFlag; } +- bool global() const { return getFlags() & GlobalFlag; } +- bool multiline() const { return getFlags() & MultilineFlag; } +- bool sticky() const { return getFlags() & StickyFlag; } +- bool unicode() const { return getFlags() & UnicodeFlag; } +- +- static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask); ++ static bool isOriginalFlagGetter(JSNative native, JS::RegExpFlags* mask); + + static RegExpShared* getShared(JSContext* cx, Handle regexp); + +- bool hasShared() { +- return !!sharedRef(); ++ bool hasShared() const { return !!sharedRef(); } ++ ++ RegExpShared* getShared() const { ++ MOZ_ASSERT(hasShared()); ++ return sharedRef(); + } + + void setShared(RegExpShared& shared) { +@@ -161,7 +165,7 @@ class RegExpObject : public NativeObject + sharedRef().init(&shared); + } + +- PreBarriered& sharedRef() { ++ PreBarriered& sharedRef() const { + auto& ref = NativeObject::privateRef(PRIVATE_SLOT); + return reinterpret_cast&>(ref); + } +@@ -169,16 +173,17 @@ class RegExpObject : public NativeObject + static void trace(JSTracer* trc, JSObject* obj); + void trace(JSTracer* trc); + +- void initIgnoringLastIndex(JSAtom* source, RegExpFlag flags); ++ void initIgnoringLastIndex(JSAtom* source, JS::RegExpFlags flags); + + // NOTE: This method is *only* safe to call on RegExps that haven't been + // exposed to script, because it requires that the "lastIndex" + // property be writable. +- void initAndZeroLastIndex(JSAtom* source, RegExpFlag flags, JSContext* cx); ++ void initAndZeroLastIndex(JSAtom* source, JS::RegExpFlags flags, JSContext* cx); + + #ifdef DEBUG +- static MOZ_MUST_USE bool dumpBytecode(JSContext* cx, Handle regexp, +- bool match_only, HandleLinearString input); ++ static MOZ_MUST_USE bool dumpBytecode(JSContext* cx, ++ Handle regexp, ++ HandleLinearString input); + #endif + + private: +@@ -199,7 +204,7 @@ class RegExpObject : public NativeObject + * N.B. flagStr must be rooted. + */ + bool +-ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut); ++ParseRegExpFlags(JSContext* cx, JSString* flagStr, JS::RegExpFlags* flagsOut); + + /* Assuming GetBuiltinClass(obj) is ESClass::RegExp, return a RegExpShared for obj. */ + inline RegExpShared* +diff -Nrup mozilla/js/src/vm/RegExpShared.h mozilla-OK/js/src/vm/RegExpShared.h +--- mozilla/js/src/vm/RegExpShared.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/RegExpShared.h 2023-02-27 08:15:51.418364373 +0300 +@@ -21,8 +21,11 @@ + #include "gc/Barrier.h" + #include "gc/Heap.h" + #include "gc/Marking.h" ++#include "jit/JitOptions.h" ++#include "js/RegExpFlags.h" + #include "js/UbiNode.h" + #include "js/Vector.h" ++#include "irregexp/RegExpTypes.h" + #include "vm/ArrayObject.h" + + struct JSContext; +@@ -39,31 +42,19 @@ using RootedRegExpShared = JS::Rooted; + using MutableHandleRegExpShared = JS::MutableHandle; + +-enum RegExpFlag : uint8_t ++enum RegExpRunStatus : int32_t + { +- IgnoreCaseFlag = 0x01, +- GlobalFlag = 0x02, +- MultilineFlag = 0x04, +- StickyFlag = 0x08, +- UnicodeFlag = 0x10, +- +- NoFlags = 0x00, +- AllFlags = 0x1f +-}; +- +-static_assert(IgnoreCaseFlag == REGEXP_IGNORECASE_FLAG && +- GlobalFlag == REGEXP_GLOBAL_FLAG && +- MultilineFlag == REGEXP_MULTILINE_FLAG && +- StickyFlag == REGEXP_STICKY_FLAG && +- UnicodeFlag == REGEXP_UNICODE_FLAG, +- "Flag values should be in sync with self-hosted JS"); +- +-enum RegExpRunStatus +-{ +- RegExpRunStatus_Error, +- RegExpRunStatus_Success, +- RegExpRunStatus_Success_NotFound ++ RegExpRunStatus_Error = -1, ++ RegExpRunStatus_Success = 1, ++ RegExpRunStatus_Success_NotFound = 0, + }; ++inline bool IsNativeRegExpEnabled(JSContext* cx) { ++#ifdef JS_CODEGEN_NONE ++ return false; ++#else ++ return cx->options().nativeRegExp(); ++#endif ++} + + /* + * A RegExpShared is the compiled representation of a regexp. A RegExpShared is +@@ -85,17 +76,22 @@ enum RegExpRunStatus + class RegExpShared : public gc::TenuredCell + { + public: +- enum CompilationMode { +- Normal, +- MatchOnly ++ enum class Kind ++ { ++ Unparsed, ++ Atom, ++ RegExp + }; + +- enum ForceByteCodeEnum { +- DontForceByteCode, +- ForceByteCode ++ enum class CodeKind ++ { ++ Bytecode, ++ Jitcode, ++ Any + }; + +- using JitCodeTable = UniquePtr; ++ using ByteCode = js::irregexp::ByteArrayData; ++ using JitCodeTable = js::irregexp::ByteArray; + using JitCodeTables = Vector; + + private: +@@ -105,63 +101,75 @@ class RegExpShared : public gc::TenuredC + struct RegExpCompilation + { + ReadBarriered jitCode; +- uint8_t* byteCode; ++ ByteCode* byteCode; + + RegExpCompilation() : byteCode(nullptr) {} + +- bool compiled(ForceByteCodeEnum force = DontForceByteCode) const { +- return byteCode || (force == DontForceByteCode && jitCode); ++ bool compiled(CodeKind kind = CodeKind::Any) const ++ { ++ switch (kind) { ++ case CodeKind::Bytecode: ++ return !!byteCode; ++ case CodeKind::Jitcode: ++ return !!jitCode; ++ case CodeKind::Any: ++ return !!byteCode || !!jitCode; ++ } ++ MOZ_CRASH("Unreachable"); + } + }; + + /* Source to the RegExp, for lazy compilation. */ + GCPtr source; + +- RegExpFlag flags; +- bool canStringMatch; +- size_t parenCount; +- +- RegExpCompilation compilationArray[4]; +- +- static int CompilationIndex(CompilationMode mode, bool latin1) { +- switch (mode) { +- case Normal: return latin1 ? 0 : 1; +- case MatchOnly: return latin1 ? 2 : 3; +- } +- MOZ_CRASH(); +- } ++ JS::RegExpFlags flags; ++ ++ RegExpShared::Kind kind_ = Kind::Unparsed; ++ GCPtrAtom patternAtom_; ++ uint32_t maxRegisters_ = 0; ++ uint32_t ticks_ = 0; ++ ++ uint32_t numNamedCaptures_ = {}; ++ uint32_t* namedCaptureIndices_ = {}; ++ GCPtr groupsTemplate_ = {}; ++ ++ size_t pairCount_; ++ ++ RegExpCompilation compilationArray[2]; ++ ++ static int CompilationIndex(bool latin1) { return latin1 ? 0 : 1; } + + // Tables referenced by JIT code. + JitCodeTables tables; + + /* Internal functions. */ +- RegExpShared(JSAtom* source, RegExpFlag flags); +- +- static bool compile(JSContext* cx, MutableHandleRegExpShared res, HandleLinearString input, +- CompilationMode mode, ForceByteCodeEnum force); +- static bool compile(JSContext* cx, MutableHandleRegExpShared res, HandleAtom pattern, +- HandleLinearString input, CompilationMode mode, ForceByteCodeEnum force); ++ RegExpShared(JSAtom* source, JS::RegExpFlags flags); + +- static bool compileIfNecessary(JSContext* cx, MutableHandleRegExpShared res, +- HandleLinearString input, CompilationMode mode, +- ForceByteCodeEnum force); ++ static bool compileIfNecessary(JSContext* cx, ++ MutableHandleRegExpShared res, ++ HandleLinearString input, ++ CodeKind code); + +- const RegExpCompilation& compilation(CompilationMode mode, bool latin1) const { +- return compilationArray[CompilationIndex(mode, latin1)]; ++ const RegExpCompilation& compilation(bool latin1) const { ++ return compilationArray[CompilationIndex(latin1)]; + } + +- RegExpCompilation& compilation(CompilationMode mode, bool latin1) { +- return compilationArray[CompilationIndex(mode, latin1)]; ++ RegExpCompilation& compilation(bool latin1) { ++ return compilationArray[CompilationIndex(latin1)]; + } + + public: + ~RegExpShared() = delete; + +- // Execute this RegExp on input starting from searchIndex, filling in +- // matches if specified and otherwise only determining if there is a match. ++ static RegExpRunStatus executeAtom(MutableHandleRegExpShared re, ++ HandleLinearString input, ++ size_t start, ++ MatchPairs* matches); ++ ++ // Execute this RegExp on input starting from searchIndex, filling in matches. + static RegExpRunStatus execute(JSContext* cx, MutableHandleRegExpShared res, + HandleLinearString input, size_t searchIndex, +- MatchPairs* matches, size_t* endIndex); ++ MatchPairs* matches); + + // Register a table with this RegExpShared, and take ownership. + bool addTable(JitCodeTable table) { +@@ -170,30 +178,63 @@ class RegExpShared : public gc::TenuredC + + /* Accessors */ + +- size_t getParenCount() const { +- MOZ_ASSERT(isCompiled()); +- return parenCount; ++ size_t pairCount() const { ++ MOZ_ASSERT(kind() != Kind::Unparsed); ++ return pairCount_; + } + +- /* Accounts for the "0" (whole match) pair. */ +- size_t pairCount() const { return getParenCount() + 1; } ++ RegExpShared::Kind kind() const { return kind_; } ++ ++ // Use simple string matching for this regexp. ++ void useAtomMatch(HandleAtom pattern); ++ ++ // Use the regular expression engine for this regexp. ++ void useRegExpMatch(size_t parenCount); ++ ++ static bool initializeNamedCaptures(JSContext* cx, ++ HandleRegExpShared re, ++ HandleNativeObject namedCaptures); ++ PlainObject* getGroupsTemplate() { return groupsTemplate_; } ++ ++ void tierUpTick(); ++ bool markedForTierUp(JSContext* cx) const; ++ ++ void setByteCode(ByteCode* code, bool latin1) { compilation(latin1).byteCode = code; } ++ ByteCode* getByteCode(bool latin1) const { return compilation(latin1).byteCode; } ++ void setJitCode(jit::JitCode* code, bool latin1) { compilation(latin1).jitCode = code; } ++ jit::JitCode* getJitCode(bool latin1) const { return compilation(latin1).jitCode; } ++ uint32_t getMaxRegisters() const { return maxRegisters_; } ++ void updateMaxRegisters(uint32_t numRegisters) ++ { ++ maxRegisters_ = std::max(maxRegisters_, numRegisters); ++ } ++ ++ uint32_t numNamedCaptures() const { return numNamedCaptures_; } ++ int32_t getNamedCaptureIndex(uint32_t idx) const ++ { ++ MOZ_ASSERT(idx < numNamedCaptures()); ++ MOZ_ASSERT(namedCaptureIndices_); ++ return namedCaptureIndices_[idx]; ++ } + + JSAtom* getSource() const { return source; } +- RegExpFlag getFlags() const { return flags; } +- bool ignoreCase() const { return flags & IgnoreCaseFlag; } +- bool global() const { return flags & GlobalFlag; } +- bool multiline() const { return flags & MultilineFlag; } +- bool sticky() const { return flags & StickyFlag; } +- bool unicode() const { return flags & UnicodeFlag; } +- +- bool isCompiled(CompilationMode mode, bool latin1, +- ForceByteCodeEnum force = DontForceByteCode) const { +- return compilation(mode, latin1).compiled(force); +- } +- bool isCompiled() const { +- return isCompiled(Normal, true) || isCompiled(Normal, false) +- || isCompiled(MatchOnly, true) || isCompiled(MatchOnly, false); ++ ++ JSAtom* patternAtom() const { return patternAtom_; } ++ ++ JS::RegExpFlags getFlags() const { return flags; } ++ ++ bool global() const { return flags.global(); } ++ bool ignoreCase() const { return flags.ignoreCase(); } ++ bool multiline() const { return flags.multiline(); } ++ bool dotAll() const { return flags.dotAll(); } ++ bool unicode() const { return flags.unicode(); } ++ bool sticky() const { return flags.sticky(); } ++ ++ bool isCompiled(bool latin1, CodeKind codeKind = CodeKind::Any) const ++ { ++ return compilation(latin1).compiled(codeKind); + } ++ bool isCompiled() const { return isCompiled(true) || isCompiled(false); } + + void traceChildren(JSTracer* trc); + void discardJitCode(); +@@ -203,55 +244,62 @@ class RegExpShared : public gc::TenuredC + return offsetof(RegExpShared, source); + } + ++ static size_t offsetOfPatternAtom() { ++ return offsetof(RegExpShared, patternAtom_); ++ } ++ + static size_t offsetOfFlags() { + return offsetof(RegExpShared, flags); + } + +- static size_t offsetOfParenCount() { +- return offsetof(RegExpShared, parenCount); ++ static size_t offsetOfPairCount() { ++ return offsetof(RegExpShared, pairCount_); ++ } ++ ++ static size_t offsetOfJitCode(bool latin1) ++ { ++ return offsetof(RegExpShared, compilationArray) + ++ (CompilationIndex(latin1) * sizeof(RegExpCompilation)) + ++ offsetof(RegExpCompilation, jitCode); + } + +- static size_t offsetOfLatin1JitCode(CompilationMode mode) { +- return offsetof(RegExpShared, compilationArray) +- + (CompilationIndex(mode, true) * sizeof(RegExpCompilation)) +- + offsetof(RegExpCompilation, jitCode); +- } +- static size_t offsetOfTwoByteJitCode(CompilationMode mode) { +- return offsetof(RegExpShared, compilationArray) +- + (CompilationIndex(mode, false) * sizeof(RegExpCompilation)) +- + offsetof(RegExpCompilation, jitCode); ++ static size_t offsetOfGroupsTemplate() { ++ return offsetof(RegExpShared, groupsTemplate_); + } + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); + + #ifdef DEBUG +- static bool dumpBytecode(JSContext* cx, MutableHandleRegExpShared res, bool match_only, ++ static bool dumpBytecode(JSContext* cx, ++ MutableHandleRegExpShared res, + HandleLinearString input); + #endif + }; + + class RegExpZone + { +- struct Key { +- JSAtom* atom; +- uint16_t flag; +- +- Key() {} +- Key(JSAtom* atom, RegExpFlag flag) +- : atom(atom), flag(flag) +- { } ++ struct Key ++ { ++ JSAtom* atom = nullptr; ++ JS::RegExpFlags flags = JS::RegExpFlag::NoFlags; ++ ++ Key() = default; ++ Key(JSAtom* atom, JS::RegExpFlags flags) ++ : atom(atom) ++ , flags(flags) ++ {} + MOZ_IMPLICIT Key(const ReadBarriered& shared) + : atom(shared.unbarrieredGet()->getSource()), +- flag(shared.unbarrieredGet()->getFlags()) ++ flags(shared.unbarrieredGet()->getFlags()) + { } + + typedef Key Lookup; + static HashNumber hash(const Lookup& l) { + HashNumber hash = DefaultHasher::hash(l.atom); +- return mozilla::AddToHash(hash, l.flag); ++ return mozilla::AddToHash(hash, l.flags.value()); + } + static bool match(Key l, Key r) { +- return l.atom == r.atom && l.flag == r.flag; ++ return l.atom == r.atom && l.flags == r.flags; + } + }; + +@@ -273,12 +321,12 @@ class RegExpZone + + bool empty() const { return set_.empty(); } + +- RegExpShared* maybeGet(JSAtom* source, RegExpFlag flags) const { ++ RegExpShared* maybeGet(JSAtom* source, JS::RegExpFlags flags) const { + Set::Ptr p = set_.lookup(Key(source, flags)); + return p ? *p : nullptr; + } + +- RegExpShared* get(JSContext* cx, HandleAtom source, RegExpFlag flags); ++ RegExpShared* get(JSContext* cx, HandleAtom source, JS::RegExpFlags flags); + + /* Like 'get', but compile 'maybeOpt' (if non-null). */ + RegExpShared* get(JSContext* cx, HandleAtom source, JSString* maybeOpt); +@@ -355,6 +403,9 @@ class RegExpCompartment + } + }; + ++RegExpRunStatus ExecuteRegExpAtomRaw(RegExpShared* re, JSLinearString* input, ++ size_t start, MatchPairs* matchPairs); ++ + } /* namespace js */ + + namespace JS { +diff -Nrup mozilla/js/src/vm/RegExpStatics.cpp mozilla-OK/js/src/vm/RegExpStatics.cpp +--- mozilla/js/src/vm/RegExpStatics.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/RegExpStatics.cpp 2023-02-27 07:30:26.230684530 +0300 +@@ -95,8 +95,7 @@ RegExpStatics::executeLazy(JSContext* cx + + /* Execute the full regular expression. */ + RootedLinearString input(cx, matchesInput); +- RegExpRunStatus status = RegExpShared::execute(cx, &shared, input, lazyIndex, &this->matches, +- nullptr); ++ RegExpRunStatus status = RegExpShared::execute(cx, &shared, input, lazyIndex, &this->matches); + if (status == RegExpRunStatus_Error) + return false; + +diff -Nrup mozilla/js/src/vm/RegExpStatics.h mozilla-OK/js/src/vm/RegExpStatics.h +--- mozilla/js/src/vm/RegExpStatics.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/RegExpStatics.h 2023-02-27 07:04:13.340911788 +0300 +@@ -31,8 +31,8 @@ class RegExpStatics + * a different compartment via evalcx(). + */ + HeapPtr lazySource; +- RegExpFlag lazyFlags; +- size_t lazyIndex; ++ JS::RegExpFlags lazyFlags; ++ size_t lazyIndex; + + /* The latest RegExp input, set before execution. */ + HeapPtr pendingInput; +@@ -279,7 +279,7 @@ RegExpStatics::clear() + matches.forgetArray(); + matchesInput = nullptr; + lazySource = nullptr; +- lazyFlags = RegExpFlag(0); ++ lazyFlags = JS::RegExpFlag::NoFlags; + lazyIndex = size_t(-1); + pendingInput = nullptr; + pendingLazyEvaluation = false; +diff -Nrup mozilla/js/src/vm/Runtime.h mozilla-OK/js/src/vm/Runtime.h +--- mozilla/js/src/vm/Runtime.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/Runtime.h 2023-02-27 07:59:40.451242930 +0300 +@@ -31,7 +31,6 @@ + #include "gc/GCRuntime.h" + #include "gc/Tracer.h" + #include "gc/ZoneGroup.h" +-#include "irregexp/RegExpStack.h" + #include "js/Debug.h" + #include "js/GCVector.h" + #include "js/HashTable.h" +diff -Nrup mozilla/js/src/vm/SelfHosting.cpp mozilla-OK/js/src/vm/SelfHosting.cpp +--- mozilla/js/src/vm/SelfHosting.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/SelfHosting.cpp 2023-02-27 07:46:51.314696194 +0300 +@@ -854,6 +854,21 @@ js::intrinsic_NewStringIterator(JSContex + return true; + } + ++bool ++js::intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, Value* vp) ++{ ++ CallArgs args = CallArgsFromVp(argc, vp); ++ MOZ_ASSERT(args.length() == 0); ++ ++ JSObject* obj = NewRegExpStringIteratorObject(cx); ++ if (!obj) { ++ return false; ++ } ++ ++ args.rval().setObject(*obj); ++ return true; ++} ++ + static bool + intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp) + { +@@ -1582,7 +1597,7 @@ static bool + intrinsic_RegExpGetSubstitution(JSContext* cx, unsigned argc, Value* vp) + { + CallArgs args = CallArgsFromVp(argc, vp); +- MOZ_ASSERT(args.length() == 5); ++ MOZ_ASSERT(args.length() == 6); + + RootedArrayObject matchResult(cx, &args[0].toObject().as()); + +@@ -1600,8 +1615,17 @@ intrinsic_RegExpGetSubstitution(JSContex + int32_t firstDollarIndex = int32_t(args[4].toNumber()); + MOZ_ASSERT(firstDollarIndex >= 0); + +- return RegExpGetSubstitution(cx, matchResult, string, size_t(position), replacement, +- size_t(firstDollarIndex), args.rval()); ++ RootedValue namedCaptures(cx, args[5]); ++ MOZ_ASSERT(namedCaptures.isUndefined() || namedCaptures.isObject()); ++ ++ return RegExpGetSubstitution(cx, ++ matchResult, ++ string, ++ size_t(position), ++ replacement, ++ size_t(firstDollarIndex), ++ namedCaptures, ++ args.rval()); + } + + static bool +@@ -2329,6 +2353,10 @@ static const JSFunctionSpec intrinsic_fu + intrinsic_GuardToBuiltin, 1,0, + IntrinsicGuardToStringIterator), + ++ JS_INLINABLE_FN("GuardToRegExpStringIterator", ++ intrinsic_IsInstanceOfBuiltin, 1,0, ++ IntrinsicGuardToRegExpStringIterator), ++ + JS_FN("_CreateMapIterationResultPair", intrinsic_CreateMapIterationResultPair, 0, 0), + JS_INLINABLE_FN("_GetNextMapEntryForIterator", intrinsic_GetNextMapEntryForIterator, 2,0, + IntrinsicGetNextMapEntryForIterator), +@@ -2347,6 +2375,12 @@ static const JSFunctionSpec intrinsic_fu + JS_FN("CallStringIteratorMethodIfWrapped", + CallNonGenericSelfhostedMethod>, 2,0), + ++ JS_INLINABLE_FN("NewRegExpStringIterator", ++ intrinsic_NewRegExpStringIterator, 0, 0, ++ IntrinsicNewRegExpStringIterator), ++ JS_FN("CallRegExpStringIteratorMethodIfWrapped", ++ CallNonGenericSelfhostedMethod>, 2, 0), ++ + JS_FN("IsGeneratorObject", + intrinsic_IsInstanceOfBuiltin, 1,0), + JS_FN("GeneratorObjectIsClosed", intrinsic_GeneratorObjectIsClosed, 1,0), +diff -Nrup mozilla/js/src/vm/SelfHosting.h mozilla-OK/js/src/vm/SelfHosting.h +--- mozilla/js/src/vm/SelfHosting.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/SelfHosting.h 2023-02-27 07:46:51.314696194 +0300 +@@ -56,6 +56,9 @@ intrinsic_NewStringIterator(JSContext* c + bool + intrinsic_IsSuspendedGenerator(JSContext* cx, unsigned argc, JS::Value* vp); + ++bool ++intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc, JS::Value* vp); ++ + } /* namespace js */ + + #endif /* vm_SelfHosting_h_ */ +diff -Nrup mozilla/js/src/vm/StructuredClone.cpp mozilla-OK/js/src/vm/StructuredClone.cpp +--- mozilla/js/src/vm/StructuredClone.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/StructuredClone.cpp 2023-02-27 07:24:02.494415868 +0300 +@@ -29,6 +29,7 @@ + + #include "js/StructuredClone.h" + ++#include "mozilla/Casting.h" + #include "mozilla/CheckedInt.h" + #include "mozilla/EndianUtils.h" + #include "mozilla/FloatingPoint.h" +@@ -44,6 +45,7 @@ + #include "builtin/MapObject.h" + #include "js/Date.h" + #include "js/GCHashTable.h" ++#include "js/RegExpFlags.h" + #include "vm/RegExpObject.h" + #include "vm/SavedFrame.h" + #include "vm/SharedArrayObject.h" +@@ -55,12 +57,15 @@ + + using namespace js; + ++using mozilla::AssertedCast; + using mozilla::BitwiseCast; + using mozilla::IsNaN; + using mozilla::LittleEndian; + using mozilla::NativeEndian; + using mozilla::NumbersAreIdentical; + using JS::CanonicalizeNaN; ++using JS::RegExpFlag; ++using JS::RegExpFlags; + + // When you make updates here, make sure you consider whether you need to bump the + // value of JS_STRUCTURED_CLONE_VERSION in js/public/StructuredClone.h. You will +@@ -1485,7 +1490,7 @@ JSStructuredCloneWriter::startWrite(Hand + RegExpShared* re = RegExpToShared(context(), obj); + if (!re) + return false; +- return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags()) && ++ return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags().value()) && + writeString(SCTAG_STRING, re->getSource()); + } else if (cls == ESClass::Date) { + RootedValue unboxed(context()); +@@ -2126,7 +2131,14 @@ JSStructuredCloneReader::startRead(Mutab + } + + case SCTAG_REGEXP_OBJECT: { +- RegExpFlag flags = RegExpFlag(data); ++ if ((data & RegExpFlag::AllFlags) != data) { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, ++ JSMSG_SC_BAD_SERIALIZED_DATA, "regexp"); ++ return false; ++ } ++ ++ RegExpFlags flags(AssertedCast(data)); ++ + uint32_t tag2, stringData; + if (!in.readPair(&tag2, &stringData)) + return false; +@@ -2136,6 +2148,7 @@ JSStructuredCloneReader::startRead(Mutab + "regexp"); + return false; + } ++ + JSString* str = readString(stringData); + if (!str) + return false; +diff -Nrup mozilla/js/src/vm/UnicodeNonBMP.h mozilla-OK/js/src/vm/UnicodeNonBMP.h +--- mozilla/js/src/vm/UnicodeNonBMP.h 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/UnicodeNonBMP.h 2023-02-27 08:10:08.166795459 +0300 +@@ -48,32 +48,4 @@ + macro(0x16e60, 0x16e7f, 0xd81b, 0xde60, 0xde7f, -32) \ + macro(0x1e922, 0x1e943, 0xd83a, 0xdd22, 0xdd43, -34) + +-// U+10400 DESERET CAPITAL LETTER LONG I .. U+10427 DESERET CAPITAL LETTER EW +-// U+104B0 OSAGE CAPITAL LETTER A .. U+104D3 OSAGE CAPITAL LETTER ZHA +-// U+10C80 OLD HUNGARIAN CAPITAL LETTER A .. U+10CB2 OLD HUNGARIAN CAPITAL LETTER US +-// U+118A0 WARANG CITI CAPITAL LETTER NGAA .. U+118BF WARANG CITI CAPITAL LETTER VIYO +-// U+16E40 MEDEFAIDRIN CAPITAL LETTER M .. U+16E5F MEDEFAIDRIN CAPITAL LETTER Y +-// U+1E900 ADLAM CAPITAL LETTER ALIF .. U+1E921 ADLAM CAPITAL LETTER SHA +-#define FOR_EACH_NON_BMP_CASE_FOLDING(macro) \ +- macro(0x10400, 0x10427, 0xd801, 0xdc00, 0xdc27, 40) \ +- macro(0x104b0, 0x104d3, 0xd801, 0xdcb0, 0xdcd3, 40) \ +- macro(0x10c80, 0x10cb2, 0xd803, 0xdc80, 0xdcb2, 64) \ +- macro(0x118a0, 0x118bf, 0xd806, 0xdca0, 0xdcbf, 32) \ +- macro(0x16e40, 0x16e5f, 0xd81b, 0xde40, 0xde5f, 32) \ +- macro(0x1e900, 0x1e921, 0xd83a, 0xdd00, 0xdd21, 34) +- +-// U+10428 DESERET SMALL LETTER LONG I .. U+1044F DESERET SMALL LETTER EW +-// U+104D8 OSAGE SMALL LETTER A .. U+104FB OSAGE SMALL LETTER ZHA +-// U+10CC0 OLD HUNGARIAN SMALL LETTER A .. U+10CF2 OLD HUNGARIAN SMALL LETTER US +-// U+118C0 WARANG CITI SMALL LETTER NGAA .. U+118DF WARANG CITI SMALL LETTER VIYO +-// U+16E60 MEDEFAIDRIN SMALL LETTER M .. U+16E7F MEDEFAIDRIN SMALL LETTER Y +-// U+1E922 ADLAM SMALL LETTER ALIF .. U+1E943 ADLAM SMALL LETTER SHA +-#define FOR_EACH_NON_BMP_REV_CASE_FOLDING(macro) \ +- macro(0x10428, 0x1044f, 0xd801, 0xdc28, 0xdc4f, -40) \ +- macro(0x104d8, 0x104fb, 0xd801, 0xdcd8, 0xdcfb, -40) \ +- macro(0x10cc0, 0x10cf2, 0xd803, 0xdcc0, 0xdcf2, -64) \ +- macro(0x118c0, 0x118df, 0xd806, 0xdcc0, 0xdcdf, -32) \ +- macro(0x16e60, 0x16e7f, 0xd81b, 0xde60, 0xde7f, -32) \ +- macro(0x1e922, 0x1e943, 0xd83a, 0xdd22, 0xdd43, -34) +- + #endif /* vm_UnicodeNonBMP_h */ +diff -Nrup mozilla/js/src/vm/make_unicode.py mozilla-OK/js/src/vm/make_unicode.py +--- mozilla/js/src/vm/make_unicode.py 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/js/src/vm/make_unicode.py 2023-02-27 08:12:59.618581156 +0300 +@@ -403,18 +403,11 @@ def process_case_folding(case_folding): + folding_tests = [] + folding_codes = set() + +- non_bmp_folding_map = {} +- non_bmp_rev_folding_map = {} +- + for row in read_case_folding(case_folding): + code = row[0] + mapping = row[2] + folding_map[code] = mapping + +- if code > MAX_BMP: +- non_bmp_folding_map[code] = mapping +- non_bmp_rev_folding_map[mapping] = code +- + if mapping not in rev_folding_map: + rev_folding_map[mapping] = [code] + else: +@@ -469,7 +462,6 @@ def process_case_folding(case_folding): + folding_index[code] = i + return ( + folding_table, folding_index, +- non_bmp_folding_map, non_bmp_rev_folding_map, + folding_tests + ) + +@@ -613,7 +605,6 @@ def process_special_casing(special_casin + + def make_non_bmp_file(version, + non_bmp_lower_map, non_bmp_upper_map, +- non_bmp_folding_map, non_bmp_rev_folding_map, + codepoint_table): + file_name = 'UnicodeNonBMP.h'; + with io.open(file_name, mode='w', encoding='utf-8') as non_bmp_file: +@@ -640,10 +631,6 @@ def make_non_bmp_file(version, + make_non_bmp_convert_macro(non_bmp_file, 'LOWERCASE', non_bmp_lower_map, codepoint_table) + non_bmp_file.write('\n') + make_non_bmp_convert_macro(non_bmp_file, 'UPPERCASE', non_bmp_upper_map, codepoint_table) +- non_bmp_file.write('\n') +- make_non_bmp_convert_macro(non_bmp_file, 'CASE_FOLDING', non_bmp_folding_map, codepoint_table) +- non_bmp_file.write('\n') +- make_non_bmp_convert_macro(non_bmp_file, 'REV_CASE_FOLDING', non_bmp_rev_folding_map, codepoint_table) + + non_bmp_file.write(""" + #endif /* util_UnicodeNonBMP_h */ +@@ -1305,205 +1292,6 @@ def splitbins(t): + assert t[i] == t2[(t1[i >> shift] << shift) + (i & mask)] + return best + +-def make_irregexp_tables(version, +- table, index, +- folding_table, folding_index, +- codepoint_table): +- import string +- +- MAX_ASCII = 0x7F +- MAX_LATIN1 = 0xFF +- LEAD_SURROGATE_MIN = 0xD800 +- TRAIL_SURROGATE_MAX = 0xDFFF +- +- def hex2(n): +- assert 0 <= n and n < 16**2 +- return '0x{:02X}'.format(n) +- +- def hex4(n): +- assert 0 <= n and n < 16**4 +- return '0x{:04X}'.format(n) +- +- def uhex4(n): +- assert 0 <= n and n < 16**4 +- return 'U+{:04X}'.format(n) +- +- def case_info(code): +- assert 0 <= code and code <= MAX_BMP +- (upper, lower, flags) = table[index[code]] +- return ((code + upper) & 0xffff, (code + lower) & 0xffff, flags) +- +- def is_space(code): +- (_, _, flags) = case_info(code) +- return bool(flags & FLAG_SPACE) +- +- def to_upper(code): +- (upper, _, _) = case_info(code) +- return upper +- +- def casefold(code): +- assert 0 <= code and code <= MAX_BMP +- (folding, _, _, _) = folding_table[folding_index[code]] +- return (code + folding) & 0xffff +- +- def casefolds_to_ascii(code): +- return casefold(code) <= MAX_ASCII +- +- def casefolds_to_latin1(code): +- return casefold(code) <= MAX_LATIN1 +- +- def casemaps_to_nonlatin1(code): +- upper = to_upper(code) +- return upper > MAX_LATIN1 +- +- def char_name(code): +- assert 0 <= code and code <= MAX_BMP +- if code not in codepoint_table: +- return '' +- if code == LEAD_SURROGATE_MIN: +- return '' +- if code == TRAIL_SURROGATE_MAX: +- return '' +- (_, _, name, alias) = codepoint_table[code] +- return name if not name.startswith('<') else alias +- +- def write_character_range(println, name, characters): +- char_ranges = list(int_ranges(characters)) +- println('') +- println('const int js::irregexp::k{}Ranges[] = {{'.format(name)) +- for (start, end) in char_ranges: +- s_name = char_name(start) +- e_name = char_name(end) +- println(' {}, {} + 1, // {}'.format(hex4(start), hex4(end), +- '{}..{}'.format(s_name, e_name) +- if start != end else s_name)) +- println(' {} + 1'.format(hex4(MAX_BMP))) +- println('};') +- println('const int js::irregexp::k{}RangeCount = {};'.format(name, +- len(char_ranges) * 2 + 1)) +- +- def write_character_test(println, test, consequent, default): +- # Latin1 characters which, when case-mapped through +- # String.prototype.toUpperCase(), canonicalize to a non-Latin1 character. +- # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize +- casemapped_to_nonlatin1 = filter(casemaps_to_nonlatin1, range(0, MAX_LATIN1 + 1)) +- +- def casemap_closure(ch): +- upper = to_upper(ch) +- return (ch, [c for c in range(MAX_LATIN1 + 1, MAX_BMP + 1) if upper == to_upper(c)]) +- +- # Mapping from Latin1 characters to the list of case map equivalent +- # non-Latin1 characters. +- casemap_for_latin1 = dict(chain(map(casemap_closure, casemapped_to_nonlatin1))) +- +- # Non-latin1 characters which, when Unicode case-folded, canonicalize to +- # a Latin1 character. +- # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize +- casefolded_to_latin1 = filter(casefolds_to_latin1, range(MAX_LATIN1 + 1, MAX_BMP + 1)) +- +- println(' if (unicode) {') +- for ch in casefolded_to_latin1: +- casefolded = casefold(ch) +- # Skip if also handled below for case mapping. +- if casefolded in casemap_for_latin1 and ch in casemap_for_latin1[casefolded]: +- continue +- println(' // "{}" case folds to "{}".'.format(char_name(ch), +- char_name(casefolded))) +- println(' if ({}) {{'.format(test(ch))) +- println(' return {};'.format(consequent(casefolded))) +- println(' }') +- println(' }') +- println('') +- for (ch, casemapped_chars) in casemap_for_latin1.items(): +- for casemapped in casemapped_chars: +- println(' // "{}" case maps to "{}".'.format(char_name(casemapped), +- char_name(ch))) +- println(' if ({}) {{'.format(' || '.join(map(test, casemapped_chars)))) +- println(' return {};'.format(consequent(ch))) +- println(' }') +- println(' return {};'.format(default)) +- +- with io.open('../irregexp/RegExpCharacters-inl.h', 'w', encoding='utf-8') as chars_file: +- write = partial(print, file=chars_file, sep='', end='') +- println = partial(write, end='\n') +- +- write(warning_message) +- write(unicode_version_message.format(version)) +- +- println('#ifndef V8_JSREGEXPCHARACTERS_INL_H_') +- println('#define V8_JSREGEXPCHARACTERS_INL_H_') +- println('') +- println('namespace js {') +- println('') +- println('namespace irregexp {') +- println('') +- +- println('static inline bool') +- println('RangeContainsLatin1Equivalents(CharacterRange range, bool unicode)') +- println('{') +- write_character_test(println, lambda ch: 'range.Contains({})'.format(hex4(ch)), +- lambda _: 'true', 'false') +- println('}') +- +- println('') +- println('} } // namespace js::irregexp') +- println('') +- println('#endif // V8_JSREGEXPCHARACTERS_INL_H_') +- +- with io.open('../irregexp/RegExpCharacters.cpp', 'w', encoding='utf-8') as chars_file: +- write = partial(print, file=chars_file, sep='', end='') +- println = partial(write, end='\n') +- character_range = partial(write_character_range, println) +- +- # Characters in \s, 21.2.2.12 CharacterClassEscape. +- space_chars = [ch for ch in range(0, MAX_BMP + 1) if is_space(ch)] +- +- # Characters in \d, 21.2.2.12 CharacterClassEscape. +- digit_chars = [ord(ch) for ch in string.digits] +- assert all(ch <= MAX_ASCII for ch in digit_chars) +- +- # Characters in \w, 21.2.2.12 CharacterClassEscape. +- word_chars = [ord(ch) for ch in string.digits + string.ascii_letters + '_'] +- assert all(ch <= MAX_ASCII for ch in word_chars) +- +- # Characters which case-fold to characters in \w. +- ignorecase_word_chars = (word_chars + +- [ch for ch in range(MAX_ASCII + 1, MAX_BMP + 1) if casefolds_to_ascii(ch)]) +- +- # Surrogate characters. +- surrogate_chars = [ch for ch in range(LEAD_SURROGATE_MIN, TRAIL_SURROGATE_MAX + 1)] +- +- write(warning_message) +- write(unicode_version_message.format(version)) +- println('#include "irregexp/RegExpCharacters.h"') +- println('') +- println('#include "mozilla/Assertions.h"') +- println('') +- +- println('char16_t') +- println('js::irregexp::ConvertNonLatin1ToLatin1(char16_t c, bool unicode)') +- println('{') +- println(' MOZ_ASSERT(c > {}, "Character mustn\'t be Latin1");'.format(hex2(MAX_LATIN1))) +- write_character_test(println, lambda ch: 'c == {}'.format(hex4(ch)), hex2, '0') +- println('}') +- +- character_range('Space', space_chars) +- character_range('SpaceAndSurrogate', space_chars + surrogate_chars) +- +- character_range('Word', word_chars) +- character_range('IgnoreCaseWord', ignorecase_word_chars) +- character_range('WordAndSurrogate', word_chars + surrogate_chars) +- character_range('NegatedIgnoreCaseWordAndSurrogate', +- set(range(0, MAX_BMP + 1)) - set(ignorecase_word_chars + surrogate_chars)) +- +- character_range('Digit', digit_chars) +- character_range('DigitAndSurrogate', digit_chars + surrogate_chars) +- +- character_range('Surrogate', surrogate_chars) +- +- character_range('LineTerminator', line_terminator) +- character_range('LineTerminatorAndSurrogate', line_terminator + surrogate_chars) +- + def update_unicode(args): + base_path = os.getcwd() + +@@ -1553,7 +1341,6 @@ def update_unicode(args): + ) = process_unicode_data(unicode_data, derived_core_properties) + ( + folding_table, folding_index, +- non_bmp_folding_map, non_bmp_rev_folding_map, + folding_tests + ) = process_case_folding(case_folding) + ( +@@ -1571,12 +1358,7 @@ def update_unicode(args): + codepoint_table) + make_non_bmp_file(unicode_version, + non_bmp_lower_map, non_bmp_upper_map, +- non_bmp_folding_map, non_bmp_rev_folding_map, + codepoint_table) +- make_irregexp_tables(unicode_version, +- table, index, +- folding_table, folding_index, +- codepoint_table) + + make_bmp_mapping_test(unicode_version, + codepoint_table, unconditional_tolower, unconditional_toupper) +diff -Nrup mozilla/toolkit/components/extensions/MatchPattern.cpp mozilla-OK/toolkit/components/extensions/MatchPattern.cpp +--- mozilla/toolkit/components/extensions/MatchPattern.cpp 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla-OK/toolkit/components/extensions/MatchPattern.cpp 2023-02-27 07:03:29.871223712 +0300 +@@ -6,6 +6,7 @@ + #include "mozilla/extensions/MatchPattern.h" + #include "mozilla/extensions/MatchGlob.h" + ++#include "js/RegExp.h" // JS::NewUCRegExpObject, JS::ExecuteRegExpNoStatics + #include "mozilla/dom/ScriptSettings.h" + #include "mozilla/HoldDropJSObjects.h" + #include "mozilla/Unused.h" +@@ -697,7 +698,7 @@ MatchGlob::Init(JSContext* aCx, const ns + // TODO: Switch to the Rust regexp crate, when Rust integration is easier. + // It uses a much more efficient, linear time matching algorithm, and + // doesn't require special casing for the literal and prefix cases. +- mRegExp = JS_NewUCRegExpObject(aCx, escaped.get(), escaped.Length(), 0); ++ mRegExp = JS::NewUCRegExpObject(aCx, escaped.get(), escaped.Length(), 0); + if (mRegExp) { + mozilla::HoldJSObjects(this); + } else { +@@ -721,7 +722,7 @@ MatchGlob::Matches(const nsAString& aStr + nsString input(aString); + + size_t index = 0; +- if (!JS_ExecuteRegExpNoStatics(cx, regexp, input.BeginWriting(), aString.Length(), ++ if (!JS::ExecuteRegExpNoStatics(cx, regexp, input.BeginWriting(), aString.Length(), + &index, true, &result)) { + return false; + } diff --git a/seamonkey-2.53.16-stylo_config.patch b/seamonkey-2.53.16-stylo_config.patch new file mode 100644 index 0000000..465b7ee --- /dev/null +++ b/seamonkey-2.53.16-stylo_config.patch @@ -0,0 +1,156 @@ +diff -Nrup mozilla-OLD/moz.configure mozilla/moz.configure +--- mozilla-OLD/moz.configure 2023-02-25 21:34:57.000000000 +0300 ++++ mozilla/moz.configure 2023-02-27 13:37:14.148043308 +0300 +@@ -256,8 +256,76 @@ set_config('IMPORT_LIB_SUFFIX', library_ + set_define('MOZ_DLL_SUFFIX', depends(library_name_info.dll.suffix)(lambda s: '"%s"' % s)) + + # Depends on host_library_name_info, so needs to go here. ++# Servo integration ++# ============================================================== ++option('--enable-stylo', nargs='?', choices=('build', 'only'), ++ help='Include Stylo in the build. "build" means to disable Stylo at ' + ++ 'runtime, and "only" means to exclude the old style system from ' + ++ 'the build.') ++ ++@depends('--enable-stylo', '--help') ++def stylo_config(value, _): ++ build_stylo = None ++ enable_stylo = None ++ old_style = True ++ ++ # If nothing is specified, default to building and enabling Stylo, ++ # and building the old style system. ++ if value.origin == 'default': ++ pass ++ elif len(value) and value[0] == 'build': ++ # Build but disable by request. ++ build_stylo = True ++ elif len(value) and value[0] == 'only': ++ # Disable the old style system. ++ build_stylo = True ++ enable_stylo = True ++ old_style = None ++ elif bool(value): ++ # Build and enable. ++ build_stylo = True ++ enable_stylo = True ++ ++ return namespace( ++ build = build_stylo, ++ enable = enable_stylo, ++ old_style = old_style, ++ ) ++ ++option('--disable-stylo-build-bindgen', ++ help='Disable build-time bindgen for Stylo') ++ ++@depends(stylo_config, '--enable-stylo-build-bindgen', '--enable-compile-environment') ++def building_stylo_bindgen(stylo_config, bindgen_enabled, compile_environment): ++ if not compile_environment: ++ return False ++ if not bindgen_enabled: ++ return False ++ return stylo_config.build ++ ++ set_config('MOZ_STYLO_BINDGEN', depends_if('--enable-stylo-build-bindgen')(lambda _: True)) ++ + include('build/moz.configure/bindgen.configure', +- when='--enable-compile-environment') ++ when=building_stylo_bindgen) ++ ++set_config('MOZ_STYLO', stylo_config.build) ++set_define('MOZ_STYLO', stylo_config.build) ++set_config('MOZ_STYLO_ENABLE', stylo_config.enable) ++set_define('MOZ_STYLO_ENABLE', stylo_config.enable) ++set_config('MOZ_OLD_STYLE', stylo_config.old_style) ++set_define('MOZ_OLD_STYLE', stylo_config.old_style) ++ ++option('--with-servo', env='SERVO_TARGET_DIR', nargs=1, ++ help='Absolute path of the target directory where libgeckoservo can ' ++ 'be found. This is generally servo_src_dir/target/release.') ++ ++@depends_if('--with-servo') ++def servo_target_dir(value): ++ return value[0] ++ ++set_config('SERVO_TARGET_DIR', servo_target_dir) ++ ++ + include(include_project_configure) + + @depends('--help') +diff -Nrup mozilla-OLD/toolkit/moz.configure mozilla/toolkit/moz.configure +--- mozilla-OLD/toolkit/moz.configure 2023-02-27 13:23:44.000000000 +0300 ++++ mozilla/toolkit/moz.configure 2023-02-27 13:34:15.868323967 +0300 +@@ -669,71 +669,6 @@ simple_keyfile('Adjust SDK') + + id_and_secret_keyfile('Leanplum SDK') + +-# Servo integration +-# ============================================================== +-option('--enable-stylo', nargs='?', choices=('build', 'only'), +- help='Include Stylo in the build. "build" means to disable Stylo at ' + +- 'runtime, and "only" means to exclude the old style system from ' + +- 'the build.') +- +-@depends('--enable-stylo', '--help') +-def stylo_config(value, _): +- build_stylo = None +- enable_stylo = None +- old_style = True +- +- # If nothing is specified, default to building and enabling Stylo, +- # and building the old style system. +- if value.origin == 'default': +- pass +- elif len(value) and value[0] == 'build': +- # Build but disable by request. +- build_stylo = True +- elif len(value) and value[0] == 'only': +- # Disable the old style system. +- build_stylo = True +- enable_stylo = True +- old_style = None +- elif bool(value): +- # Build and enable. +- build_stylo = True +- enable_stylo = True +- +- return namespace( +- build = build_stylo, +- enable = enable_stylo, +- old_style = old_style, +- ) +- +-option('--disable-stylo-build-bindgen', +- help='Disable build-time bindgen for Stylo') +- +-@depends(stylo_config, '--enable-stylo-build-bindgen', '--enable-compile-environment') +-def building_stylo_bindgen(stylo_config, bindgen_enabled, compile_environment): +- if not compile_environment: +- return False +- if not bindgen_enabled: +- return False +- return stylo_config.build +- +- set_config('MOZ_STYLO_BINDGEN', depends_if('--enable-stylo-build-bindgen')(lambda _: True)) +- +-set_config('MOZ_STYLO', stylo_config.build) +-set_define('MOZ_STYLO', stylo_config.build) +-set_config('MOZ_STYLO_ENABLE', stylo_config.enable) +-set_define('MOZ_STYLO_ENABLE', stylo_config.enable) +-set_config('MOZ_OLD_STYLE', stylo_config.old_style) +-set_define('MOZ_OLD_STYLE', stylo_config.old_style) +- +-option('--with-servo', env='SERVO_TARGET_DIR', nargs=1, +- help='Absolute path of the target directory where libgeckoservo can ' +- 'be found. This is generally servo_src_dir/target/release.') +- +-@depends_if('--with-servo') +-def servo_target_dir(value): +- return value[0] +- +-set_config('SERVO_TARGET_DIR', servo_target_dir) + + # WebRender integration + option('--enable-webrender', nargs='?', choices=('build',), diff --git a/seamonkey.spec b/seamonkey.spec index 7ab1c55..8c2fa90 100644 --- a/seamonkey.spec +++ b/seamonkey.spec @@ -38,8 +38,8 @@ Name: seamonkey Summary: Web browser, e-mail, news, IRC client, HTML editor -Version: 2.53.15 -Release: 2%{?dist} +Version: 2.53.16 +Release: 1%{?dist} URL: http://www.seamonkey-project.org License: MPLv2.0 @@ -49,7 +49,7 @@ Source0: http://archive.mozilla.org/pub/seamonkey/releases/%{version}/source/sea Source1: http://archive.mozilla.org/pub/seamonkey/releases/%{version}/source/seamonkey-%{version}.source-l10n.tar.xz %endif -Source3: seamonkey-2.53.15-GNUmakefile +Source3: seamonkey-2.53.16-GNUmakefile Source4: seamonkey.desktop Source5: seamonkey-mail.desktop Source6: seamonkey-ua-update.json.in @@ -60,8 +60,7 @@ Patch5: firefox-35-rhbz-1173156.patch Patch7: firefox-51-mozilla-1005640.patch Patch9: seamonkey-2.53.1-mozilla-revert-1332139.patch Patch10: seamonkey-2.53.7-mozilla-440908.patch -Patch11: seamonkey-2.53.14-mozilla-1434478.patch -Patch12: seamonkey-2.53.10-mozilla-1449641.patch +Patch11: seamonkey-2.53.16-mozilla-1434478.patch Patch13: seamonkey-2.53.10-mozilla-1460295.patch Patch14: seamonkey-2.53.11-adjacent-sibling.patch Patch15: seamonkey-2.53.10-mozilla-1442861.patch @@ -83,27 +82,22 @@ Patch31: seamonkey-2.53.1-mozilla-526293.patch Patch34: seamonkey-2.53.3-startupcache.patch Patch35: seamonkey-2.53.8-server-folder.patch Patch36: seamonkey-2.53.15-locale-matchos-UI.patch -Patch37: seamonkey-2.53.15-mozilla-1720968.patch +Patch37: seamonkey-2.53.16-mozilla-1720968.patch Patch38: seamonkey-2.53.8-mozilla-521861.patch Patch39: seamonkey-2.53.8.1-dateformat.patch Patch40: seamonkey-2.53.10-slowscript.patch Patch41: seamonkey-2.53.15-revert-1737436.patch Patch42: seamonkey-2.53.10-postmessage.patch -Patch44: seamonkey-2.53.15-pre-regexp.patch -Patch45: seamonkey-2.53.13-regexp.patch +Patch45: seamonkey-2.53.16-regexp.patch Patch46: seamonkey-2.53.10-regexp-imported.patch -Patch47: seamonkey-2.53.13-ffmpeg59-headers.patch -Patch48: seamonkey-2.53.15-ffmpeg59-1750760.patch -Patch49: seamonkey-2.53.15-post-regexp.patch -Patch50: seamonkey-2.53.15-mozilla-1464782.patch Patch60: seamonkey-2.53.11-ua-update.patch Patch61: seamonkey-2.53.13-ua-update-preload.patch Patch62: seamonkey-2.53.11-compat-version.patch -Patch63: seamonkey-2.53.11-mozilla-1513677.patch Patch66: seamonkey-2.53.11-startupcache1.patch Patch67: seamonkey-2.53.13-wasm-gc.patch -Patch68: seamonkey-2.53.14-cbindgen.patch +Patch68: seamonkey-2.53.16-mozilla-1519319.patch +Patch69: seamonkey-2.53.16-stylo_config.patch %{?with_system_nspr:BuildRequires: nspr-devel >= %{nspr_version}} %{?with_system_nss:BuildRequires: nss-devel >= %{nss_version}} @@ -206,7 +200,6 @@ cp %{SOURCE3} GNUmakefile %{?with_system_libvpx:%patch9 -p1 -b .1332139} %patch10 -p1 -b .440908 %patch11 -p1 -b .1434478 -%patch12 -p1 -b .1449641 %patch13 -p1 -b .1460295 %patch14 -p1 -b .adjacent-sibling %patch15 -p1 -b .1442861 @@ -238,21 +231,16 @@ cp %{SOURCE3} GNUmakefile # just pre-remove to avoid huge patches... rm -rf js/src/{irregexp,new-regexp} -%patch44 -p0 %patch45 -p1 %patch46 -p1 -%patch47 -p1 -%patch48 -p1 -b .1750760 -%patch49 -p0 -%patch50 -p1 -b .1464782 %patch60 -p1 -b .ua-update %patch61 -p1 -b .ua-update-preload %patch62 -p1 -b .compat-version -%patch63 -p1 -b .1513677 %patch66 -p1 -b .startupcache1 %patch67 -p1 -b .wasm-gc -%patch68 -p1 -b .no-cbindgen +%patch68 -p1 -b .1519319 +%patch69 -p1 -b .stylo_config %if %{without calendar} sed -i 's/MOZ_CALENDAR/UNDEF_MOZ_CALENDAR/' comm/suite/installer/package-manifest.in @@ -535,6 +523,9 @@ mkdir -p $RPM_BUILD_ROOT%{_libdir}/mozilla/extensions/%{seamonkey_app_id} %changelog +* Thu Mar 30 2023 Dmitry Butskoy 2.53.16-1 +- update to 2.53.16 + * Wed Feb 15 2023 Tom Callaway - 2.53.15-2 - rebuild for libvpx diff --git a/sources b/sources index e75b136..cd57a87 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (seamonkey-2.53.15.source.tar.xz) = f4735af98be0e27a935852de9d309317e1639a420189b0432cb7bdf9707bab706ceec65e96b94953a6e4285b4501dcd25745fb9250b8bf30845d2b855dcc8b13 -SHA512 (seamonkey-2.53.15.source-l10n.tar.xz) = 91a3be1dfcd6c06953430afd2d07036c525b73e0132690575275430bca5ffe3082cb5c30df4cd921d961aa79333b6cefb6eace157fc65368254f4099ae879131 +SHA512 (seamonkey-2.53.16.source.tar.xz) = 7be2788f63fb7e2f75c0023ffb00afb28e74e93c0b1c066be97588b614faf181a549234114fc4bb03422b34ce48d76b4a001f4e992c494058663e7d382300da8 +SHA512 (seamonkey-2.53.16.source-l10n.tar.xz) = cb6f7aea35e966b21d330bdf910aba6bf40f2386876983a510d9bd02bf9d37c33f80b9b509c912deacc47bf804c22f3274ff138ffaaed11231eaad502bec39ee