mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 23:08:39 +09:00
Revert "Revert "Attempt fix regexp crash. Not working.""
This reverts commit 7f55d9bbf5cc0cc471750f232a7b5bf877aafebc.
This commit is contained in:
parent
857a456665
commit
4a4ab4f90a
4 changed files with 81 additions and 51 deletions
|
|
@ -217,6 +217,10 @@ js::CreateRegExpMatchResult(JSContext* cx, RegExpShared& re,
|
|||
// Step 34b (reordered)
|
||||
// Set the |indices| property.
|
||||
if (hasIndices) {
|
||||
fprintf(stderr,
|
||||
"regexp indices store: arr=%p comp=%p zone=%p | indices=%p comp=%p zone=%p\n",
|
||||
arr.get(), arr->compartment(), arr->zone(),
|
||||
indices.get(), indices->compartment(), indices->zone());
|
||||
arr->setSlot(3, ObjectValue(*indices));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -859,8 +859,10 @@ class NativeObject : public ShapedObject
|
|||
|
||||
// Check requirements on values stored to this object.
|
||||
MOZ_ALWAYS_INLINE void checkStoredValue(const Value& v) {
|
||||
MOZ_ASSERT(IsObjectValueInCompartment(v, compartment()));
|
||||
MOZ_ASSERT(AtomIsMarked(zoneFromAnyThread(), v));
|
||||
if (!IsObjectValueInCompartment(v, compartment()))
|
||||
MOZ_CRASH("compartment mismatch");
|
||||
if (!AtomIsMarked(zoneFromAnyThread(), v))
|
||||
MOZ_CRASH("AtomIsMarked failed");
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void setSlot(uint32_t slot, const Value& value) {
|
||||
|
|
|
|||
|
|
@ -1297,11 +1297,12 @@ RegExpShared::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
|
|||
/* RegExpCompartment */
|
||||
|
||||
RegExpCompartment::RegExpCompartment(Zone* zone)
|
||||
: optimizableRegExpPrototypeShape_(nullptr),
|
||||
: perCompartment_(zone),
|
||||
optimizableRegExpPrototypeShape_(nullptr),
|
||||
optimizableRegExpInstanceShape_(nullptr)
|
||||
{
|
||||
for (auto& templateObj : matchResultTemplateObjects_) {
|
||||
templateObj = nullptr;
|
||||
{
|
||||
MOZ_ALWAYS_TRUE(perCompartment_.init(4));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1311,9 +1312,30 @@ RegExpCompartment::~RegExpCompartment()
|
|||
}
|
||||
|
||||
ArrayObject*
|
||||
RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind)
|
||||
RegExpCompartment::getOrCreateMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind)
|
||||
{
|
||||
MOZ_ASSERT(!matchResultTemplateObjects_[kind]);
|
||||
JSCompartment* comp = cx->compartment();
|
||||
|
||||
auto p = perCompartment_.lookupForAdd(comp);
|
||||
if (!p) {
|
||||
PerCompartmentData init;
|
||||
if (!perCompartment_.add(p, comp, init))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PerCompartmentData& data = p->value();
|
||||
if (data.matchResultTemplateObjects_[kind])
|
||||
return data.matchResultTemplateObjects_[kind];
|
||||
|
||||
return createMatchResultTemplateObject(cx, kind, data);
|
||||
}
|
||||
|
||||
ArrayObject*
|
||||
RegExpCompartment::createMatchResultTemplateObject(JSContext* cx,
|
||||
ResultTemplateKind kind,
|
||||
PerCompartmentData& data)
|
||||
{
|
||||
MOZ_ASSERT(!data.matchResultTemplateObjects_[kind]);
|
||||
|
||||
/* Create template array object */
|
||||
RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount,
|
||||
|
|
@ -1337,8 +1359,8 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplate
|
|||
return nullptr;
|
||||
}
|
||||
AddTypePropertyId(cx, templateObject, NameToId(cx->names().groups), TypeSet::AnyObjectType());
|
||||
matchResultTemplateObjects_[kind].set(templateObject);
|
||||
return matchResultTemplateObjects_[kind];
|
||||
data.matchResultTemplateObjects_[kind].set(templateObject);
|
||||
return data.matchResultTemplateObjects_[kind];
|
||||
}
|
||||
|
||||
/* Set dummy index property */
|
||||
|
|
@ -1377,9 +1399,8 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplate
|
|||
AddTypePropertyId(cx, templateObject, NameToId(cx->names().indices), TypeSet::AnyObjectType());
|
||||
}
|
||||
|
||||
matchResultTemplateObjects_[kind].set(templateObject);
|
||||
|
||||
return matchResultTemplateObjects_[kind];
|
||||
data.matchResultTemplateObjects_[kind].set(templateObject);
|
||||
return data.matchResultTemplateObjects_[kind];
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1397,22 +1418,21 @@ RegExpCompartment::init(JSContext* cx)
|
|||
void
|
||||
RegExpCompartment::sweep(JSRuntime* rt)
|
||||
{
|
||||
for (auto& templateObject : matchResultTemplateObjects_) {
|
||||
if (templateObject && IsAboutToBeFinalized(&templateObject)) {
|
||||
templateObject.set(nullptr);
|
||||
}
|
||||
}
|
||||
for (auto iter = perCompartment_.all(); !iter.empty(); iter.popFront()) {
|
||||
PerCompartmentData& data = iter.front().value();
|
||||
|
||||
if (optimizableRegExpPrototypeShape_ &&
|
||||
IsAboutToBeFinalized(&optimizableRegExpPrototypeShape_))
|
||||
{
|
||||
optimizableRegExpPrototypeShape_.set(nullptr);
|
||||
}
|
||||
for (auto& templateObject : data.matchResultTemplateObjects_) {
|
||||
if (templateObject && IsAboutToBeFinalized(&templateObject))
|
||||
templateObject.set(nullptr);
|
||||
}
|
||||
|
||||
if (optimizableRegExpInstanceShape_ &&
|
||||
IsAboutToBeFinalized(&optimizableRegExpInstanceShape_))
|
||||
{
|
||||
optimizableRegExpInstanceShape_.set(nullptr);
|
||||
if (data.optimizableRegExpPrototypeShape_ &&
|
||||
IsAboutToBeFinalized(&data.optimizableRegExpPrototypeShape_))
|
||||
data.optimizableRegExpPrototypeShape_.set(nullptr);
|
||||
|
||||
if (data.optimizableRegExpInstanceShape_ &&
|
||||
IsAboutToBeFinalized(&data.optimizableRegExpInstanceShape_))
|
||||
data.optimizableRegExpInstanceShape_.set(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef vm_RegExpShared_h
|
||||
#define vm_RegExpShared_h
|
||||
|
||||
#include "js/GCHashTable.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
#include "gc/Barrier.h"
|
||||
#include "gc/Heap.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "jsalloc.h"
|
||||
#include "js/UbiNode.h"
|
||||
#include "js/Vector.h"
|
||||
#include "irregexp/InfallibleVector.h"
|
||||
|
|
@ -310,23 +312,31 @@ public:
|
|||
enum ResultTemplateKind { Normal, WithIndices, Indices, NumKinds };
|
||||
|
||||
private:
|
||||
/*
|
||||
* The template objects that the result of re.exec() is based on, if
|
||||
* there is a result. These are used in CreateRegExpMatchResult.
|
||||
* There are three template objects, each of which is an ArrayObject
|
||||
* with some additional properties. We decide which to use based on
|
||||
* the |hasIndices| (/d) flag.
|
||||
*
|
||||
* Normal: Has |index|, |input|, and |groups| properties.
|
||||
* Used for the result object if |hasIndices| is not set.
|
||||
*
|
||||
* WithIndices: Has |index|, |input|, |groups|, and |indices| properties.
|
||||
* Used for the result object if |hasIndices| is set.
|
||||
*
|
||||
* Indices: Has a |groups| property. If |hasIndices| is set, used
|
||||
* for the |.indices| property of the result object.
|
||||
*/
|
||||
ReadBarriered<ArrayObject*> matchResultTemplateObjects_[ResultTemplateKind::NumKinds];
|
||||
|
||||
struct PerCompartmentData {
|
||||
ReadBarriered<ArrayObject*> matchResultTemplateObjects_[NumKinds];
|
||||
ReadBarriered<Shape*> optimizableRegExpPrototypeShape_;
|
||||
ReadBarriered<Shape*> optimizableRegExpInstanceShape_;
|
||||
|
||||
PerCompartmentData()
|
||||
: optimizableRegExpPrototypeShape_(nullptr),
|
||||
optimizableRegExpInstanceShape_(nullptr)
|
||||
{
|
||||
for (auto& t : matchResultTemplateObjects_)
|
||||
t = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
using PerCompartmentMap =
|
||||
GCHashMap<JSCompartment*, PerCompartmentData,
|
||||
DefaultHasher<JSCompartment*>,
|
||||
ZoneAllocPolicy>;
|
||||
|
||||
PerCompartmentMap perCompartment_; // <-- add this
|
||||
|
||||
ArrayObject* createMatchResultTemplateObject(JSContext* cx,
|
||||
ResultTemplateKind kind,
|
||||
PerCompartmentData& data);
|
||||
|
||||
/*
|
||||
* The shape of RegExp.prototype object that satisfies following:
|
||||
|
|
@ -349,19 +359,13 @@ private:
|
|||
*/
|
||||
ReadBarriered<Shape*> optimizableRegExpInstanceShape_;
|
||||
|
||||
ArrayObject* createMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind);
|
||||
|
||||
public:
|
||||
explicit RegExpCompartment(Zone* zone);
|
||||
|
||||
void sweep(JSRuntime* rt);
|
||||
|
||||
/* Get or create template object used to base the result of .exec() on. */
|
||||
ArrayObject* getOrCreateMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind = ResultTemplateKind::Normal) {
|
||||
if (matchResultTemplateObjects_[kind])
|
||||
return matchResultTemplateObjects_[kind];
|
||||
return createMatchResultTemplateObject(cx, kind);
|
||||
}
|
||||
ArrayObject* getOrCreateMatchResultTemplateObject(JSContext* cx,
|
||||
ResultTemplateKind kind = Normal);
|
||||
|
||||
Shape* getOptimizableRegExpPrototypeShape() {
|
||||
return optimizableRegExpPrototypeShape_;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue