From 2265e713ffae9a86970052af2de90604850df3d3 Mon Sep 17 00:00:00 2001
From: Jonas Jenwald
Date: Thu, 25 Oct 2018 15:52:02 +0200
Subject: [PATCH 01/26] Bug 1365105 - Clear all find highlights, in the PDF
Viewer, when the findbar is closed. r=bdahl,paolo
In order to support this, a new "findbarclose" event (mirroring the pre-existing "findbaropen" one) was added to the `MozFindbar.close` method in the findbar.js file.
---
.../test/general/browser_findbarClose.js | 3 ++
.../pdfjs/content/PdfjsChromeUtils.jsm | 34 +++++++++++--------
toolkit/content/widgets/findbar.js | 4 +++
3 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/browser/base/content/test/general/browser_findbarClose.js b/browser/base/content/test/general/browser_findbarClose.js
index c48952020335..5fa6ac82026d 100644
--- a/browser/base/content/test/general/browser_findbarClose.js
+++ b/browser/base/content/test/general/browser_findbarClose.js
@@ -27,7 +27,10 @@ add_task(async function findbar_test() {
ok(!gFindBar.hidden, "the Find bar isn't hidden after the location of a " +
"subdocument changes");
+ let findBarClosePromise = promiseWaitForEvent(gBrowser, "findbarclose");
gFindBar.close();
+ await findBarClosePromise;
+
gBrowser.removeTab(newTab);
});
diff --git a/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm b/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
index 4c39a1c7646f..85f0f4c00bfd 100644
--- a/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
+++ b/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
@@ -192,24 +192,27 @@ var PdfjsChromeUtils = {
},
handleEvent(aEvent) {
+ const type = aEvent.type;
// Handle the tab find initialized event specially:
- if (aEvent.type == "TabFindInitialized") {
+ if (type == "TabFindInitialized") {
let browser = aEvent.target.linkedBrowser;
this._hookupEventListeners(browser);
- aEvent.target.removeEventListener(aEvent.type, this);
+ aEvent.target.removeEventListener(type, this);
return;
}
// To avoid forwarding the message as a CPOW, create a structured cloneable
// version of the event for both performance, and ease of usage, reasons.
- let type = aEvent.type;
- let detail = {
- query: aEvent.detail.query,
- caseSensitive: aEvent.detail.caseSensitive,
- entireWord: aEvent.detail.entireWord,
- highlightAll: aEvent.detail.highlightAll,
- findPrevious: aEvent.detail.findPrevious,
- };
+ let detail = null;
+ if (type !== "findbarclose") {
+ detail = {
+ query: aEvent.detail.query,
+ caseSensitive: aEvent.detail.caseSensitive,
+ entireWord: aEvent.detail.entireWord,
+ highlightAll: aEvent.detail.highlightAll,
+ findPrevious: aEvent.detail.findPrevious,
+ };
+ }
let browser = aEvent.currentTarget.browser;
if (!this._browsers.has(browser)) {
@@ -222,10 +225,13 @@ var PdfjsChromeUtils = {
aEvent.preventDefault();
},
- _types: ["find",
- "findagain",
- "findhighlightallchange",
- "findcasesensitivitychange"],
+ _types: [
+ "find",
+ "findagain",
+ "findhighlightallchange",
+ "findcasesensitivitychange",
+ "findbarclose",
+ ],
_addEventListener(aMsg) {
let browser = aMsg.target;
diff --git a/toolkit/content/widgets/findbar.js b/toolkit/content/widgets/findbar.js
index 6270e844fc1f..0a744b26a158 100644
--- a/toolkit/content/widgets/findbar.js
+++ b/toolkit/content/widgets/findbar.js
@@ -668,6 +668,10 @@ class MozFindbar extends XULElement {
this.setAttribute("noanim", true);
this.hidden = true;
+ let event = document.createEvent("Events");
+ event.initEvent("findbarclose", true, false);
+ this.dispatchEvent(event);
+
// 'focusContent()' iterates over all listeners in the chrome
// process, so we need to call it from here.
this.browser.finder.focusContent();
From a4dfaf285f2dcb056a5849108d3359b2f8fd8497 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sat, 20 Oct 2018 09:22:11 -0600
Subject: [PATCH 02/26] Bug 1488453 - Use release mode assertions in HashTable,
r=mccr8.
--HG--
extra : rebase_source : 95945068c173777a422f459ad46af91f3889d7cd
---
toolkit/recordreplay/HashTable.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/toolkit/recordreplay/HashTable.cpp b/toolkit/recordreplay/HashTable.cpp
index 2305ee7b7841..692828e05f75 100644
--- a/toolkit/recordreplay/HashTable.cpp
+++ b/toolkit/recordreplay/HashTable.cpp
@@ -87,7 +87,7 @@ class StableHashTableInfo
// Get an existing key in the table.
KeyInfo* FindKeyInfo(HashNumber aOriginalHash, const void* aKey, HashInfo** aHashInfo = nullptr) {
HashToKeyMap::iterator iter = mHashToKey.find(aOriginalHash);
- MOZ_ASSERT(iter != mHashToKey.end());
+ MOZ_RELEASE_ASSERT(iter != mHashToKey.end());
HashInfo* hashInfo = iter->second.get();
for (KeyInfo& keyInfo : hashInfo->mKeys) {
@@ -114,7 +114,7 @@ public:
}
~StableHashTableInfo() {
- MOZ_ASSERT(mHashToKey.empty());
+ MOZ_RELEASE_ASSERT(mHashToKey.empty());
DeallocateMemory(mCallbackStorage, CallbackStorageCapacity, MemoryKind::Tracked);
}
@@ -175,7 +175,7 @@ public:
HashNumber GetOriginalHashNumber(const void* aKey) {
KeyToHashMap::iterator iter = mKeyToHash.find(aKey);
- MOZ_ASSERT(iter != mKeyToHash.end());
+ MOZ_RELEASE_ASSERT(iter != mKeyToHash.end());
return iter->second;
}
@@ -212,7 +212,7 @@ public:
}
HashNumber GetLastNewHash(const void* aKey) {
- MOZ_ASSERT(aKey == mLastKey);
+ MOZ_RELEASE_ASSERT(aKey == mLastKey);
return mLastNewHash;
}
@@ -302,7 +302,7 @@ WrapPLHashAllocEntry(void* aAllocPrivate, const void* aKey)
// the hashes are supplied directly to the table and we don't have a chance
// to modify them. Fortunately, none of these tables are iterated in a way
// that can cause the replay to diverge, so just punt in these cases.
- MOZ_ASSERT(info->IsEmpty());
+ MOZ_RELEASE_ASSERT(info->IsEmpty());
}
return info->mAllocOps
From d59167832b9fb4b6e2d5ffd16c249254ce30b451 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sat, 20 Oct 2018 09:23:36 -0600
Subject: [PATCH 03/26] Bug 1500690 - Relax compositor thread ID assertion,
r=nical.
--HG--
extra : rebase_source : 8a45cb4265fd27ec20d56610398005ce849e1126
---
toolkit/recordreplay/ipc/ChildIPC.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/recordreplay/ipc/ChildIPC.cpp b/toolkit/recordreplay/ipc/ChildIPC.cpp
index b1c3e73b740e..0316961d6fba 100644
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -545,7 +545,7 @@ PaintFromMainThread()
void
NotifyPaintComplete()
{
- MOZ_RELEASE_ASSERT(Thread::Current()->Id() == gCompositorThreadId);
+ MOZ_RELEASE_ASSERT(!gCompositorThreadId || Thread::Current()->Id() == gCompositorThreadId);
// Notify the main thread in case it is waiting for this paint to complete.
{
From 0ceed43834366703a353050f4e7221dd98e7d88d Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sat, 20 Oct 2018 10:41:21 -0600
Subject: [PATCH 04/26] Bug 1500697 - Redirect SCDynamicStore APIs, r=mccr8.
--HG--
extra : rebase_source : 16212915fc4f519cc851adca66a1c75449084395
---
toolkit/recordreplay/ProcessRedirectDarwin.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/toolkit/recordreplay/ProcessRedirectDarwin.cpp b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
index 8d3be45f1aa6..f63c01c94d46 100644
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp
+++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
@@ -291,6 +291,7 @@ namespace recordreplay {
MACRO(CFRunLoopGetCurrent, RR_ScalarRval) \
MACRO(CFRunLoopRemoveSource) \
MACRO(CFRunLoopSourceCreate, RR_ScalarRval, Preamble_CFRunLoopSourceCreate) \
+ MACRO(CFRunLoopSourceInvalidate) \
MACRO(CFRunLoopSourceSignal) \
MACRO(CFRunLoopWakeUp) \
MACRO(CFStringAppendCharacters) \
@@ -589,6 +590,11 @@ namespace recordreplay {
MACRO(ReleaseEvent, RR_ScalarRval) \
MACRO(RemoveEventFromQueue, RR_ScalarRval) \
MACRO(RetainEvent, RR_ScalarRval) \
+ MACRO(SCDynamicStoreCopyProxies, RR_ScalarRval) \
+ MACRO(SCDynamicStoreCreate, RR_ScalarRval) \
+ MACRO(SCDynamicStoreCreateRunLoopSource, RR_ScalarRval) \
+ MACRO(SCDynamicStoreKeyCreateProxies, RR_ScalarRval) \
+ MACRO(SCDynamicStoreSetNotificationKeys, RR_ScalarRval) \
MACRO(SendEventToEventTarget, RR_ScalarRval) \
/* These are not public APIs, but other redirected functions may be aliases for */ \
/* these which are dynamically installed on the first call in a way that our */ \
From 274519d9f89e993367db6bcbbd7f34cbe8455951 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:01:54 -0600
Subject: [PATCH 05/26] Bug 1500805 Part 1 - Allow idle threads to be
selectively resumed, r=mccr8.
--HG--
extra : rebase_source : a29ef7316aea2ce566023349639f489ff7b0d9b5
---
toolkit/recordreplay/Thread.cpp | 39 +++++++++++++--------------------
toolkit/recordreplay/Thread.h | 10 +++++++++
2 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/toolkit/recordreplay/Thread.cpp b/toolkit/recordreplay/Thread.cpp
index 21f9aadcd85f..efffd4d44702 100644
--- a/toolkit/recordreplay/Thread.cpp
+++ b/toolkit/recordreplay/Thread.cpp
@@ -364,24 +364,16 @@ RecordReplayInterface_InternalAreThreadEventsDisallowed()
// Thread Coordination
///////////////////////////////////////////////////////////////////////////////
-// Whether all threads should attempt to idle.
-static Atomic gThreadsShouldIdle;
-
-// Whether all threads are considered to be idle.
-static Atomic gThreadsAreIdle;
-
/* static */ void
Thread::WaitForIdleThreads()
{
MOZ_RELEASE_ASSERT(CurrentIsMainThread());
- MOZ_RELEASE_ASSERT(!gThreadsShouldIdle);
- MOZ_RELEASE_ASSERT(!gThreadsAreIdle);
- gThreadsShouldIdle = true;
-
MonitorAutoLock lock(*gMonitor);
for (size_t i = MainThreadId + 1; i <= MaxRecordedThreadId; i++) {
- GetById(i)->mUnrecordedWaitNotified = false;
+ Thread* thread = GetById(i);
+ thread->mShouldIdle = true;
+ thread->mUnrecordedWaitNotified = false;
}
while (true) {
bool done = true;
@@ -426,23 +418,21 @@ Thread::WaitForIdleThreads()
MonitorAutoUnlock unlock(*gMonitor);
WaitNoIdle();
}
+}
- gThreadsAreIdle = true;
+/* static */ void
+Thread::ResumeSingleIdleThread(size_t aId)
+{
+ GetById(aId)->mShouldIdle = false;
+ Notify(aId);
}
/* static */ void
Thread::ResumeIdleThreads()
{
MOZ_RELEASE_ASSERT(CurrentIsMainThread());
-
- MOZ_RELEASE_ASSERT(gThreadsAreIdle);
- gThreadsAreIdle = false;
-
- MOZ_RELEASE_ASSERT(gThreadsShouldIdle);
- gThreadsShouldIdle = false;
-
for (size_t i = MainThreadId + 1; i <= MaxRecordedThreadId; i++) {
- Notify(i);
+ ResumeSingleIdleThread(i);
}
}
@@ -464,7 +454,7 @@ Thread::NotifyUnrecordedWait(const std::function& aCallback, bool aOnlyW
// The main thread might be able to make progress now by calling the routine
// if it is waiting for idle replay threads.
- if (gThreadsShouldIdle) {
+ if (mShouldIdle) {
Notify(MainThreadId);
}
}
@@ -473,7 +463,8 @@ Thread::NotifyUnrecordedWait(const std::function& aCallback, bool aOnlyW
Thread::MaybeWaitForCheckpointSave()
{
MonitorAutoLock lock(*gMonitor);
- while (gThreadsShouldIdle) {
+ Thread* thread = Thread::Current();
+ while (thread->mShouldIdle) {
MonitorAutoUnlock unlock(*gMonitor);
Wait();
}
@@ -531,7 +522,7 @@ Thread::Wait()
}
thread->mIdle = true;
- if (gThreadsShouldIdle) {
+ if (thread->mShouldIdle) {
// Notify the main thread that we just became idle.
Notify(MainThreadId);
}
@@ -546,7 +537,7 @@ Thread::Wait()
RestoreThreadStack(thread->Id());
Unreachable();
}
- } while (gThreadsShouldIdle);
+ } while (thread->mShouldIdle);
thread->mIdle = false;
thread->SetPassThrough(false);
diff --git a/toolkit/recordreplay/Thread.h b/toolkit/recordreplay/Thread.h
index 569a18036483..ac0984f85662 100644
--- a/toolkit/recordreplay/Thread.h
+++ b/toolkit/recordreplay/Thread.h
@@ -127,6 +127,9 @@ private:
// File descriptor to notify to wake the thread up, fixed at creation.
FileHandle mNotifyfd;
+ // Whether the thread should attempt to idle.
+ Atomic mShouldIdle;
+
// Whether the thread is waiting on idlefd.
Atomic mIdle;
@@ -289,6 +292,13 @@ public:
// After WaitForIdleThreads(), the main thread will call this to allow
// other threads to resume execution.
static void ResumeIdleThreads();
+
+ // Allow a single thread to resume execution.
+ static void ResumeSingleIdleThread(size_t aId);
+
+ // Return whether this thread is in the idle state entered after
+ // WaitForIdleThreads.
+ bool IsIdle() { return mIdle; }
};
// This uses a stack pointer instead of TLS to make sure events are passed
From f804910b8601f54643b849da3c0390fb802eeac0 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:02:32 -0600
Subject: [PATCH 06/26] Bug 1500805 Part 2 - Ensure non-main threads are idle
when diverging from the recording, r=mccr8.
--HG--
extra : rebase_source : 0d9e1ae7f0bcda2631781cc4b4a73cee88e886c8
---
toolkit/recordreplay/ProcessRewind.cpp | 5 +++++
toolkit/recordreplay/ipc/ChildIPC.cpp | 23 +++++++++++------------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/toolkit/recordreplay/ProcessRewind.cpp b/toolkit/recordreplay/ProcessRewind.cpp
index 91bc29ef1b0b..d0cd978b5ea3 100644
--- a/toolkit/recordreplay/ProcessRewind.cpp
+++ b/toolkit/recordreplay/ProcessRewind.cpp
@@ -199,6 +199,11 @@ DivergeFromRecording()
// Reset middleman call state whenever we first diverge from the recording.
child::SendResetMiddlemanCalls();
+ // Make sure all non-main threads are idle before we begin diverging. This
+ // thread's new behavior can change values used by other threads and induce
+ // recording mismatches.
+ Thread::WaitForIdleThreads();
+
thread->DivergeFromRecording();
}
diff --git a/toolkit/recordreplay/ipc/ChildIPC.cpp b/toolkit/recordreplay/ipc/ChildIPC.cpp
index 0316961d6fba..0efa27599731 100644
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -577,22 +577,21 @@ Repaint(size_t* aWidth, size_t* aHeight)
// and the last graphics we sent will still be correct.
Thread* compositorThread = Thread::GetById(gCompositorThreadId);
if (!compositorThread->WillDivergeFromRecordingSoon()) {
+ // Allow the compositor to diverge from the recording so it can perform
+ // any paint we are about to trigger, or finish any in flight paint that
+ // that existed at the point we are paused at.
+ Thread::GetById(gCompositorThreadId)->SetShouldDivergeFromRecording();
+ Thread::ResumeSingleIdleThread(gCompositorThreadId);
+
// Create an artifical vsync to see if graphics have changed since the last
// paint and a new paint is needed.
NotifyVsyncObserver();
- if (gNumPendingPaints) {
- // Allow the compositor to diverge from the recording so it can perform
- // any paint we just triggered, or finish any in flight paint that that
- // existed at the point we are paused at.
- Thread::GetById(gCompositorThreadId)->SetShouldDivergeFromRecording();
-
- // Wait for the compositor to finish all in flight paints, including any
- // one we just triggered.
- MonitorAutoLock lock(*gMonitor);
- while (gNumPendingPaints) {
- gMonitor->Wait();
- }
+ // Wait for the compositor to finish all in flight paints, including any
+ // one we just triggered.
+ MonitorAutoLock lock(*gMonitor);
+ while (gNumPendingPaints) {
+ gMonitor->Wait();
}
}
From cb7d3c281c1cbfc2793aabd398d6bd4ef34b4d91 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:03:34 -0600
Subject: [PATCH 07/26] Bug 1500805 Part 3 - Rewind instead of deadlocking when
taking a lock held by an idle thread, r=mccr8.
--HG--
extra : rebase_source : 6d3dd61782990d5a80d0469f44cd5801faa1d6d1
---
toolkit/recordreplay/Lock.cpp | 20 ++++++++++++++++++--
toolkit/recordreplay/Lock.h | 5 ++++-
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/toolkit/recordreplay/Lock.cpp b/toolkit/recordreplay/Lock.cpp
index 85a236d0939e..da567fc82852 100644
--- a/toolkit/recordreplay/Lock.cpp
+++ b/toolkit/recordreplay/Lock.cpp
@@ -135,10 +135,21 @@ Lock::Find(void* aNativeLock)
// should be generated right now. Doing things in this order avoids
// reentrancy issues when initializing the thread-local state used by
// these calls.
- if (AreThreadEventsPassedThrough() || HasDivergedFromRecording()) {
+ Lock* lock = iter->second;
+ if (AreThreadEventsPassedThrough()) {
return nullptr;
}
- return iter->second;
+ if (HasDivergedFromRecording()) {
+ // When diverged from the recording, don't allow uses of locks that are
+ // held by idling threads that have not diverged from the recording.
+ // This will cause the process to deadlock, so rewind instead.
+ if (lock->mOwner && Thread::GetById(lock->mOwner)->IsIdle()) {
+ EnsureNotDivergedFromRecording();
+ Unreachable();
+ }
+ return nullptr;
+ }
+ return lock;
}
}
@@ -171,6 +182,9 @@ Lock::Enter()
while (thread->Id() != acquires->mNextOwner && !thread->MaybeDivergeFromRecording()) {
Thread::Wait();
}
+ if (!thread->HasDivergedFromRecording()) {
+ mOwner = thread->Id();
+ }
}
}
@@ -179,6 +193,8 @@ Lock::Exit()
{
Thread* thread = Thread::Current();
if (IsReplaying() && !thread->HasDivergedFromRecording()) {
+ mOwner = 0;
+
// Notify the next owner before releasing the lock.
LockAcquires* acquires = gLockAcquires.Get(mId);
acquires->ReadAndNotifyNextOwner(thread);
diff --git a/toolkit/recordreplay/Lock.h b/toolkit/recordreplay/Lock.h
index 3afe03c03027..db70cb0ca507 100644
--- a/toolkit/recordreplay/Lock.h
+++ b/toolkit/recordreplay/Lock.h
@@ -30,9 +30,12 @@ class Lock
// Unique ID for this lock.
size_t mId;
+ // When replaying, any thread owning this lock as part of the recording.
+ Atomic mOwner;
+
public:
explicit Lock(size_t aId)
- : mId(aId)
+ : mId(aId), mOwner(0)
{
MOZ_ASSERT(aId);
}
From 650805afa6f0f1b25ffb63d83c2a1931f3bbed9e Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:04:18 -0600
Subject: [PATCH 08/26] Bug 1500805 Part 4 - Watch for bogus pointers when
checking for constant compile time strings, r=mccr8.
--HG--
extra : rebase_source : 7517295161e729dabdeae940b8ba4569df8f7754
---
toolkit/recordreplay/MemorySnapshot.cpp | 11 ++++
toolkit/recordreplay/MemorySnapshot.h | 5 ++
.../recordreplay/ProcessRedirectDarwin.cpp | 55 +++++++++----------
3 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/toolkit/recordreplay/MemorySnapshot.cpp b/toolkit/recordreplay/MemorySnapshot.cpp
index 9eb14dc4dc1e..a8dc49d7a56e 100644
--- a/toolkit/recordreplay/MemorySnapshot.cpp
+++ b/toolkit/recordreplay/MemorySnapshot.cpp
@@ -662,6 +662,17 @@ HandleDirtyMemoryFault(uint8_t* aAddress)
return true;
}
+bool
+MemoryRangeIsTracked(void* aAddress, size_t aSize)
+{
+ for (uint8_t* ptr = PageBase(aAddress); ptr < (uint8_t*) aAddress + aSize; ptr += PageSize) {
+ if (!IsTrackedAddress(ptr, nullptr)) {
+ return false;
+ }
+ }
+ return true;
+}
+
void
UnrecoverableSnapshotFailure()
{
diff --git a/toolkit/recordreplay/MemorySnapshot.h b/toolkit/recordreplay/MemorySnapshot.h
index 0ffdb65d76f8..f44adf05d96b 100644
--- a/toolkit/recordreplay/MemorySnapshot.h
+++ b/toolkit/recordreplay/MemorySnapshot.h
@@ -50,6 +50,11 @@ void RegisterAllocatedMemory(void* aBaseAddress, size_t aSize, MemoryKind aKind)
// been reached.
void AddInitialUntrackedMemoryRegion(uint8_t* aBase, size_t aSize);
+// Return whether a range of memory is in a tracked region. This excludes
+// memory that was allocated after the last checkpoint and is not write
+// protected.
+bool MemoryRangeIsTracked(void* aAddress, size_t aSize);
+
// Initialize the memory snapshots system.
void InitializeMemorySnapshots();
diff --git a/toolkit/recordreplay/ProcessRedirectDarwin.cpp b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
index f63c01c94d46..c7d4ce79c9bb 100644
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp
+++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
@@ -695,20 +695,6 @@ ReplayInvokeCallback(size_t aCallbackId)
// Middleman Call Helpers
///////////////////////////////////////////////////////////////////////////////
-static bool
-TestObjCObjectClass(id aObj, const char* aName)
-{
- Class cls = object_getClass(aObj);
- while (cls) {
- const char* className = class_getName(cls);
- if (!strcmp(className, aName)) {
- return true;
- }
- cls = class_getSuperclass(cls);
- }
- return false;
-}
-
// Inputs that originate from static data in the replaying process itself
// rather than from previous middleman calls.
enum class ObjCInputKind {
@@ -716,6 +702,14 @@ enum class ObjCInputKind {
ConstantString,
};
+// Internal layout of a constant compile time CFStringRef.
+struct CFConstantString {
+ Class mClass;
+ size_t mStuff;
+ char* mData;
+ size_t mLength;
+};
+
// Capture an Objective C or CoreFoundation input to a call, which may come
// either from another middleman call, or from static data in the replaying
// process.
@@ -759,22 +753,23 @@ Middleman_ObjCInput(MiddlemanCallContext& aCx, id* aThingPtr)
}
// Watch for constant compile time strings baked into the generated code or
- // stored in system libraries. We can crash here if the object came from
- // e.g. a replayed pointer from the recording, as can happen if not enough
- // redirections have middleman call hooks. We could do better here to make
- // sure the pointer looks like it could be a constant string, but it seems
- // better and simpler to crash more reliably here than mask problems due to
- // missing middleman call hooks.
- if (TestObjCObjectClass(*aThingPtr, "NSString")) {
- AutoPassThroughThreadEvents pt;
- CFIndex len = CFStringGetLength((CFStringRef)*aThingPtr);
- InfallibleVector buffer;
- buffer.appendN(0, len);
- CFStringGetCharacters((CFStringRef)*aThingPtr, { 0, len }, buffer.begin());
- aCx.WriteInputScalar((size_t) ObjCInputKind::ConstantString);
- aCx.WriteInputScalar(len);
- aCx.WriteInputBytes(buffer.begin(), len * sizeof(UniChar));
- return;
+ // stored in system libraries. Be careful when accessing the pointer as in
+ // the case where a middleman call hook for a function is missing the
+ // pointer could have originated from the recording and its address may not
+ // be mapped. In this case we would rather gracefully recover and fail to
+ // paint, instead of crashing.
+ if (MemoryRangeIsTracked(*aThingPtr, sizeof(CFConstantString))) {
+ CFConstantString* str = (CFConstantString*) *aThingPtr;
+ if (str->mClass == objc_lookUpClass("__NSCFConstantString") &&
+ str->mLength <= 4096 && // Sanity check.
+ MemoryRangeIsTracked(str->mData, str->mLength)) {
+ InfallibleVector buffer;
+ NS_ConvertUTF8toUTF16 converted(str->mData, str->mLength);
+ aCx.WriteInputScalar((size_t) ObjCInputKind::ConstantString);
+ aCx.WriteInputScalar(str->mLength);
+ aCx.WriteInputBytes(converted.get(), str->mLength * sizeof(UniChar));
+ return;
+ }
}
aCx.MarkAsFailed();
From d03d8f7b0bdc2eb92c1d68c357f7aa1d81a8f0b7 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:05:00 -0600
Subject: [PATCH 09/26] Bug 1500805 Part 5 - Fix handling when creating threads
after diverging from the recording, r=mccr8.
--HG--
extra : rebase_source : 1d1f02c7a07e25a4219b145deffae7b44217c6da
---
toolkit/recordreplay/ProcessRedirectDarwin.cpp | 8 +++++++-
toolkit/recordreplay/Thread.cpp | 3 +--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/toolkit/recordreplay/ProcessRedirectDarwin.cpp b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
index c7d4ce79c9bb..30ed612c4157 100644
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp
+++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
@@ -152,7 +152,7 @@ namespace recordreplay {
MACRO(pthread_cond_wait, nullptr, Preamble_pthread_cond_wait) \
MACRO(pthread_cond_timedwait, nullptr, Preamble_pthread_cond_timedwait) \
MACRO(pthread_cond_timedwait_relative_np, nullptr, Preamble_pthread_cond_timedwait_relative_np) \
- MACRO(pthread_create, nullptr, Preamble_pthread_create, nullptr, Preamble_SetError) \
+ MACRO(pthread_create, nullptr, Preamble_pthread_create) \
MACRO(pthread_join, nullptr, Preamble_pthread_join) \
MACRO(pthread_mutex_init, nullptr, Preamble_pthread_mutex_init) \
MACRO(pthread_mutex_destroy, nullptr, Preamble_pthread_mutex_destroy) \
@@ -1213,6 +1213,12 @@ Preamble_pthread_create(CallArguments* aArguments)
*token = Thread::StartThread((Thread::Callback) start, startArg,
detachState == PTHREAD_CREATE_JOINABLE);
+ if (!*token) {
+ // Don't create new threads after diverging from the recording.
+ MOZ_RELEASE_ASSERT(HasDivergedFromRecording());
+ return Preamble_SetError(aArguments);
+ }
+
aArguments->Rval() = 0;
return PreambleResult::Veto;
}
diff --git a/toolkit/recordreplay/Thread.cpp b/toolkit/recordreplay/Thread.cpp
index efffd4d44702..d07b70e58273 100644
--- a/toolkit/recordreplay/Thread.cpp
+++ b/toolkit/recordreplay/Thread.cpp
@@ -237,8 +237,7 @@ Thread::StartThread(Callback aStart, void* aArgument, bool aNeedsJoin)
Thread* thread = Thread::Current();
RecordingEventSection res(thread);
if (!res.CanAccessEvents()) {
- EnsureNotDivergedFromRecording();
- Unreachable();
+ return 0;
}
MonitorAutoLock lock(*gMonitor);
From 565ba58f1b76f38a6df7ad7fc23599de01880533 Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:09:13 -0600
Subject: [PATCH 10/26] Bug 1500805 Part 6 - Add middleman call hooks for some
graphics APIs, r=mccr8.
--HG--
extra : rebase_source : 7ace44a7b32a0878607e53e913017a4f439b87b6
---
toolkit/recordreplay/MiddlemanCall.h | 2 +-
.../recordreplay/ProcessRedirectDarwin.cpp | 54 ++++++++++++++++---
2 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/toolkit/recordreplay/MiddlemanCall.h b/toolkit/recordreplay/MiddlemanCall.h
index b7236081b46c..d8880d02e565 100644
--- a/toolkit/recordreplay/MiddlemanCall.h
+++ b/toolkit/recordreplay/MiddlemanCall.h
@@ -354,7 +354,7 @@ void ResetMiddlemanCalls();
///////////////////////////////////////////////////////////////////////////////
// Capture the contents of an input buffer at BufferArg with element count at CountArg.
-template
+template
static inline void
Middleman_Buffer(MiddlemanCallContext& aCx)
{
diff --git a/toolkit/recordreplay/ProcessRedirectDarwin.cpp b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
index 30ed612c4157..0a4695c885bf 100644
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp
+++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
@@ -329,9 +329,9 @@ namespace recordreplay {
MACRO(CFURLCreateWithString, RR_ScalarRval) \
MACRO(CFURLGetFileSystemRepresentation, RR_Compose>) \
MACRO(CFURLGetFSRef, RR_Compose>) \
- MACRO(CFUUIDCreate, RR_ScalarRval) \
+ MACRO(CFUUIDCreate, RR_ScalarRval, nullptr, Middleman_CreateCFTypeRval) \
MACRO(CFUUIDCreateString, RR_ScalarRval) \
- MACRO(CFUUIDGetUUIDBytes, RR_ComplexScalarRval) \
+ MACRO(CFUUIDGetUUIDBytes, RR_ComplexScalarRval, nullptr, Middleman_CFTypeArg<0>) \
MACRO(CGAffineTransformConcat, RR_OversizeRval) \
MACRO(CGBitmapContextCreateImage, RR_ScalarRval) \
MACRO(CGBitmapContextCreateWithData, \
@@ -387,8 +387,9 @@ namespace recordreplay {
Middleman_StackArgumentData>) \
MACRO(CGContextScaleCTM, nullptr, nullptr, Middleman_UpdateCFTypeArg<0>) \
MACRO(CGContextTranslateCTM, nullptr, nullptr, Middleman_UpdateCFTypeArg<0>) \
- MACRO(CGDataProviderCreateWithData, RR_Compose) \
- MACRO(CGDataProviderRelease) \
+ MACRO(CGDataProviderCreateWithData, RR_Compose, \
+ nullptr, Middleman_CGDataProviderCreateWithData) \
+ MACRO(CGDataProviderRelease, nullptr, nullptr, nullptr, Preamble_Veto<0>) \
MACRO(CGDisplayCopyColorSpace, RR_ScalarRval) \
MACRO(CGDisplayIOServicePort, RR_ScalarRval) \
MACRO(CGEventSourceCounterForEventType, RR_ScalarRval) \
@@ -399,7 +400,8 @@ namespace recordreplay {
MACRO(CGFontCopyVariations, RR_ScalarRval, nullptr, \
Middleman_Compose, Middleman_CreateCFTypeRval>) \
MACRO(CGFontCreateCopyWithVariations, RR_ScalarRval) \
- MACRO(CGFontCreateWithDataProvider, RR_ScalarRval) \
+ MACRO(CGFontCreateWithDataProvider, RR_ScalarRval, nullptr, \
+ Middleman_Compose, Middleman_CreateCFTypeRval>) \
MACRO(CGFontCreateWithFontName, RR_ScalarRval, nullptr, \
Middleman_Compose, Middleman_CreateCFTypeRval>) \
MACRO(CGFontCreateWithPlatformFont, RR_ScalarRval) \
@@ -443,10 +445,14 @@ namespace recordreplay {
Middleman_Compose, Middleman_CreateCFTypeRval>) \
MACRO(CTFontCopyTable, RR_ScalarRval, nullptr, \
Middleman_Compose, Middleman_CreateCFTypeRval>) \
- MACRO(CTFontCopyVariationAxes, RR_ScalarRval) \
+ MACRO(CTFontCopyVariationAxes, RR_ScalarRval, nullptr, \
+ Middleman_Compose, Middleman_CreateCFTypeRval>) \
MACRO(CTFontCreateForString, RR_ScalarRval, nullptr, \
Middleman_Compose, Middleman_CFTypeArg<1>, Middleman_CreateCFTypeRval>) \
- MACRO(CTFontCreatePathForGlyph, RR_ScalarRval) \
+ MACRO(CTFontCreatePathForGlyph, RR_ScalarRval, nullptr, \
+ Middleman_Compose, \
+ Middleman_BufferFixedSize<2, sizeof(CGAffineTransform)>, \
+ Middleman_CreateCFTypeRval>) \
MACRO(CTFontCreateWithFontDescriptor, RR_ScalarRval, nullptr, \
Middleman_Compose, \
Middleman_BufferFixedSize<1, sizeof(CGAffineTransform)>, \
@@ -1759,6 +1765,7 @@ Middleman_CFArrayGetValueAtIndex(MiddlemanCallContext& aCx)
if (call) {
switch (call->mCallId) {
case CallEvent_CTLineGetGlyphRuns:
+ case CallEvent_CTFontCopyVariationAxes:
case CallEvent_CTFontDescriptorCreateMatchingFontDescriptors:
isCFTypeRval = true;
break;
@@ -2055,6 +2062,39 @@ RR_CGDataProviderCreateWithData(Stream& aEvents, CallArguments* aArguments, Erro
}
}
+static void
+ReleaseDataCallback(void*, const void* aData, size_t)
+{
+ free((void*) aData);
+}
+
+static void
+Middleman_CGDataProviderCreateWithData(MiddlemanCallContext& aCx)
+{
+ Middleman_Buffer<1, 2>(aCx);
+ Middleman_CreateCFTypeRval(aCx);
+
+ auto& info = aCx.mArguments->Arg<0, void*>();
+ auto& data = aCx.mArguments->Arg<1, const void*>();
+ auto& size = aCx.mArguments->Arg<2, size_t>();
+ auto& releaseData = aCx.mArguments->Arg<3, CGDataProviderReleaseDataCallback>();
+
+ // Make a copy of the data that won't be released the next time middleman
+ // calls are reset, in case CoreGraphics decides to hang onto the data
+ // provider after that point.
+ if (aCx.mPhase == MiddlemanCallPhase::MiddlemanInput) {
+ void* newData = malloc(size);
+ memcpy(newData, data, size);
+ data = newData;
+ releaseData = ReleaseDataCallback;
+ }
+
+ // Immediately release the data in the replaying process.
+ if (aCx.mPhase == MiddlemanCallPhase::ReplayInput) {
+ releaseData(info, data, size);
+ }
+}
+
static PreambleResult
Preamble_CGPathApply(CallArguments* aArguments)
{
From 39ea3e05d1c7be06f971ed62c1905565586e4acc Mon Sep 17 00:00:00 2001
From: Brian Hackett
Date: Sun, 21 Oct 2018 15:09:20 -0600
Subject: [PATCH 11/26] Bug 1500805 Part 7 - Avoid crashing after a middleman
call returns a null value, r=mccr8.
--HG--
extra : rebase_source : 4274b07437e31938349823b9229ccf3add164e9f
---
toolkit/recordreplay/MiddlemanCall.cpp | 5 ++++-
toolkit/recordreplay/ProcessRedirect.cpp | 6 ++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/toolkit/recordreplay/MiddlemanCall.cpp b/toolkit/recordreplay/MiddlemanCall.cpp
index 23bb91e01f7f..5de4a6531a3e 100644
--- a/toolkit/recordreplay/MiddlemanCall.cpp
+++ b/toolkit/recordreplay/MiddlemanCall.cpp
@@ -163,7 +163,7 @@ ProcessMiddlemanCall(const char* aInputData, size_t aInputSize,
call->DecodeInput(inputStream);
const Redirection& redirection = gRedirections[call->mCallId];
- MOZ_RELEASE_ASSERT(gRedirections[call->mCallId].mMiddlemanCall);
+ MOZ_RELEASE_ASSERT(redirection.mMiddlemanCall);
CallArguments arguments;
call->mArguments.CopyTo(&arguments);
@@ -323,6 +323,9 @@ void
Middleman_SystemOutput(MiddlemanCallContext& aCx, const void** aOutput, bool aUpdating)
{
if (!*aOutput) {
+ if (aCx.mPhase == MiddlemanCallPhase::MiddlemanOutput) {
+ aCx.mCall->SetMiddlemanValue(*aOutput);
+ }
return;
}
diff --git a/toolkit/recordreplay/ProcessRedirect.cpp b/toolkit/recordreplay/ProcessRedirect.cpp
index 8a1669d7640e..8d27457efb3a 100644
--- a/toolkit/recordreplay/ProcessRedirect.cpp
+++ b/toolkit/recordreplay/ProcessRedirect.cpp
@@ -8,6 +8,7 @@
#include "InfallibleVector.h"
#include "MiddlemanCall.h"
+#include "ipc/ParentInternal.h"
#include "mozilla/Sprintf.h"
#include
@@ -99,6 +100,11 @@ RecordReplayInterceptCall(int aCallId, CallArguments* aArguments)
}
}
+ if (parent::InRepaintStressMode()) {
+ // We're about to crash, so print out the name of the call that failed.
+ Print("Could not perform middleman call: %s\n", redirection.mName);
+ }
+
// Calling any redirection which performs the standard steps will cause
// debugger operations that have diverged from the recording to fail.
EnsureNotDivergedFromRecording();
From 7059a8ac77b35f4572e4a3cea97f133bdc83ef8a Mon Sep 17 00:00:00 2001
From: Nika Layzell
Date: Wed, 24 Oct 2018 23:40:37 -0400
Subject: [PATCH 12/26] Bug 1501910 - Pass enumerableOnly into
nsIXPCScriptable::NewEnumerate, r=bzbarsky
Differential Revision: https://phabricator.services.mozilla.com/D9749
---
js/xpconnect/idl/nsIXPCScriptable.idl | 3 ++-
js/xpconnect/public/xpc_map_end.h | 2 +-
js/xpconnect/src/XPCComponents.cpp | 5 +++++
js/xpconnect/src/XPCWrappedNativeJSOps.cpp | 3 ++-
4 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/js/xpconnect/idl/nsIXPCScriptable.idl b/js/xpconnect/idl/nsIXPCScriptable.idl
index 5a0bbf12ca51..160a0dba59ef 100644
--- a/js/xpconnect/idl/nsIXPCScriptable.idl
+++ b/js/xpconnect/idl/nsIXPCScriptable.idl
@@ -79,7 +79,8 @@ interface nsIXPCScriptable : nsISupports
boolean newEnumerate(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj,
- in JSAutoIdVector properties);
+ in JSAutoIdVector properties,
+ in boolean enumerableOnly);
boolean resolve(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj, in jsid id,
diff --git a/js/xpconnect/public/xpc_map_end.h b/js/xpconnect/public/xpc_map_end.h
index a638b9c81d8a..4fcb2ef05315 100644
--- a/js/xpconnect/public/xpc_map_end.h
+++ b/js/xpconnect/public/xpc_map_end.h
@@ -65,7 +65,7 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::PreCreate(nsISupports* nativeObj, JSContext * c
#endif
#if !((XPC_MAP_FLAGS) & XPC_SCRIPTABLE_WANT_NEWENUMERATE)
-NS_IMETHODIMP XPC_MAP_CLASSNAME::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext * cx, JSObject * obj, JS::AutoIdVector& properties, bool* _retval)
+NS_IMETHODIMP XPC_MAP_CLASSNAME::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext * cx, JSObject * obj, JS::AutoIdVector& properties, bool enumerableOnly, bool* _retval)
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp
index f713c1179b08..eb4bfe4b52f1 100644
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -207,6 +207,7 @@ NS_IMETHODIMP
nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
JSContext* cx, JSObject* obj,
JS::AutoIdVector& properties,
+ bool enumerableOnly,
bool* _retval)
{
@@ -394,6 +395,7 @@ NS_IMETHODIMP
nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
JSContext* cx, JSObject* obj,
JS::AutoIdVector& properties,
+ bool enumerableOnly,
bool* _retval)
{
@@ -589,6 +591,7 @@ NS_IMETHODIMP
nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
JSContext* cx, JSObject* obj,
JS::AutoIdVector& properties,
+ bool enumerableOnly,
bool* _retval)
{
nsCOMPtr compMgr;
@@ -784,6 +787,7 @@ NS_IMETHODIMP
nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
JSContext* cx, JSObject* obj,
JS::AutoIdVector& properties,
+ bool enumerableOnly,
bool* _retval)
{
@@ -993,6 +997,7 @@ NS_IMETHODIMP
nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
JSContext* cx, JSObject* obj,
JS::AutoIdVector& properties,
+ bool enumerableOnly,
bool* _retval)
{
const char* name;
diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
index 7caabef6f7b9..c6ec25c3fc44 100644
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -941,7 +941,8 @@ XPC_WN_NewEnumerate(JSContext* cx, HandleObject obj, AutoIdVector& properties,
}
bool retval = true;
- nsresult rv = scr->NewEnumerate(wrapper, cx, obj, properties, &retval);
+ nsresult rv = scr->NewEnumerate(wrapper, cx, obj, properties,
+ enumerableOnly, &retval);
if (NS_FAILED(rv)) {
return Throw(rv, cx);
}
From 84828b5af3c52a104ae6dc8e9762762bb1736e58 Mon Sep 17 00:00:00 2001
From: Nika Layzell
Date: Wed, 24 Oct 2018 19:14:35 -0400
Subject: [PATCH 13/26] Bug 1501124 - Switch BackstagePass to use
WebIDLGlobalNameHash, r=bzbarsky
Differential Revision: https://phabricator.services.mozilla.com/D9736
---
dom/base/ContentFrameMessageManager.h | 1 -
dom/base/ContentProcessMessageManager.cpp | 1 -
dom/base/nsFrameMessageManager.cpp | 1 -
dom/bindings/BindingUtils.cpp | 24 ---
dom/bindings/Codegen.py | 179 ------------------
dom/bindings/WebIDLGlobalNameHash.cpp | 74 ++++++++
dom/bindings/WebIDLGlobalNameHash.h | 11 ++
dom/bindings/mozwebidlcodegen/__init__.py | 2 -
js/xpconnect/src/XPCRuntimeService.cpp | 23 ++-
js/xpconnect/src/nsXPConnect.cpp | 5 -
.../lib/environments/jsm.js | 4 +-
11 files changed, 104 insertions(+), 221 deletions(-)
diff --git a/dom/base/ContentFrameMessageManager.h b/dom/base/ContentFrameMessageManager.h
index b4660b15a9fd..89dde8bda93e 100644
--- a/dom/base/ContentFrameMessageManager.h
+++ b/dom/base/ContentFrameMessageManager.h
@@ -9,7 +9,6 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/MessageManagerGlobal.h"
-#include "mozilla/dom/ResolveSystemBinding.h"
#include "nsContentUtils.h"
#include "xpcpublic.h"
diff --git a/dom/base/ContentProcessMessageManager.cpp b/dom/base/ContentProcessMessageManager.cpp
index 2085db19d18b..05e1a835548d 100644
--- a/dom/base/ContentProcessMessageManager.cpp
+++ b/dom/base/ContentProcessMessageManager.cpp
@@ -10,7 +10,6 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/MessageManagerBinding.h"
#include "mozilla/dom/ParentProcessMessageManager.h"
-#include "mozilla/dom/ResolveSystemBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ipc/SharedMap.h"
diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp
index 418087e95379..79cda17c2553 100644
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -47,7 +47,6 @@
#include "mozilla/dom/ParentProcessMessageManager.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/ProcessMessageManager.h"
-#include "mozilla/dom/ResolveSystemBinding.h"
#include "mozilla/dom/SameProcessMessageQueue.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ToJSValue.h"
diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp
index 01846e81e70f..8b79a0e822ac 100644
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -56,7 +56,6 @@
#include "mozilla/dom/XULPopupElementBinding.h"
#include "mozilla/dom/XULTextElementBinding.h"
#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/ResolveSystemBinding.h"
#include "mozilla/dom/WebIDLGlobalNameHash.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WorkerScope.h"
@@ -3512,29 +3511,6 @@ UnwrapWindowProxyImpl(JSContext* cx,
return NS_OK;
}
-bool
-SystemGlobalResolve(JSContext* cx, JS::Handle obj,
- JS::Handle id, bool* resolvedp)
-{
- if (!ResolveGlobal(cx, obj, id, resolvedp)) {
- return false;
- }
-
- if (*resolvedp) {
- return true;
- }
-
- return ResolveSystemBinding(cx, obj, id, resolvedp);
-}
-
-bool
-SystemGlobalEnumerate(JSContext* cx, JS::Handle obj)
-{
- bool ignored = false;
- return JS_EnumerateStandardClasses(cx, obj) &&
- ResolveSystemBinding(cx, obj, JSID_VOIDHANDLE, &ignored);
-}
-
template
bool
GetMaplikeSetlikeBackingObject(JSContext* aCx, JS::Handle aObj,
diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py
index 2496bd496a53..7ee6a47b6dcf 100644
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -13576,121 +13576,6 @@ class CGRegisterWorkletBindings(CGAbstractMethod):
return CGList(lines, "\n").define()
-class CGSystemBindingInitIds(CGAbstractMethod):
- def __init__(self):
- CGAbstractMethod.__init__(self, None, 'SystemBindingInitIds', 'bool',
- [Argument('JSContext*', 'aCx')])
-
- def definition_body(self):
- return dedent("""
- MOZ_ASSERT(NS_IsMainThread());
-
- if (!idsInited) {
- // We can't use range-based for because we need the index to call IdString.
- for (uint32_t i = 0; i < ArrayLength(properties); ++i) {
- if (!properties[i].id.init(aCx, IdString(i))) {
- return false;
- }
- }
- idsInited = true;
- }
-
- return true;
- """)
-
-
-class CGResolveSystemBinding(CGAbstractMethod):
- def __init__(self):
- CGAbstractMethod.__init__(self, None, 'ResolveSystemBinding', 'bool',
- [Argument('JSContext*', 'aCx'),
- Argument('JS::Handle', 'aObj'),
- Argument('JS::Handle', 'aId'),
- Argument('bool*', 'aResolvedp')])
-
- def definition_body(self):
- return dedent("""
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(idsInited);
-
- if (JSID_IS_VOID(aId)) {
- for (const auto& property : properties) {
- if (!property.enabled || property.enabled(aCx, aObj)) {
- if (!property.define(aCx)) {
- return false;
- }
- *aResolvedp = true;
- }
- }
- return true;
- }
-
- for (const auto& property : properties) {
- if (property.id == aId) {
- if (!property.enabled || property.enabled(aCx, aObj)) {
- if (!property.define(aCx)) {
- return false;
- }
- *aResolvedp = true;
- break;
- }
- }
- }
- return true;
- """)
-
-
-class CGMayResolveAsSystemBindingName(CGAbstractMethod):
- def __init__(self):
- CGAbstractMethod.__init__(self, None, 'MayResolveAsSystemBindingName', 'bool',
- [Argument('jsid', 'aId')])
-
- def definition_body(self):
- return dedent("""
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(idsInited);
-
- for (const auto& property : properties) {
- if (aId == property.id) {
- return true;
- }
- }
- return false;
- """)
-
-
-class CGGetSystemBindingNames(CGAbstractMethod):
- def __init__(self):
- CGAbstractMethod.__init__(self, None, 'GetSystemBindingNames', 'void',
- [Argument('JSContext*', 'aCx'),
- Argument('JS::Handle', 'aObj'),
- Argument('JS::AutoIdVector&', 'aNames'),
- Argument('bool', 'aEnumerableOnly'),
- Argument('mozilla::ErrorResult&', 'aRv')])
-
- def definition_body(self):
- return dedent("""
- MOZ_ASSERT(NS_IsMainThread());
-
- if (aEnumerableOnly) {
- return;
- }
-
- if (!SystemBindingInitIds(aCx)) {
- aRv.NoteJSContextException(aCx);
- return;
- }
-
- for (const auto& property : properties) {
- if (!property.enabled || property.enabled(aCx, aObj)) {
- if (!aNames.append(property.id)) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return;
- }
- }
- }
- """)
-
-
def getGlobalNames(config):
names = []
for desc in config.getDescriptors(registersGlobalNamesOnWindow=True):
@@ -17259,70 +17144,6 @@ class GlobalGenRoots():
# Done.
return curr
- @staticmethod
- def ResolveSystemBinding(config):
- curr = CGList([], "\n")
-
- descriptors = config.getDescriptors(hasInterfaceObject=True,
- isExposedInWindow=True,
- register=True)
- properties = [desc.name for desc in descriptors]
-
- curr.append(CGStringTable("IdString", properties, static=True))
-
- initValues = []
- for desc in descriptors:
- bindingNS = toBindingNamespace(desc.name)
- if desc.isExposedConditionally():
- enabled = "%s::ConstructorEnabled" % bindingNS
- else:
- enabled = "nullptr"
- define = "%s::GetConstructorObject" % bindingNS
- initValues.append("{ %s, %s },\n" % (enabled, define))
- curr.append(CGGeneric(fill("""
- struct SystemProperty
- {
- WebIDLGlobalNameHash::ConstructorEnabled enabled;
- ProtoGetter define;
- PinnedStringId id;
- };
-
- static SystemProperty properties[] = {
- $*{init}
- };
-
- static bool idsInited = false;
- """,
- init="".join(initValues))))
-
- curr.append(CGSystemBindingInitIds())
- curr.append(CGResolveSystemBinding())
- curr.append(CGMayResolveAsSystemBindingName())
- curr.append(CGGetSystemBindingNames())
-
- # Wrap all of that in our namespaces.
- curr = CGNamespace.build(['mozilla', 'dom'],
- CGWrapper(curr, post='\n'))
- curr = CGWrapper(curr, post='\n')
-
- # Add the includes
- defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
- for desc in config.getDescriptors(hasInterfaceObject=True,
- register=True,
- isExposedInWindow=True)]
- defineIncludes.append("nsThreadUtils.h") # For NS_IsMainThread
- defineIncludes.append("js/Id.h") # For jsid
- defineIncludes.append("mozilla/dom/WebIDLGlobalNameHash.h")
-
- curr = CGHeaders([], [], [], [], [], defineIncludes,
- 'ResolveSystemBinding', curr)
-
- # Add include guards.
- curr = CGIncludeGuard('ResolveSystemBinding', curr)
-
- # Done.
- return curr
-
@staticmethod
def UnionTypes(config):
unionTypes = UnionsForFile(config, None)
diff --git a/dom/bindings/WebIDLGlobalNameHash.cpp b/dom/bindings/WebIDLGlobalNameHash.cpp
index 0943364aee20..548e5f6e0907 100644
--- a/dom/bindings/WebIDLGlobalNameHash.cpp
+++ b/dom/bindings/WebIDLGlobalNameHash.cpp
@@ -206,5 +206,79 @@ WebIDLGlobalNameHash::GetNames(JSContext* aCx, JS::Handle aObj,
return true;
}
+/* static */
+bool
+WebIDLGlobalNameHash::ResolveForSystemGlobal(JSContext* aCx,
+ JS::Handle aObj,
+ JS::Handle aId,
+ bool* aResolvedp)
+{
+ MOZ_ASSERT(JS_IsGlobalObject(aObj));
+
+ // First we try to resolve standard classes.
+ if (!JS_ResolveStandardClass(aCx, aObj, aId, aResolvedp)) {
+ return false;
+ }
+ if (*aResolvedp) {
+ return true;
+ }
+
+ // We don't resolve any non-string entries.
+ if (!JSID_IS_STRING(aId)) {
+ return true;
+ }
+
+ // XXX(nika): In the Window case, we unwrap our global object here to handle
+ // XRays. I don't think we ever create xrays to system globals, so I believe
+ // we can skip this step.
+ MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(aObj), "Xrays not supported!");
+
+ // Look up the corresponding entry in the name table, and resolve if enabled.
+ const WebIDLNameTableEntry* entry = GetEntry(JSID_TO_FLAT_STRING(aId));
+ if (entry && (!entry->mEnabled || entry->mEnabled(aCx, aObj))) {
+ if (NS_WARN_IF(!GetPerInterfaceObjectHandle(aCx, entry->mConstructorId,
+ entry->mCreate,
+ /* aDefineOnGlobal = */ true))) {
+ return Throw(aCx, NS_ERROR_FAILURE);
+ }
+
+ *aResolvedp = true;
+ }
+ return true;
+}
+
+/* static */
+bool
+WebIDLGlobalNameHash::NewEnumerateSystemGlobal(JSContext* aCx,
+ JS::Handle aObj,
+ JS::AutoIdVector& aProperties,
+ bool aEnumerableOnly)
+{
+ MOZ_ASSERT(JS_IsGlobalObject(aObj));
+
+ if (!JS_NewEnumerateStandardClasses(aCx, aObj, aProperties, aEnumerableOnly)) {
+ return false;
+ }
+
+ // All properties defined on our global are non-enumerable, so we can skip
+ // remaining properties.
+ if (aEnumerableOnly) {
+ return true;
+ }
+
+ // Enumerate all entries & add enabled ones.
+ for (size_t i = 0; i < sCount; ++i) {
+ const WebIDLNameTableEntry& entry = sEntries[i];
+ if (!entry.mEnabled || entry.mEnabled(aCx, aObj)) {
+ JSString* str = JS_AtomizeStringN(aCx, sNames + entry.mNameOffset,
+ entry.mNameLength);
+ if (!str || !aProperties.append(NON_INTEGER_ATOM_TO_JSID(str))) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
} // namespace dom
} // namespace mozilla
diff --git a/dom/bindings/WebIDLGlobalNameHash.h b/dom/bindings/WebIDLGlobalNameHash.h
index 58bf02a2f262..e210bb3045cd 100644
--- a/dom/bindings/WebIDLGlobalNameHash.h
+++ b/dom/bindings/WebIDLGlobalNameHash.h
@@ -64,6 +64,17 @@ public:
NameType aNameType,
JS::AutoIdVector& aNames);
+ // Helpers for resolving & enumerating names on the system global.
+ // NOTE: These are distinct as it currently lacks a ProtoAndIfaceCache, and is
+ // an XPCOM global.
+ static bool ResolveForSystemGlobal(JSContext* aCx, JS::Handle aObj,
+ JS::Handle aId, bool* aResolvedp);
+
+ static bool NewEnumerateSystemGlobal(JSContext* aCx,
+ JS::Handle aObj,
+ JS::AutoIdVector& aProperties,
+ bool aEnumerableOnly);
+
private:
friend struct WebIDLNameTableEntry;
diff --git a/dom/bindings/mozwebidlcodegen/__init__.py b/dom/bindings/mozwebidlcodegen/__init__.py
index 050ec2d829b0..5b5a72b637ce 100644
--- a/dom/bindings/mozwebidlcodegen/__init__.py
+++ b/dom/bindings/mozwebidlcodegen/__init__.py
@@ -134,7 +134,6 @@ class WebIDLCodegenManager(LoggingMixin):
'RegisterWorkerBindings.h',
'RegisterWorkerDebuggerBindings.h',
'RegisterWorkletBindings.h',
- 'ResolveSystemBinding.h',
'UnionConversions.h',
'UnionTypes.h',
}
@@ -145,7 +144,6 @@ class WebIDLCodegenManager(LoggingMixin):
'RegisterWorkerBindings.cpp',
'RegisterWorkerDebuggerBindings.cpp',
'RegisterWorkletBindings.cpp',
- 'ResolveSystemBinding.cpp',
'UnionTypes.cpp',
'PrototypeList.cpp',
}
diff --git a/js/xpconnect/src/XPCRuntimeService.cpp b/js/xpconnect/src/XPCRuntimeService.cpp
index 21af20b0208a..2bce89f5ca5b 100644
--- a/js/xpconnect/src/XPCRuntimeService.cpp
+++ b/js/xpconnect/src/XPCRuntimeService.cpp
@@ -10,6 +10,9 @@
#include "BackstagePass.h"
#include "nsIPrincipal.h"
#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/WebIDLGlobalNameHash.h"
+
+using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(BackstagePass,
nsIXPCScriptable,
@@ -18,11 +21,15 @@ NS_IMPL_ISUPPORTS(BackstagePass,
nsIScriptObjectPrincipal,
nsISupportsWeakReference)
+// XXX(nika): It appears we don't have support for mayresolve hooks in
+// nsIXPCScriptable, and I don't really want to add it because I'd rather just
+// kill nsIXPCScriptable alltogether, so we don't use it here.
+
// The nsIXPCScriptable map declaration that will generate stubs for us...
#define XPC_MAP_CLASSNAME BackstagePass
#define XPC_MAP_QUOTED_CLASSNAME "BackstagePass"
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
- XPC_SCRIPTABLE_WANT_ENUMERATE | \
+ XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
XPC_SCRIPTABLE_WANT_FINALIZE | \
XPC_SCRIPTABLE_WANT_PRECREATE | \
XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \
@@ -58,17 +65,21 @@ BackstagePass::Resolve(nsIXPConnectWrappedNative* wrapper,
{
JS::RootedObject obj(cx, objArg);
JS::RootedId id(cx, idArg);
- *_retval = mozilla::dom::SystemGlobalResolve(cx, obj, id, resolvedp);
+ *_retval =
+ WebIDLGlobalNameHash::ResolveForSystemGlobal(cx, obj, id, resolvedp);
return *_retval ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
-BackstagePass::Enumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
- JSObject* objArg, bool* _retval)
+BackstagePass::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
+ JSObject* objArg, JS::AutoIdVector& properties,
+ bool enumerableOnly, bool* _retval)
{
JS::RootedObject obj(cx, objArg);
- *_retval = mozilla::dom::SystemGlobalEnumerate(cx, obj);
- return *_retval ? NS_OK : NS_ERROR_FAILURE;
+ *_retval =
+ WebIDLGlobalNameHash::NewEnumerateSystemGlobal(cx, obj, properties,
+ enumerableOnly);
+ return *_retval ? NS_OK : NS_ERROR_FAILURE;
}
/***************************************************************************/
diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp
index 82e5e0e72c60..dd4952175e97 100644
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -27,7 +27,6 @@
#include "mozilla/dom/DOMPrefs.h"
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/ResolveSystemBinding.h"
#include "nsDOMMutationObserver.h"
#include "nsICycleCollectorListener.h"
@@ -580,10 +579,6 @@ InitClassesWithNewWrappedGlobal(JSContext* aJSContext,
// we need to have a principal.
MOZ_ASSERT(aPrincipal);
- if (!SystemBindingInitIds(aJSContext)) {
- return NS_ERROR_FAILURE;
- }
-
InitGlobalObjectOptions(aOptions, aPrincipal);
// Call into XPCWrappedNative to make a new global object, scope, and global
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/jsm.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/jsm.js
index ac1870724f64..eb2c71992866 100644
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/jsm.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/jsm.js
@@ -23,8 +23,8 @@ module.exports = {
"Ci": false,
"Cr": false,
"Cu": false,
- // These globals are made available via WebIDL files, see ResolveSystemBinding in:
- // https://searchfox.org/mozilla-central/source/__GENERATED__/dom/bindings/ResolveSystemBinding.cpp
+ // These globals are made available via WebIDL files, see WebIDLGlobalNameHash.
+ // XXX(nika): We should also explicitly include window-defined globals here now.
"AbortController": false,
"AbortSignal": false,
"AddonManagerPermissions": false,
From 66c9ef81880e9b832f8099ac8affc8441a5122bb Mon Sep 17 00:00:00 2001
From: Mats Palmgren
Date: Thu, 25 Oct 2018 16:51:44 +0200
Subject: [PATCH 14/26] Bug 1453298 - [css-text] Resolve 'text-indent'
percentage against the content-box inline-size of the box itself, not its
containing block. r=emilio
---
layout/generic/nsLineLayout.cpp | 15 ++++-----------
layout/reftests/bugs/reftest.list | 2 +-
.../text-indent-parent-dynamic-ref.html | 2 +-
.../text-indent-single-line-percent-ref.html | 2 +-
.../text-indent-percentage-001.xht.ini | 3 ---
.../text-indent-percentage-002.html.ini | 2 --
.../text-indent-percentage-003.html.ini | 6 ------
.../text-indent-percentage-004.html.ini | 2 --
.../tests/css/CSS2/css1/c547-indent-001-ref.xht | 12 ++----------
.../tests/css/CSS2/css1/c547-indent-001.xht | 2 +-
.../css/CSS2/text/text-indent-percent-001-ref.xht | 4 ++--
.../reference/text-indent-percentage-001-ref.xht | 4 ++--
.../reference/text-indent-percentage-002-ref.html | 2 +-
.../text-indent/text-indent-percentage-001.xht | 6 +++---
.../text-indent/text-indent-percentage-002.html | 7 ++-----
.../text-indent/text-indent-percentage-003.html | 7 ++-----
.../text-indent/text-indent-percentage-004.html | 7 ++-----
17 files changed, 24 insertions(+), 61 deletions(-)
delete mode 100644 testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-001.xht.ini
delete mode 100644 testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-002.html.ini
delete mode 100644 testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-003.html.ini
delete mode 100644 testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-004.html.ini
diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp
index aea8b67b7d3f..8d3f1297fed3 100644
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -219,17 +219,10 @@ nsLineLayout::BeginLineReflow(nscoord aICoord, nscoord aBCoord,
// property amounts to anything.
if (0 == mLineNumber && !HasPrevInFlow(mBlockReflowInput->mFrame)) {
- const nsStyleCoord &textIndent = mStyleText->mTextIndent;
- nscoord pctBasis = 0;
- if (textIndent.HasPercent()) {
- pctBasis =
- mBlockReflowInput->GetContainingBlockContentISize(aWritingMode);
- }
- nscoord indent = textIndent.ComputeCoordPercentCalc(pctBasis);
-
- mTextIndent = indent;
-
- psd->mICoord += indent;
+ nscoord pctBasis = mBlockReflowInput->ComputedISize();
+ mTextIndent = nsLayoutUtils::ResolveToLength(mStyleText->mTextIndent,
+ pctBasis);
+ psd->mICoord += mTextIndent;
}
PerFrameData* pfd = NewPerFrameData(mBlockReflowInput->mFrame);
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
index 0f2cc70d058b..8a7d607283e3 100644
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -2045,7 +2045,7 @@ skip-if(isDebugBuild&&winWidget) == 1330051.svg 1330051-ref.svg
== 1375674.html 1375674-ref.html
== 1372041.html 1372041-ref.html
== 1376092.html 1376092-ref.html
-fuzzy-if(Android&&debug,1-1,1-1) needs-focus == 1377447-1.html 1377447-1-ref.html
+fuzzy-if(Android,0-3,0-3) needs-focus == 1377447-1.html 1377447-1-ref.html
needs-focus != 1377447-1.html 1377447-2.html
== 1379041.html 1379041-ref.html
== 1379696.html 1379696-ref.html
diff --git a/layout/reftests/text-indent/text-indent-parent-dynamic-ref.html b/layout/reftests/text-indent/text-indent-parent-dynamic-ref.html
index 8995a2727f45..8109f19e5986 100644
--- a/layout/reftests/text-indent/text-indent-parent-dynamic-ref.html
+++ b/layout/reftests/text-indent/text-indent-parent-dynamic-ref.html
@@ -3,7 +3,7 @@
diff --git a/layout/reftests/text-indent/text-indent-single-line-percent-ref.html b/layout/reftests/text-indent/text-indent-single-line-percent-ref.html
index 8240ff74f05d..0eafe7c97cbb 100644
--- a/layout/reftests/text-indent/text-indent-single-line-percent-ref.html
+++ b/layout/reftests/text-indent/text-indent-single-line-percent-ref.html
@@ -3,7 +3,7 @@
text-indent test
diff --git a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-001.xht.ini b/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-001.xht.ini
deleted file mode 100644
index 8bbfee1878bd..000000000000
--- a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-001.xht.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[text-indent-percentage-001.xht]
- expected:
- if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
diff --git a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-002.html.ini b/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-002.html.ini
deleted file mode 100644
index 6969edd19784..000000000000
--- a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-002.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-indent-percentage-002.html]
- expected: FAIL
diff --git a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-003.html.ini b/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-003.html.ini
deleted file mode 100644
index 935bca6121bb..000000000000
--- a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-003.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[text-indent-percentage-003.html]
- expected:
- if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
- if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
- if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
- if not debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): FAIL
diff --git a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-004.html.ini b/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-004.html.ini
deleted file mode 100644
index 3bf7fa2a1f1b..000000000000
--- a/testing/web-platform/meta/css/css-text/text-indent/text-indent-percentage-004.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-indent-percentage-004.html]
- expected: FAIL
diff --git a/testing/web-platform/tests/css/CSS2/css1/c547-indent-001-ref.xht b/testing/web-platform/tests/css/CSS2/css1/c547-indent-001-ref.xht
index f66ec9432a23..013a5414bc01 100644
--- a/testing/web-platform/tests/css/CSS2/css1/c547-indent-001-ref.xht
+++ b/testing/web-platform/tests/css/CSS2/css1/c547-indent-001-ref.xht
@@ -32,13 +32,7 @@
margin-top: 0em;
}
- div#X
- {
- float: left;
- margin-left: 50%;
- }
-
- div#after-X
+ div
{
background-color: aqua;
width: 25%;
@@ -58,9 +52,7 @@
the others should all be
aligned on the left of the window.
- X
-
-
The X on the previous line should be centered across the window.
+ X The first X in this sentence should be indented to the center of this block.