Example #1
0
bool
js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *chars, size_t length,
                            MatchPairs &matches, MutableHandleValue rval)
{
    RootedString input(cx, input_);

    /*
     * Create the (slow) result array for a match.
     *
     * Array contents:
     *  0:              matched string
     *  1..pairCount-1: paren matches
     *  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);

    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;
        } else {
            captured = js_NewDependentString(cx, input, pair.start, pair.length());
            RootedValue value(cx, StringValue(captured));
            if (!captured || !builder.append(i, value))
                return false;
        }
    }

    if (!builder.setIndex(matches[0].start) || !builder.setInput(input))
        return false;

    rval.setObject(*array);
    return true;
}
Example #2
0
bool
js::CreateRegExpMatchResult(JSContext* cx, HandleString input, const MatchPairs& matches,
                            MutableHandleValue rval)
{
    MOZ_ASSERT(input);

    /*
     * Create the (slow) result array for a match.
     *
     * Array contents:
     *  0:              matched string
     *  1..pairCount-1: paren matches
     *  input:          input string
     *  index:          start index for the match
     */

    /* Get the templateObject that defines the shape and type of the output object */
    JSObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
    if (!templateObject)
        return false;

    size_t numPairs = matches.length();
    MOZ_ASSERT(numPairs > 0);

    RootedArrayObject arr(cx, NewDenseFullyAllocatedArrayWithTemplate(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()) {
            MOZ_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
            arr->setDenseInitializedLength(i + 1);
            arr->initDenseElement(i, UndefinedValue());
        } else {
            JSLinearString* str = 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) */
    arr->setSlot(0, Int32Value(matches[0].start));

    /* Set the |input| property. (TemplateObject positions it in slot 1) */
    arr->setSlot(1, StringValue(input));

#ifdef DEBUG
    RootedValue test(cx);
    RootedId id(cx, NameToId(cx->names().index));
    if (!NativeGetProperty(cx, arr, id, &test))
        return false;
    MOZ_ASSERT(test == arr->getSlot(0));
    id = NameToId(cx->names().input);
    if (!NativeGetProperty(cx, arr, id, &test))
        return false;
    MOZ_ASSERT(test == arr->getSlot(1));
#endif

    rval.setObject(*arr);
    return true;
}
Example #3
0
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.
     *
     * Array contents:
     *  0:              matched string
     *  1..pairCount-1: paren matches
     *  input:          input string
     *  index:          start index for the match
     */
    if (!input) {
        input = js_NewStringCopyN<CanGC>(cx, chars, length);
        if (!input)
            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(undefinedValue);
        } else {
            JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
            if (!str)
                return false;
            elements.infallibleAppend(StringValue(str));
        }
    }

    /* 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);
    return true;
}