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; }
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; }
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; }