mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge from mozilla-central to mozilla-inbound
This commit is contained in:
commit
6cc14fe75a
@ -178,6 +178,9 @@ NS_IMETHODIMP
|
||||
nsDOMFileBase::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
|
||||
{
|
||||
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||
if (IsDateUnknown()) {
|
||||
mLastModificationDate = PR_Now();
|
||||
}
|
||||
*aLastModifiedDate = mLastModificationDate;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -489,7 +492,6 @@ nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
|
||||
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||
|
||||
PRTime msecs;
|
||||
mFile->GetLastModifiedTime(&msecs);
|
||||
if (IsDateUnknown()) {
|
||||
nsresult rv = mFile->GetLastModifiedTime(&msecs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -562,6 +564,12 @@ NS_IMETHODIMP
|
||||
nsDOMFileFile::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
|
||||
{
|
||||
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||
if (IsDateUnknown()) {
|
||||
PRTime msecs;
|
||||
nsresult rv = mFile->GetLastModifiedTime(&msecs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mLastModificationDate = msecs;
|
||||
}
|
||||
*aLastModifiedDate = mLastModificationDate;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -933,7 +933,7 @@ fast_composite_scaled_bilinear ## scale_func_name (pixman_implementation_t *imp,
|
||||
{ \
|
||||
vx = v.vector[0]; \
|
||||
repeat (PIXMAN_REPEAT_NORMAL, &vx, pixman_int_to_fixed(src_image->bits.width)); \
|
||||
max_x = pixman_fixed_to_int (vx + (width - 1) * unit_x) + 1; \
|
||||
max_x = pixman_fixed_to_int (vx + (width - 1) * (int64_t)unit_x) + 1; \
|
||||
\
|
||||
if (src_image->bits.width < REPEAT_NORMAL_MIN_WIDTH) \
|
||||
{ \
|
||||
|
@ -114,7 +114,7 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString string, MatchPairs &matc
|
||||
}
|
||||
|
||||
RegExpRunStatus
|
||||
ExecuteRegExpImpl(JSContext *cx, RegExpStatics *res, RegExpShared &re,
|
||||
ExecuteRegExpImpl(JSContext *cx, RegExpStatics *res, RegExpShared &re, RegExpObject ®exp,
|
||||
JSLinearString *input, StableCharPtr chars, size_t length,
|
||||
size_t *lastIndex, MatchConduit &matches)
|
||||
{
|
||||
@ -126,7 +126,7 @@ ExecuteRegExpImpl(JSContext *cx, RegExpStatics *res, RegExpShared &re,
|
||||
/* Only one MatchPair slot provided: execute short-circuiting regexp. */
|
||||
status = re.executeMatchOnly(cx, chars, length, lastIndex, *matches.u.pair);
|
||||
if (status == RegExpRunStatus_Success && res)
|
||||
res->updateLazily(cx, input, &re, lastIndex_orig);
|
||||
res->updateLazily(cx, input, ®exp, lastIndex_orig);
|
||||
} else {
|
||||
/* Vector of MatchPairs provided: execute full regexp. */
|
||||
status = re.execute(cx, chars, length, lastIndex, *matches.u.pairs);
|
||||
@ -151,7 +151,7 @@ js::ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
|
||||
MatchConduit conduit(&matches);
|
||||
|
||||
RegExpRunStatus status =
|
||||
ExecuteRegExpImpl(cx, res, *shared, input, chars, length, lastIndex, conduit);
|
||||
ExecuteRegExpImpl(cx, res, *shared, reobj, input, chars, length, lastIndex, conduit);
|
||||
|
||||
if (status == RegExpRunStatus_Error)
|
||||
return false;
|
||||
@ -591,7 +591,7 @@ js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string, Match
|
||||
/* Steps 8-21. */
|
||||
size_t lastIndexInt(i);
|
||||
RegExpRunStatus status =
|
||||
ExecuteRegExpImpl(cx, res, *re, stableInput, chars, length, &lastIndexInt, matches);
|
||||
ExecuteRegExpImpl(cx, res, *re, *reobj, stableInput, chars, length, &lastIndexInt, matches);
|
||||
|
||||
if (status == RegExpRunStatus_Error)
|
||||
return RegExpRunStatus_Error;
|
||||
|
@ -332,6 +332,7 @@ DeclMarkerImpl(Object, DebugScopeObject)
|
||||
DeclMarkerImpl(Object, GlobalObject)
|
||||
DeclMarkerImpl(Object, JSObject)
|
||||
DeclMarkerImpl(Object, JSFunction)
|
||||
DeclMarkerImpl(Object, RegExpObject)
|
||||
DeclMarkerImpl(Object, ScopeObject)
|
||||
DeclMarkerImpl(Script, JSScript)
|
||||
DeclMarkerImpl(Shape, Shape)
|
||||
|
@ -97,6 +97,7 @@ DeclMarker(Object, DebugScopeObject)
|
||||
DeclMarker(Object, GlobalObject)
|
||||
DeclMarker(Object, JSObject)
|
||||
DeclMarker(Object, JSFunction)
|
||||
DeclMarker(Object, RegExpObject)
|
||||
DeclMarker(Object, ScopeObject)
|
||||
DeclMarker(Script, JSScript)
|
||||
DeclMarker(Shape, Shape)
|
||||
|
@ -674,6 +674,9 @@ Shape::Range::AutoRooter::trace(JSTracer *trc)
|
||||
void
|
||||
RegExpStatics::AutoRooter::trace(JSTracer *trc)
|
||||
{
|
||||
if (statics->regexp)
|
||||
MarkObjectRoot(trc, reinterpret_cast<JSObject**>(&statics->regexp),
|
||||
"RegExpStatics::AutoRooter regexp");
|
||||
if (statics->matchesInput)
|
||||
MarkStringRoot(trc, reinterpret_cast<JSString**>(&statics->matchesInput),
|
||||
"RegExpStatics::AutoRooter matchesInput");
|
||||
|
114
js/src/jsstr.cpp
114
js/src/jsstr.cpp
@ -2308,114 +2308,6 @@ BuildDollarReplacement(JSContext *cx, JSString *textstrArg, JSLinearString *reps
|
||||
return true;
|
||||
}
|
||||
|
||||
struct StringRange
|
||||
{
|
||||
size_t start;
|
||||
size_t length;
|
||||
|
||||
StringRange(size_t s, size_t l)
|
||||
: start(s), length(l)
|
||||
{ }
|
||||
};
|
||||
|
||||
static JSString *
|
||||
AppendSubstrings(JSContext *cx, Handle<JSStableString*> stableStr,
|
||||
const StringRange *ranges, size_t rangesLen)
|
||||
{
|
||||
JS_ASSERT(rangesLen);
|
||||
|
||||
/* For single substrings, construct a dependent string. */
|
||||
if (rangesLen == 1)
|
||||
return js_NewDependentString(cx, stableStr, ranges[0].start, ranges[0].length);
|
||||
|
||||
/* Collect substrings into a rope. */
|
||||
RopeBuilder rope(cx);
|
||||
for (size_t i = 0; i < rangesLen; i++) {
|
||||
const StringRange &sr = ranges[i];
|
||||
|
||||
RootedString substr(cx, js_NewDependentString(cx, stableStr, sr.start, sr.length));
|
||||
if (!substr)
|
||||
return NULL;
|
||||
|
||||
/* Appending to the rope permanently roots the substring. */
|
||||
rope.append(substr);
|
||||
}
|
||||
|
||||
return rope.result();
|
||||
}
|
||||
|
||||
static bool
|
||||
str_replace_regexp_remove(JSContext *cx, CallArgs args, HandleString str, RegExpShared &re)
|
||||
{
|
||||
Rooted<JSStableString*> stableStr(cx, str->ensureStable(cx));
|
||||
if (!stableStr)
|
||||
return false;
|
||||
|
||||
Vector<StringRange, 16, SystemAllocPolicy> ranges;
|
||||
|
||||
StableCharPtr chars = stableStr->chars();
|
||||
size_t charsLen = stableStr->length();
|
||||
|
||||
MatchPair match;
|
||||
size_t startIndex = 0; /* Index used for iterating through the string. */
|
||||
size_t lastIndex = 0; /* Index after last successful match. */
|
||||
|
||||
/* Accumulate StringRanges for unmatched substrings. */
|
||||
while (startIndex <= charsLen) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx))
|
||||
return false;
|
||||
|
||||
RegExpRunStatus status = re.executeMatchOnly(cx, chars, charsLen, &startIndex, match);
|
||||
if (status == RegExpRunStatus_Error)
|
||||
return false;
|
||||
if (status == RegExpRunStatus_Success_NotFound)
|
||||
break;
|
||||
|
||||
/* Include the latest unmatched substring. */
|
||||
if (size_t(match.start) > lastIndex) {
|
||||
if (!ranges.append(StringRange(lastIndex, match.start - lastIndex)))
|
||||
return false;
|
||||
}
|
||||
|
||||
lastIndex = startIndex;
|
||||
|
||||
/* Non-global removal executes at most once. */
|
||||
if (!re.global())
|
||||
break;
|
||||
|
||||
if (match.isEmpty())
|
||||
startIndex++;
|
||||
}
|
||||
|
||||
/* If unmatched, return the input string. */
|
||||
if (!lastIndex) {
|
||||
args.rval().setString(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The last successful match updates the RegExpStatics. */
|
||||
cx->regExpStatics()->updateLazily(cx, stableStr, &re, lastIndex);
|
||||
|
||||
/* Include any remaining part of the string. */
|
||||
if (lastIndex < charsLen) {
|
||||
if (!ranges.append(StringRange(lastIndex, charsLen - lastIndex)))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Handle the empty string before calling .begin(). */
|
||||
if (ranges.empty()) {
|
||||
args.rval().setString(cx->runtime->emptyString);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSString *result = AppendSubstrings(cx, stableStr, ranges.begin(), ranges.length());
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
args.rval().setString(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
str_replace_regexp(JSContext *cx, CallArgs args, ReplaceData &rdata)
|
||||
{
|
||||
@ -2428,12 +2320,6 @@ str_replace_regexp(JSContext *cx, CallArgs args, ReplaceData &rdata)
|
||||
RegExpStatics *res = cx->regExpStatics();
|
||||
RegExpShared &re = rdata.g.regExp();
|
||||
|
||||
/* Optimize removal. */
|
||||
if (rdata.repstr && rdata.repstr->length() == 0 && !rdata.dollar) {
|
||||
JS_ASSERT(!rdata.lambda && !rdata.elembase);
|
||||
return str_replace_regexp_remove(cx, args, rdata.str, re);
|
||||
}
|
||||
|
||||
Value tmp;
|
||||
if (!DoMatch(cx, res, rdata.str, re, ReplaceRegExpCallback, &rdata, REPLACE_ARGS, &tmp))
|
||||
return false;
|
||||
|
@ -645,18 +645,6 @@ RegExpCompartment::RegExpCompartment(JSRuntime *rt)
|
||||
RegExpCompartment::~RegExpCompartment()
|
||||
{
|
||||
JS_ASSERT(map_.empty());
|
||||
|
||||
/*
|
||||
* RegExpStatics may have prevented a single RegExpShared from
|
||||
* being collected during RegExpCompartment::sweep().
|
||||
*/
|
||||
if (!inUse_.empty()) {
|
||||
PendingSet::Enum e(inUse_);
|
||||
RegExpShared *shared = e.front();
|
||||
JS_ASSERT(shared->activeUseCount == 0);
|
||||
js_delete(shared);
|
||||
e.removeFront();
|
||||
}
|
||||
JS_ASSERT(inUse_.empty());
|
||||
}
|
||||
|
||||
|
@ -198,31 +198,22 @@ class RegExpShared
|
||||
class RegExpGuard
|
||||
{
|
||||
RegExpShared *re_;
|
||||
|
||||
private:
|
||||
RegExpGuard(const RegExpGuard &) MOZ_DELETE;
|
||||
void operator=(const RegExpGuard &) MOZ_DELETE;
|
||||
|
||||
public:
|
||||
RegExpGuard() : re_(NULL) {}
|
||||
RegExpGuard(RegExpShared &re) : re_(&re) {
|
||||
re_->incRef();
|
||||
}
|
||||
~RegExpGuard() { release(); }
|
||||
|
||||
public:
|
||||
void init(RegExpShared &re) {
|
||||
JS_ASSERT(!initialized());
|
||||
JS_ASSERT(!re_);
|
||||
re_ = &re;
|
||||
re_->incRef();
|
||||
}
|
||||
void release() {
|
||||
if (re_) {
|
||||
~RegExpGuard() {
|
||||
if (re_)
|
||||
re_->decRef();
|
||||
re_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool initialized() const { return !!re_; }
|
||||
RegExpShared *re() const { JS_ASSERT(initialized()); return re_; }
|
||||
RegExpShared *operator->() { return re(); }
|
||||
@ -234,12 +225,9 @@ class RegExpCompartment
|
||||
struct Key {
|
||||
JSAtom *atom;
|
||||
uint16_t flag;
|
||||
|
||||
Key() {}
|
||||
Key(JSAtom *atom, RegExpFlag flag)
|
||||
: atom(atom), flag(flag)
|
||||
{ }
|
||||
|
||||
: atom(atom), flag(flag) {}
|
||||
typedef Key Lookup;
|
||||
static HashNumber hash(const Lookup &l) {
|
||||
return DefaultHasher<JSAtom *>::hash(l.atom) ^ (l.flag << 1);
|
||||
|
@ -27,6 +27,15 @@ SizeOfRegExpStaticsData(const JSObject *obj, JSMallocSizeOfFun mallocSizeOf)
|
||||
return mallocSizeOf(obj->getPrivate());
|
||||
}
|
||||
|
||||
inline
|
||||
RegExpStatics::RegExpStatics()
|
||||
: pendingLazyEvaluation(false),
|
||||
bufferLink(NULL),
|
||||
copied(false)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
inline bool
|
||||
RegExpStatics::createDependent(JSContext *cx, size_t start, size_t end, Value *out)
|
||||
{
|
||||
@ -222,20 +231,15 @@ RegExpStatics::copyTo(RegExpStatics &dst)
|
||||
if (!pendingLazyEvaluation)
|
||||
dst.matches.initArrayFrom(matches);
|
||||
|
||||
if (regexpGuard.initialized())
|
||||
dst.regexpGuard.init(*regexpGuard);
|
||||
else
|
||||
dst.regexpGuard.release();
|
||||
|
||||
dst.matchesInput = matchesInput;
|
||||
dst.regexp = regexp;
|
||||
dst.lastIndex = lastIndex;
|
||||
dst.pendingInput = pendingInput;
|
||||
dst.flags = flags;
|
||||
dst.pendingLazyEvaluation = pendingLazyEvaluation;
|
||||
|
||||
JS_ASSERT_IF(pendingLazyEvaluation, regexpGuard.initialized());
|
||||
JS_ASSERT_IF(pendingLazyEvaluation, regexp);
|
||||
JS_ASSERT_IF(pendingLazyEvaluation, matchesInput);
|
||||
JS_ASSERT(regexpGuard.initialized() == dst.regexpGuard.initialized());
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -257,20 +261,17 @@ RegExpStatics::restore()
|
||||
|
||||
inline void
|
||||
RegExpStatics::updateLazily(JSContext *cx, JSLinearString *input,
|
||||
RegExpShared *shared, size_t lastIndex)
|
||||
RegExpObject *regexp, size_t lastIndex)
|
||||
{
|
||||
JS_ASSERT(input && shared);
|
||||
JS_ASSERT(input && regexp);
|
||||
aboutToWrite();
|
||||
|
||||
BarrieredSetPair<JSString, JSLinearString>(cx->compartment,
|
||||
pendingInput, input,
|
||||
matchesInput, input);
|
||||
if (regexpGuard.initialized())
|
||||
regexpGuard.release();
|
||||
regexpGuard.init(*shared);
|
||||
|
||||
this->lastIndex = lastIndex;
|
||||
pendingLazyEvaluation = true;
|
||||
this->regexp = regexp;
|
||||
this->lastIndex = lastIndex;
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -281,7 +282,7 @@ RegExpStatics::updateFromMatchPairs(JSContext *cx, JSLinearString *input, MatchP
|
||||
|
||||
/* Unset all lazy state. */
|
||||
pendingLazyEvaluation = false;
|
||||
this->regexpGuard.release();
|
||||
this->regexp = NULL;
|
||||
this->lastIndex = size_t(-1);
|
||||
|
||||
BarrieredSetPair<JSString, JSLinearString>(cx->compartment,
|
||||
@ -300,14 +301,11 @@ inline void
|
||||
RegExpStatics::clear()
|
||||
{
|
||||
aboutToWrite();
|
||||
|
||||
matches.forgetArray();
|
||||
matchesInput = NULL;
|
||||
regexpGuard.release();
|
||||
lastIndex = size_t(-1);
|
||||
pendingInput = NULL;
|
||||
flags = RegExpFlag(0);
|
||||
pendingInput = NULL;
|
||||
pendingLazyEvaluation = false;
|
||||
matchesInput = NULL;
|
||||
matches.forgetArray();
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -365,9 +363,8 @@ RegExpStatics::checkInvariants()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (pendingLazyEvaluation) {
|
||||
JS_ASSERT(regexpGuard.initialized());
|
||||
JS_ASSERT(regexp);
|
||||
JS_ASSERT(pendingInput);
|
||||
JS_ASSERT(lastIndex != size_t(-1));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ RegExpStatics::executeLazy(JSContext *cx)
|
||||
if (!pendingLazyEvaluation)
|
||||
return true;
|
||||
|
||||
JS_ASSERT(regexpGuard.initialized());
|
||||
JS_ASSERT(regexp);
|
||||
JS_ASSERT(matchesInput);
|
||||
JS_ASSERT(lastIndex != size_t(-1));
|
||||
|
||||
@ -87,14 +87,17 @@ RegExpStatics::executeLazy(JSContext *cx)
|
||||
StableCharPtr chars(matchesInput->chars(), length);
|
||||
|
||||
/* Execute the full regular expression. */
|
||||
RegExpRunStatus status = regexpGuard->execute(cx, chars, length, &this->lastIndex, this->matches);
|
||||
RegExpGuard shared;
|
||||
if (!regexp->getShared(cx, &shared))
|
||||
return false;
|
||||
|
||||
RegExpRunStatus status = shared->execute(cx, chars, length, &this->lastIndex, this->matches);
|
||||
if (status == RegExpRunStatus_Error)
|
||||
return false;
|
||||
|
||||
/* Unset lazy state and remove rooted values that now have no use. */
|
||||
pendingLazyEvaluation = false;
|
||||
regexpGuard.release();
|
||||
lastIndex = size_t(-1);
|
||||
regexp = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "js/Vector.h"
|
||||
|
||||
#include "vm/MatchPairs.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -26,7 +25,7 @@ class RegExpStatics
|
||||
HeapPtr<JSLinearString> matchesInput;
|
||||
|
||||
/* The previous RegExp input, used to resolve lazy state. */
|
||||
RegExpGuard regexpGuard; /* Strong reference to RegExpShared. */
|
||||
HeapPtr<RegExpObject> regexp;
|
||||
size_t lastIndex;
|
||||
|
||||
/* The latest RegExp input, set before execution. */
|
||||
@ -34,7 +33,7 @@ class RegExpStatics
|
||||
RegExpFlag flags;
|
||||
|
||||
/*
|
||||
* If true, |matchesInput|, |regexpGuard|, and |lastIndex| may be used
|
||||
* If true, |matchesInput|, |regexp|, and |lastIndex| may be used
|
||||
* to replay the last executed RegExp, and |matches| is invalid.
|
||||
*/
|
||||
bool pendingLazyEvaluation;
|
||||
@ -43,10 +42,6 @@ class RegExpStatics
|
||||
RegExpStatics *bufferLink;
|
||||
bool copied;
|
||||
|
||||
public:
|
||||
RegExpStatics() : bufferLink(NULL), copied(false) { clear(); }
|
||||
static JSObject *create(JSContext *cx, GlobalObject *parent);
|
||||
|
||||
private:
|
||||
bool executeLazy(JSContext *cx);
|
||||
|
||||
@ -83,9 +78,14 @@ class RegExpStatics
|
||||
friend class PreserveRegExpStatics;
|
||||
|
||||
public:
|
||||
inline RegExpStatics();
|
||||
|
||||
static JSObject *create(JSContext *cx, GlobalObject *parent);
|
||||
|
||||
/* Mutators. */
|
||||
|
||||
inline void updateLazily(JSContext *cx, JSLinearString *input,
|
||||
RegExpShared *shared, size_t lastIndex);
|
||||
RegExpObject *regexp, size_t lastIndex);
|
||||
inline bool updateFromMatchPairs(JSContext *cx, JSLinearString *input, MatchPairs &newPairs);
|
||||
inline void setMultiline(JSContext *cx, bool enabled);
|
||||
|
||||
@ -118,6 +118,8 @@ class RegExpStatics
|
||||
}
|
||||
|
||||
void mark(JSTracer *trc) {
|
||||
if (regexp)
|
||||
gc::MarkObject(trc, ®exp, "res->regexp");
|
||||
if (pendingInput)
|
||||
MarkString(trc, &pendingInput, "res->pendingInput");
|
||||
if (matchesInput)
|
||||
|
Loading…
Reference in New Issue
Block a user