Bug 1681084 - Part 2: Avoid unnecessary string atomization in EscapeRegExpPattern. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D98929
This commit is contained in:
André Bargull 2020-12-11 10:57:43 +00:00
Родитель 6b4d8692a3
Коммит f2eea9a341
4 изменённых файлов: 20 добавлений и 18 удалений

Просмотреть файл

@ -750,7 +750,7 @@ static bool regexp_source(JSContext* cx, unsigned argc, JS::Value* vp) {
cx->markAtom(src);
// Step 7.
JSAtom* escaped = EscapeRegExpPattern(cx, src);
JSString* escaped = EscapeRegExpPattern(cx, src);
if (!escaped) {
return false;
}

Просмотреть файл

@ -1174,7 +1174,8 @@ static UniqueChars ToDisassemblySource(JSContext* cx, HandleValue v) {
}
if (obj.is<RegExpObject>()) {
JSString* source = obj.as<RegExpObject>().toString(cx);
Rooted<RegExpObject*> reobj(cx, &obj.as<RegExpObject>());
JSString* source = RegExpObject::toString(cx, reobj);
if (!source) {
return nullptr;
}
@ -1907,8 +1908,8 @@ bool ExpressionDecompiler::decompilePC(jsbytecode* pc, uint8_t defIndex) {
case JSOp::NewArray:
return write("[]");
case JSOp::RegExp: {
RootedObject obj(cx, script->getObject(pc));
JSString* str = obj->as<RegExpObject>().toString(cx);
Rooted<RegExpObject*> obj(cx, &script->getObject(pc)->as<RegExpObject>());
JSString* str = RegExpObject::toString(cx, obj);
if (!str) {
return false;
}

Просмотреть файл

@ -448,14 +448,14 @@ static bool EscapeRegExpPattern(StringBuffer& sb, const CharT* oldChars,
}
// ES6 draft rev32 21.2.3.2.4.
JSAtom* js::EscapeRegExpPattern(JSContext* cx, HandleAtom src) {
JSLinearString* js::EscapeRegExpPattern(JSContext* cx, HandleAtom src) {
// Step 2.
if (src->length() == 0) {
return cx->names().emptyRegExp;
}
// We may never need to use |sb|. Start using it lazily.
StringBuffer sb(cx);
JSStringBuilder sb(cx);
if (src->hasLatin1Chars()) {
JS::AutoCheckCannotGC nogc;
@ -470,17 +470,18 @@ JSAtom* js::EscapeRegExpPattern(JSContext* cx, HandleAtom src) {
}
// Step 3.
return sb.empty() ? src : sb.finishAtom();
return sb.empty() ? src : sb.finishString();
}
// ES6 draft rev32 21.2.5.14. Optimized for RegExpObject.
JSLinearString* RegExpObject::toString(JSContext* cx) const {
JSLinearString* RegExpObject::toString(JSContext* cx,
Handle<RegExpObject*> obj) {
// Steps 3-4.
RootedAtom src(cx, getSource());
RootedAtom src(cx, obj->getSource());
if (!src) {
return nullptr;
}
RootedAtom escapedSrc(cx, EscapeRegExpPattern(cx, src));
RootedLinearString escapedSrc(cx, EscapeRegExpPattern(cx, src));
// Step 7.
JSStringBuilder sb(cx);
@ -495,22 +496,22 @@ JSLinearString* RegExpObject::toString(JSContext* cx) const {
sb.infallibleAppend('/');
// Steps 5-7.
if (global() && !sb.append('g')) {
if (obj->global() && !sb.append('g')) {
return nullptr;
}
if (ignoreCase() && !sb.append('i')) {
if (obj->ignoreCase() && !sb.append('i')) {
return nullptr;
}
if (multiline() && !sb.append('m')) {
if (obj->multiline() && !sb.append('m')) {
return nullptr;
}
if (dotAll() && !sb.append('s')) {
if (obj->dotAll() && !sb.append('s')) {
return nullptr;
}
if (unicode() && !sb.append('u')) {
if (obj->unicode() && !sb.append('u')) {
return nullptr;
}
if (sticky() && !sb.append('y')) {
if (obj->sticky() && !sb.append('y')) {
return nullptr;
}

Просмотреть файл

@ -129,7 +129,7 @@ class RegExpObject : public NativeObject {
setSlot(LAST_INDEX_SLOT, Int32Value(0));
}
JSLinearString* toString(JSContext* cx) const;
static JSLinearString* toString(JSContext* cx, Handle<RegExpObject*> obj);
JSAtom* getSource() const {
return &getSlot(SOURCE_SLOT).toString()->asAtom();
@ -224,7 +224,7 @@ XDRResult XDRScriptRegExpObject(XDRState<mode>* xdr,
extern JSObject* CloneScriptRegExpObject(JSContext* cx, RegExpObject& re);
/* Escape all slashes and newlines in the given string. */
extern JSAtom* EscapeRegExpPattern(JSContext* cx, HandleAtom src);
extern JSLinearString* EscapeRegExpPattern(JSContext* cx, HandleAtom src);
template <typename CharT>
extern bool HasRegExpMetaChars(const CharT* chars, size_t length);