mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 877021 - Speed up CreateRegExpMatchResult(). r=h4writer
This commit is contained in:
parent
ceb33f4d35
commit
d4f121fc23
@ -18,42 +18,19 @@ using namespace js::types;
|
||||
|
||||
using mozilla::ArrayLength;
|
||||
|
||||
class RegExpMatchBuilder
|
||||
static inline bool
|
||||
DefinePropertyHelper(JSContext *cx, HandleObject obj, Handle<PropertyName*> name, HandleValue v)
|
||||
{
|
||||
JSContext * const cx;
|
||||
RootedObject array;
|
||||
|
||||
bool setProperty(Handle<PropertyName*> name, HandleValue v) {
|
||||
return !!baseops::DefineProperty(cx, array, name, v,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
public:
|
||||
RegExpMatchBuilder(JSContext *cx, HandleObject array) : cx(cx), array(cx, array) {}
|
||||
|
||||
bool append(uint32_t index, HandleValue v) {
|
||||
JS_ASSERT(!array->getOps()->getElement);
|
||||
return !!baseops::DefineElement(cx, array, index, v, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
bool setIndex(int index) {
|
||||
RootedValue value(cx, Int32Value(index));
|
||||
return setProperty(cx->names().index, value);
|
||||
}
|
||||
|
||||
bool setInput(HandleString str) {
|
||||
JS_ASSERT(str);
|
||||
RootedValue value(cx, StringValue(str));
|
||||
return setProperty(cx->names().input, value);
|
||||
}
|
||||
};
|
||||
return !!baseops::DefineProperty(cx, obj, name, v,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
bool
|
||||
js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *chars, size_t length,
|
||||
MatchPairs &matches, MutableHandleValue rval)
|
||||
{
|
||||
RootedString input(cx, input_);
|
||||
RootedValue undefinedValue(cx, UndefinedValue());
|
||||
|
||||
/*
|
||||
* Create the (slow) result array for a match.
|
||||
@ -64,39 +41,47 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *ch
|
||||
* input: input string
|
||||
* index: start index for the match
|
||||
*/
|
||||
RootedObject array(cx, NewDenseEmptyArray(cx));
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
if (!input) {
|
||||
input = js_NewStringCopyN<CanGC>(cx, chars, length);
|
||||
if (!input)
|
||||
return false;
|
||||
}
|
||||
|
||||
RegExpMatchBuilder builder(cx, array);
|
||||
RootedValue undefinedValue(cx, UndefinedValue());
|
||||
|
||||
size_t numPairs = matches.length();
|
||||
JS_ASSERT(numPairs > 0);
|
||||
|
||||
AutoValueVector elements(cx);
|
||||
if (!elements.reserve(numPairs))
|
||||
return false;
|
||||
|
||||
/* Accumulate a Value for each pair, in a rooted vector. */
|
||||
for (size_t i = 0; i < numPairs; ++i) {
|
||||
const MatchPair &pair = matches[i];
|
||||
|
||||
RootedString captured(cx);
|
||||
if (pair.isUndefined()) {
|
||||
JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
|
||||
if (!builder.append(i, undefinedValue))
|
||||
return false;
|
||||
elements.infallibleAppend(undefinedValue);
|
||||
} else {
|
||||
captured = js_NewDependentString(cx, input, pair.start, pair.length());
|
||||
RootedValue value(cx, StringValue(captured));
|
||||
if (!captured || !builder.append(i, value))
|
||||
JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
|
||||
if (!str)
|
||||
return false;
|
||||
elements.infallibleAppend(StringValue(str));
|
||||
}
|
||||
}
|
||||
|
||||
if (!builder.setIndex(matches[0].start) || !builder.setInput(input))
|
||||
/* Copy the rooted vector into the array object. */
|
||||
RootedObject array(cx, NewDenseCopiedArray(cx, elements.length(), elements.begin()));
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
/* Set the |index| property. */
|
||||
RootedValue index(cx, Int32Value(matches[0].start));
|
||||
if (!DefinePropertyHelper(cx, array, cx->names().index, index))
|
||||
return false;
|
||||
|
||||
/* Set the |input| property. */
|
||||
RootedValue inputVal(cx, StringValue(input));
|
||||
if (!DefinePropertyHelper(cx, array, cx->names().input, inputVal))
|
||||
return false;
|
||||
|
||||
rval.setObject(*array);
|
||||
|
Loading…
Reference in New Issue
Block a user