mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-07 03:45:42 +00:00
Backed out changeset 759b21bbb64b (bug 610223) due to Windows build bustage, a=red
This commit is contained in:
parent
e7f1aced19
commit
a9d2b1cd5a
@ -1,8 +0,0 @@
|
|||||||
var re = /(pattern)/g;
|
|
||||||
var input = "patternpatternpattern";
|
|
||||||
re.exec(input)
|
|
||||||
RegExp.input = "satturn";
|
|
||||||
assertEq(RegExp.$1, "pattern");
|
|
||||||
assertEq(RegExp.lastMatch, "pattern");
|
|
||||||
assertEq(RegExp.lastParen, "pattern");
|
|
||||||
assertEq(RegExp.rightContext, "patternpattern");
|
|
@ -1,8 +0,0 @@
|
|||||||
var re = /abc(WHOO!)?def/y;
|
|
||||||
var input = 'abcdefabcdefabcdef';
|
|
||||||
var count = 0;
|
|
||||||
while ((match = re.exec(input)) !== null) {
|
|
||||||
print(count++);
|
|
||||||
assertEq(match[0], 'abcdef');
|
|
||||||
assertEq(match[1], undefined);
|
|
||||||
}
|
|
@ -393,7 +393,7 @@ regexp_resolve(JSContext *cx, JSObject *obj, jsid id, uint32 flags, JSObject **o
|
|||||||
code; \
|
code; \
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_STATIC_GETTER(static_input_getter, return res->createPendingInput(cx, Valueify(vp)))
|
DEFINE_STATIC_GETTER(static_input_getter, return res->createInput(cx, Valueify(vp)))
|
||||||
DEFINE_STATIC_GETTER(static_multiline_getter, *vp = BOOLEAN_TO_JSVAL(res->multiline());
|
DEFINE_STATIC_GETTER(static_multiline_getter, *vp = BOOLEAN_TO_JSVAL(res->multiline());
|
||||||
return true)
|
return true)
|
||||||
DEFINE_STATIC_GETTER(static_lastMatch_getter, return res->createLastMatch(cx, Valueify(vp)))
|
DEFINE_STATIC_GETTER(static_lastMatch_getter, return res->createLastMatch(cx, Valueify(vp)))
|
||||||
@ -423,7 +423,7 @@ DEFINE_STATIC_GETTER(static_paren9_getter, return res->createParen(cx, 8,
|
|||||||
DEFINE_STATIC_SETTER(static_input_setter,
|
DEFINE_STATIC_SETTER(static_input_setter,
|
||||||
if (!JSVAL_IS_STRING(*vp) && !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp))
|
if (!JSVAL_IS_STRING(*vp) && !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp))
|
||||||
return false;
|
return false;
|
||||||
res->setPendingInput(JSVAL_TO_STRING(*vp)))
|
res->setInput(JSVAL_TO_STRING(*vp)))
|
||||||
DEFINE_STATIC_SETTER(static_multiline_setter,
|
DEFINE_STATIC_SETTER(static_multiline_setter,
|
||||||
if (!JSVAL_IS_BOOLEAN(*vp) && !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp))
|
if (!JSVAL_IS_BOOLEAN(*vp) && !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp))
|
||||||
return false;
|
return false;
|
||||||
@ -783,7 +783,7 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, Value *argv, JSBool te
|
|||||||
argv[0] = StringValue(str);
|
argv[0] = StringValue(str);
|
||||||
} else {
|
} else {
|
||||||
/* Need to grab input from statics. */
|
/* Need to grab input from statics. */
|
||||||
str = res->getPendingInput();
|
str = res->getInput();
|
||||||
if (!str) {
|
if (!str) {
|
||||||
const char *sourceBytes = js_GetStringBytes(cx, re->getSource());
|
const char *sourceBytes = js_GetStringBytes(cx, re->getSource());
|
||||||
if (sourceBytes) {
|
if (sourceBytes) {
|
||||||
|
@ -59,14 +59,11 @@ namespace js {
|
|||||||
class RegExpStatics
|
class RegExpStatics
|
||||||
{
|
{
|
||||||
typedef Vector<int, 20, SystemAllocPolicy> MatchPairs;
|
typedef Vector<int, 20, SystemAllocPolicy> MatchPairs;
|
||||||
MatchPairs matchPairs;
|
MatchPairs matchPairs;
|
||||||
/* The input that was used to produce matchPairs. */
|
JSString *input;
|
||||||
JSString *matchPairsInput;
|
uintN flags;
|
||||||
/* The input last set on the statics. */
|
RegExpStatics *bufferLink;
|
||||||
JSString *pendingInput;
|
bool copied;
|
||||||
uintN flags;
|
|
||||||
RegExpStatics *bufferLink;
|
|
||||||
bool copied;
|
|
||||||
|
|
||||||
bool createDependent(JSContext *cx, size_t start, size_t end, Value *out) const;
|
bool createDependent(JSContext *cx, size_t start, size_t end, Value *out) const;
|
||||||
|
|
||||||
@ -79,8 +76,7 @@ class RegExpStatics
|
|||||||
dst.matchPairs.clear();
|
dst.matchPairs.clear();
|
||||||
/* 'save' has already reserved space in matchPairs */
|
/* 'save' has already reserved space in matchPairs */
|
||||||
JS_ALWAYS_TRUE(dst.matchPairs.append(matchPairs));
|
JS_ALWAYS_TRUE(dst.matchPairs.append(matchPairs));
|
||||||
dst.matchPairsInput = matchPairsInput;
|
dst.input = input;
|
||||||
dst.pendingInput = pendingInput;
|
|
||||||
dst.flags = flags;
|
dst.flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +87,25 @@ class RegExpStatics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether the index at |checkValidIndex| is valid (>= 0).
|
||||||
|
* If so, construct a string for it and place it in |*out|.
|
||||||
|
* If not, place undefined in |*out|.
|
||||||
|
*/
|
||||||
|
bool makeMatch(JSContext *cx, size_t checkValidIndex, size_t pairNum, Value *out) const;
|
||||||
|
static const uintN allFlags = JSREG_FOLD | JSREG_GLOB | JSREG_STICKY | JSREG_MULTILINE;
|
||||||
|
friend class RegExp;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegExpStatics() : bufferLink(NULL), copied(false) { clear(); }
|
||||||
|
|
||||||
|
struct InitBuffer {};
|
||||||
|
explicit RegExpStatics(InitBuffer) : bufferLink(NULL), copied(false) {}
|
||||||
|
|
||||||
|
static RegExpStatics *extractFrom(JSObject *global);
|
||||||
|
|
||||||
|
/* Mutators. */
|
||||||
|
|
||||||
bool save(JSContext *cx, RegExpStatics *buffer) {
|
bool save(JSContext *cx, RegExpStatics *buffer) {
|
||||||
JS_ASSERT(!buffer->copied && !buffer->bufferLink);
|
JS_ASSERT(!buffer->copied && !buffer->bufferLink);
|
||||||
buffer->bufferLink = bufferLink;
|
buffer->bufferLink = bufferLink;
|
||||||
@ -108,76 +123,6 @@ class RegExpStatics
|
|||||||
bufferLink = bufferLink->bufferLink;
|
bufferLink = bufferLink->bufferLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkInvariants() {
|
|
||||||
#if DEBUG
|
|
||||||
if (pairCount() == 0) {
|
|
||||||
JS_ASSERT(!matchPairsInput);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pair count is non-zero, so there must be match pairs input. */
|
|
||||||
JS_ASSERT(matchPairsInput);
|
|
||||||
size_t mpiLen = matchPairsInput->length();
|
|
||||||
|
|
||||||
JS_ASSERT(pairIsPresent(0));
|
|
||||||
|
|
||||||
/* Present pairs must be valid. */
|
|
||||||
for (size_t i = 0; i < pairCount(); ++i) {
|
|
||||||
if (!pairIsPresent(i))
|
|
||||||
continue;
|
|
||||||
int start = get(i, 0);
|
|
||||||
int limit = get(i, 1);
|
|
||||||
JS_ASSERT(mpiLen >= size_t(limit) && limit >= start && start >= 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int get(size_t pairNum, bool which) const {
|
|
||||||
JS_ASSERT(pairNum < pairCount());
|
|
||||||
return matchPairs[2 * pairNum + which];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether the index at |checkValidIndex| is valid (>= 0).
|
|
||||||
* If so, construct a string for it and place it in |*out|.
|
|
||||||
* If not, place undefined in |*out|.
|
|
||||||
*/
|
|
||||||
bool makeMatch(JSContext *cx, size_t checkValidIndex, size_t pairNum, Value *out) const;
|
|
||||||
|
|
||||||
static const uintN allFlags = JSREG_FOLD | JSREG_GLOB | JSREG_STICKY | JSREG_MULTILINE;
|
|
||||||
|
|
||||||
struct InitBuffer {};
|
|
||||||
explicit RegExpStatics(InitBuffer) : bufferLink(NULL), copied(false) {}
|
|
||||||
|
|
||||||
friend class PreserveRegExpStatics;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RegExpStatics() : bufferLink(NULL), copied(false) { clear(); }
|
|
||||||
|
|
||||||
static RegExpStatics *extractFrom(JSObject *global);
|
|
||||||
|
|
||||||
/* Mutators. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The inputOffset parameter is added to the present (i.e. non-negative) match items to emulate
|
|
||||||
* sticky mode.
|
|
||||||
*/
|
|
||||||
bool updateFromMatch(JSContext *cx, JSString *input, int *buf, size_t matchItemCount) {
|
|
||||||
aboutToWrite();
|
|
||||||
pendingInput = input;
|
|
||||||
|
|
||||||
if (!matchPairs.resizeUninitialized(matchItemCount)) {
|
|
||||||
js_ReportOutOfMemory(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < matchItemCount; ++i)
|
|
||||||
matchPairs[i] = buf[i];
|
|
||||||
|
|
||||||
matchPairsInput = input;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMultiline(bool enabled) {
|
void setMultiline(bool enabled) {
|
||||||
aboutToWrite();
|
aboutToWrite();
|
||||||
if (enabled)
|
if (enabled)
|
||||||
@ -188,61 +133,43 @@ class RegExpStatics
|
|||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
aboutToWrite();
|
aboutToWrite();
|
||||||
|
input = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
pendingInput = NULL;
|
|
||||||
matchPairsInput = NULL;
|
|
||||||
matchPairs.clear();
|
matchPairs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pairIsPresent(size_t pairNum) { return get(0, 0) != -1; }
|
void checkInvariants() {
|
||||||
|
if (pairCount() > 0) {
|
||||||
|
JS_ASSERT(input);
|
||||||
|
JS_ASSERT(get(0, 0) <= get(0, 1));
|
||||||
|
JS_ASSERT(get(0, 1) <= int(input->length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Corresponds to JSAPI functionality to set the pending RegExp input. */
|
|
||||||
void reset(JSString *newInput, bool newMultiline) {
|
void reset(JSString *newInput, bool newMultiline) {
|
||||||
aboutToWrite();
|
aboutToWrite();
|
||||||
clear();
|
clear();
|
||||||
pendingInput = newInput;
|
input = newInput;
|
||||||
setMultiline(newMultiline);
|
setMultiline(newMultiline);
|
||||||
checkInvariants();
|
checkInvariants();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPendingInput(JSString *newInput) {
|
void setInput(JSString *newInput) {
|
||||||
aboutToWrite();
|
aboutToWrite();
|
||||||
pendingInput = newInput;
|
input = newInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accessors. */
|
/* Accessors. */
|
||||||
|
|
||||||
JSString *getPendingInput() const { return pendingInput; }
|
JSString *getInput() const { return input; }
|
||||||
uintN getFlags() const { return flags; }
|
uintN getFlags() const { return flags; }
|
||||||
bool multiline() const { return flags & JSREG_MULTILINE; }
|
bool multiline() const { return flags & JSREG_MULTILINE; }
|
||||||
|
bool matched() const { JS_ASSERT(pairCount() > 0); return get(0, 1) - get(0, 0) > 0; }
|
||||||
size_t matchStart() const {
|
size_t getParenCount() const { JS_ASSERT(pairCount() > 0); return pairCount() - 1; }
|
||||||
int start = get(0, 0);
|
|
||||||
JS_ASSERT(start >= 0);
|
|
||||||
return size_t(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t matchLimit() const {
|
|
||||||
int limit = get(0, 1);
|
|
||||||
JS_ASSERT(size_t(limit) >= matchStart() && limit >= 0);
|
|
||||||
return size_t(limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matched() const {
|
|
||||||
JS_ASSERT(pairCount() > 0);
|
|
||||||
return get(0, 1) - get(0, 0) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getParenCount() const {
|
|
||||||
JS_ASSERT(pairCount() > 0);
|
|
||||||
return pairCount() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mark(JSTracer *trc) const {
|
void mark(JSTracer *trc) const {
|
||||||
if (pendingInput)
|
if (input)
|
||||||
JS_CALL_STRING_TRACER(trc, pendingInput, "res->pendingInput");
|
JS_CALL_STRING_TRACER(trc, input, "res->input");
|
||||||
if (matchPairsInput)
|
|
||||||
JS_CALL_STRING_TRACER(trc, matchPairsInput, "res->matchPairsInput");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getParenLength(size_t parenNum) const {
|
size_t getParenLength(size_t parenNum) const {
|
||||||
@ -251,9 +178,14 @@ class RegExpStatics
|
|||||||
return get(parenNum + 1, 1) - get(parenNum + 1, 0);
|
return get(parenNum + 1, 1) - get(parenNum + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get(size_t pairNum, bool which) const {
|
||||||
|
JS_ASSERT(pairNum < pairCount());
|
||||||
|
return matchPairs[2 * pairNum + which];
|
||||||
|
}
|
||||||
|
|
||||||
/* Value creators. */
|
/* Value creators. */
|
||||||
|
|
||||||
bool createPendingInput(JSContext *cx, Value *out) const;
|
bool createInput(JSContext *cx, Value *out) const;
|
||||||
bool createLastMatch(JSContext *cx, Value *out) const { return makeMatch(cx, 0, 0, out); }
|
bool createLastMatch(JSContext *cx, Value *out) const { return makeMatch(cx, 0, 0, out); }
|
||||||
bool createLastParen(JSContext *cx, Value *out) const;
|
bool createLastParen(JSContext *cx, Value *out) const;
|
||||||
bool createLeftContext(JSContext *cx, Value *out) const;
|
bool createLeftContext(JSContext *cx, Value *out) const;
|
||||||
@ -272,26 +204,6 @@ class RegExpStatics
|
|||||||
void getRightContext(JSSubString *out) const;
|
void getRightContext(JSSubString *out) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreserveRegExpStatics
|
|
||||||
{
|
|
||||||
RegExpStatics *const original;
|
|
||||||
RegExpStatics buffer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit PreserveRegExpStatics(RegExpStatics *original)
|
|
||||||
: original(original),
|
|
||||||
buffer(RegExpStatics::InitBuffer())
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool init(JSContext *cx) {
|
|
||||||
return original->save(cx, &buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PreserveRegExpStatics() {
|
|
||||||
original->restore();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
@ -93,8 +93,9 @@ class RegExp
|
|||||||
void handlePCREError(JSContext *cx, int error);
|
void handlePCREError(JSContext *cx, int error);
|
||||||
void handleYarrError(JSContext *cx, int error);
|
void handleYarrError(JSContext *cx, int error);
|
||||||
static inline bool initArena(JSContext *cx);
|
static inline bool initArena(JSContext *cx);
|
||||||
static inline void checkMatchPairs(JSString *input, int *buf, size_t matchItemCount);
|
static inline void checkMatchPairs(int *buf, size_t matchItemCount);
|
||||||
static JSObject *createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemCount);
|
JSObject *createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemCount,
|
||||||
|
size_t inputOffset);
|
||||||
inline bool executeInternal(JSContext *cx, RegExpStatics *res, JSString *input,
|
inline bool executeInternal(JSContext *cx, RegExpStatics *res, JSString *input,
|
||||||
size_t *lastIndex, bool test, Value *rval);
|
size_t *lastIndex, bool test, Value *rval);
|
||||||
|
|
||||||
@ -217,29 +218,19 @@ RegExp::initArena(JSContext *cx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
RegExp::checkMatchPairs(JSString *input, int *buf, size_t matchItemCount)
|
RegExp::checkMatchPairs(int *buf, size_t matchItemCount)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
size_t inputLength = input->length();
|
for (size_t i = 0; i < matchItemCount; i += 2)
|
||||||
int largestStartSeen = 0;
|
JS_ASSERT(buf[i + 1] >= buf[i]); /* Limit index must be larger than the start index. */
|
||||||
for (size_t i = 0; i < matchItemCount; i += 2) {
|
|
||||||
int start = buf[i];
|
|
||||||
int limit = buf[i + 1];
|
|
||||||
JS_ASSERT(limit >= start); /* Limit index must be larger than the start index. */
|
|
||||||
if (start == -1)
|
|
||||||
continue;
|
|
||||||
JS_ASSERT(start >= 0);
|
|
||||||
JS_ASSERT(size_t(limit) <= inputLength);
|
|
||||||
/* Test the monotonically increasing nature of left parens. */
|
|
||||||
JS_ASSERT(start >= largestStartSeen);
|
|
||||||
largestStartSeen = start;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline JSObject *
|
inline JSObject *
|
||||||
RegExp::createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemCount)
|
RegExp::createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemCount,
|
||||||
|
size_t inputOffset)
|
||||||
{
|
{
|
||||||
|
#define MATCH_VALUE(__index) (buf[(__index)] + inputOffset)
|
||||||
/*
|
/*
|
||||||
* Create the result array for a match. Array contents:
|
* Create the result array for a match. Array contents:
|
||||||
* 0: matched string
|
* 0: matched string
|
||||||
@ -251,13 +242,13 @@ RegExp::createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemC
|
|||||||
|
|
||||||
RegExpMatchBuilder builder(cx, array);
|
RegExpMatchBuilder builder(cx, array);
|
||||||
for (size_t i = 0; i < matchItemCount; i += 2) {
|
for (size_t i = 0; i < matchItemCount; i += 2) {
|
||||||
int start = buf[i];
|
int start = MATCH_VALUE(i);
|
||||||
int end = buf[i + 1];
|
int end = MATCH_VALUE(i + 1);
|
||||||
|
|
||||||
JSString *captured;
|
JSString *captured;
|
||||||
if (start >= 0) {
|
if (start >= 0) {
|
||||||
JS_ASSERT(start <= end);
|
JS_ASSERT(start <= end);
|
||||||
JS_ASSERT(unsigned(end) <= input->length());
|
JS_ASSERT((unsigned) end <= input->length());
|
||||||
captured = js_NewDependentString(cx, input, start, end - start);
|
captured = js_NewDependentString(cx, input, start, end - start);
|
||||||
if (!(captured && builder.append(i / 2, captured)))
|
if (!(captured && builder.append(i / 2, captured)))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -270,11 +261,12 @@ RegExp::createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!builder.appendIndex(buf[0]) ||
|
if (!builder.appendIndex(MATCH_VALUE(0)) ||
|
||||||
!builder.appendInput(input))
|
!builder.appendInput(input))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
|
#undef MATCH_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -305,11 +297,6 @@ RegExp::executeInternal(JSContext *cx, RegExpStatics *res, JSString *input,
|
|||||||
|
|
||||||
const jschar *chars = input->chars();
|
const jschar *chars = input->chars();
|
||||||
size_t len = input->length();
|
size_t len = input->length();
|
||||||
|
|
||||||
/*
|
|
||||||
* inputOffset emulates sticky mode by matching from this offset into the char buf and
|
|
||||||
* subtracting the delta off at the end.
|
|
||||||
*/
|
|
||||||
size_t inputOffset = 0;
|
size_t inputOffset = 0;
|
||||||
|
|
||||||
if (sticky()) {
|
if (sticky()) {
|
||||||
@ -331,29 +318,27 @@ RegExp::executeInternal(JSContext *cx, RegExpStatics *res, JSString *input,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
checkMatchPairs(buf, matchItemCount);
|
||||||
* Adjust buf for the inputOffset. Use of sticky is rare and the matchItemCount is small, so
|
|
||||||
* just do another pass.
|
if (res) {
|
||||||
*/
|
res->aboutToWrite();
|
||||||
if (JS_UNLIKELY(inputOffset)) {
|
res->input = input;
|
||||||
|
if (!res->matchPairs.resizeUninitialized(matchItemCount)) {
|
||||||
|
js_ReportOutOfMemory(cx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (size_t i = 0; i < matchItemCount; ++i)
|
for (size_t i = 0; i < matchItemCount; ++i)
|
||||||
buf[i] = buf[i] < 0 ? -1 : buf[i] + inputOffset;
|
res->matchPairs[i] = buf[i] + inputOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the populated contents of |buf| are sane values against |input|. */
|
*lastIndex = buf[1] + inputOffset;
|
||||||
checkMatchPairs(input, buf, matchItemCount);
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
res->updateFromMatch(cx, input, buf, matchItemCount);
|
|
||||||
|
|
||||||
*lastIndex = buf[1];
|
|
||||||
|
|
||||||
if (test) {
|
if (test) {
|
||||||
*rval = BooleanValue(true);
|
*rval = BooleanValue(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject *array = createResult(cx, input, buf, matchItemCount);
|
JSObject *array = createResult(cx, input, buf, matchItemCount, inputOffset);
|
||||||
if (!array)
|
if (!array)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -545,8 +530,8 @@ inline bool
|
|||||||
RegExpStatics::createDependent(JSContext *cx, size_t start, size_t end, Value *out) const
|
RegExpStatics::createDependent(JSContext *cx, size_t start, size_t end, Value *out) const
|
||||||
{
|
{
|
||||||
JS_ASSERT(start <= end);
|
JS_ASSERT(start <= end);
|
||||||
JS_ASSERT(end <= matchPairsInput->length());
|
JS_ASSERT(end <= input->length());
|
||||||
JSString *str = js_NewDependentString(cx, matchPairsInput, start, end - start);
|
JSString *str = js_NewDependentString(cx, input, start, end - start);
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
*out = StringValue(str);
|
*out = StringValue(str);
|
||||||
@ -554,9 +539,9 @@ RegExpStatics::createDependent(JSContext *cx, size_t start, size_t end, Value *o
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
RegExpStatics::createPendingInput(JSContext *cx, Value *out) const
|
RegExpStatics::createInput(JSContext *cx, Value *out) const
|
||||||
{
|
{
|
||||||
out->setString(pendingInput ? pendingInput : cx->runtime->emptyString);
|
out->setString(input ? input : cx->runtime->emptyString);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,13 +599,13 @@ RegExpStatics::createRightContext(JSContext *cx, Value *out) const
|
|||||||
*out = UndefinedValue();
|
*out = UndefinedValue();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return createDependent(cx, matchPairs[1], matchPairsInput->length(), out);
|
return createDependent(cx, matchPairs[1], input->length(), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
RegExpStatics::getParen(size_t num, JSSubString *out) const
|
RegExpStatics::getParen(size_t num, JSSubString *out) const
|
||||||
{
|
{
|
||||||
out->chars = matchPairsInput->chars() + get(num + 1, 0);
|
out->chars = input->chars() + get(num + 1, 0);
|
||||||
out->length = getParenLength(num);
|
out->length = getParenLength(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,8 +616,8 @@ RegExpStatics::getLastMatch(JSSubString *out) const
|
|||||||
*out = js_EmptySubString;
|
*out = js_EmptySubString;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JS_ASSERT(matchPairsInput);
|
JS_ASSERT(input);
|
||||||
out->chars = matchPairsInput->chars() + get(0, 0);
|
out->chars = input->chars() + get(0, 0);
|
||||||
JS_ASSERT(get(0, 1) >= get(0, 0));
|
JS_ASSERT(get(0, 1) >= get(0, 0));
|
||||||
out->length = get(0, 1) - get(0, 0);
|
out->length = get(0, 1) - get(0, 0);
|
||||||
}
|
}
|
||||||
@ -645,7 +630,7 @@ RegExpStatics::getLastParen(JSSubString *out) const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t num = pairCount() - 1;
|
size_t num = pairCount() - 1;
|
||||||
out->chars = matchPairsInput->chars() + get(num, 0);
|
out->chars = input->chars() + get(num, 0);
|
||||||
JS_ASSERT(get(num, 1) >= get(num, 0));
|
JS_ASSERT(get(num, 1) >= get(num, 0));
|
||||||
out->length = get(num, 1) - get(num, 0);
|
out->length = get(num, 1) - get(num, 0);
|
||||||
}
|
}
|
||||||
@ -657,7 +642,7 @@ RegExpStatics::getLeftContext(JSSubString *out) const
|
|||||||
*out = js_EmptySubString;
|
*out = js_EmptySubString;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out->chars = matchPairsInput->chars();
|
out->chars = input->chars();
|
||||||
out->length = get(0, 0);
|
out->length = get(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,9 +653,9 @@ RegExpStatics::getRightContext(JSSubString *out) const
|
|||||||
*out = js_EmptySubString;
|
*out = js_EmptySubString;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out->chars = matchPairsInput->chars() + get(0, 1);
|
out->chars = input->chars() + get(0, 1);
|
||||||
JS_ASSERT(get(0, 1) <= int(matchPairsInput->length()));
|
JS_ASSERT(get(0, 1) <= int(input->length()));
|
||||||
out->length = matchPairsInput->length() - get(0, 1);
|
out->length = input->length() - get(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1955,7 +1955,7 @@ str_search(JSContext *cx, uintN argc, Value *vp)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (vp->isTrue())
|
if (vp->isTrue())
|
||||||
vp->setInt32(res->matchStart());
|
vp->setInt32(res->get(0, 0));
|
||||||
else
|
else
|
||||||
vp->setInt32(-1);
|
vp->setInt32(-1);
|
||||||
return true;
|
return true;
|
||||||
@ -2045,6 +2045,26 @@ InterpretDollar(JSContext *cx, RegExpStatics *res, jschar *dp, jschar *ep, Repla
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PreserveRegExpStatics
|
||||||
|
{
|
||||||
|
js::RegExpStatics *const original;
|
||||||
|
js::RegExpStatics buffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PreserveRegExpStatics(RegExpStatics *original)
|
||||||
|
: original(original),
|
||||||
|
buffer(RegExpStatics::InitBuffer())
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool init(JSContext *cx) {
|
||||||
|
return original->save(cx, &buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
~PreserveRegExpStatics() {
|
||||||
|
original->restore();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t *sizep)
|
FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t *sizep)
|
||||||
{
|
{
|
||||||
@ -2135,7 +2155,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Push match index and input string. */
|
/* Push match index and input string. */
|
||||||
session[argi++].setInt32(res->matchStart());
|
session[argi++].setInt32(res->get(0, 0));
|
||||||
session[argi].setString(rdata.str);
|
session[argi].setString(rdata.str);
|
||||||
|
|
||||||
if (!session.invoke(cx))
|
if (!session.invoke(cx))
|
||||||
@ -2202,8 +2222,8 @@ ReplaceCallback(JSContext *cx, RegExpStatics *res, size_t count, void *p)
|
|||||||
JSString *str = rdata.str;
|
JSString *str = rdata.str;
|
||||||
size_t leftoff = rdata.leftIndex;
|
size_t leftoff = rdata.leftIndex;
|
||||||
const jschar *left = str->chars() + leftoff;
|
const jschar *left = str->chars() + leftoff;
|
||||||
size_t leftlen = res->matchStart() - leftoff;
|
size_t leftlen = res->get(0, 0) - leftoff;
|
||||||
rdata.leftIndex = res->matchLimit();
|
rdata.leftIndex = res->get(0, 1);
|
||||||
|
|
||||||
size_t replen = 0; /* silence 'unused' warning */
|
size_t replen = 0; /* silence 'unused' warning */
|
||||||
if (!FindReplaceLength(cx, res, rdata, &replen))
|
if (!FindReplaceLength(cx, res, rdata, &replen))
|
||||||
|
Loading…
Reference in New Issue
Block a user