mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1438310 - Remove ScopedMatchPairs and devirtualize MatchPairs to avoid triggering undefined behavior. r=jwalden
This commit is contained in:
parent
efd8bcc49b
commit
de47aa59e3
@ -120,7 +120,7 @@ CreateRegExpSearchResult(const MatchPairs& matches)
|
||||
*/
|
||||
static RegExpRunStatus
|
||||
ExecuteRegExpImpl(JSContext* cx, RegExpStatics* res, MutableHandleRegExpShared re,
|
||||
HandleLinearString input, size_t searchIndex, MatchPairs* matches,
|
||||
HandleLinearString input, size_t searchIndex, VectorMatchPairs* matches,
|
||||
size_t* endIndex)
|
||||
{
|
||||
RegExpRunStatus status = RegExpShared::execute(cx, re, input, searchIndex, matches, endIndex);
|
||||
@ -147,7 +147,7 @@ js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, Handle<RegExpObject*>
|
||||
if (!shared)
|
||||
return false;
|
||||
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
VectorMatchPairs matches;
|
||||
|
||||
RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &shared, input, *lastIndex,
|
||||
&matches, nullptr);
|
||||
@ -904,7 +904,7 @@ IsTrailSurrogateWithLeadSurrogate(HandleLinearString input, int32_t index)
|
||||
*/
|
||||
static RegExpRunStatus
|
||||
ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string, int32_t lastIndex,
|
||||
MatchPairs* matches, size_t* endIndex)
|
||||
VectorMatchPairs* matches, size_t* endIndex)
|
||||
{
|
||||
/*
|
||||
* WARNING: Despite the presence of spec step comment numbers, this
|
||||
@ -979,7 +979,7 @@ RegExpMatcherImpl(JSContext* cx, HandleObject regexp, HandleString string, int32
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
/* Execute regular expression and gather matches. */
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
VectorMatchPairs matches;
|
||||
|
||||
/* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr);
|
||||
@ -1048,7 +1048,7 @@ RegExpSearcherImpl(JSContext* cx, HandleObject regexp, HandleString string, int3
|
||||
int32_t* result)
|
||||
{
|
||||
/* Execute regular expression and gather matches. */
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
VectorMatchPairs matches;
|
||||
|
||||
/* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr);
|
||||
|
@ -51,7 +51,8 @@ struct MatchPair
|
||||
}
|
||||
};
|
||||
|
||||
/* Base class for RegExp execution output. */
|
||||
// MachPairs is used as base class for VectorMatchPairs but can also be
|
||||
// stack-allocated (without a Vector) in JIT code.
|
||||
class MatchPairs
|
||||
{
|
||||
protected:
|
||||
@ -72,10 +73,6 @@ class MatchPairs
|
||||
friend class RegExpShared;
|
||||
friend class RegExpStatics;
|
||||
|
||||
/* MatchPair buffer allocator: set pairs_ and pairCount_. */
|
||||
virtual bool allocOrExpandArray(size_t pairCount) = 0;
|
||||
|
||||
bool initArrayFrom(MatchPairs& copyFrom);
|
||||
void forgetArray() { pairs_ = nullptr; }
|
||||
|
||||
void checkAgainst(size_t inputLength) {
|
||||
@ -114,37 +111,18 @@ class MatchPairs
|
||||
}
|
||||
};
|
||||
|
||||
/* MatchPairs allocated into temporary storage, removed when out of scope. */
|
||||
class ScopedMatchPairs : public MatchPairs
|
||||
{
|
||||
LifoAllocScope lifoScope_;
|
||||
|
||||
public:
|
||||
/* Constructs an implicit LifoAllocScope. */
|
||||
explicit ScopedMatchPairs(LifoAlloc* lifoAlloc)
|
||||
: lifoScope_(lifoAlloc)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
bool allocOrExpandArray(size_t pairCount) override;
|
||||
};
|
||||
|
||||
/*
|
||||
* MatchPairs allocated into permanent storage, for RegExpStatics.
|
||||
* The Vector of MatchPairs is reusable by Vector expansion.
|
||||
*/
|
||||
class VectorMatchPairs : public MatchPairs
|
||||
{
|
||||
Vector<MatchPair, 10, SystemAllocPolicy> vec_;
|
||||
|
||||
public:
|
||||
VectorMatchPairs() {
|
||||
vec_.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class RegExpShared;
|
||||
friend class RegExpStatics;
|
||||
bool allocOrExpandArray(size_t pairCount) override;
|
||||
|
||||
/* MatchPair buffer allocator: set pairs_ and pairCount_. */
|
||||
bool allocOrExpandArray(size_t pairCount);
|
||||
|
||||
bool initArrayFrom(VectorMatchPairs& copyFrom);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -70,7 +70,7 @@ js::RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto /* = nu
|
||||
/* MatchPairs */
|
||||
|
||||
bool
|
||||
MatchPairs::initArrayFrom(MatchPairs& copyFrom)
|
||||
VectorMatchPairs::initArrayFrom(VectorMatchPairs& copyFrom)
|
||||
{
|
||||
MOZ_ASSERT(copyFrom.pairCount() > 0);
|
||||
|
||||
@ -82,29 +82,10 @@ MatchPairs::initArrayFrom(MatchPairs& copyFrom)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScopedMatchPairs::allocOrExpandArray(size_t pairCount)
|
||||
{
|
||||
/* Array expansion is forbidden, but array reuse is acceptable. */
|
||||
if (pairCount_) {
|
||||
MOZ_ASSERT(pairs_);
|
||||
MOZ_ASSERT(pairCount_ == pairCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!pairs_);
|
||||
pairs_ = (MatchPair*)lifoScope_.alloc().alloc(sizeof(MatchPair) * pairCount);
|
||||
if (!pairs_)
|
||||
return false;
|
||||
|
||||
pairCount_ = pairCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VectorMatchPairs::allocOrExpandArray(size_t pairCount)
|
||||
{
|
||||
if (!vec_.resizeUninitialized(sizeof(MatchPair) * pairCount))
|
||||
if (!vec_.resizeUninitialized(pairCount))
|
||||
return false;
|
||||
|
||||
pairs_ = &vec_[0];
|
||||
@ -1082,7 +1063,7 @@ RegExpShared::compileIfNecessary(JSContext* cx, MutableHandleRegExpShared re,
|
||||
|
||||
/* static */ RegExpRunStatus
|
||||
RegExpShared::execute(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input,
|
||||
size_t start, MatchPairs* matches, size_t* endIndex)
|
||||
size_t start, VectorMatchPairs* matches, size_t* endIndex)
|
||||
{
|
||||
MOZ_ASSERT_IF(matches, !endIndex);
|
||||
MOZ_ASSERT_IF(!matches, endIndex);
|
||||
|
@ -28,10 +28,10 @@
|
||||
namespace js {
|
||||
|
||||
class ArrayObject;
|
||||
class MatchPairs;
|
||||
class RegExpCompartment;
|
||||
class RegExpShared;
|
||||
class RegExpStatics;
|
||||
class VectorMatchPairs;
|
||||
|
||||
using RootedRegExpShared = JS::Rooted<RegExpShared*>;
|
||||
using HandleRegExpShared = JS::Handle<RegExpShared*>;
|
||||
@ -159,7 +159,7 @@ class RegExpShared : public gc::TenuredCell
|
||||
// matches if specified and otherwise only determining if there is a match.
|
||||
static RegExpRunStatus execute(JSContext* cx, MutableHandleRegExpShared res,
|
||||
HandleLinearString input, size_t searchIndex,
|
||||
MatchPairs* matches, size_t* endIndex);
|
||||
VectorMatchPairs* matches, size_t* endIndex);
|
||||
|
||||
// Register a table with this RegExpShared, and take ownership.
|
||||
bool addTable(JitCodeTable table) {
|
||||
|
@ -62,7 +62,8 @@ class RegExpStatics
|
||||
/* Mutators. */
|
||||
inline void updateLazily(JSContext* cx, JSLinearString* input,
|
||||
RegExpShared* shared, size_t lastIndex);
|
||||
inline bool updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchPairs& newPairs);
|
||||
inline bool updateFromMatchPairs(JSContext* cx, JSLinearString* input,
|
||||
VectorMatchPairs& newPairs);
|
||||
|
||||
inline void clear();
|
||||
|
||||
@ -251,7 +252,8 @@ RegExpStatics::updateLazily(JSContext* cx, JSLinearString* input,
|
||||
}
|
||||
|
||||
inline bool
|
||||
RegExpStatics::updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchPairs& newPairs)
|
||||
RegExpStatics::updateFromMatchPairs(JSContext* cx, JSLinearString* input,
|
||||
VectorMatchPairs& newPairs)
|
||||
{
|
||||
MOZ_ASSERT(input);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user