Bug 974350 part 1 - Rewrite CreateRegExpMatchResult to not use an AutoValueVector. r=h4writer

--HG--
extra : rebase_source : ea7ea2218bd93f4b9e2c67e67bdbb4cf30fe3c1c
This commit is contained in:
Jan de Mooij 2014-02-19 17:37:17 +01:00
parent b63570395c
commit f35b41773e
3 changed files with 25 additions and 36 deletions

View File

@ -39,39 +39,35 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *ch
return false;
}
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];
if (pair.isUndefined()) {
JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
elements.infallibleAppend(UndefinedHandleValue);
} else {
JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
if (!str)
return false;
elements.infallibleAppend(StringValue(str));
}
}
/* Get the templateObject that defines the shape and type of the output object */
JSObject *templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
if (!templateObject)
return false;
/* Copy the rooted vector into the array object. */
RootedObject arr(cx, NewDenseCopiedArrayWithTemplate(cx, elements.length(), elements.begin(),
templateObject));
size_t numPairs = matches.length();
JS_ASSERT(numPairs > 0);
RootedObject arr(cx, NewDenseAllocatedArrayWithTemplate(cx, numPairs, templateObject));
if (!arr)
return false;
/* Store a Value for each pair. */
for (size_t i = 0; i < numPairs; i++) {
const MatchPair &pair = matches[i];
if (pair.isUndefined()) {
JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
arr->setDenseInitializedLength(i + 1);
arr->initDenseElement(i, UndefinedValue());
} else {
JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
if (!str)
return false;
arr->setDenseInitializedLength(i + 1);
arr->initDenseElement(i, StringValue(str));
}
}
/* Set the |index| property. (TemplateObject positions it in slot 0) */
RootedValue index(cx, Int32Value(matches[0].start));
arr->nativeSetSlot(0, index);

View File

@ -3277,8 +3277,7 @@ js::NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values,
}
ArrayObject *
js::NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value *values,
JSObject *templateObject)
js::NewDenseAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject *templateObject)
{
gc::AllocKind allocKind = GuessArrayGCKind(length);
JS_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
@ -3300,9 +3299,6 @@ js::NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value
if (!EnsureNewArrayElements(cx, arr, length))
return nullptr;
arr->setDenseInitializedLength(length);
arr->initDenseElements(0, values, length);
probes::CreateObject(cx, arr);
return arr;

View File

@ -70,13 +70,10 @@ extern ArrayObject *
NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, JSObject *proto = nullptr,
NewObjectKind newKind = GenericObject);
/*
* Create a dense array based on templateObject from the given array values,
* which must be rooted.
*/
/* Create a dense array based on templateObject with the given length. */
extern ArrayObject *
NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value *values,
JSObject *templateObject);
NewDenseAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject *templateObject);
/*
* Determines whether a write to the given element on |obj| should fail because
* |obj| is an Array with a non-writable length, and writing that element would