diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp index 2456ef065d..39db78c8e9 100644 --- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -28,6 +28,8 @@ using mozilla::ArrayLength; using mozilla::CheckedInt; using mozilla::Maybe; +using CapturesVector = GCVector; + /* * ES 2017 draft rev 6a13789aa9e7c6de4e96b7d3e24d9e6eba6584ad 21.2.5.2.2 * steps 3, 16-25. @@ -1265,7 +1267,7 @@ GetParen(JSLinearString* matched, const JS::Value& capture, JSSubString* out) template static bool InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position, size_t tailPos, - MutableHandle> captures, JSLinearString* replacement, + MutableHandle captures, JSLinearString* replacement, const CharT* replacementBegin, const CharT* currentDollar, const CharT* replacementEnd, JSSubString* out, size_t* skip) @@ -1340,7 +1342,7 @@ InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position template static bool FindReplaceLengthString(JSContext* cx, HandleLinearString matched, HandleLinearString string, - size_t position, size_t tailPos, MutableHandle> captures, + size_t position, size_t tailPos, MutableHandle captures, HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep) { CheckedInt replen = replacement->length(); @@ -1379,7 +1381,7 @@ FindReplaceLengthString(JSContext* cx, HandleLinearString matched, HandleLinearS static bool FindReplaceLength(JSContext* cx, HandleLinearString matched, HandleLinearString string, - size_t position, size_t tailPos, MutableHandle> captures, + size_t position, size_t tailPos, MutableHandle captures, HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep) { return replacement->hasLatin1Chars() @@ -1397,7 +1399,7 @@ FindReplaceLength(JSContext* cx, HandleLinearString matched, HandleLinearString template static void DoReplace(HandleLinearString matched, HandleLinearString string, - size_t position, size_t tailPos, MutableHandle> captures, + size_t position, size_t tailPos, MutableHandle captures, HandleLinearString replacement, size_t firstDollarIndex, StringBuffer &sb) { JS::AutoCheckCannotGC nogc; @@ -1432,7 +1434,7 @@ DoReplace(HandleLinearString matched, HandleLinearString string, static bool NeedTwoBytes(HandleLinearString string, HandleLinearString replacement, - HandleLinearString matched, Handle> captures) + HandleLinearString matched, Handle captures) { if (string->hasTwoByteChars()) return true; @@ -1475,7 +1477,7 @@ js::RegExpGetSubstitution(JSContext* cx, HandleLinearString matched, HandleLinea if (!GetLengthProperty(cx, capturesObj, &nCaptures)) return false; - Rooted> captures(cx, GCVector(cx)); + Rooted captures(cx, CapturesVector(cx)); if (!captures.reserve(nCaptures)) return false; diff --git a/js/src/irregexp/InfallibleVector.h b/js/src/irregexp/InfallibleVector.h new file mode 100644 index 0000000000..1c0e5bca22 --- /dev/null +++ b/js/src/irregexp/InfallibleVector.h @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_INFALLIBLEVECTOR_H_ +#define V8_INFALLIBLEVECTOR_H_ + +namespace js { +namespace irregexp { + +// InfallibleVector is like Vector, but all its methods are infallible (they +// crash on OOM). We use this class instead of Vector to avoid a ton of +// MOZ_MUST_USE warnings in irregexp code (imported from V8). +template +class InfallibleVector +{ + Vector> vector_; + + InfallibleVector(const InfallibleVector&) = delete; + void operator=(const InfallibleVector&) = delete; + + public: + explicit InfallibleVector(const LifoAllocPolicy& alloc) : vector_(alloc) {} + + void append(const T& t) { MOZ_ALWAYS_TRUE(vector_.append(t)); } + void append(const T* begin, size_t length) { MOZ_ALWAYS_TRUE(vector_.append(begin, length)); } + + // Move a number of elements in a zonelist to another position + // in the same list. Handles overlapping source and target areas. + void moveReplace(int from, int to, int count) + { + T* array = begin(); + if (from < to) { + for (int i = count - 1; i >= 0; i--) + array[to + i] = array[from + i]; + } else { + for (int i = 0; i < count; i++) + array[to + i] = array[from + i]; + } + } + + void clear() { vector_.clear(); } + void popBack() { vector_.popBack(); } + void reserve(size_t n) { MOZ_ALWAYS_TRUE(vector_.reserve(n)); } + + + size_t length() const { return vector_.length(); } + T popCopy() { return vector_.popCopy(); } + + T* begin() { return vector_.begin(); } + const T* begin() const { return vector_.begin(); } + + T* end() { return vector_.end(); } + const T* end() const { return vector_.end(); } + + T& operator[](size_t index) { return vector_[index]; } + const T& operator[](size_t index) const { return vector_[index]; } + + InfallibleVector& operator=(InfallibleVector&& rhs) { vector_ = Move(rhs.vector_); return *this; } + + bool equals(const InfallibleVector& other) const { + if (length() != other.length()) { + return false; + } + return 0 == memcmp(begin(), other.begin(), length() * sizeof(T)); + } + inline bool operator==(const InfallibleVector& rhs) const { + return equals(rhs); + } +}; + +typedef InfallibleVector CharacterVector; +typedef InfallibleVector CharacterVectorVector; +typedef InfallibleVector IntegerVector; + +} } // namespace js::irregexp + +#endif // V8_INFALLIBLEVECTOR_H_ \ No newline at end of file diff --git a/js/src/irregexp/RegExpAST.h b/js/src/irregexp/RegExpAST.h index 37c85b7427..bd01f6c6cd 100644 --- a/js/src/irregexp/RegExpAST.h +++ b/js/src/irregexp/RegExpAST.h @@ -234,8 +234,6 @@ class RegExpCharacterClass : public RegExpTree bool is_negated_; }; -typedef InfallibleVector CharacterVector; - class RegExpAtom : public RegExpTree { public: diff --git a/js/src/irregexp/RegExpEngine.h b/js/src/irregexp/RegExpEngine.h index c665105d7c..7505636100 100644 --- a/js/src/irregexp/RegExpEngine.h +++ b/js/src/irregexp/RegExpEngine.h @@ -127,39 +127,6 @@ InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* chars, size_t FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE) #undef FORWARD_DECLARE -// InfallibleVector is like Vector, but all its methods are infallible (they -// crash on OOM). We use this class instead of Vector to avoid a ton of -// MOZ_MUST_USE warnings in irregexp code (imported from V8). -template -class InfallibleVector -{ - Vector> vector_; - - InfallibleVector(const InfallibleVector&) = delete; - void operator=(const InfallibleVector&) = delete; - - public: - explicit InfallibleVector(const LifoAllocPolicy& alloc) : vector_(alloc) {} - - void append(const T& t) { MOZ_ALWAYS_TRUE(vector_.append(t)); } - void append(const T* begin, size_t length) { MOZ_ALWAYS_TRUE(vector_.append(begin, length)); } - - void clear() { vector_.clear(); } - void popBack() { vector_.popBack(); } - void reserve(size_t n) { MOZ_ALWAYS_TRUE(vector_.reserve(n)); } - - size_t length() const { return vector_.length(); } - T popCopy() { return vector_.popCopy(); } - - T* begin() { return vector_.begin(); } - const T* begin() const { return vector_.begin(); } - - T& operator[](size_t index) { return vector_[index]; } - const T& operator[](size_t index) const { return vector_[index]; } - - InfallibleVector& operator=(InfallibleVector&& rhs) { vector_ = Move(rhs.vector_); return *this; } -}; - class CharacterRange; typedef InfallibleVector CharacterRangeVector;