Compare commits

..
12 changed files with 142 additions and 170 deletions

No files matched your search

@@ -249,6 +249,39 @@ ConsoleOutput.prototype = {
return message.render().element;
},
/**
* Clear the netRequests Map in this.owner.window.
* Items of NetRequest() in chrome/devtools/modules/devtools/client/webconsole/net/net-request.js
* netRequest.file holds response
* netRequest.parentNode holds div above bodyWrapper here in console-output.js
*/
onConsoleClear: function() {
let netRequests = this.owner.?window.?netRequests;
let toClear = [];
if(netRequests && netRequests.forEach){
// Build list of items to clear
netRequests.forEach(
function(netReq,key){
if (netReq.parentNode && !netReq.parentNode.parentNode) {
// DOM node was removed from the browser console output, but still referenced...
toClear.push({netReq:netReq,
key:key});
}
});
// ... and clean them up
toClear.forEach(
function(item){
let netReq = item.netReq, key = item.key;
let file = netReq.file || {};
netReq.parentNode = file.node = null;
file.request = file.response = file.cause = file.updates = null;
netReq.client = netReq.owner = netReq.file = null;
item.netReq = null;
netRequests.delete(key);
});
}
},
/**
* Get an array of selected messages. This list is based on the text selection
* start and end points.
+4
View File
@@ -960,6 +960,10 @@ JSTerm.prototype = {
hud.newConsoleOutput.dispatchMessagesClear();
}
if(hud.output && hud.output.onConsoleClear) {
hud.output.onConsoleClear();
}
this.emit("messages-cleared");
},
+37 -1
View File
@@ -309,7 +309,7 @@ WebConsoleActor.prototype =
actorPrefix: "console",
get globalDebugObject() {
return this.parentActor.threadActor.globalDebugObject;
return this.parentActor?.threadActor?.globalDebugObject;
},
grip: function WCA_grip()
@@ -1071,6 +1071,42 @@ WebConsoleActor.prototype =
ConsoleAPIStorage.clearEvents(aId);
});
if (this._actorPool && this.networkMonitor) {
// Clear NetworkEventActor items from its NetworkMonitor
let actor, aid, n;
let allActors = this._actorPool._actors;
let voidActor = {actorID:0,
release:function(){},
stub:true};
// Build list of NetworkEventActors
let netActors = [];
for (n in allActors) {
if (n.indexOf('netEvent')>=0) {
netActors.push(allActors[n]);
}
}
// ... and release them.
for (actor of netActors) {
if(actor) {
if (actor.release) {
actor.release();
}
}
}
// XXX: Sometimes the actors are not removed upon calling release() (async?)
// Force the issue by unlinking the actor from active scripting and deleting.
for (actor of netActors) {
if(actor) {
aid = actor.actorID;
if (aid && allActors[aid]) {
allActors[aid] = voidActor;
delete allActors[aid];
}
}
}
}
if (this.parentActor.isRootActor) {
Services.console.logStringMessage(null); // for the Error Console
Services.console.reset();
+3 -43
View File
@@ -32,7 +32,7 @@ using mozilla::Maybe;
using CapturesVector = GCVector<Value, 4>;
/*
* Implements RegExpBuiltinExec: Steps 18-35
* ES 2021 draft 21.2.5.2.2: Steps 16-28
* https://tc39.es/ecma262/#sec-regexpbuiltinexec
*/
bool
@@ -51,16 +51,10 @@ js::CreateRegExpMatchResult(JSContext* cx, RegExpShared& re,
* input: input string
* index: start index for the match
* groups: named capture groups for the match
* indices: capture indices for the match, if required
*/
bool hasIndices = re.hasIndices();
/* Get the templateObject that defines the shape and type of the output object */
RegExpCompartment::ResultTemplateKind kind =
hasIndices ? RegExpCompartment::ResultTemplateKind::WithIndices
: RegExpCompartment::ResultTemplateKind::Normal;
JSObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx, kind);
JSObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
if (!templateObject)
return false;
@@ -824,42 +818,15 @@ js::regexp_unicode(JSContext* cx, unsigned argc, JS::Value* vp)
return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_unicode_impl>(cx, args);
}
// ES 2022 22.2.5.6.
MOZ_ALWAYS_INLINE bool
regexp_hasIndices_impl(JSContext* cx, const CallArgs& args)
{
MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
// Step 2.a.
if (!IsRegExpObject(args.thisv())) {
args.rval().setUndefined();
return true;
}
// Steps 3-5.
Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
args.rval().setBoolean(reObj->hasIndices());
return true;
}
bool
js::regexp_hasIndices(JSContext* cx, unsigned argc, JS::Value* vp)
{
// Steps 1-3.
CallArgs args = CallArgsFromVp(argc, vp);
return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_hasIndices_impl>(cx, args);
}
const JSPropertySpec js::regexp_properties[] = {
JS_SELF_HOSTED_GET("flags", "RegExpFlagsGetter", 0),
JS_PSG("hasIndices", regexp_hasIndices, 0),
JS_PSG("global", regexp_global, 0),
JS_PSG("ignoreCase", regexp_ignoreCase, 0),
JS_PSG("multiline", regexp_multiline, 0),
JS_PSG("dotAll", regexp_dotAll, 0),
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
};
@@ -1835,13 +1802,6 @@ js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto)
if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter))
return false;
JSNative hasIndicesGetter;
if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().hasIndices), &hasIndicesGetter))
return false;
if (hasIndicesGetter != regexp_hasIndices)
return false;
JSNative globalGetter;
if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().global), &globalGetter))
return false;
+2 -4
View File
@@ -124,19 +124,17 @@ extern const JSFunctionSpec regexp_methods[];
// Used in RegExpObject::isOriginalFlagGetter.
[[nodiscard]] extern bool
regexp_hasIndices(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_global(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_ignoreCase(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_multiline(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_dotAll(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_sticky(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_unicode(JSContext* cx, unsigned argc, JS::Value* vp);
[[nodiscard]] extern bool
regexp_dotAll(JSContext* cx, unsigned argc, JS::Value* vp);
} /* namespace js */
+11 -17
View File
@@ -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/. */
// ES2022 22.2.5.4 get RegExp.prototype.flags
// ES6 draft rev34 (2015/02/20) 21.2.5.3 get RegExp.prototype.flags
// Updated for ES2018 /s (dotAll)
function RegExpFlagsGetter() {
// Steps 1-2.
var R = this;
@@ -12,36 +13,31 @@ function RegExpFlagsGetter() {
// Step 3.
var result = "";
// Steps 4-5.
if (R.hasIndices)
result += "d";
// Steps 6-7.
// Steps 4-6.
if (R.global)
result += "g";
// Steps 8-9.
// Steps 7-9.
if (R.ignoreCase)
result += "i";
// Steps 10-11.
// Steps 10-12.
if (R.multiline)
result += "m";
// Steps 12-13.
if (R.dotAll)
result += "s";
// Steps 14-15.
// Steps 13-15.
if (R.unicode)
result += "u";
// Steps 16-17.
// Steps 16-18.
if (R.sticky)
result += "y";
// ES2018
if (R.dotAll)
result += "s";
// Step 18.
// Step 19.
return result;
}
_SetCanonicalName(RegExpFlagsGetter, "get flags");
@@ -231,11 +227,9 @@ function RegExpGlobalMatchOpt(rx, S, fullUnicode) {
// Checks if following properties and getters are not modified, and accessing
// them not observed by content script:
// * flags
// * hasIndices
// * global
// * ignoreCase
// * multiline
// * dotAll
// * sticky
// * unicode
// * exec
-1
View File
@@ -85,7 +85,6 @@
#define REGEXP_STICKY_FLAG 0x08
#define REGEXP_UNICODE_FLAG 0x10
#define REGEXP_DOTALL_FLAG 0x20
#define REGEXP_HASINDICES_FLAG 0x40
#define REGEXP_STRING_ITERATOR_REGEXP_SLOT 0
#define REGEXP_STRING_ITERATOR_STRING_SLOT 1
+1 -3
View File
@@ -2083,9 +2083,7 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
while (true) {
if (!peekChar(&c))
goto error;
if (c == 'd' && !(reflags & HasIndicesFlag))
reflags = RegExpFlag(reflags | HasIndicesFlag);
else if (c == 'g' && !(reflags & GlobalFlag))
if (c == 'g' && !(reflags & GlobalFlag))
reflags = RegExpFlag(reflags | GlobalFlag);
else if (c == 'i' && !(reflags & IgnoreCaseFlag))
reflags = RegExpFlag(reflags | IgnoreCaseFlag);
+6 -7
View File
@@ -5831,13 +5831,12 @@ JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate);
/*
* 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 */
#define JSREG_DOTALL 0x20u /* match . to everything including newlines */
#define JSREG_HASINDICES 0x40u /* add .indices property to the match result */
#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 */
#define JSREG_DOTALL 0x20u /* match . to everything including newlines */
extern JS_PUBLIC_API(JSObject*)
JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags);
-2
View File
@@ -183,7 +183,6 @@
macro(groups, groups, "groups") \
macro(Handle, Handle, "Handle") \
macro(has, has, "has") \
macro(hasIndices, hasIndices, "hasIndices") \
macro(hasOwn, hasOwn, "hasOwn") \
macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \
macro(highWaterMark, highWaterMark, "highWaterMark") \
@@ -198,7 +197,6 @@
macro(includes, includes, "includes") \
macro(incumbentGlobal, incumbentGlobal, "incumbentGlobal") \
macro(index, index, "index") \
macro(indices, indices, "indices") \
macro(infinity, infinity, "infinity") \
macro(Infinity, Infinity, "Infinity") \
macro(InitializeCollator, InitializeCollator, "InitializeCollator") \
+29 -57
View File
@@ -51,7 +51,6 @@ JS_STATIC_ASSERT(MultilineFlag == JSREG_MULTILINE);
JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
JS_STATIC_ASSERT(UnicodeFlag == JSREG_UNICODE);
JS_STATIC_ASSERT(DotAllFlag == JSREG_DOTALL);
JS_STATIC_ASSERT(HasIndicesFlag == JSREG_HASINDICES);
RegExpObject*
js::RegExpAlloc(ExclusiveContext* cx, HandleObject proto /* = nullptr */)
@@ -137,10 +136,6 @@ RegExpObject::getShared(JSContext* cx, Handle<RegExpObject*> regexp,
/* static */ bool
RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlag* mask)
{
if (native == regexp_hasIndices) {
*mask = HasIndicesFlag;
return true;
}
if (native == regexp_global) {
*mask = GlobalFlag;
return true;
@@ -153,10 +148,6 @@ RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlag* mask)
*mask = MultilineFlag;
return true;
}
if (native == regexp_dotAll) {
*mask = DotAllFlag;
return true;
}
if (native == regexp_sticky) {
*mask = StickyFlag;
return true;
@@ -165,6 +156,10 @@ RegExpObject::isOriginalFlagGetter(JSNative native, RegExpFlag* mask)
*mask = UnicodeFlag;
return true;
}
if (native == regexp_dotAll) {
*mask = DotAllFlag;
return true;
}
return false;
}
@@ -493,16 +488,12 @@ RegExpObject::toString(JSContext* cx) const
sb.infallibleAppend('/');
// Steps 5-7.
if (hasIndices() && !sb.append('d'))
return nullptr;
if (global() && !sb.append('g'))
return nullptr;
if (ignoreCase() && !sb.append('i'))
return nullptr;
if (multiline() && !sb.append('m'))
return nullptr;
if (dotAll() && !sb.append('s'))
return nullptr;
if (unicode() && !sb.append('u'))
return nullptr;
if (sticky() && !sb.append('y'))
@@ -1297,13 +1288,10 @@ RegExpShared::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
RegExpCompartment::RegExpCompartment(Zone* zone)
: set_(zone, Set(zone->runtimeFromMainThread())),
matchResultTemplateObject_(nullptr),
optimizableRegExpPrototypeShape_(nullptr),
optimizableRegExpInstanceShape_(nullptr)
{
for (auto& templateObj : matchResultTemplateObjects_) {
templateObj = nullptr;
}
}
{}
RegExpCompartment::~RegExpCompartment()
{
@@ -1311,41 +1299,29 @@ RegExpCompartment::~RegExpCompartment()
}
ArrayObject*
RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind)
RegExpCompartment::createMatchResultTemplateObject(JSContext* cx)
{
MOZ_ASSERT(!matchResultTemplateObjects_[kind]);
MOZ_ASSERT(!matchResultTemplateObject_);
/* Create template array object */
RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount,
nullptr, TenuredObject));
if (!templateObject) {
return nullptr;
}
if (!templateObject)
return matchResultTemplateObject_; // = nullptr
// Create a new group for the template.
Rooted<TaggedProto> proto(cx, templateObject->taggedProto());
ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, templateObject->getClass(), proto);
if (!group)
return nullptr;
return matchResultTemplateObject_; // = nullptr
templateObject->setGroup(group);
if (kind == ResultTemplateKind::Indices) {
/* The |indices| array only has a |groups| property. */
RootedValue groupsVal(cx, UndefinedValue());
if (!NativeDefineProperty(cx, templateObject, cx->names().groups,
groupsVal, nullptr, nullptr, JSPROP_ENUMERATE)) {
return nullptr;
}
matchResultTemplateObjects_[kind].set(templateObject);
return matchResultTemplateObjects_[kind];
}
/* Set dummy index property */
RootedValue index(cx, Int32Value(0));
if (!NativeDefineProperty(cx, templateObject, cx->names().index, index, nullptr, nullptr,
JSPROP_ENUMERATE))
{
return nullptr;
return matchResultTemplateObject_; // = nullptr
}
/* Set dummy input property */
@@ -1353,7 +1329,7 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplate
if (!NativeDefineProperty(cx, templateObject, cx->names().input, inputVal, nullptr, nullptr,
JSPROP_ENUMERATE))
{
return nullptr;
return matchResultTemplateObject_; // = nullptr
}
/* Set dummy groups property */
@@ -1363,14 +1339,14 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplate
return nullptr;
}
if (kind == ResultTemplateKind::WithIndices) {
/* Set dummy indices property */
RootedValue indicesVal(cx, UndefinedValue());
if (!NativeDefineProperty(cx, templateObject, cx->names().indices,
indicesVal, nullptr, nullptr, JSPROP_ENUMERATE)) {
return nullptr;
}
}
// Make sure that the properties are in the right slots.
DebugOnly<Shape*> shape = templateObject->lastProperty();
MOZ_ASSERT(shape->slot() == 2 &&
shape->propidRef() == NameToId(cx->names().groups));
MOZ_ASSERT(shape->previous()->slot() == 1 &&
shape->previous()->propidRef() == NameToId(cx->names().input));
MOZ_ASSERT(shape->previous()->previous()->slot() == 0 &&
shape->previous()->previous()->propidRef() == NameToId(cx->names().index));
// Make sure type information reflects the indexed properties which might
// be added.
@@ -1378,9 +1354,9 @@ RegExpCompartment::createMatchResultTemplateObject(JSContext* cx, ResultTemplate
AddTypePropertyId(cx, templateObject, JSID_VOID, TypeSet::UndefinedType());
AddTypePropertyId(cx, templateObject, NameToId(cx->names().groups), TypeSet::AnyObjectType());
matchResultTemplateObjects_[kind].set(templateObject);
matchResultTemplateObject_.set(templateObject);
return matchResultTemplateObjects_[kind];
return matchResultTemplateObject_;
}
bool
@@ -1398,10 +1374,10 @@ RegExpCompartment::init(JSContext* cx)
void
RegExpCompartment::sweep(JSRuntime* rt)
{
for (auto& templateObject : matchResultTemplateObjects_) {
if (templateObject && IsAboutToBeFinalized(&templateObject)) {
templateObject.set(nullptr);
}
if (matchResultTemplateObject_ &&
IsAboutToBeFinalized(&matchResultTemplateObject_))
{
matchResultTemplateObject_.set(nullptr);
}
if (optimizableRegExpPrototypeShape_ &&
@@ -1507,18 +1483,14 @@ ParseRegExpFlags(const CharT* chars, size_t length, RegExpFlag* flagsOut, char16
for (size_t i = 0; i < length; i++) {
*lastParsedOut = chars[i];
switch (chars[i]) {
case 'd':
if (!HandleRegExpFlag(HasIndicesFlag, flagsOut))
case 'i':
if (!HandleRegExpFlag(IgnoreCaseFlag, flagsOut))
return false;
break;
case 'g':
if (!HandleRegExpFlag(GlobalFlag, flagsOut))
return false;
break;
case 'i':
if (!HandleRegExpFlag(IgnoreCaseFlag, flagsOut))
return false;
break;
case 'm':
if (!HandleRegExpFlag(MultilineFlag, flagsOut))
return false;
+16 -35
View File
@@ -56,7 +56,6 @@ enum RegExpFlag : uint8_t
StickyFlag = 0x08,
UnicodeFlag = 0x10,
DotAllFlag = 0x20,
HasIndicesFlag = 0x40,
NoFlags = 0x00,
AllFlags = 0x3f
@@ -67,8 +66,7 @@ static_assert(IgnoreCaseFlag == REGEXP_IGNORECASE_FLAG &&
MultilineFlag == REGEXP_MULTILINE_FLAG &&
StickyFlag == REGEXP_STICKY_FLAG &&
UnicodeFlag == REGEXP_UNICODE_FLAG &&
DotAllFlag == REGEXP_DOTALL_FLAG &&
HasIndicesFlag == REGEXP_HASINDICES_FLAG,
DotAllFlag == REGEXP_DOTALL_FLAG,
"Flag values should be in sync with self-hosted JS");
enum RegExpRunStatus
@@ -208,13 +206,12 @@ class RegExpShared : public gc::TenuredCell
JSAtom* getSource() const { return source; }
RegExpFlag getFlags() const { return flags; }
bool hasIndices() const { return flags & HasIndicesFlag; }
bool global() const { return flags & GlobalFlag; }
bool ignoreCase() const { return flags & IgnoreCaseFlag; }
bool global() const { return flags & GlobalFlag; }
bool multiline() const { return flags & MultilineFlag; }
bool dotAll() const { return flags & DotAllFlag; }
bool unicode() const { return flags & UnicodeFlag; }
bool sticky() const { return flags & StickyFlag; }
bool unicode() const { return flags & UnicodeFlag; }
bool dotAll() const { return flags & DotAllFlag; }
bool isCompiled(CompilationMode mode, bool latin1,
ForceByteCodeEnum force = DontForceByteCode) const {
@@ -298,27 +295,12 @@ class RegExpCompartment
using Set = GCHashSet<ReadBarriered<RegExpShared*>, Key, RuntimeAllocPolicy>;
JS::WeakCache<Set> set_;
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.
* This is the template object where the result of re.exec() is based on,
* if there is a result. This is used in CreateRegExpMatchResult to set
* the input/index properties faster.
*/
ReadBarriered<ArrayObject*> matchResultTemplateObjects_[ResultTemplateKind::NumKinds];
ReadBarriered<ArrayObject*> matchResultTemplateObject_;
/*
* The shape of RegExp.prototype object that satisfies following:
@@ -341,7 +323,7 @@ private:
*/
ReadBarriered<Shape*> optimizableRegExpInstanceShape_;
ArrayObject* createMatchResultTemplateObject(JSContext* cx, ResultTemplateKind kind);
ArrayObject* createMatchResultTemplateObject(JSContext* cx);
public:
explicit RegExpCompartment(Zone* zone);
@@ -359,10 +341,10 @@ private:
MutableHandleRegExpShared shared);
/* 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) {
if (matchResultTemplateObject_)
return matchResultTemplateObject_;
return createMatchResultTemplateObject(cx);
}
Shape* getOptimizableRegExpPrototypeShape() {
@@ -469,13 +451,12 @@ class RegExpObject : public NativeObject
setSlot(FLAGS_SLOT, Int32Value(flags));
}
bool hasIndices() const { return getFlags() & HasIndicesFlag; }
bool global() const { return getFlags() & GlobalFlag; }
bool ignoreCase() const { return getFlags() & IgnoreCaseFlag; }
bool global() const { return getFlags() & GlobalFlag; }
bool multiline() const { return getFlags() & MultilineFlag; }
bool dotAll() const { return getFlags() & DotAllFlag; }
bool unicode() const { return getFlags() & UnicodeFlag; }
bool sticky() const { return getFlags() & StickyFlag; }
bool unicode() const { return getFlags() & UnicodeFlag; }
bool dotAll() const { return getFlags() & DotAllFlag; }
static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask);