mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-27 02:43:07 +00:00
Bug 637905 - Add (asserted-infallible) append methods to js::Vector, for use when the vector in question has previously had space reserved, and use them a bunch of places. r=luke
--HG-- extra : rebase_source : 89002f1cb5160d89e90a22e54bdca1d57bf9deda
This commit is contained in:
parent
6aa57eef52
commit
6a6126ed94
@ -4782,8 +4782,8 @@ NewFunctionInfo(JSContext* cx,
|
||||
if (!ffiType)
|
||||
return NULL;
|
||||
|
||||
fninfo->mArgTypes.append(argType);
|
||||
fninfo->mFFITypes.append(ffiType);
|
||||
fninfo->mArgTypes.infallibleAppend(argType);
|
||||
fninfo->mFFITypes.infallibleAppend(ffiType);
|
||||
}
|
||||
|
||||
if (fninfo->mIsVariadic)
|
||||
|
@ -1336,13 +1336,14 @@ JS_TransplantObject(JSContext *cx, JSObject *origobj, JSObject *target)
|
||||
Value targetv = ObjectValue(*obj);
|
||||
WrapperVector &vector = cx->runtime->compartments;
|
||||
AutoValueVector toTransplant(cx);
|
||||
toTransplant.reserve(vector.length());
|
||||
if (!toTransplant.reserve(vector.length()))
|
||||
return NULL;
|
||||
|
||||
for (JSCompartment **p = vector.begin(), **end = vector.end(); p != end; ++p) {
|
||||
WrapperMap &pmap = (*p)->crossCompartmentWrappers;
|
||||
if (WrapperMap::Ptr wp = pmap.lookup(origv)) {
|
||||
// We found a wrapper. Remember and root it.
|
||||
toTransplant.append(wp->value);
|
||||
toTransplant.infallibleAppend(wp->value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1429,13 +1430,14 @@ js_TransplantObjectWithWrapper(JSContext *cx,
|
||||
Value targetv = ObjectValue(*targetobj);
|
||||
WrapperVector &vector = cx->runtime->compartments;
|
||||
AutoValueVector toTransplant(cx);
|
||||
toTransplant.reserve(vector.length());
|
||||
if (!toTransplant.reserve(vector.length()))
|
||||
return NULL;
|
||||
|
||||
for (JSCompartment **p = vector.begin(), **end = vector.end(); p != end; ++p) {
|
||||
WrapperMap &pmap = (*p)->crossCompartmentWrappers;
|
||||
if (WrapperMap::Ptr wp = pmap.lookup(origv)) {
|
||||
// We found a wrapper. Remember and root it.
|
||||
toTransplant.append(wp->value);
|
||||
toTransplant.infallibleAppend(wp->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3257,7 +3257,7 @@ js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone)
|
||||
*/
|
||||
jsuint jsvalCount = JS_MIN(obj->getDenseArrayCapacity(), length);
|
||||
|
||||
js::AutoValueVector vector(cx);
|
||||
AutoValueVector vector(cx);
|
||||
if (!vector.reserve(jsvalCount))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -3277,7 +3277,7 @@ js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
vector.append(val);
|
||||
vector.infallibleAppend(val);
|
||||
}
|
||||
|
||||
*clone = NewDenseCopiedArray(cx, jsvalCount, vector.begin());
|
||||
|
@ -3242,6 +3242,9 @@ class AutoVectorRooter : protected AutoGCRooter
|
||||
|
||||
bool append(const T &v) { return vector.append(v); }
|
||||
|
||||
/* For use when space has already been reserved. */
|
||||
void infallibleAppend(const T &v) { vector.infallibleAppend(v); }
|
||||
|
||||
void popBack() { vector.popBack(); }
|
||||
|
||||
bool growBy(size_t inc) {
|
||||
|
@ -1887,7 +1887,7 @@ obj_keys(JSContext *cx, uintN argc, Value *vp)
|
||||
JSString *str = js_IntToString(cx, JSID_TO_INT(id));
|
||||
if (!str)
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(vals.append(StringValue(str)));
|
||||
vals.infallibleAppend(StringValue(str));
|
||||
} else {
|
||||
JS_ASSERT(JSID_IS_OBJECT(id));
|
||||
}
|
||||
|
@ -1841,7 +1841,7 @@ ASTSerializer::statements(JSParseNode *pn, NodeVector &elts)
|
||||
Value elt;
|
||||
if (!sourceElement(next, &elt))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(elts.append(elt)); /* space check above */
|
||||
elts.infallibleAppend(elt);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1857,7 +1857,7 @@ ASTSerializer::expressions(JSParseNode *pn, NodeVector &elts)
|
||||
Value elt;
|
||||
if (!expression(next, &elt))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(elts.append(elt)); /* space check above */
|
||||
elts.infallibleAppend(elt);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1873,7 +1873,7 @@ ASTSerializer::xmls(JSParseNode *pn, NodeVector &elts)
|
||||
Value elt;
|
||||
if (!xml(next, &elt))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(elts.append(elt)); /* space check above */
|
||||
elts.infallibleAppend(elt);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1938,8 +1938,6 @@ ASTSerializer::variableDeclaration(JSParseNode *pn, bool let, Value *dst)
|
||||
VarDeclKind kind = let ? VARDECL_LET : VARDECL_VAR;
|
||||
|
||||
NodeVector dtors(cx);
|
||||
if (!dtors.reserve(pn->pn_count))
|
||||
return false;
|
||||
|
||||
/* In a for-in context, variable declarations contain just a single pattern. */
|
||||
if (pn->pn_xflags & PNX_FORINVAR) {
|
||||
@ -1950,11 +1948,13 @@ ASTSerializer::variableDeclaration(JSParseNode *pn, bool let, Value *dst)
|
||||
builder.variableDeclaration(dtors, kind, &pn->pn_pos, dst);
|
||||
}
|
||||
|
||||
if (!dtors.reserve(pn->pn_count))
|
||||
return false;
|
||||
for (JSParseNode *next = pn->pn_head; next; next = next->pn_next) {
|
||||
Value child;
|
||||
if (!variableDeclarator(next, &kind, &child))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(dtors.append(child)); /* space check above */
|
||||
dtors.infallibleAppend(child);
|
||||
}
|
||||
|
||||
return builder.variableDeclaration(dtors, kind, &pn->pn_pos, dst);
|
||||
@ -2000,7 +2000,7 @@ ASTSerializer::letHead(JSParseNode *pn, NodeVector &dtors)
|
||||
*/
|
||||
if (!variableDeclarator(next, &kind, &child))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(dtors.append(child)); /* space check above */
|
||||
dtors.infallibleAppend(child);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2048,7 +2048,7 @@ ASTSerializer::switchStatement(JSParseNode *pn, Value *dst)
|
||||
#endif
|
||||
if (!switchCase(next, &child))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(cases.append(child)); /* space check above */
|
||||
cases.infallibleAppend(child);
|
||||
}
|
||||
|
||||
return builder.switchStatement(disc, cases, lexical, &pn->pn_pos, dst);
|
||||
@ -2081,7 +2081,7 @@ ASTSerializer::tryStatement(JSParseNode *pn, Value *dst)
|
||||
Value clause;
|
||||
if (!catchClause(next->pn_expr, &clause))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(clauses.append(clause)); /* space check above */
|
||||
clauses.infallibleAppend(clause);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2578,7 +2578,7 @@ ASTSerializer::expression(JSParseNode *pn, Value *dst)
|
||||
Value arg;
|
||||
if (!expression(next, &arg))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(args.append(arg)); /* space check above */
|
||||
args.infallibleAppend(arg);
|
||||
}
|
||||
|
||||
return PN_TYPE(pn) == TOK_NEW
|
||||
@ -2616,12 +2616,12 @@ ASTSerializer::expression(JSParseNode *pn, Value *dst)
|
||||
|
||||
for (JSParseNode *next = pn->pn_head; next; next = next->pn_next) {
|
||||
if (PN_TYPE(next) == TOK_COMMA) {
|
||||
JS_ALWAYS_TRUE(elts.append(MagicValue(JS_SERIALIZE_NO_NODE))); /* space check above */
|
||||
elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE));
|
||||
} else {
|
||||
Value expr;
|
||||
if (!expression(next, &expr))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(elts.append(expr)); /* space check above */
|
||||
elts.infallibleAppend(expr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2638,7 +2638,7 @@ ASTSerializer::expression(JSParseNode *pn, Value *dst)
|
||||
Value prop;
|
||||
if (!property(next, &prop))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(elts.append(prop)); /* space check above */
|
||||
elts.infallibleAppend(prop);
|
||||
}
|
||||
|
||||
return builder.objectExpression(elts, &pn->pn_pos, dst);
|
||||
@ -2937,12 +2937,12 @@ ASTSerializer::arrayPattern(JSParseNode *pn, VarDeclKind *pkind, Value *dst)
|
||||
|
||||
for (JSParseNode *next = pn->pn_head; next; next = next->pn_next) {
|
||||
if (PN_TYPE(next) == TOK_COMMA) {
|
||||
JS_ALWAYS_TRUE(elts.append(MagicValue(JS_SERIALIZE_NO_NODE))); /* space check above */
|
||||
elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE));
|
||||
} else {
|
||||
Value patt;
|
||||
if (!pattern(next, pkind, &patt))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(elts.append(patt)); /* space check above */
|
||||
elts.infallibleAppend(patt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2968,7 +2968,7 @@ ASTSerializer::objectPattern(JSParseNode *pn, VarDeclKind *pkind, Value *dst)
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_ALWAYS_TRUE(elts.append(prop)); /* space check above */
|
||||
elts.infallibleAppend(prop);
|
||||
}
|
||||
|
||||
return builder.objectPattern(elts, &pn->pn_pos, dst);
|
||||
|
@ -588,9 +588,9 @@ js_regexp_toString(JSContext *cx, JSObject *obj, Value *vp)
|
||||
if (size_t len = src->length()) {
|
||||
if (!sb.reserve(len + 2))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(sb.append('/'));
|
||||
JS_ALWAYS_TRUE(sb.append(src->chars(), len));
|
||||
JS_ALWAYS_TRUE(sb.append('/'));
|
||||
sb.infallibleAppend('/');
|
||||
sb.infallibleAppend(src->chars(), len);
|
||||
sb.infallibleAppend('/');
|
||||
} else {
|
||||
if (!sb.append("/(?:)/"))
|
||||
return false;
|
||||
@ -641,7 +641,7 @@ EscapeNakedForwardSlashes(JSContext *cx, JSString *unescaped)
|
||||
if (!newChars.length()) {
|
||||
if (!newChars.reserve(oldLen + 1))
|
||||
return NULL;
|
||||
JS_ALWAYS_TRUE(newChars.append(oldChars, size_t(it - oldChars)));
|
||||
newChars.infallibleAppend(oldChars, size_t(it - oldChars));
|
||||
}
|
||||
if (!newChars.append('\\'))
|
||||
return NULL;
|
||||
@ -651,17 +651,17 @@ EscapeNakedForwardSlashes(JSContext *cx, JSString *unescaped)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (newChars.length()) {
|
||||
size_t len = newChars.length();
|
||||
if (!newChars.append('\0'))
|
||||
return NULL;
|
||||
jschar *chars = newChars.extractRawBuffer();
|
||||
JSString *escaped = js_NewString(cx, chars, len);
|
||||
if (!escaped)
|
||||
cx->free(chars);
|
||||
return escaped;
|
||||
}
|
||||
return unescaped;
|
||||
if (newChars.empty())
|
||||
return unescaped;
|
||||
|
||||
size_t len = newChars.length();
|
||||
if (!newChars.append('\0'))
|
||||
return NULL;
|
||||
jschar *chars = newChars.extractRawBuffer();
|
||||
JSString *escaped = js_NewString(cx, chars, len);
|
||||
if (!escaped)
|
||||
cx->free(chars);
|
||||
return escaped;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -73,7 +73,7 @@ class RegExpStatics
|
||||
void copyTo(RegExpStatics &dst) {
|
||||
dst.matchPairs.clear();
|
||||
/* 'save' has already reserved space in matchPairs */
|
||||
JS_ALWAYS_TRUE(dst.matchPairs.append(matchPairs));
|
||||
dst.matchPairs.infallibleAppend(matchPairs);
|
||||
dst.matchPairsInput = matchPairsInput;
|
||||
dst.pendingInput = pendingInput;
|
||||
dst.flags = flags;
|
||||
|
@ -521,9 +521,9 @@ RegExp::compile(JSContext *cx)
|
||||
StringBuffer sb(cx);
|
||||
if (!sb.reserve(JS_ARRAY_LENGTH(prefix) + source->length() + JS_ARRAY_LENGTH(postfix)))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(sb.append(prefix, JS_ARRAY_LENGTH(prefix)));
|
||||
JS_ALWAYS_TRUE(sb.append(source->chars(), source->length()));
|
||||
JS_ALWAYS_TRUE(sb.append(postfix, JS_ARRAY_LENGTH(postfix)));
|
||||
sb.infallibleAppend(prefix, JS_ARRAY_LENGTH(prefix));
|
||||
sb.infallibleAppend(source->chars(), source->length());
|
||||
sb.infallibleAppend(postfix, JS_ARRAY_LENGTH(postfix));
|
||||
|
||||
JSLinearString *fakeySource = sb.finishString();
|
||||
if (!fakeySource)
|
||||
|
@ -2146,14 +2146,14 @@ DoReplace(JSContext *cx, RegExpStatics *res, ReplaceData &rdata)
|
||||
for (; dp; dp = js_strchr_limit(dp, '$', ep)) {
|
||||
/* Move one of the constant portions of the replacement value. */
|
||||
size_t len = dp - cp;
|
||||
JS_ALWAYS_TRUE(rdata.sb.append(cp, len));
|
||||
rdata.sb.infallibleAppend(cp, len);
|
||||
cp = dp;
|
||||
|
||||
JSSubString sub;
|
||||
size_t skip;
|
||||
if (InterpretDollar(cx, res, dp, ep, rdata, &sub, &skip)) {
|
||||
len = sub.length;
|
||||
JS_ALWAYS_TRUE(rdata.sb.append(sub.chars, len));
|
||||
rdata.sb.infallibleAppend(sub.chars, len);
|
||||
cp += skip;
|
||||
dp += skip;
|
||||
} else {
|
||||
@ -2182,7 +2182,7 @@ ReplaceRegExpCallback(JSContext *cx, RegExpStatics *res, size_t count, void *p)
|
||||
size_t growth = leftlen + replen;
|
||||
if (!rdata.sb.reserve(rdata.sb.length() + growth))
|
||||
return false;
|
||||
JS_ALWAYS_TRUE(rdata.sb.append(left, leftlen)); /* skipped-over portion of the search value */
|
||||
rdata.sb.infallibleAppend(left, leftlen); /* skipped-over portion of the search value */
|
||||
DoReplace(cx, res, rdata);
|
||||
return true;
|
||||
}
|
||||
@ -2294,7 +2294,7 @@ BuildDollarReplacement(JSContext *cx, JSString *textstrArg, JSLinearString *reps
|
||||
return false;
|
||||
|
||||
/* Move the pre-dollar chunk in bulk. */
|
||||
JS_ALWAYS_TRUE(newReplaceChars.append(repstr->chars(), firstDollar));
|
||||
newReplaceChars.infallibleAppend(repstr->chars(), firstDollar);
|
||||
|
||||
/* Move the rest char-by-char, interpreting dollars as we encounter them. */
|
||||
#define ENSURE(__cond) if (!(__cond)) return false;
|
||||
|
@ -84,6 +84,21 @@ class StringBuffer
|
||||
bool append(JSAtom *atom);
|
||||
bool appendN(const jschar c, size_t n);
|
||||
bool appendInflated(const char *cstr, size_t len);
|
||||
|
||||
/* Infallible variants usable when the corresponding space is reserved. */
|
||||
void infallibleAppend(const jschar c) {
|
||||
cb.infallibleAppend(c);
|
||||
}
|
||||
void infallibleAppend(const jschar *chars, size_t len) {
|
||||
cb.infallibleAppend(chars, len);
|
||||
}
|
||||
void infallibleAppend(const jschar *begin, const jschar *end) {
|
||||
cb.infallibleAppend(begin, end);
|
||||
}
|
||||
void infallibleAppendN(const jschar c, size_t n) {
|
||||
cb.infallibleAppendN(c, n);
|
||||
}
|
||||
|
||||
JSAtom *atomize(uintN flags = 0);
|
||||
static JSAtom *atomize(JSContext *cx, const CharBuffer &cb, uintN flags = 0);
|
||||
static JSAtom *atomize(JSContext *cx, const jschar *begin, size_t length, uintN flags = 0);
|
||||
|
@ -225,11 +225,16 @@ class Vector : AllocPolicy
|
||||
/*
|
||||
* Pointer to the buffer, be it inline or heap-allocated. Only [mBegin,
|
||||
* mBegin + mLength) hold valid constructed T objects. The range [mBegin +
|
||||
* mLength, mBegin + mCapacity) holds uninitialized memory.
|
||||
* mLength, mBegin + mCapacity) holds uninitialized memory. The range
|
||||
* [mBegin + mLength, mBegin + mReserved) also holds uninitialized memory
|
||||
* previously allocated by a call to reserve().
|
||||
*/
|
||||
T *mBegin;
|
||||
size_t mLength; /* Number of elements in the Vector. */
|
||||
size_t mCapacity; /* Max number of elements storable in the Vector without resizing. */
|
||||
#ifdef DEBUG
|
||||
size_t mReserved; /* Max elements of reserved or used space in this vector. */
|
||||
#endif
|
||||
|
||||
AlignedStorage<sInlineBytes> storage;
|
||||
|
||||
@ -259,6 +264,14 @@ class Vector : AllocPolicy
|
||||
return mBegin + mLength;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t reserved() const {
|
||||
JS_ASSERT(mReserved <= mCapacity);
|
||||
JS_ASSERT(mLength <= mReserved);
|
||||
return mReserved;
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef T ElementType;
|
||||
|
||||
@ -325,7 +338,10 @@ class Vector : AllocPolicy
|
||||
/* If reserve(length() + N) succeeds, the N next appends are guaranteed to succeed. */
|
||||
bool reserve(size_t capacity);
|
||||
|
||||
/* Destroy elements in the range [begin() + incr, end()). */
|
||||
/*
|
||||
* Destroy elements in the range [end() - incr, end()). Does not deallocate
|
||||
* or unreserve storage for those elements.
|
||||
*/
|
||||
void shrinkBy(size_t incr);
|
||||
|
||||
/* Grow the vector by incr elements. */
|
||||
@ -338,14 +354,41 @@ class Vector : AllocPolicy
|
||||
bool growByUninitialized(size_t incr);
|
||||
bool resizeUninitialized(size_t newLength);
|
||||
|
||||
/* Shorthand for shrinkBy(length()). */
|
||||
void clear();
|
||||
|
||||
/* Potentially fallible append operations. */
|
||||
bool append(const T &t);
|
||||
bool appendN(const T &t, size_t n);
|
||||
template <class U> bool append(const U *begin, const U *end);
|
||||
template <class U> bool append(const U *begin, size_t length);
|
||||
template <class U, size_t O, class BP> bool append(const Vector<U,O,BP> &other);
|
||||
|
||||
/*
|
||||
* Guaranteed-infallible append operations for use upon vectors whose
|
||||
* memory has been pre-reserved.
|
||||
*/
|
||||
void infallibleAppend(const T &t) {
|
||||
JS_ASSERT(mLength + 1 <= reserved());
|
||||
JS_ALWAYS_TRUE(append(t));
|
||||
}
|
||||
void infallibleAppendN(const T &t, size_t n) {
|
||||
JS_ASSERT(mLength + n <= reserved());
|
||||
JS_ALWAYS_TRUE(appendN(t, n));
|
||||
}
|
||||
template <class U> void infallibleAppend(const U *begin, const U *end) {
|
||||
JS_ASSERT(mLength + PointerRangeSize(begin, end) <= reserved());
|
||||
JS_ALWAYS_TRUE(append(begin, end));
|
||||
}
|
||||
template <class U> void infallibleAppend(const U *begin, size_t length) {
|
||||
JS_ASSERT(mLength + length <= reserved());
|
||||
JS_ALWAYS_TRUE(append(begin, length));
|
||||
}
|
||||
template <class U, size_t O, class BP> void infallibleAppend(const Vector<U,O,BP> &other) {
|
||||
JS_ASSERT(mLength + other.length() <= reserved());
|
||||
JS_ALWAYS_TRUE(append(other));
|
||||
}
|
||||
|
||||
void popBack();
|
||||
|
||||
T popCopy();
|
||||
@ -384,6 +427,8 @@ class Vector : AllocPolicy
|
||||
#define REENTRANCY_GUARD_ET_AL \
|
||||
ReentrancyGuard g(*this); \
|
||||
JS_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \
|
||||
JS_ASSERT(reserved() <= mCapacity); \
|
||||
JS_ASSERT(mLength <= reserved()); \
|
||||
JS_ASSERT(mLength <= mCapacity)
|
||||
|
||||
/* Vector Implementation */
|
||||
@ -394,7 +439,7 @@ Vector<T,N,AllocPolicy>::Vector(AllocPolicy ap)
|
||||
: AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0),
|
||||
mCapacity(sInlineCapacity)
|
||||
#ifdef DEBUG
|
||||
, entered(false)
|
||||
, mReserved(0), entered(false)
|
||||
#endif
|
||||
{}
|
||||
|
||||
@ -503,9 +548,16 @@ inline bool
|
||||
Vector<T,N,AP>::reserve(size_t request)
|
||||
{
|
||||
REENTRANCY_GUARD_ET_AL;
|
||||
if (request > mCapacity)
|
||||
return growStorageBy(request - mLength);
|
||||
return true;
|
||||
if (request <= mCapacity || growStorageBy(request - mLength)) {
|
||||
#ifdef DEBUG
|
||||
if (request > mReserved)
|
||||
mReserved = request;
|
||||
JS_ASSERT(mLength <= mReserved);
|
||||
JS_ASSERT(mReserved <= mCapacity);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T, size_t N, class AP>
|
||||
@ -532,6 +584,10 @@ Vector<T,N,AP>::growByImpl(size_t incr)
|
||||
if (InitNewElems)
|
||||
Impl::initialize(endNoCheck(), newend);
|
||||
mLength += incr;
|
||||
#ifdef DEBUG
|
||||
if (mLength > mReserved)
|
||||
mReserved = mLength;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -592,6 +648,10 @@ Vector<T,N,AP>::append(const T &t)
|
||||
JS_ASSERT(mLength < mCapacity);
|
||||
new(endNoCheck()) T(t);
|
||||
++mLength;
|
||||
#ifdef DEBUG
|
||||
if (mLength > mReserved)
|
||||
mReserved = mLength;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -606,6 +666,10 @@ Vector<T,N,AP>::appendN(const T &t, size_t needed)
|
||||
JS_ASSERT(mLength + needed <= mCapacity);
|
||||
Impl::copyConstructN(endNoCheck(), needed, t);
|
||||
mLength += needed;
|
||||
#ifdef DEBUG
|
||||
if (mLength > mReserved)
|
||||
mReserved = mLength;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -655,6 +719,10 @@ Vector<T,N,AP>::append(const U *insBegin, const U *insEnd)
|
||||
JS_ASSERT(mLength + needed <= mCapacity);
|
||||
Impl::copyConstruct(endNoCheck(), insBegin, insEnd);
|
||||
mLength += needed;
|
||||
#ifdef DEBUG
|
||||
if (mLength > mReserved)
|
||||
mReserved = mLength;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -711,6 +779,9 @@ Vector<T,N,AP>::extractRawBuffer()
|
||||
mBegin = (T *)storage.addr();
|
||||
mLength = 0;
|
||||
mCapacity = sInlineCapacity;
|
||||
#ifdef DEBUG
|
||||
mReserved = 0;
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -744,6 +815,9 @@ Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length)
|
||||
mLength = length;
|
||||
mCapacity = length;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mReserved = length;
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -1057,14 +1057,12 @@ ResolveRelativePath(JSContext *cx, const char *base, JSString *filename)
|
||||
size_t nchars;
|
||||
if (!JS_DecodeBytes(cx, base, dirLen + 1, NULL, &nchars))
|
||||
return NULL;
|
||||
if (!result.reserve(dirLen + 1 + fileLen)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
if (!result.reserve(dirLen + 1 + fileLen))
|
||||
return NULL;
|
||||
}
|
||||
JS_ALWAYS_TRUE(result.resize(dirLen + 1));
|
||||
if (!JS_DecodeBytes(cx, base, dirLen + 1, result.begin(), &nchars))
|
||||
return NULL;
|
||||
JS_ALWAYS_TRUE(result.append(fileChars, fileLen));
|
||||
result.infallibleAppend(fileChars, fileLen);
|
||||
return JS_NewUCStringCopyN(cx, result.begin(), result.length());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user