mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
import change from rmottola/Arctic-Fox:
- Bug 1130439 - Trigger compacting GCs after the user becomes inactive (aa5936222)
- Bug 1139429 - Fix ICU configuration for SunOS/OpenSolaris. (a0e4467b4)
- Bug 1143521 - Remove IsPoisonedPtr stuff (341899b88)
- Bug 1142351 - Part 1: Collect telemetry about deprecated flag argument for String.prototype.{search,match,replace}. (3ad712689) (partly)
- Bug 1142351 - Part 2: Warn about deprecated flag argument for String.prototype (66c280d79)
- Bug 1083498 - Remove SpiderMonkey's nonstandard behavior for destructuring for..in loops in JS1.7. (428b6a0d1)
This commit is contained in:
@@ -95,7 +95,7 @@ if test -n "$USE_ICU"; then
|
||||
MOZ_ICU_DBG_SUFFIX=d
|
||||
fi
|
||||
;;
|
||||
Darwin|Linux|DragonFly|FreeBSD|NetBSD|OpenBSD|GNU/kFreeBSD)
|
||||
Darwin|Linux|DragonFly|FreeBSD|NetBSD|OpenBSD|GNU/kFreeBSD|SunOS)
|
||||
ICU_LIB_NAMES="icui18n icuuc icudata"
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -107,6 +107,10 @@ const size_t gStackSize = 8192;
|
||||
|
||||
#define NS_FULL_GC_DELAY 60000 // ms
|
||||
|
||||
// The amount of time to wait from the user being idle to starting a shrinking
|
||||
// GC.
|
||||
#define NS_SHRINKING_GC_DELAY 15000 // ms
|
||||
|
||||
// Maximum amount of time that should elapse between incremental GC slices
|
||||
#define NS_INTERSLICE_GC_DELAY 100 // ms
|
||||
|
||||
@@ -148,6 +152,7 @@ static const uint32_t kMaxICCDuration = 2000; // ms
|
||||
|
||||
static nsITimer *sGCTimer;
|
||||
static nsITimer *sShrinkGCBuffersTimer;
|
||||
static nsITimer *sShrinkingGCTimer;
|
||||
static nsITimer *sCCTimer;
|
||||
static nsITimer *sICCTimer;
|
||||
static nsITimer *sFullGCTimer;
|
||||
@@ -212,6 +217,7 @@ static nsIScriptSecurityManager *sSecurityManager;
|
||||
// the appropriate pref is set.
|
||||
|
||||
static bool sGCOnMemoryPressure;
|
||||
static bool sCompactOnUserInactive;
|
||||
|
||||
// In testing, we call RunNextCollectorTimer() to ensure that the collectors are run more
|
||||
// aggressively than they would be in regular browsing. sExpensiveCollectorPokes keeps
|
||||
@@ -234,6 +240,7 @@ static void
|
||||
KillTimers()
|
||||
{
|
||||
nsJSContext::KillGCTimer();
|
||||
nsJSContext::KillShrinkingGCTimer();
|
||||
nsJSContext::KillShrinkGCBuffersTimer();
|
||||
nsJSContext::KillCCTimer();
|
||||
nsJSContext::KillICCTimer();
|
||||
@@ -266,22 +273,30 @@ NS_IMETHODIMP
|
||||
nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (sGCOnMemoryPressure && !nsCRT::strcmp(aTopic, "memory-pressure")) {
|
||||
if(StringBeginsWith(nsDependentString(aData),
|
||||
NS_LITERAL_STRING("low-memory-ongoing"))) {
|
||||
// Don't GC/CC if we are in an ongoing low-memory state since its very
|
||||
// slow and it likely won't help us anyway.
|
||||
return NS_OK;
|
||||
}
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
|
||||
nsJSContext::NonIncrementalGC,
|
||||
nsJSContext::ShrinkingGC);
|
||||
nsJSContext::CycleCollectNow();
|
||||
if (NeedsGCAfterCC()) {
|
||||
if (!nsCRT::strcmp(aTopic, "memory-pressure")) {
|
||||
if (sGCOnMemoryPressure) {
|
||||
if(StringBeginsWith(nsDependentString(aData),
|
||||
NS_LITERAL_STRING("low-memory-ongoing"))) {
|
||||
// Don't GC/CC if we are in an ongoing low-memory state since its very
|
||||
// slow and it likely won't help us anyway.
|
||||
return NS_OK;
|
||||
}
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
|
||||
nsJSContext::NonIncrementalGC,
|
||||
nsJSContext::ShrinkingGC);
|
||||
nsJSContext::CycleCollectNow();
|
||||
if (NeedsGCAfterCC()) {
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
|
||||
nsJSContext::NonIncrementalGC,
|
||||
nsJSContext::ShrinkingGC);
|
||||
}
|
||||
}
|
||||
} else if (!nsCRT::strcmp(aTopic, "user-interaction-inactive")) {
|
||||
if (sCompactOnUserInactive) {
|
||||
nsJSContext::PokeShrinkingGC();
|
||||
}
|
||||
} else if (!nsCRT::strcmp(aTopic, "user-interaction-active")) {
|
||||
nsJSContext::KillShrinkingGCTimer();
|
||||
} else if (!nsCRT::strcmp(aTopic, "quit-application") ||
|
||||
!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
sShuttingDown = true;
|
||||
@@ -1284,12 +1299,11 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
|
||||
return;
|
||||
}
|
||||
|
||||
JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL;
|
||||
JS::PrepareForFullGC(sRuntime);
|
||||
if (aIncremental == IncrementalGC) {
|
||||
MOZ_ASSERT(aShrinking == NonShrinkingGC);
|
||||
JS::StartIncrementalGC(sRuntime, GC_NORMAL, aReason, aSliceMillis);
|
||||
JS::StartIncrementalGC(sRuntime, gckind, aReason, aSliceMillis);
|
||||
} else {
|
||||
JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL;
|
||||
JS::GCForReason(sRuntime, gckind, aReason);
|
||||
}
|
||||
}
|
||||
@@ -1798,6 +1812,16 @@ ShrinkGCBuffersTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
nsJSContext::ShrinkGCBuffersNow();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
ShrinkingGCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
nsJSContext::KillShrinkingGCTimer();
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::USER_INACTIVE,
|
||||
nsJSContext::IncrementalGC,
|
||||
nsJSContext::ShrinkingGC);
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldTriggerCC(uint32_t aSuspected)
|
||||
{
|
||||
@@ -2030,6 +2054,26 @@ nsJSContext::PokeShrinkGCBuffers()
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSContext::PokeShrinkingGC()
|
||||
{
|
||||
if (sShrinkingGCTimer || sShuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallCreateInstance("@mozilla.org/timer;1", &sShrinkingGCTimer);
|
||||
|
||||
if (!sShrinkingGCTimer) {
|
||||
// Failed to create timer (probably because we're in XPCOM shutdown)
|
||||
return;
|
||||
}
|
||||
|
||||
sShrinkingGCTimer->InitWithFuncCallback(ShrinkingGCTimerFired, nullptr,
|
||||
NS_SHRINKING_GC_DELAY,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSContext::MaybePokeCC()
|
||||
@@ -2091,6 +2135,16 @@ nsJSContext::KillShrinkGCBuffersTimer()
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillShrinkingGCTimer()
|
||||
{
|
||||
if (sShrinkingGCTimer) {
|
||||
sShrinkingGCTimer->Cancel();
|
||||
NS_RELEASE(sShrinkingGCTimer);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillCCTimer()
|
||||
@@ -2282,7 +2336,7 @@ void
|
||||
mozilla::dom::StartupJSEnvironment()
|
||||
{
|
||||
// initialize all our statics, so that we can restart XPCOM
|
||||
sGCTimer = sFullGCTimer = sCCTimer = sICCTimer = nullptr;
|
||||
sGCTimer = sShrinkingGCTimer = sFullGCTimer = sCCTimer = sICCTimer = nullptr;
|
||||
sCCLockedOut = false;
|
||||
sCCLockedOutTime = 0;
|
||||
sLastCCEndTime = TimeStamp();
|
||||
@@ -2692,8 +2746,14 @@ nsJSContext::EnsureStatics()
|
||||
"javascript.options.gc_on_memory_pressure",
|
||||
true);
|
||||
|
||||
Preferences::AddBoolVarCache(&sCompactOnUserInactive,
|
||||
"javascript.options.compact_on_user_inactive",
|
||||
true);
|
||||
|
||||
nsIObserver* observer = new nsJSEnvironmentObserver();
|
||||
obs->AddObserver(observer, "memory-pressure", false);
|
||||
obs->AddObserver(observer, "user-interaction-inactive", false);
|
||||
obs->AddObserver(observer, "user-interaction-active", false);
|
||||
obs->AddObserver(observer, "quit-application", false);
|
||||
obs->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
|
||||
|
||||
@@ -116,6 +116,9 @@ public:
|
||||
static void PokeShrinkGCBuffers();
|
||||
static void KillShrinkGCBuffersTimer();
|
||||
|
||||
static void PokeShrinkingGC();
|
||||
static void KillShrinkingGCTimer();
|
||||
|
||||
static void MaybePokeCC();
|
||||
static void KillCCTimer();
|
||||
static void KillICCTimer();
|
||||
|
||||
@@ -91,11 +91,6 @@ struct GCMethods<nsXBLMaybeCompiled<UncompiledT> >
|
||||
|
||||
static nsXBLMaybeCompiled<UncompiledT> initial() { return nsXBLMaybeCompiled<UncompiledT>(); }
|
||||
|
||||
static bool poisoned(nsXBLMaybeCompiled<UncompiledT> function)
|
||||
{
|
||||
return function.IsCompiled() && Base::poisoned(function.GetJSFunction());
|
||||
}
|
||||
|
||||
static bool needsPostBarrier(nsXBLMaybeCompiled<UncompiledT> function)
|
||||
{
|
||||
return function.IsCompiled() && Base::needsPostBarrier(function.GetJSFunction());
|
||||
|
||||
+2
-1
@@ -99,7 +99,8 @@ namespace JS {
|
||||
D(REFRESH_FRAME) \
|
||||
D(FULL_GC_TIMER) \
|
||||
D(SHUTDOWN_CC) \
|
||||
D(FINISH_LARGE_EVALUATE)
|
||||
D(FINISH_LARGE_EVALUATE) \
|
||||
D(USER_INACTIVE)
|
||||
|
||||
namespace gcreason {
|
||||
|
||||
|
||||
@@ -546,7 +546,6 @@ struct PointerHasher
|
||||
{
|
||||
typedef Key Lookup;
|
||||
static HashNumber hash(const Lookup& l) {
|
||||
MOZ_ASSERT(!JS::IsPoisonedPtr(l));
|
||||
size_t word = reinterpret_cast<size_t>(l) >> zeroBits;
|
||||
static_assert(sizeof(HashNumber) == 4,
|
||||
"subsequent code assumes a four-byte hash");
|
||||
@@ -560,8 +559,6 @@ struct PointerHasher
|
||||
#endif
|
||||
}
|
||||
static bool match(const Key& k, const Lookup& l) {
|
||||
MOZ_ASSERT(!JS::IsPoisonedPtr(k));
|
||||
MOZ_ASSERT(!JS::IsPoisonedPtr(l));
|
||||
return k == l;
|
||||
}
|
||||
static void rekey(Key& k, const Key& newKey) {
|
||||
|
||||
@@ -126,7 +126,6 @@ SYMBOL_TO_JSID(JS::Symbol* sym)
|
||||
MOZ_ASSERT(sym != nullptr);
|
||||
MOZ_ASSERT((size_t(sym) & JSID_TYPE_MASK) == 0);
|
||||
MOZ_ASSERT(!js::gc::IsInsideNursery(reinterpret_cast<js::gc::Cell*>(sym)));
|
||||
MOZ_ASSERT(!JS::IsPoisonedPtr(sym));
|
||||
JSID_BITS(id) = (size_t(sym) | JSID_TYPE_SYMBOL);
|
||||
return id;
|
||||
}
|
||||
@@ -169,20 +168,9 @@ extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE;
|
||||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
IsPoisonedId(jsid id)
|
||||
{
|
||||
if (JSID_IS_STRING(id))
|
||||
return JS::IsPoisonedPtr(JSID_TO_STRING(id));
|
||||
if (JSID_IS_SYMBOL(id))
|
||||
return JS::IsPoisonedPtr(JSID_TO_SYMBOL(id));
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> struct GCMethods<jsid>
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
static bool needsPostBarrier(jsid id) { return false; }
|
||||
static void postBarrier(jsid* idp) {}
|
||||
static void relocate(jsid* idp) {}
|
||||
|
||||
@@ -282,14 +282,12 @@ class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T>
|
||||
|
||||
private:
|
||||
void init(T newPtr) {
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
|
||||
ptr = newPtr;
|
||||
if (js::GCMethods<T>::needsPostBarrier(ptr))
|
||||
post();
|
||||
}
|
||||
|
||||
void set(T newPtr) {
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
|
||||
if (js::GCMethods<T>::needsPostBarrier(newPtr)) {
|
||||
ptr = newPtr;
|
||||
post();
|
||||
@@ -362,7 +360,6 @@ class TenuredHeap : public js::HeapBase<T>
|
||||
|
||||
void setPtr(T newPtr) {
|
||||
MOZ_ASSERT((reinterpret_cast<uintptr_t>(newPtr) & flagsMask) == 0);
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
|
||||
if (newPtr)
|
||||
AssertGCThingMustBeTenured(newPtr);
|
||||
bits = (bits & flagsMask) | reinterpret_cast<uintptr_t>(newPtr);
|
||||
@@ -526,7 +523,6 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
|
||||
|
||||
public:
|
||||
void set(T v) {
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(v));
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
@@ -642,7 +638,6 @@ template <typename T>
|
||||
struct GCMethods<T*>
|
||||
{
|
||||
static T* initial() { return nullptr; }
|
||||
static bool poisoned(T* v) { return JS::IsPoisonedPtr(v); }
|
||||
static bool needsPostBarrier(T* v) { return false; }
|
||||
static void postBarrier(T** vp) {}
|
||||
static void relocate(T** vp) {}
|
||||
@@ -652,7 +647,6 @@ template <>
|
||||
struct GCMethods<JSObject*>
|
||||
{
|
||||
static JSObject* initial() { return nullptr; }
|
||||
static bool poisoned(JSObject* v) { return JS::IsPoisonedPtr(v); }
|
||||
static gc::Cell* asGCThingOrNull(JSObject* v) {
|
||||
if (!v)
|
||||
return nullptr;
|
||||
@@ -674,7 +668,6 @@ template <>
|
||||
struct GCMethods<JSFunction*>
|
||||
{
|
||||
static JSFunction* initial() { return nullptr; }
|
||||
static bool poisoned(JSFunction* v) { return JS::IsPoisonedPtr(v); }
|
||||
static bool needsPostBarrier(JSFunction* v) {
|
||||
return v != nullptr && gc::IsInsideNursery(reinterpret_cast<gc::Cell*>(v));
|
||||
}
|
||||
@@ -708,8 +701,6 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
this->stack = &cx->thingGCRooters[kind];
|
||||
this->prev = *stack;
|
||||
*stack = reinterpret_cast<Rooted<void*>*>(this);
|
||||
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(ptr));
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -789,7 +780,6 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
* interchangeably with a MutableHandleValue.
|
||||
*/
|
||||
void set(T value) {
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(value));
|
||||
ptr = value;
|
||||
}
|
||||
|
||||
@@ -889,7 +879,6 @@ class FakeRooted : public RootedBase<T>
|
||||
T ptr;
|
||||
|
||||
void set(const T& value) {
|
||||
MOZ_ASSERT(!GCMethods<T>::poisoned(value));
|
||||
ptr = value;
|
||||
}
|
||||
|
||||
@@ -912,7 +901,6 @@ class FakeMutableHandle : public js::MutableHandleBase<T>
|
||||
}
|
||||
|
||||
void set(T v) {
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(v));
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
@@ -1169,7 +1157,6 @@ class PersistentRooted : public js::PersistentRootedBase<T>,
|
||||
private:
|
||||
void set(T value) {
|
||||
MOZ_ASSERT(initialized());
|
||||
MOZ_ASSERT(!js::GCMethods<T>::poisoned(value));
|
||||
ptr = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -415,40 +415,6 @@ ScrambleHashCode(HashNumber h)
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
/*
|
||||
* Methods for poisoning GC heap pointer words and checking for poisoned words.
|
||||
* These are in this file for use in Value methods and so forth.
|
||||
*
|
||||
* If the moving GC hazard analysis is in use and detects a non-rooted stack
|
||||
* pointer to a GC thing, one byte of that pointer is poisoned to refer to an
|
||||
* invalid location. For both 32 bit and 64 bit systems, the fourth byte of the
|
||||
* pointer is overwritten, to reduce the likelihood of accidentally changing
|
||||
* a live integer value.
|
||||
*/
|
||||
|
||||
inline void PoisonPtr(void* v)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) && defined(JS_DEBUG)
|
||||
uint8_t* ptr = (uint8_t*) v + 3;
|
||||
*ptr = JS_FREE_PATTERN;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool IsPoisonedPtr(T* v)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) && defined(JS_DEBUG)
|
||||
uint32_t mask = uintptr_t(v) & 0xff000000;
|
||||
return mask == uint32_t(JS_FREE_PATTERN << 24);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* sixgill annotation defines */
|
||||
#ifndef HAVE_STATIC_ANNOTATIONS
|
||||
# define HAVE_STATIC_ANNOTATIONS
|
||||
|
||||
@@ -1043,17 +1043,14 @@ class Value
|
||||
}
|
||||
|
||||
void setString(JSString* str) {
|
||||
MOZ_ASSERT(!IsPoisonedPtr(str));
|
||||
data = STRING_TO_JSVAL_IMPL(str);
|
||||
}
|
||||
|
||||
void setSymbol(JS::Symbol* sym) {
|
||||
MOZ_ASSERT(!IsPoisonedPtr(sym));
|
||||
data = SYMBOL_TO_JSVAL_IMPL(sym);
|
||||
}
|
||||
|
||||
void setObject(JSObject& obj) {
|
||||
MOZ_ASSERT(!IsPoisonedPtr(&obj));
|
||||
data = OBJECT_TO_JSVAL_IMPL(&obj);
|
||||
}
|
||||
|
||||
@@ -1641,17 +1638,11 @@ namespace js {
|
||||
template <> struct GCMethods<const JS::Value>
|
||||
{
|
||||
static JS::Value initial() { return JS::UndefinedValue(); }
|
||||
static bool poisoned(const JS::Value& v) {
|
||||
return v.isMarkable() && JS::IsPoisonedPtr(v.toGCThing());
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GCMethods<JS::Value>
|
||||
{
|
||||
static JS::Value initial() { return JS::UndefinedValue(); }
|
||||
static bool poisoned(const JS::Value& v) {
|
||||
return v.isMarkable() && JS::IsPoisonedPtr(v.toGCThing());
|
||||
}
|
||||
static gc::Cell* asGCThingOrNull(const JS::Value& v) {
|
||||
return v.isMarkable() ? v.toGCThing() : nullptr;
|
||||
}
|
||||
@@ -1890,12 +1881,6 @@ IMPL_TO_JSVAL(jsval_layout l)
|
||||
|
||||
namespace JS {
|
||||
|
||||
inline bool
|
||||
IsPoisonedValue(const Value& v)
|
||||
{
|
||||
return js::GCMethods<Value>::poisoned(v);
|
||||
}
|
||||
|
||||
#ifdef JS_DEBUG
|
||||
namespace detail {
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ using JS::BooleanValue;
|
||||
using JS::DoubleValue;
|
||||
using JS::Float32Value;
|
||||
using JS::Int32Value;
|
||||
using JS::IsPoisonedValue;
|
||||
using JS::MagicValue;
|
||||
using JS::NullValue;
|
||||
using JS::NumberValue;
|
||||
@@ -67,8 +66,6 @@ using JS::PrivateValue;
|
||||
using JS::StringValue;
|
||||
using JS::UndefinedValue;
|
||||
|
||||
using JS::IsPoisonedPtr;
|
||||
|
||||
using JS::Latin1Char;
|
||||
using JS::Latin1Chars;
|
||||
using JS::Latin1CharsZ;
|
||||
|
||||
+12
-71
@@ -56,7 +56,6 @@ typedef Handle<StaticBlockObject*> HandleStaticBlockObject;
|
||||
typedef Rooted<NestedScopeObject*> RootedNestedScopeObject;
|
||||
typedef Handle<NestedScopeObject*> HandleNestedScopeObject;
|
||||
|
||||
|
||||
/* Read a token. Report an error and return null() if that token isn't of type tt. */
|
||||
#define MUST_MATCH_TOKEN(tt, errno) \
|
||||
JS_BEGIN_MACRO \
|
||||
@@ -568,7 +567,7 @@ template <typename ParseHandler>
|
||||
ObjectBox*
|
||||
Parser<ParseHandler>::newObjectBox(NativeObject* obj)
|
||||
{
|
||||
MOZ_ASSERT(obj && !IsPoisonedPtr(obj));
|
||||
MOZ_ASSERT(obj);
|
||||
|
||||
/*
|
||||
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
|
||||
@@ -646,7 +645,7 @@ FunctionBox*
|
||||
Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
|
||||
Directives inheritedDirectives, GeneratorKind generatorKind)
|
||||
{
|
||||
MOZ_ASSERT(fun && !IsPoisonedPtr(fun));
|
||||
MOZ_ASSERT(fun);
|
||||
|
||||
/*
|
||||
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
|
||||
@@ -4378,40 +4377,16 @@ Parser<FullParseHandler>::isValidForStatementLHS(ParseNode* pn1, JSVersion versi
|
||||
bool isForDecl, bool isForEach,
|
||||
ParseNodeKind headKind)
|
||||
{
|
||||
if (isForDecl) {
|
||||
if (pn1->pn_count > 1)
|
||||
return false;
|
||||
if (pn1->isKind(PNK_CONST))
|
||||
return false;
|
||||
|
||||
// In JS 1.7 only, for (var [K, V] in EXPR) has a special meaning.
|
||||
// Hence all other destructuring decls are banned there.
|
||||
if (version == JSVERSION_1_7 && !isForEach && headKind == PNK_FORIN) {
|
||||
ParseNode* lhs = pn1->pn_head;
|
||||
if (lhs->isKind(PNK_ASSIGN))
|
||||
lhs = lhs->pn_left;
|
||||
|
||||
if (lhs->isKind(PNK_OBJECT))
|
||||
return false;
|
||||
if (lhs->isKind(PNK_ARRAY) && lhs->pn_count != 2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (isForDecl)
|
||||
return pn1->pn_count < 2 && !pn1->isKind(PNK_CONST);
|
||||
|
||||
switch (pn1->getKind()) {
|
||||
case PNK_NAME:
|
||||
case PNK_DOT:
|
||||
case PNK_CALL:
|
||||
case PNK_ELEM:
|
||||
return true;
|
||||
|
||||
case PNK_ARRAY:
|
||||
case PNK_CALL:
|
||||
case PNK_DOT:
|
||||
case PNK_ELEM:
|
||||
case PNK_NAME:
|
||||
case PNK_OBJECT:
|
||||
// In JS 1.7 only, for ([K, V] in EXPR) has a special meaning.
|
||||
// Hence all other destructuring left-hand sides are banned there.
|
||||
if (version == JSVERSION_1_7 && !isForEach && headKind == PNK_FORIN)
|
||||
return pn1->isKind(PNK_ARRAY) && pn1->pn_count == 2;
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -4703,29 +4678,12 @@ Parser<FullParseHandler>::forStatement()
|
||||
return null();
|
||||
}
|
||||
|
||||
switch (pn2->getKind()) {
|
||||
case PNK_NAME:
|
||||
ParseNodeKind kind2 = pn2->getKind();
|
||||
MOZ_ASSERT(kind2 != PNK_ASSIGN, "forStatement TOK_ASSIGN");
|
||||
|
||||
if (kind2 == PNK_NAME) {
|
||||
/* Beware 'for (arguments in ...)' with or without a 'var'. */
|
||||
pn2->markAsAssigned();
|
||||
break;
|
||||
|
||||
case PNK_ASSIGN:
|
||||
MOZ_CRASH("forStatement TOK_ASSIGN");
|
||||
|
||||
case PNK_ARRAY:
|
||||
case PNK_OBJECT:
|
||||
if (versionNumber() == JSVERSION_1_7) {
|
||||
/*
|
||||
* Destructuring for-in requires [key, value] enumeration
|
||||
* in JS1.7.
|
||||
*/
|
||||
if (!isForEach && headKind == PNK_FORIN) {
|
||||
iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
} else {
|
||||
if (isForEach) {
|
||||
@@ -5840,7 +5798,6 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
|
||||
return null();
|
||||
return classStatement();
|
||||
|
||||
|
||||
/* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
|
||||
case TOK_CATCH:
|
||||
report(ParseError, false, null(), JSMSG_CATCH_WITHOUT_TRY);
|
||||
@@ -6877,22 +6834,6 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
|
||||
case TOK_LC:
|
||||
if (!checkDestructuring(&data, pn3))
|
||||
return null();
|
||||
|
||||
if (versionNumber() == JSVERSION_1_7 &&
|
||||
!(pn2->pn_iflags & JSITER_FOREACH) &&
|
||||
!isForOf)
|
||||
{
|
||||
/* Destructuring requires [key, value] enumeration in JS1.7. */
|
||||
if (!pn3->isKind(PNK_ARRAY) || pn3->pn_count != 2) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_FOR_LEFTSIDE);
|
||||
return null();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(pn2->isOp(JSOP_ITER));
|
||||
MOZ_ASSERT(pn2->pn_iflags & JSITER_ENUMERATE);
|
||||
MOZ_ASSERT(headKind == PNK_FORIN);
|
||||
pn2->pn_iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_NAME:
|
||||
|
||||
@@ -115,7 +115,6 @@ struct Token
|
||||
|
||||
void setName(PropertyName* name) {
|
||||
MOZ_ASSERT(type == TOK_NAME);
|
||||
MOZ_ASSERT(!IsPoisonedPtr(name));
|
||||
u.name = name;
|
||||
}
|
||||
|
||||
@@ -123,7 +122,6 @@ struct Token
|
||||
MOZ_ASSERT(type == TOK_STRING ||
|
||||
type == TOK_TEMPLATE_HEAD ||
|
||||
type == TOK_NO_SUBS_TEMPLATE);
|
||||
MOZ_ASSERT(!IsPoisonedPtr(atom));
|
||||
u.atom = atom;
|
||||
}
|
||||
|
||||
|
||||
@@ -443,7 +443,6 @@ class MOZ_NON_MEMMOVABLE BarrieredBase : public BarrieredBaseMixins<T>
|
||||
|
||||
public:
|
||||
void init(T v) {
|
||||
MOZ_ASSERT(!GCMethods<T>::poisoned(v));
|
||||
this->value = v;
|
||||
}
|
||||
|
||||
@@ -508,7 +507,6 @@ class PreBarriered : public BarrieredBase<T>
|
||||
private:
|
||||
void set(const T& v) {
|
||||
this->pre();
|
||||
MOZ_ASSERT(!GCMethods<T>::poisoned(v));
|
||||
this->value = v;
|
||||
}
|
||||
};
|
||||
@@ -541,7 +539,6 @@ class HeapPtr : public BarrieredBase<T>
|
||||
#endif
|
||||
|
||||
void init(T v) {
|
||||
MOZ_ASSERT(!GCMethods<T>::poisoned(v));
|
||||
this->value = v;
|
||||
post();
|
||||
}
|
||||
@@ -554,7 +551,6 @@ class HeapPtr : public BarrieredBase<T>
|
||||
private:
|
||||
void set(const T& v) {
|
||||
this->pre();
|
||||
MOZ_ASSERT(!GCMethods<T>::poisoned(v));
|
||||
this->value = v;
|
||||
post();
|
||||
}
|
||||
@@ -652,7 +648,6 @@ class RelocatablePtr : public BarrieredBase<T>
|
||||
}
|
||||
|
||||
void postBarrieredSet(const T& v) {
|
||||
MOZ_ASSERT(!GCMethods<T>::poisoned(v));
|
||||
if (GCMethods<T>::needsPostBarrier(v)) {
|
||||
this->value = v;
|
||||
post();
|
||||
@@ -858,14 +853,12 @@ class HeapSlot : public BarrieredBase<Value>
|
||||
explicit HeapSlot(NativeObject* obj, Kind kind, uint32_t slot, const Value& v)
|
||||
: BarrieredBase<Value>(v)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedValue(v));
|
||||
post(obj, kind, slot, v);
|
||||
}
|
||||
|
||||
explicit HeapSlot(NativeObject* obj, Kind kind, uint32_t slot, const HeapSlot& s)
|
||||
: BarrieredBase<Value>(s.value)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedValue(s.value));
|
||||
post(obj, kind, slot, s);
|
||||
}
|
||||
|
||||
@@ -886,7 +879,6 @@ class HeapSlot : public BarrieredBase<Value>
|
||||
|
||||
void set(NativeObject* owner, Kind kind, uint32_t slot, const Value& v) {
|
||||
MOZ_ASSERT(preconditionForSet(owner, kind, slot));
|
||||
MOZ_ASSERT(!IsPoisonedValue(v));
|
||||
pre();
|
||||
value = v;
|
||||
post(owner, kind, slot, v);
|
||||
@@ -894,7 +886,6 @@ class HeapSlot : public BarrieredBase<Value>
|
||||
|
||||
void set(Zone* zone, NativeObject* owner, Kind kind, uint32_t slot, const Value& v) {
|
||||
MOZ_ASSERT(preconditionForSet(zone, owner, kind, slot));
|
||||
MOZ_ASSERT(!IsPoisonedValue(v));
|
||||
pre(zone);
|
||||
value = v;
|
||||
post(owner, kind, slot, v);
|
||||
|
||||
@@ -226,8 +226,6 @@ class ImmMaybeNurseryPtr
|
||||
public:
|
||||
explicit ImmMaybeNurseryPtr(const gc::Cell* ptr) : value(ptr)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedPtr(ptr));
|
||||
|
||||
// asm.js shouldn't be creating GC things
|
||||
MOZ_ASSERT(!IsCompilingAsmJS());
|
||||
}
|
||||
@@ -257,7 +255,6 @@ class ImmGCPtr
|
||||
|
||||
explicit ImmGCPtr(const gc::Cell* ptr) : value(ptr)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedPtr(ptr));
|
||||
MOZ_ASSERT_IF(ptr, ptr->isTenured());
|
||||
|
||||
// asm.js shouldn't be creating GC things
|
||||
@@ -266,7 +263,6 @@ class ImmGCPtr
|
||||
|
||||
explicit ImmGCPtr(IonNurseryPtr ptr) : value(ptr.ptr)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedPtr(value));
|
||||
MOZ_ASSERT(value);
|
||||
|
||||
// asm.js shouldn't be creating GC things
|
||||
@@ -279,8 +275,6 @@ class ImmGCPtr
|
||||
friend class AssemblerShared;
|
||||
explicit ImmGCPtr(ImmMaybeNurseryPtr ptr) : value(ptr.value)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedPtr(ptr.value));
|
||||
|
||||
// asm.js shouldn't be creating GC things
|
||||
MOZ_ASSERT(!IsCompilingAsmJS());
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 0, JSEXN_SYNTAXERR, "missing } in compoun
|
||||
MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
|
||||
MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
|
||||
MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
|
||||
MSG_DEF(JSMSG_DEPRECATED_FLAGS_ARG, 0, JSEXN_NONE, "flags argument of String.prototype.{search,match,replace} is deprecated")
|
||||
MSG_DEF(JSMSG_DEPRECATED_FOR_EACH, 0, JSEXN_NONE, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead")
|
||||
MSG_DEF(JSMSG_DEPRECATED_OCTAL, 0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
|
||||
MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
|
||||
|
||||
@@ -2670,12 +2670,6 @@ namespace js {
|
||||
template <>
|
||||
struct GCMethods<JSPropertyDescriptor> {
|
||||
static JSPropertyDescriptor initial() { return JSPropertyDescriptor(); }
|
||||
static bool poisoned(const JSPropertyDescriptor& desc) {
|
||||
return (desc.obj && JS::IsPoisonedPtr(desc.obj)) ||
|
||||
(desc.attrs & JSPROP_GETTER && desc.getter && JS::IsPoisonedPtr(desc.getter)) ||
|
||||
(desc.attrs & JSPROP_SETTER && desc.setter && JS::IsPoisonedPtr(desc.setter)) ||
|
||||
(desc.value.isGCThing() && JS::IsPoisonedPtr(desc.value.toGCThing()));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -383,7 +383,6 @@ ExclusiveContext::typeLifoAlloc()
|
||||
inline void
|
||||
JSContext::setPendingException(js::Value v)
|
||||
{
|
||||
MOZ_ASSERT(!IsPoisonedValue(v));
|
||||
// overRecursed_ is set after the fact by ReportOverRecursed.
|
||||
this->overRecursed_ = false;
|
||||
this->throwing = true;
|
||||
|
||||
@@ -46,6 +46,7 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
|
||||
isSelfHosting(false),
|
||||
marked(true),
|
||||
warnedAboutNoSuchMethod(false),
|
||||
warnedAboutFlagsArgument(false),
|
||||
addonId(options.addonIdOrNull()),
|
||||
#ifdef DEBUG
|
||||
firedOnNewGlobalObject(false),
|
||||
@@ -241,9 +242,6 @@ bool
|
||||
JSCompartment::putWrapper(JSContext* cx, const CrossCompartmentKey& wrapped, const js::Value& wrapper)
|
||||
{
|
||||
MOZ_ASSERT(wrapped.wrapped);
|
||||
MOZ_ASSERT(!IsPoisonedPtr(wrapped.wrapped));
|
||||
MOZ_ASSERT(!IsPoisonedPtr(wrapped.debugger));
|
||||
MOZ_ASSERT(!IsPoisonedPtr(wrapper.toGCThing()));
|
||||
MOZ_ASSERT_IF(wrapped.kind == CrossCompartmentKey::StringWrapper, wrapper.isString());
|
||||
MOZ_ASSERT_IF(wrapped.kind != CrossCompartmentKey::StringWrapper, wrapper.isObject());
|
||||
bool success = crossCompartmentWrappers.put(wrapped, ReadBarriered<Value>(wrapper));
|
||||
|
||||
@@ -110,7 +110,6 @@ struct CrossCompartmentKey
|
||||
struct WrapperHasher : public DefaultHasher<CrossCompartmentKey>
|
||||
{
|
||||
static HashNumber hash(const CrossCompartmentKey& key) {
|
||||
MOZ_ASSERT(!IsPoisonedPtr(key.wrapped));
|
||||
static_assert(sizeof(HashNumber) == sizeof(uint32_t),
|
||||
"subsequent code assumes a four-byte hash");
|
||||
return uint32_t(uintptr_t(key.wrapped)) | uint32_t(key.kind);
|
||||
@@ -150,6 +149,7 @@ struct JSCompartment
|
||||
bool isSelfHosting;
|
||||
bool marked;
|
||||
bool warnedAboutNoSuchMethod;
|
||||
bool warnedAboutFlagsArgument;
|
||||
|
||||
// A null add-on ID means that the compartment is not associated with an
|
||||
// add-on.
|
||||
@@ -542,12 +542,13 @@ struct JSCompartment
|
||||
|
||||
enum DeprecatedLanguageExtension {
|
||||
DeprecatedForEach = 0, // JS 1.6+
|
||||
DeprecatedDestructuringForIn = 1, // JS 1.7 only
|
||||
// NO LONGER USING 1
|
||||
DeprecatedLegacyGenerator = 2, // JS 1.7+
|
||||
DeprecatedExpressionClosure = 3, // Added in JS 1.8
|
||||
DeprecatedLetBlock = 4, // Added in JS 1.7
|
||||
// No longer using 5 (was: let expressions)
|
||||
DeprecatedNoSuchMethod = 6, // JS 1.7+
|
||||
DeprecatedFlagsArgument = 7, // JS 1.3 or older
|
||||
DeprecatedLanguageExtensionCount
|
||||
};
|
||||
};
|
||||
|
||||
@@ -363,7 +363,9 @@ js::AssertSameCompartment(JSObject* objA, JSObject* objB)
|
||||
JS_FRIEND_API(void)
|
||||
js::NotifyAnimationActivity(JSObject* obj)
|
||||
{
|
||||
obj->compartment()->lastAnimationTime = PRMJ_Now();
|
||||
int64_t timeNow = PRMJ_Now();
|
||||
obj->compartment()->lastAnimationTime = timeNow;
|
||||
obj->runtimeFromMainThread()->lastAnimationTime = timeNow;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(uint32_t)
|
||||
|
||||
+4
-1
@@ -1893,7 +1893,10 @@ ArenaLists::allocateFromArenaInner(JS::Zone* zone, ArenaHeader* aheader, AllocKi
|
||||
bool
|
||||
GCRuntime::shouldCompact()
|
||||
{
|
||||
return invocationKind == GC_SHRINK && isCompactingGCEnabled();
|
||||
// Compact on shrinking GC if enabled, but skip compacting in incremental
|
||||
// GCs if we are currently animating.
|
||||
return invocationKind == GC_SHRINK && isCompactingGCEnabled() &&
|
||||
(!isIncremental || rt->lastAnimationTime + PRMJ_USEC_PER_SEC < PRMJ_Now());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -323,9 +323,6 @@ class Bindings
|
||||
template <>
|
||||
struct GCMethods<Bindings> {
|
||||
static Bindings initial();
|
||||
static bool poisoned(const Bindings& bindings) {
|
||||
return IsPoisonedPtr(bindings.callObjShape());
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptCounts
|
||||
|
||||
@@ -2139,6 +2139,13 @@ class MOZ_STACK_CLASS StringRegExpGuard
|
||||
/* Build RegExp from pattern string. */
|
||||
RootedString opt(cx);
|
||||
if (optarg < args.length()) {
|
||||
if (!cx->compartment()->warnedAboutFlagsArgument) {
|
||||
if (!JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, GetErrorMessage, nullptr,
|
||||
JSMSG_DEPRECATED_FLAGS_ARG))
|
||||
return false;
|
||||
cx->compartment()->warnedAboutFlagsArgument = true;
|
||||
}
|
||||
|
||||
opt = ToString<CanGC>(cx, args[optarg]);
|
||||
if (!opt)
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// |reftest| skip-if(!xulRuntime.shell)
|
||||
|
||||
var BUGNUMBER = 1142351;
|
||||
var summary = 'Add console warnings for non-standard flag argument of String.prototype.{search,match,replace}.';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
options("werror");
|
||||
assertEq(evaluate("'aaaA'.match('a', 'i')", {catchTermination: true}), "terminated");
|
||||
assertEq(evaluate("'aaaA'.search('a', 'i')", {catchTermination: true}), "terminated");
|
||||
assertEq(evaluate("'aaaA'.replace('a', 'b', 'g')", {catchTermination: true}), "terminated");
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
@@ -24,19 +24,23 @@ function f() {
|
||||
}
|
||||
|
||||
function g() {
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected values were a == "x" and b == 7.
|
||||
for (var [a,b] in {x:7}) {
|
||||
if (a != "x" || b != 7)
|
||||
if (a !== "x" || typeof b !== "undefined")
|
||||
throw "fail";
|
||||
}
|
||||
|
||||
{
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected values were a == "y" and b == 8.
|
||||
for (let [a,b] in {y:8}) {
|
||||
if (a != "y" || b != 8)
|
||||
if (a !== "y" || typeof b !== "undefined")
|
||||
throw "fail";
|
||||
}
|
||||
}
|
||||
|
||||
if (a != "x" || b != 7)
|
||||
if (a !== "x" || typeof b !== "undefined")
|
||||
throw "fail";
|
||||
}
|
||||
|
||||
@@ -47,17 +51,17 @@ if (typeof a != "undefined" || typeof b != "undefined" || typeof x != "undefined
|
||||
throw "fail";
|
||||
|
||||
function h() {
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected values were a == "x" and b == 9.
|
||||
for ([a,b] in {z:9}) {
|
||||
if (a != "z" || b != 9)
|
||||
if (a !== "z" || typeof b !== "undefined")
|
||||
throw "fail";
|
||||
}
|
||||
}
|
||||
|
||||
h();
|
||||
|
||||
if (a != "z" || b != 9)
|
||||
if (a !== "z" || typeof b !== "undefined")
|
||||
throw "fail";
|
||||
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
|
||||
@@ -34,13 +34,19 @@ function test()
|
||||
actual = arr.toString();
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected result was 'aa,bb,cc'.
|
||||
arr=[x+x for ([,x] in ["a","b","c"])];
|
||||
expect = 'aa,bb,cc';
|
||||
expect = 'NaN,NaN,NaN';
|
||||
actual = arr.toString();
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected result was '0a,1b,2c'.
|
||||
arr=[x+y for ([x,y] in ["a","b","c"])];
|
||||
expect = '0a,1b,2c';
|
||||
expect = '0undefined,1undefined,2undefined';
|
||||
actual = arr.toString();
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
||||
|
||||
@@ -19,15 +19,21 @@ function test()
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = '23';
|
||||
actual = '';
|
||||
for (let [, { a: b }] in [{ a: 2 }, { a: 3 }])
|
||||
{
|
||||
actual += b;
|
||||
}
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected result was '23'.
|
||||
expect = 'TypeError';
|
||||
actual = '';
|
||||
try {
|
||||
for (let [, { a: b }] in [{ a: 2 }, { a: 3 }]) {
|
||||
actual += b;
|
||||
}
|
||||
reportCompare(expect, actual, summary);
|
||||
} catch (ex) {
|
||||
actual = ex.name;
|
||||
}
|
||||
|
||||
expect = '23';
|
||||
actual = '';
|
||||
for each (let { a: b } in [{ a: 2 }, { a: 3 }])
|
||||
{
|
||||
|
||||
@@ -60,24 +60,24 @@ function test()
|
||||
|
||||
reportCompare(expect, actual, summary + ': 3');
|
||||
|
||||
// syntax error in js17
|
||||
// Before JS1.7's destructuring for…in was fixed to match JS1.8's,
|
||||
// the expected result was a SyntaxError about the for…in loop's lhs.
|
||||
var iter2 = gen(list2);
|
||||
expect = /SyntaxError: (invalid for.in left-hand side|Left hand side of for..in loop must be an array of length 2 to accept key.value pair.)/;
|
||||
expect = '1,2,3;4,5,6;7,8,9;';
|
||||
actual = '';
|
||||
|
||||
try
|
||||
{
|
||||
eval('for (var [foo, bar, baz] in iter2) {' +
|
||||
'actual += foo + "," + bar + "," + baz + ";";' +
|
||||
'actual += foo + "," + bar + "," + baz + ";";' +
|
||||
'}');
|
||||
actual = 'No Error';
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
|
||||
reportMatch(expect, actual, summary + ': 4');
|
||||
|
||||
reportCompare(expect, actual, summary + ': 4');
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
||||
|
||||
@@ -6122,8 +6122,6 @@ EvaluateInEnv(JSContext* cx, Handle<Env*> env, HandleValue thisv, AbstractFrameP
|
||||
MOZ_ASSERT_IF(frame, thisv.get() == frame.thisValue());
|
||||
MOZ_ASSERT_IF(frame, pc);
|
||||
|
||||
MOZ_ASSERT(!IsPoisonedPtr(chars.start().get()));
|
||||
|
||||
/*
|
||||
* NB: This function breaks the assumption that the compiler can see all
|
||||
* calls and properly compute a static level. In practice, any non-zero
|
||||
|
||||
@@ -71,13 +71,11 @@ struct RootKind<TaggedProto>
|
||||
template <> struct GCMethods<const TaggedProto>
|
||||
{
|
||||
static TaggedProto initial() { return TaggedProto(); }
|
||||
static bool poisoned(const TaggedProto& v) { return IsPoisonedPtr(v.raw()); }
|
||||
};
|
||||
|
||||
template <> struct GCMethods<TaggedProto>
|
||||
{
|
||||
static TaggedProto initial() { return TaggedProto(); }
|
||||
static bool poisoned(const TaggedProto& v) { return IsPoisonedPtr(v.raw()); }
|
||||
};
|
||||
|
||||
template<class Outer>
|
||||
|
||||
@@ -214,7 +214,8 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
||||
#endif
|
||||
largeAllocationFailureCallback(nullptr),
|
||||
oomCallback(nullptr),
|
||||
debuggerMallocSizeOf(ReturnZeroSize)
|
||||
debuggerMallocSizeOf(ReturnZeroSize),
|
||||
lastAnimationTime(0)
|
||||
{
|
||||
setGCStoreBufferPtr(&gc.storeBuffer);
|
||||
|
||||
|
||||
@@ -1435,6 +1435,9 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
* function to assess the size of malloc'd blocks of memory.
|
||||
*/
|
||||
mozilla::MallocSizeOf debuggerMallocSizeOf;
|
||||
|
||||
/* Last time at which an animation was played for this runtime. */
|
||||
int64_t lastAnimationTime;
|
||||
};
|
||||
|
||||
namespace js {
|
||||
|
||||
@@ -162,10 +162,7 @@ AutoRooterGetterSetter::Inner::Inner(ExclusiveContext *cx, uint8_t attrs,
|
||||
GetterOp *pgetter_, SetterOp *psetter_)
|
||||
: CustomAutoRooter(cx), attrs(attrs),
|
||||
pgetter(pgetter_), psetter(psetter_)
|
||||
{
|
||||
MOZ_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter));
|
||||
MOZ_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter));
|
||||
}
|
||||
{}
|
||||
|
||||
inline
|
||||
AutoRooterGetterSetter::AutoRooterGetterSetter(ExclusiveContext *cx, uint8_t attrs,
|
||||
|
||||
@@ -1289,9 +1289,6 @@ struct StackShape
|
||||
{}
|
||||
|
||||
void updateGetterSetter(GetterOp rawGetter, SetterOp rawSetter) {
|
||||
MOZ_ASSERT_IF((attrs & JSPROP_GETTER) && rawGetter, !IsPoisonedPtr(rawGetter));
|
||||
MOZ_ASSERT_IF((attrs & JSPROP_SETTER) && rawSetter, !IsPoisonedPtr(rawSetter));
|
||||
|
||||
if (rawGetter || rawSetter || (attrs & (JSPROP_GETTER|JSPROP_SETTER)))
|
||||
flags |= Shape::ACCESSOR_SHAPE;
|
||||
else
|
||||
|
||||
@@ -136,7 +136,6 @@ MOZ_ALWAYS_INLINE void
|
||||
JSDependentString::init(js::ExclusiveContext *cx, JSLinearString *base, size_t start,
|
||||
size_t length)
|
||||
{
|
||||
MOZ_ASSERT(!js::IsPoisonedPtr(base));
|
||||
MOZ_ASSERT(start + length <= base->length());
|
||||
d.u1.length = length;
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
||||
@@ -1098,20 +1098,12 @@ template <>
|
||||
struct GCMethods<const TypeSet::Type>
|
||||
{
|
||||
static TypeSet::Type initial() { return TypeSet::UnknownType(); }
|
||||
static bool poisoned(TypeSet::Type v) {
|
||||
return (v.isGroup() && IsPoisonedPtr(v.group()))
|
||||
|| (v.isSingleton() && IsPoisonedPtr(v.singleton()));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct GCMethods<TypeSet::Type>
|
||||
{
|
||||
static TypeSet::Type initial() { return TypeSet::UnknownType(); }
|
||||
static bool poisoned(TypeSet::Type v) {
|
||||
return (v.isGroup() && IsPoisonedPtr(v.group()))
|
||||
|| (v.isSingleton() && IsPoisonedPtr(v.singleton()));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@ namespace js {
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 255;
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 256;
|
||||
static const uint32_t XDR_BYTECODE_VERSION =
|
||||
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
||||
|
||||
static_assert(JSErr_Limit == 383,
|
||||
static_assert(JSErr_Limit == 384,
|
||||
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
|
||||
"removed MSG_DEFs from js.msg, you should increment "
|
||||
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
|
||||
|
||||
@@ -1386,6 +1386,7 @@ pref("javascript.options.mem.gc_compacting", true);
|
||||
pref("javascript.options.mem.log", false);
|
||||
pref("javascript.options.mem.notify", false);
|
||||
pref("javascript.options.gc_on_memory_pressure", true);
|
||||
pref("javascript.options.compact_on_user_inactive", true);
|
||||
|
||||
pref("javascript.options.mem.gc_high_frequency_time_limit_ms", 1000);
|
||||
pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 100);
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 10,
|
||||
"description": "Use of SpiderMonkey's deprecated language extensions in web content: ForEach=0, DestructuringForIn=1, LegacyGenerator=2, ExpressionClosure=3, LetBlock=4, LetExpression=5, NoSuchMethod=6"
|
||||
"description": "Use of SpiderMonkey's deprecated language extensions in web content: ForEach=0, DestructuringForIn=1, LegacyGenerator=2, ExpressionClosure=3, LetBlock=4, LetExpression=5, NoSuchMethod=6, FlagsArgument=7"
|
||||
},
|
||||
"TELEMETRY_PING": {
|
||||
"expires_in_version": "never",
|
||||
|
||||
Reference in New Issue
Block a user