mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 04:17:31 +09:00
Issue #2083 - Part 2: Remove use of RegExpGuard.
Based on Mozilla bug 1345177. There were more uses of RegExpGuard in js/src/builtin/RegExp.cpp not found in the original bug's patch.
This commit is contained in:
parent
3796c7c1e1
commit
d163d08cb2
21 changed files with 92 additions and 73 deletions
|
|
@ -128,7 +128,8 @@ class CPOWProxyHandler : public BaseProxyHandler
|
||||||
virtual bool isArray(JSContext* cx, HandleObject obj,
|
virtual bool isArray(JSContext* cx, HandleObject obj,
|
||||||
IsArrayAnswer* answer) const override;
|
IsArrayAnswer* answer) const override;
|
||||||
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared) const override;
|
||||||
virtual void finalize(JSFreeOp* fop, JSObject* proxy) const override;
|
virtual void finalize(JSFreeOp* fop, JSObject* proxy) const override;
|
||||||
virtual void objectMoved(JSObject* proxy, const JSObject* old) const override;
|
virtual void objectMoved(JSObject* proxy, const JSObject* old) const override;
|
||||||
virtual bool isCallable(JSObject* obj) const override;
|
virtual bool isCallable(JSObject* obj) const override;
|
||||||
|
|
@ -854,13 +855,14 @@ WrapperOwner::getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* is
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CPOWProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
|
CPOWProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared) const
|
||||||
{
|
{
|
||||||
FORWARD(regexp_toShared, (cx, proxy, g));
|
FORWARD(regexp_toShared, (cx, proxy, shared));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WrapperOwner::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g)
|
WrapperOwner::regexp_toShared(JSContext* cx, HandleObject proxy, MutableHandle<RegExpShared*> shared)
|
||||||
{
|
{
|
||||||
ObjectId objId = idOf(proxy);
|
ObjectId objId = idOf(proxy);
|
||||||
|
|
||||||
|
|
@ -880,7 +882,7 @@ WrapperOwner::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g)
|
||||||
if (!regexp)
|
if (!regexp)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return js::RegExpToSharedNonInline(cx, regexp, g);
|
return js::RegExpToSharedNonInline(cx, regexp, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,8 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||||
bool getPrototypeIfOrdinary(JSContext* cx, JS::HandleObject proxy, bool* isOrdinary,
|
bool getPrototypeIfOrdinary(JSContext* cx, JS::HandleObject proxy, bool* isOrdinary,
|
||||||
JS::MutableHandleObject protop);
|
JS::MutableHandleObject protop);
|
||||||
|
|
||||||
bool regexp_toShared(JSContext* cx, JS::HandleObject proxy, js::RegExpGuard* g);
|
bool regexp_toShared(JSContext* cx, JS::HandleObject proxy,
|
||||||
|
js::MutableHandle<js::RegExpShared*> shared);
|
||||||
|
|
||||||
nsresult instanceOf(JSObject* obj, const nsID* id, bool* bp);
|
nsresult instanceOf(JSObject* obj, const nsID* id, bool* bp);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ using JS::PrivateValue;
|
||||||
using JS::PropertyDescriptor;
|
using JS::PropertyDescriptor;
|
||||||
using JS::Value;
|
using JS::Value;
|
||||||
|
|
||||||
using RegExpGuard = JS::Rooted<RegExpShared*>;
|
class RegExpShared;
|
||||||
|
|
||||||
class JS_FRIEND_API(Wrapper);
|
class JS_FRIEND_API(Wrapper);
|
||||||
|
|
||||||
|
|
@ -328,7 +328,8 @@ class JS_FRIEND_API(BaseProxyHandler)
|
||||||
virtual bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const;
|
virtual bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const;
|
||||||
virtual const char* className(JSContext* cx, HandleObject proxy) const;
|
virtual const char* className(JSContext* cx, HandleObject proxy) const;
|
||||||
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, bool isToSource) const;
|
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy, bool isToSource) const;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const;
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<js::RegExpShared*> shared) const;
|
||||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const;
|
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const;
|
||||||
virtual void trace(JSTracer* trc, JSObject* proxy) const;
|
virtual void trace(JSTracer* trc, JSObject* proxy) const;
|
||||||
virtual void finalize(JSFreeOp* fop, JSObject* proxy) const;
|
virtual void finalize(JSFreeOp* fop, JSObject* proxy) const;
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, Handle<RegExpObject*>
|
||||||
HandleLinearString input, size_t* lastIndex, bool test,
|
HandleLinearString input, size_t* lastIndex, bool test,
|
||||||
MutableHandleValue rval)
|
MutableHandleValue rval)
|
||||||
{
|
{
|
||||||
RegExpGuard shared(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!RegExpObject::getShared(cx, reobj, &shared))
|
if (!RegExpObject::getShared(cx, reobj, &shared))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -275,7 +275,7 @@ RegExpInitializeIgnoringLastIndex(JSContext* cx, Handle<RegExpObject*> obj,
|
||||||
|
|
||||||
if (sharedUse == UseRegExpShared) {
|
if (sharedUse == UseRegExpShared) {
|
||||||
/* Steps 7-8. */
|
/* Steps 7-8. */
|
||||||
RegExpGuard re(cx);
|
RootedRegExpShared re(cx);
|
||||||
if (!cx->compartment()->regExps.get(cx, pattern, flags, &re))
|
if (!cx->compartment()->regExps.get(cx, pattern, flags, &re))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -381,7 +381,7 @@ regexp_compile_impl(JSContext* cx, const CallArgs& args)
|
||||||
RegExpFlag flags;
|
RegExpFlag flags;
|
||||||
{
|
{
|
||||||
// Step 3b.
|
// Step 3b.
|
||||||
RegExpGuard g(cx);
|
RootedRegExpShared g(cx);
|
||||||
if (!RegExpToShared(cx, patternObj, &g))
|
if (!RegExpToShared(cx, patternObj, &g))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -476,7 +476,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||||
RegExpFlag flags;
|
RegExpFlag flags;
|
||||||
{
|
{
|
||||||
// Step 4.a.
|
// Step 4.a.
|
||||||
RegExpGuard g(cx);
|
RootedRegExpShared g(cx);
|
||||||
if (!RegExpToShared(cx, patternObj, &g))
|
if (!RegExpToShared(cx, patternObj, &g))
|
||||||
return false;
|
return false;
|
||||||
sourceAtom = g->getSource();
|
sourceAtom = g->getSource();
|
||||||
|
|
@ -603,7 +603,7 @@ js::regexp_clone(JSContext* cx, unsigned argc, Value* vp)
|
||||||
RootedAtom sourceAtom(cx);
|
RootedAtom sourceAtom(cx);
|
||||||
RegExpFlag flags;
|
RegExpFlag flags;
|
||||||
{
|
{
|
||||||
RegExpGuard g(cx);
|
RootedRegExpShared g(cx);
|
||||||
if (!RegExpToShared(cx, from, &g))
|
if (!RegExpToShared(cx, from, &g))
|
||||||
return false;
|
return false;
|
||||||
sourceAtom = g->getSource();
|
sourceAtom = g->getSource();
|
||||||
|
|
@ -985,7 +985,7 @@ ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string,
|
||||||
/* Steps 1-2 performed by the caller. */
|
/* Steps 1-2 performed by the caller. */
|
||||||
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
||||||
|
|
||||||
RegExpGuard re(cx);
|
RootedRegExpShared re(cx);
|
||||||
if (!RegExpObject::getShared(cx, reobj, &re))
|
if (!RegExpObject::getShared(cx, reobj, &re))
|
||||||
return RegExpRunStatus_Error;
|
return RegExpRunStatus_Error;
|
||||||
|
|
||||||
|
|
@ -1070,7 +1070,7 @@ RegExpMatcherImpl(JSContext* cx, HandleObject regexp, HandleString string,
|
||||||
|
|
||||||
/* Steps 16-25 */
|
/* Steps 16-25 */
|
||||||
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
||||||
RegExpGuard shared(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!RegExpObject::getShared(cx, reobj, &shared))
|
if (!RegExpObject::getShared(cx, reobj, &shared))
|
||||||
return false;
|
return false;
|
||||||
return CreateRegExpMatchResult(cx, *shared, string, matches, rval);
|
return CreateRegExpMatchResult(cx, *shared, string, matches, rval);
|
||||||
|
|
@ -1117,7 +1117,7 @@ js::RegExpMatcherRaw(JSContext* cx, HandleObject regexp, HandleString input,
|
||||||
// successful only if the pairs have actually been filled in.
|
// successful only if the pairs have actually been filled in.
|
||||||
if (maybeMatches && maybeMatches->pairsRaw()[0] >= 0) {
|
if (maybeMatches && maybeMatches->pairsRaw()[0] >= 0) {
|
||||||
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
Rooted<RegExpObject*> reobj(cx, ®exp->as<RegExpObject>());
|
||||||
RegExpGuard shared(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!RegExpObject::getShared(cx, reobj, &shared))
|
if (!RegExpObject::getShared(cx, reobj, &shared))
|
||||||
return false;
|
return false;
|
||||||
return CreateRegExpMatchResult(cx, *shared, input, *maybeMatches, output);
|
return CreateRegExpMatchResult(cx, *shared, input, *maybeMatches, output);
|
||||||
|
|
|
||||||
|
|
@ -6141,7 +6141,7 @@ JS_GetRegExpFlags(JSContext* cx, HandleObject obj)
|
||||||
AssertHeapIsIdle(cx);
|
AssertHeapIsIdle(cx);
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
|
|
||||||
RegExpGuard shared(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!RegExpToShared(cx, obj, &shared))
|
if (!RegExpToShared(cx, obj, &shared))
|
||||||
return false;
|
return false;
|
||||||
return shared->getFlags();
|
return shared->getFlags();
|
||||||
|
|
@ -6153,7 +6153,7 @@ JS_GetRegExpSource(JSContext* cx, HandleObject obj)
|
||||||
AssertHeapIsIdle(cx);
|
AssertHeapIsIdle(cx);
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
|
|
||||||
RegExpGuard shared(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!RegExpToShared(cx, obj, &shared))
|
if (!RegExpToShared(cx, obj, &shared))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return shared->getSource();
|
return shared->getSource();
|
||||||
|
|
|
||||||
|
|
@ -1114,9 +1114,9 @@ extern JS_FRIEND_API(unsigned)
|
||||||
GetEnterCompartmentDepth(JSContext* cx);
|
GetEnterCompartmentDepth(JSContext* cx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using RegExpGuard = JS::Rooted<RegExpShared*>;
|
|
||||||
extern JS_FRIEND_API(bool)
|
extern JS_FRIEND_API(bool)
|
||||||
RegExpToSharedNonInline(JSContext* cx, JS::HandleObject regexp, RegExpGuard* shared);
|
RegExpToSharedNonInline(JSContext* cx, JS::HandleObject regexp,
|
||||||
|
JS::MutableHandle<RegExpShared*> shared);
|
||||||
|
|
||||||
/* Implemented in jswrapper.cpp. */
|
/* Implemented in jswrapper.cpp. */
|
||||||
typedef enum NukeReferencesToWindow {
|
typedef enum NukeReferencesToWindow {
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ class JS_FRIEND_API(Wrapper) : public BaseProxyHandler
|
||||||
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
||||||
bool isToSource) const override;
|
bool isToSource) const override;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
RegExpGuard* g) const override;
|
MutableHandle<RegExpShared*> shared) const override;
|
||||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy,
|
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy,
|
||||||
MutableHandleValue vp) const override;
|
MutableHandleValue vp) const override;
|
||||||
virtual bool isCallable(JSObject* obj) const override;
|
virtual bool isCallable(JSObject* obj) const override;
|
||||||
|
|
@ -211,7 +211,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
|
||||||
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
||||||
virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper,
|
virtual JSString* fun_toString(JSContext* cx, HandleObject wrapper,
|
||||||
bool isToSource) const override;
|
bool isToSource) const override;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared) const override;
|
||||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
|
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
|
||||||
|
|
||||||
// Allocate CrossCompartmentWrappers in the nursery.
|
// Allocate CrossCompartmentWrappers in the nursery.
|
||||||
|
|
@ -312,7 +313,8 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
|
||||||
const CallArgs& args) const override;
|
const CallArgs& args) const override;
|
||||||
virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override;
|
virtual bool getBuiltinClass(JSContext* cx, HandleObject wrapper, ESClass* cls) const override;
|
||||||
virtual bool isArray(JSContext* cx, HandleObject wrapper, JS::IsArrayAnswer* answer) const override;
|
virtual bool isArray(JSContext* cx, HandleObject wrapper, JS::IsArrayAnswer* answer) const override;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared) const override;
|
||||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
|
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const override;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ BaseProxyHandler::fun_toString(JSContext* cx, HandleObject proxy, bool isToSourc
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BaseProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy,
|
BaseProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
RegExpGuard* g) const
|
MutableHandleRegExpShared shared) const
|
||||||
{
|
{
|
||||||
MOZ_CRASH("This should have been a wrapped regexp");
|
MOZ_CRASH("This should have been a wrapped regexp");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,9 +437,10 @@ CrossCompartmentWrapper::fun_toString(JSContext* cx, HandleObject wrapper, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CrossCompartmentWrapper::regexp_toShared(JSContext* cx, HandleObject wrapper, RegExpGuard* g) const
|
CrossCompartmentWrapper::regexp_toShared(JSContext* cx, HandleObject wrapper,
|
||||||
|
MutableHandleRegExpShared shared) const
|
||||||
{
|
{
|
||||||
RegExpGuard re(cx);
|
RootedRegExpShared re(cx);
|
||||||
{
|
{
|
||||||
AutoCompartment call(cx, wrappedObject(wrapper));
|
AutoCompartment call(cx, wrappedObject(wrapper));
|
||||||
if (!Wrapper::regexp_toShared(cx, wrapper, &re))
|
if (!Wrapper::regexp_toShared(cx, wrapper, &re))
|
||||||
|
|
@ -447,7 +448,7 @@ CrossCompartmentWrapper::regexp_toShared(JSContext* cx, HandleObject wrapper, Re
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an equivalent RegExpShared associated with the current compartment.
|
// Get an equivalent RegExpShared associated with the current compartment.
|
||||||
return cx->compartment()->regExps.get(cx, re->getSource(), re->getFlags(), g);
|
return cx->compartment()->regExps.get(cx, re->getSource(), re->getFlags(), shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,8 @@ DeadObjectProxy::fun_toString(JSContext* cx, HandleObject proxy, bool isToSource
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DeadObjectProxy::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
|
DeadObjectProxy::regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared) const
|
||||||
{
|
{
|
||||||
ReportDead(cx);
|
ReportDead(cx);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,8 @@ class DeadObjectProxy : public BaseProxyHandler
|
||||||
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
virtual const char* className(JSContext* cx, HandleObject proxy) const override;
|
||||||
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
||||||
bool isToSource) const override;
|
bool isToSource) const override;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const override;
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared) const override;
|
||||||
|
|
||||||
virtual bool isCallable(JSObject* obj) const override;
|
virtual bool isCallable(JSObject* obj) const override;
|
||||||
virtual bool isConstructor(JSObject* obj) const override;
|
virtual bool isConstructor(JSObject* obj) const override;
|
||||||
|
|
|
||||||
|
|
@ -488,10 +488,10 @@ Proxy::fun_toString(JSContext* cx, HandleObject proxy, bool isToSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Proxy::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g)
|
Proxy::regexp_toShared(JSContext* cx, HandleObject proxy, MutableHandleRegExpShared shared)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
return proxy->as<ProxyObject>().handler()->regexp_toShared(cx, proxy, g);
|
return proxy->as<ProxyObject>().handler()->regexp_toShared(cx, proxy, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,8 @@ class Proxy
|
||||||
static bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer);
|
static bool isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer);
|
||||||
static const char* className(JSContext* cx, HandleObject proxy);
|
static const char* className(JSContext* cx, HandleObject proxy);
|
||||||
static JSString* fun_toString(JSContext* cx, HandleObject proxy, bool isToSource);
|
static JSString* fun_toString(JSContext* cx, HandleObject proxy, bool isToSource);
|
||||||
static bool regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g);
|
static bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandle<RegExpShared*> shared);
|
||||||
static bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp);
|
static bool boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp);
|
||||||
|
|
||||||
static bool getElements(JSContext* cx, HandleObject obj, uint32_t begin, uint32_t end,
|
static bool getElements(JSContext* cx, HandleObject obj, uint32_t begin, uint32_t end,
|
||||||
|
|
|
||||||
|
|
@ -1265,7 +1265,8 @@ ScriptedProxyHandler::fun_toString(JSContext* cx, HandleObject proxy, bool isToS
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ScriptedProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
|
ScriptedProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
|
MutableHandleRegExpShared shared) const
|
||||||
{
|
{
|
||||||
MOZ_CRASH("Should not end up in ScriptedProxyHandler::regexp_toShared");
|
MOZ_CRASH("Should not end up in ScriptedProxyHandler::regexp_toShared");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ class ScriptedProxyHandler : public BaseProxyHandler
|
||||||
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
|
||||||
bool isToSource) const override;
|
bool isToSource) const override;
|
||||||
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
virtual bool regexp_toShared(JSContext* cx, HandleObject proxy,
|
||||||
RegExpGuard* g) const override;
|
MutableHandle<RegExpShared*> shared) const override;
|
||||||
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy,
|
virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy,
|
||||||
MutableHandleValue vp) const override;
|
MutableHandleValue vp) const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,10 @@ SecurityWrapper<Base>::isArray(JSContext* cx, HandleObject obj, JS::IsArrayAnswe
|
||||||
|
|
||||||
template <class Base>
|
template <class Base>
|
||||||
bool
|
bool
|
||||||
SecurityWrapper<Base>::regexp_toShared(JSContext* cx, HandleObject obj, RegExpGuard* g) const
|
SecurityWrapper<Base>::regexp_toShared(JSContext* cx, HandleObject obj,
|
||||||
|
MutableHandle<RegExpShared*> shared) const
|
||||||
{
|
{
|
||||||
return Base::regexp_toShared(cx, obj, g);
|
return Base::regexp_toShared(cx, obj, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Base>
|
template <class Base>
|
||||||
|
|
|
||||||
|
|
@ -267,10 +267,10 @@ Wrapper::fun_toString(JSContext* cx, HandleObject proxy, bool isToSource) const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Wrapper::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
|
Wrapper::regexp_toShared(JSContext* cx, HandleObject proxy, MutableHandleRegExpShared shared) const
|
||||||
{
|
{
|
||||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||||
return RegExpToShared(cx, target, g);
|
return RegExpToShared(cx, target, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -122,14 +122,15 @@ VectorMatchPairs::allocOrExpandArray(size_t pairCount)
|
||||||
/* RegExpObject */
|
/* RegExpObject */
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
RegExpObject::getShared(JSContext* cx, Handle<RegExpObject*> regexp, RegExpGuard* g)
|
RegExpObject::getShared(JSContext* cx, Handle<RegExpObject*> regexp,
|
||||||
|
MutableHandleRegExpShared shared)
|
||||||
{
|
{
|
||||||
if (regexp->hasShared()) {
|
if (regexp->hasShared()) {
|
||||||
g->set(regexp->sharedRef());
|
shared.set(regexp->sharedRef());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return createShared(cx, regexp, g);
|
return createShared(cx, regexp, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
|
|
@ -278,13 +279,14 @@ RegExpObject::create(ExclusiveContext* cx, HandleAtom source, RegExpFlag flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
RegExpObject::createShared(JSContext* cx, Handle<RegExpObject*> regexp, RegExpGuard* g)
|
RegExpObject::createShared(JSContext* cx, Handle<RegExpObject*> regexp,
|
||||||
|
MutableHandleRegExpShared shared)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!regexp->hasShared());
|
MOZ_ASSERT(!regexp->hasShared());
|
||||||
if (!cx->compartment()->regExps.get(cx, regexp->getSource(), regexp->getFlags(), g))
|
if (!cx->compartment()->regExps.get(cx, regexp->getSource(), regexp->getFlags(), shared))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
regexp->setShared(**g);
|
regexp->setShared(*shared);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -891,11 +893,11 @@ RegExpShared::dumpBytecode(JSContext* cx, bool match_only, HandleLinearString in
|
||||||
RegExpObject::dumpBytecode(JSContext* cx, Handle<RegExpObject*> regexp,
|
RegExpObject::dumpBytecode(JSContext* cx, Handle<RegExpObject*> regexp,
|
||||||
bool match_only, HandleLinearString input)
|
bool match_only, HandleLinearString input)
|
||||||
{
|
{
|
||||||
RegExpGuard g(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!getShared(cx, regexp, &g))
|
if (!getShared(cx, regexp, &shared))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return g->dumpBytecode(cx, match_only, input);
|
return shared->dumpBytecode(cx, match_only, input);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1351,11 +1353,12 @@ RegExpCompartment::sweep(JSRuntime* rt)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RegExpCompartment::get(JSContext* cx, JSAtom* source, RegExpFlag flags, RegExpGuard* g)
|
RegExpCompartment::get(JSContext* cx, JSAtom* source, RegExpFlag flags,
|
||||||
|
MutableHandleRegExpShared result)
|
||||||
{
|
{
|
||||||
DependentAddPtr<Set> p(cx, set_.get(), Key(source, flags));
|
DependentAddPtr<Set> p(cx, set_.get(), Key(source, flags));
|
||||||
if (p) {
|
if (p) {
|
||||||
g->set(*p);
|
result.set(*p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1370,18 +1373,19 @@ RegExpCompartment::get(JSContext* cx, JSAtom* source, RegExpFlag flags, RegExpGu
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g->set(shared);
|
result.set(shared);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RegExpCompartment::get(JSContext* cx, HandleAtom atom, JSString* opt, RegExpGuard* g)
|
RegExpCompartment::get(JSContext* cx, HandleAtom atom, JSString* opt,
|
||||||
|
MutableHandleRegExpShared shared)
|
||||||
{
|
{
|
||||||
RegExpFlag flags = RegExpFlag(0);
|
RegExpFlag flags = RegExpFlag(0);
|
||||||
if (opt && !ParseRegExpFlags(cx, opt, &flags))
|
if (opt && !ParseRegExpFlags(cx, opt, &flags))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return get(cx, atom, flags, g);
|
return get(cx, atom, flags, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|
@ -1410,12 +1414,12 @@ js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
|
||||||
|
|
||||||
Rooted<JSAtom*> source(cx, regex->getSource());
|
Rooted<JSAtom*> source(cx, regex->getSource());
|
||||||
|
|
||||||
RegExpGuard g(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!RegExpObject::getShared(cx, regex, &g))
|
if (!RegExpObject::getShared(cx, regex, &shared))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
clone->initAndZeroLastIndex(source, g->getFlags(), cx);
|
clone->initAndZeroLastIndex(source, shared->getFlags(), cx);
|
||||||
clone->setShared(*g);
|
clone->setShared(*shared);
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
@ -1554,9 +1558,9 @@ js::CloneScriptRegExpObject(JSContext* cx, RegExpObject& reobj)
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_FRIEND_API(bool)
|
JS_FRIEND_API(bool)
|
||||||
js::RegExpToSharedNonInline(JSContext* cx, HandleObject obj, js::RegExpGuard* g)
|
js::RegExpToSharedNonInline(JSContext* cx, HandleObject obj, MutableHandleRegExpShared shared)
|
||||||
{
|
{
|
||||||
return RegExpToShared(cx, obj, g);
|
return RegExpToShared(cx, obj, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::ubi::Node::Size
|
JS::ubi::Node::Size
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,8 @@
|
||||||
*
|
*
|
||||||
* To save memory, a RegExpShared is not created for a RegExpObject until it is
|
* To save memory, a RegExpShared is not created for a RegExpObject until it is
|
||||||
* needed for execution. When a RegExpShared needs to be created, it is looked
|
* needed for execution. When a RegExpShared needs to be created, it is looked
|
||||||
* up in a per-compartment table to allow reuse between objects. Lastly, on
|
* up in a per-compartment table to allow reuse between objects. Lastly, on GC,
|
||||||
* GC, every RegExpShared (that is not active on the callstack) is discarded.
|
* every RegExpShared that is not in active use is discarded.
|
||||||
* Because of the last point, any code using a RegExpShared (viz., by executing
|
|
||||||
* a regexp) must indicate the RegExpShared is active via RegExpGuard.
|
|
||||||
*/
|
*/
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
|
|
@ -251,6 +249,10 @@ class RegExpShared : public gc::TenuredCell
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using RootedRegExpShared = JS::Rooted<RegExpShared*>;
|
||||||
|
using HandleRegExpShared = JS::Handle<RegExpShared*>;
|
||||||
|
using MutableHandleRegExpShared = JS::MutableHandle<RegExpShared*>;
|
||||||
|
|
||||||
class RegExpCompartment
|
class RegExpCompartment
|
||||||
{
|
{
|
||||||
struct Key {
|
struct Key {
|
||||||
|
|
@ -321,10 +323,11 @@ class RegExpCompartment
|
||||||
|
|
||||||
bool empty() { return set_.empty(); }
|
bool empty() { return set_.empty(); }
|
||||||
|
|
||||||
bool get(JSContext* cx, JSAtom* source, RegExpFlag flags, RegExpGuard* g);
|
bool get(JSContext* cx, JSAtom* source, RegExpFlag flags, MutableHandleRegExpShared shared);
|
||||||
|
|
||||||
/* Like 'get', but compile 'maybeOpt' (if non-null). */
|
/* Like 'get', but compile 'maybeOpt' (if non-null). */
|
||||||
bool get(JSContext* cx, HandleAtom source, JSString* maybeOpt, RegExpGuard* g);
|
bool get(JSContext* cx, HandleAtom source, JSString* maybeOpt,
|
||||||
|
MutableHandleRegExpShared shared);
|
||||||
|
|
||||||
/* Get or create template object used to base the result of .exec() on. */
|
/* Get or create template object used to base the result of .exec() on. */
|
||||||
ArrayObject* getOrCreateMatchResultTemplateObject(JSContext* cx) {
|
ArrayObject* getOrCreateMatchResultTemplateObject(JSContext* cx) {
|
||||||
|
|
@ -447,7 +450,7 @@ class RegExpObject : public NativeObject
|
||||||
static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask);
|
static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask);
|
||||||
|
|
||||||
static MOZ_MUST_USE bool getShared(JSContext* cx, Handle<RegExpObject*> regexp,
|
static MOZ_MUST_USE bool getShared(JSContext* cx, Handle<RegExpObject*> regexp,
|
||||||
RegExpGuard* g);
|
MutableHandleRegExpShared shared);
|
||||||
|
|
||||||
bool hasShared() {
|
bool hasShared() {
|
||||||
return !!sharedRef();
|
return !!sharedRef();
|
||||||
|
|
@ -479,7 +482,7 @@ class RegExpObject : public NativeObject
|
||||||
* Side effect: sets the private field.
|
* Side effect: sets the private field.
|
||||||
*/
|
*/
|
||||||
static MOZ_MUST_USE bool createShared(JSContext* cx, Handle<RegExpObject*> regexp,
|
static MOZ_MUST_USE bool createShared(JSContext* cx, Handle<RegExpObject*> regexp,
|
||||||
RegExpGuard* g);
|
MutableHandleRegExpShared shared);
|
||||||
|
|
||||||
ReadBarriered<RegExpShared*>& sharedRef() {
|
ReadBarriered<RegExpShared*>& sharedRef() {
|
||||||
auto& ref = NativeObject::privateRef(PRIVATE_SLOT);
|
auto& ref = NativeObject::privateRef(PRIVATE_SLOT);
|
||||||
|
|
@ -501,12 +504,12 @@ ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut);
|
||||||
|
|
||||||
/* Assuming GetBuiltinClass(obj) is ESClass::RegExp, return a RegExpShared for obj. */
|
/* Assuming GetBuiltinClass(obj) is ESClass::RegExp, return a RegExpShared for obj. */
|
||||||
inline bool
|
inline bool
|
||||||
RegExpToShared(JSContext* cx, HandleObject obj, RegExpGuard* g)
|
RegExpToShared(JSContext* cx, HandleObject obj, MutableHandleRegExpShared shared)
|
||||||
{
|
{
|
||||||
if (obj->is<RegExpObject>())
|
if (obj->is<RegExpObject>())
|
||||||
return RegExpObject::getShared(cx, obj.as<RegExpObject>(), g);
|
return RegExpObject::getShared(cx, obj.as<RegExpObject>(), shared);
|
||||||
|
|
||||||
return Proxy::regexp_toShared(cx, obj, g);
|
return Proxy::regexp_toShared(cx, obj, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<XDRMode mode>
|
template<XDRMode mode>
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ RegExpStatics::executeLazy(JSContext* cx)
|
||||||
MOZ_ASSERT(lazyIndex != size_t(-1));
|
MOZ_ASSERT(lazyIndex != size_t(-1));
|
||||||
|
|
||||||
/* Retrieve or create the RegExpShared in this compartment. */
|
/* Retrieve or create the RegExpShared in this compartment. */
|
||||||
RegExpGuard g(cx);
|
RootedRegExpShared shared(cx);
|
||||||
if (!cx->compartment()->regExps.get(cx, lazySource, lazyFlags, &g))
|
if (!cx->compartment()->regExps.get(cx, lazySource, lazyFlags, &shared))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -91,7 +91,7 @@ RegExpStatics::executeLazy(JSContext* cx)
|
||||||
|
|
||||||
/* Execute the full regular expression. */
|
/* Execute the full regular expression. */
|
||||||
RootedLinearString input(cx, matchesInput);
|
RootedLinearString input(cx, matchesInput);
|
||||||
RegExpRunStatus status = g->execute(cx, input, lazyIndex, &this->matches, nullptr);
|
RegExpRunStatus status = shared->execute(cx, input, lazyIndex, &this->matches, nullptr);
|
||||||
if (status == RegExpRunStatus_Error)
|
if (status == RegExpRunStatus_Error)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1402,7 +1402,7 @@ JSStructuredCloneWriter::startWrite(HandleValue v)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (cls == ESClass::RegExp) {
|
if (cls == ESClass::RegExp) {
|
||||||
RegExpGuard re(context());
|
RootedRegExpShared re(context());
|
||||||
if (!RegExpToShared(context(), obj, &re))
|
if (!RegExpToShared(context(), obj, &re))
|
||||||
return false;
|
return false;
|
||||||
return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags()) &&
|
return out.writePair(SCTAG_REGEXP_OBJECT, re->getFlags()) &&
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue