Bug 799252 - Remove SkipRoots in jsstr.cpp; r=Waldo

This commit is contained in:
Terrence Cole 2012-10-16 16:30:02 -07:00
parent 5ed542a485
commit 5929f21c7f
2 changed files with 168 additions and 134 deletions

View File

@ -1132,107 +1132,110 @@ RopeMatch(JSContext *cx, JSString *textstr, const jschar *pat, uint32_t patlen,
return true;
}
/* ES6 20120708 draft 15.5.4.24. */
/* ES6 20121026 draft 15.5.4.24. */
static JSBool
str_contains(JSContext *cx, unsigned argc, Value *vp)
{
AssertCanGC();
CallArgs args = CallArgsFromVp(argc, vp);
// Steps 1 and 2
// Steps 1, 2, and 3
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;
// Step 3
Rooted<JSLinearString *> patstr(cx, ArgToRootedString(cx, args, 0));
if (!patstr)
// Steps 4 and 5
Rooted<JSLinearString*> searchStr(cx, ArgToRootedString(cx, args, 0));
if (!searchStr)
return false;
// Step 5
uint32_t textlen = str->length();
const jschar *text = str->getChars(cx);
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
// Steps 6 and 7
uint32_t pos = 0;
if (args.hasDefined(1)) {
// Step 4
double posDouble;
if (!ToInteger(cx, args[1], &posDouble))
return false;
// Step 6
uint32_t delta = uint32_t(Min(double(textlen), Max(0.0, posDouble)));
text += delta;
textlen -= delta;
}
// Step 7
uint32_t patlen = patstr->length();
const jschar *pat = patstr->chars();
// Step 8
args.rval().setBoolean(StringMatch(text, textlen, pat, patlen) >= 0);
return true;
}
static JSBool
str_indexOf(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;
JSLinearString *patstr = ArgToRootedString(cx, args, 0);
if (!patstr)
return false;
uint32_t textlen = str->length();
const jschar *text = str->getChars(cx);
if (!text)
return false;
uint32_t patlen = patstr->length();
const jschar *pat = patstr->chars();
SkipRoot skipPat(cx, &pat);
uint32_t start;
if (args.length() > 1) {
if (args[1].isInt32()) {
int i = args[1].toInt32();
if (i <= 0) {
start = 0;
} else if (uint32_t(i) > textlen) {
start = textlen;
textlen = 0;
} else {
start = i;
text += start;
textlen -= start;
}
pos = (i < 0) ? 0U : uint32_t(i);
} else {
double d;
if (!ToInteger(cx, args[1], &d))
return false;
if (d <= 0) {
start = 0;
} else if (d > textlen) {
start = textlen;
textlen = 0;
} else {
start = (int)d;
text += start;
textlen -= start;
}
pos = uint32_t(Min(Max(d, 0.0), double(UINT32_MAX)));
}
} else {
start = 0;
}
int match = StringMatch(text, textlen, pat, patlen);
AutoAssertNoGC nogc;
// Step 8
uint32_t textLen = str->length();
const jschar *textChars = str->getChars(cx);
if (!textChars)
return false;
// Step 9
uint32_t start = Min(Max(pos, 0U), textLen);
// Step 10
uint32_t searchLen = searchStr->length();
const jschar *searchChars = searchStr->chars();
// Step 11
textChars += start;
textLen -= start;
int match = StringMatch(textChars, textLen, searchChars, searchLen);
args.rval().setBoolean(match != -1);
return true;
}
/* ES6 20120927 draft 15.5.4.7. */
static JSBool
str_indexOf(JSContext *cx, unsigned argc, Value *vp)
{
AssertCanGC();
CallArgs args = CallArgsFromVp(argc, vp);
// Steps 1, 2, and 3
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;
// Steps 4 and 5
Rooted<JSLinearString*> searchStr(cx, ArgToRootedString(cx, args, 0));
if (!searchStr)
return false;
// Steps 6 and 7
uint32_t pos = 0;
if (args.hasDefined(1)) {
if (args[1].isInt32()) {
int i = args[1].toInt32();
pos = (i < 0) ? 0U : uint32_t(i);
} else {
double d;
if (!ToInteger(cx, args[1], &d))
return false;
pos = uint32_t(Min(Max(d, 0.0), double(UINT32_MAX)));
}
}
AutoAssertNoGC nogc;
// Step 8
uint32_t textLen = str->length();
const jschar *textChars = str->getChars(cx);
if (!textChars)
return false;
// Step 9
uint32_t start = Min(Max(pos, 0U), textLen);
// Step 10
uint32_t searchLen = searchStr->length();
const jschar *searchChars = searchStr->chars();
// Step 11
textChars += start;
textLen -= start;
int match = StringMatch(textChars, textLen, searchChars, searchLen);
args.rval().setInt32((match == -1) ? -1 : start + match);
return true;
}
@ -1314,49 +1317,60 @@ str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
return true;
}
/* ES6 20120708 draft 15.5.4.22. */
/* ES6 20120927 draft 15.5.4.22. */
static JSBool
str_startsWith(JSContext *cx, unsigned argc, Value *vp)
{
AssertCanGC();
CallArgs args = CallArgsFromVp(argc, vp);
// Steps 1 and 2
// Steps 1, 2, and 3
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;
// Step 3
Rooted<JSLinearString *> patstr(cx, ArgToRootedString(cx, args, 0));
if (!patstr)
// Steps 4 and 5
Rooted<JSLinearString*> searchStr(cx, ArgToRootedString(cx, args, 0));
if (!searchStr)
return false;
// Step 5
uint32_t textlen = str->length();
const jschar *text = str->getChars(cx);
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
// Steps 6 and 7
uint32_t pos = 0;
if (args.hasDefined(1)) {
// Step 4
double posDouble;
if (!ToInteger(cx, args[1], &posDouble))
return false;
// Step 6
uint32_t position = Min(double(textlen), Max(0.0, posDouble));
text += position;
textlen -= position;
if (args[1].isInt32()) {
int i = args[1].toInt32();
pos = (i < 0) ? 0U : uint32_t(i);
} else {
double d;
if (!ToInteger(cx, args[1], &d))
return false;
pos = uint32_t(Min(Max(d, 0.0), double(UINT32_MAX)));
}
}
// Step 7
uint32_t patlen = patstr->length();
const jschar *pat = patstr->chars();
AutoAssertNoGC nogc;
// Steps 8, 9, and 10.
args.rval().setBoolean(textlen >= patlen && PodEqual(text, pat, patlen));
// Step 8
uint32_t textLen = str->length();
const jschar *textChars = str->getChars(cx);
if (!textChars)
return false;
// Step 9
uint32_t start = Min(Max(pos, 0U), textLen);
// Step 10
uint32_t searchLen = searchStr->length();
const jschar *searchChars = searchStr->chars();
// Step 11
if (searchLen + start < searchLen || searchLen + start > textLen) {
args.rval().setBoolean(false);
return true;
}
// Steps 12 and 13
args.rval().setBoolean(PodEqual(textChars + start, searchChars, searchLen));
return true;
}
@ -1364,43 +1378,61 @@ str_startsWith(JSContext *cx, unsigned argc, Value *vp)
static JSBool
str_endsWith(JSContext *cx, unsigned argc, Value *vp)
{
AssertCanGC();
CallArgs args = CallArgsFromVp(argc, vp);
// Steps 1 and 2
// Steps 1, 2, and 3
RootedString str(cx, ThisToStringForStringProto(cx, args));
if (!str)
return false;
// Step 3
Rooted<JSLinearString *> patstr(cx, ArgToRootedString(cx, args, 0));
if (!patstr)
// Steps 4 and 5
Rooted<JSLinearString *> searchStr(cx, ArgToRootedString(cx, args, 0));
if (!searchStr)
return false;
// Step 4
uint32_t textlen = str->length();
const jschar *text = str->getChars(cx);
if (!text)
return false;
// XXX fix for moving GC.
SkipRoot skip(cx, &text);
// Step 6
uint32_t textLen = str->length();
// Steps 7 and 8
uint32_t pos = textLen;
if (args.hasDefined(1)) {
// Step 5
double endPosDouble;
if (!ToInteger(cx, args[1], &endPosDouble))
return false;
// Step 6
textlen = Min(double(textlen), Max(0.0, endPosDouble));
if (args[1].isInt32()) {
int i = args[1].toInt32();
pos = (i < 0) ? 0U : uint32_t(i);
} else {
double d;
if (!ToInteger(cx, args[1], &d))
return false;
pos = uint32_t(Min(Max(d, 0.0), double(UINT32_MAX)));
}
}
// Step 7
uint32_t patlen = patstr->length();
const jschar *pat = patstr->chars();
AutoAssertNoGC nogc;
// Steps 8-11
args.rval().setBoolean(textlen >= patlen && PodEqual(text + textlen - patlen, pat, patlen));
// Step 6
const jschar *textChars = str->getChars(cx);
if (!textChars)
return false;
// Step 9
uint32_t end = Min(Max(pos, 0U), textLen);
// Step 10
uint32_t searchLen = searchStr->length();
const jschar *searchChars = searchStr->chars();
// Step 12
if (searchLen > end) {
args.rval().setBoolean(false);
return true;
}
// Step 11
uint32_t start = end - searchLen;
// Steps 13 and 14
args.rval().setBoolean(PodEqual(textChars + start, searchChars, searchLen));
return true;
}

View File

@ -60,6 +60,8 @@ class RangedPtr
#endif
}
uintptr_t asUintptr() const { return uintptr_t(ptr); }
public:
RangedPtr(T* p, T* start, T* end)
: ptr(p)
@ -128,13 +130,13 @@ class RangedPtr
RangedPtr<T> operator+(size_t inc) {
MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
MOZ_ASSERT(ptr + inc >= ptr);
MOZ_ASSERT(asUintptr() + inc * sizeof(T) >= asUintptr());
return create(ptr + inc);
}
RangedPtr<T> operator-(size_t dec) {
MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
MOZ_ASSERT(ptr - dec <= ptr);
MOZ_ASSERT(asUintptr() - dec * sizeof(T) <= asUintptr());
return create(ptr - dec);
}