mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 01:08:21 +00:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
6f9e3aa729
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsAccDocManager.h"
|
||||
#include "DocManager.h"
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "ApplicationAccessible.h"
|
||||
@ -33,14 +33,14 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager
|
||||
// DocManager
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager public
|
||||
// DocManager public
|
||||
|
||||
DocAccessible*
|
||||
nsAccDocManager::GetDocAccessible(nsIDocument *aDocument)
|
||||
DocManager::GetDocAccessible(nsIDocument* aDocument)
|
||||
{
|
||||
if (!aDocument)
|
||||
return nullptr;
|
||||
@ -56,7 +56,7 @@ nsAccDocManager::GetDocAccessible(nsIDocument *aDocument)
|
||||
}
|
||||
|
||||
Accessible*
|
||||
nsAccDocManager::FindAccessibleInCache(nsINode* aNode) const
|
||||
DocManager::FindAccessibleInCache(nsINode* aNode) const
|
||||
{
|
||||
nsSearchAccessibleInCacheArg arg;
|
||||
arg.mNode = aNode;
|
||||
@ -69,7 +69,7 @@ nsAccDocManager::FindAccessibleInCache(nsINode* aNode) const
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
nsAccDocManager::IsProcessingRefreshDriverNotification() const
|
||||
DocManager::IsProcessingRefreshDriverNotification() const
|
||||
{
|
||||
bool isDocRefreshing = false;
|
||||
mDocAccessibleCache.EnumerateRead(SearchIfDocIsRefreshing,
|
||||
@ -81,10 +81,10 @@ nsAccDocManager::IsProcessingRefreshDriverNotification() const
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager protected
|
||||
// DocManager protected
|
||||
|
||||
bool
|
||||
nsAccDocManager::Init()
|
||||
DocManager::Init()
|
||||
{
|
||||
mDocAccessibleCache.Init(4);
|
||||
|
||||
@ -101,7 +101,7 @@ nsAccDocManager::Init()
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::Shutdown()
|
||||
DocManager::Shutdown()
|
||||
{
|
||||
nsCOMPtr<nsIWebProgress> progress =
|
||||
do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
|
||||
@ -115,7 +115,7 @@ nsAccDocManager::Shutdown()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS3(nsAccDocManager,
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS3(DocManager,
|
||||
nsIWebProgressListener,
|
||||
nsIDOMEventListener,
|
||||
nsISupportsWeakReference)
|
||||
@ -124,9 +124,9 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(nsAccDocManager,
|
||||
// nsIWebProgressListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, uint32_t aStateFlags,
|
||||
nsresult aStatus)
|
||||
DocManager::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, uint32_t aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
|
||||
|
||||
@ -203,39 +203,39 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccDocManager::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress)
|
||||
DocManager::OnProgressChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccDocManager::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsIURI *aLocation,
|
||||
uint32_t aFlags)
|
||||
DocManager::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, nsIURI* aLocation,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccDocManager::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
DocManager::OnStatusChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, nsresult aStatus,
|
||||
const PRUnichar* aMessage)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccDocManager::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
uint32_t aState)
|
||||
DocManager::OnSecurityChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aState)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
@ -245,7 +245,7 @@ nsAccDocManager::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
// nsIDOMEventListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
||||
DocManager::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsAutoString type;
|
||||
aEvent->GetType(type);
|
||||
@ -303,11 +303,11 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager private
|
||||
// DocManager private
|
||||
|
||||
void
|
||||
nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
|
||||
uint32_t aLoadEventType)
|
||||
DocManager::HandleDOMDocumentLoad(nsIDocument* aDocument,
|
||||
uint32_t aLoadEventType)
|
||||
{
|
||||
// Document accessible can be created before we were notified the DOM document
|
||||
// was loaded completely. However if it's not created yet then create it.
|
||||
@ -322,8 +322,8 @@ nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::AddListeners(nsIDocument *aDocument,
|
||||
bool aAddDOMContentLoadedListener)
|
||||
DocManager::AddListeners(nsIDocument* aDocument,
|
||||
bool aAddDOMContentLoadedListener)
|
||||
{
|
||||
nsPIDOMWindow *window = aDocument->GetWindow();
|
||||
nsIDOMEventTarget *target = window->GetChromeEventHandler();
|
||||
@ -347,7 +347,7 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument,
|
||||
}
|
||||
|
||||
DocAccessible*
|
||||
nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
{
|
||||
// Ignore temporary, hiding, resource documents and documents without
|
||||
// docshell.
|
||||
@ -419,12 +419,12 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager static
|
||||
// DocManager static
|
||||
|
||||
PLDHashOperator
|
||||
nsAccDocManager::GetFirstEntryInDocCache(const nsIDocument* aKey,
|
||||
DocAccessible* aDocAccessible,
|
||||
void* aUserArg)
|
||||
DocManager::GetFirstEntryInDocCache(const nsIDocument* aKey,
|
||||
DocAccessible* aDocAccessible,
|
||||
void* aUserArg)
|
||||
{
|
||||
NS_ASSERTION(aDocAccessible,
|
||||
"No doc accessible for the object in doc accessible cache!");
|
||||
@ -434,7 +434,7 @@ nsAccDocManager::GetFirstEntryInDocCache(const nsIDocument* aKey,
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::ClearDocCache()
|
||||
DocManager::ClearDocCache()
|
||||
{
|
||||
DocAccessible* docAcc = nullptr;
|
||||
while (mDocAccessibleCache.EnumerateRead(GetFirstEntryInDocCache, static_cast<void*>(&docAcc))) {
|
||||
@ -444,9 +444,9 @@ nsAccDocManager::ClearDocCache()
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
nsAccDocManager::SearchAccessibleInDocCache(const nsIDocument* aKey,
|
||||
DocAccessible* aDocAccessible,
|
||||
void* aUserArg)
|
||||
DocManager::SearchAccessibleInDocCache(const nsIDocument* aKey,
|
||||
DocAccessible* aDocAccessible,
|
||||
void* aUserArg)
|
||||
{
|
||||
NS_ASSERTION(aDocAccessible,
|
||||
"No doc accessible for the object in doc accessible cache!");
|
||||
@ -464,9 +464,9 @@ nsAccDocManager::SearchAccessibleInDocCache(const nsIDocument* aKey,
|
||||
|
||||
#ifdef DEBUG
|
||||
PLDHashOperator
|
||||
nsAccDocManager::SearchIfDocIsRefreshing(const nsIDocument* aKey,
|
||||
DocAccessible* aDocAccessible,
|
||||
void* aUserArg)
|
||||
DocManager::SearchIfDocIsRefreshing(const nsIDocument* aKey,
|
||||
DocAccessible* aDocAccessible,
|
||||
void* aUserArg)
|
||||
{
|
||||
NS_ASSERTION(aDocAccessible,
|
||||
"No doc accessible for the object in doc accessible cache!");
|
@ -2,8 +2,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsAccDocManager_h_
|
||||
#define nsAccDocManager_h_
|
||||
#ifndef mozilla_a11_DocManager_h_
|
||||
#define mozilla_a11_DocManager_h_
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
@ -19,21 +19,15 @@ namespace a11y {
|
||||
class Accessible;
|
||||
class DocAccessible;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
* Manage the document accessible life cycle.
|
||||
*/
|
||||
class nsAccDocManager : public nsIWebProgressListener,
|
||||
public nsIDOMEventListener,
|
||||
public nsSupportsWeakReference
|
||||
class DocManager : public nsIWebProgressListener,
|
||||
public nsIDOMEventListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
typedef mozilla::a11y::Accessible Accessible;
|
||||
typedef mozilla::a11y::DocAccessible DocAccessible;
|
||||
|
||||
virtual ~nsAccDocManager() { }
|
||||
virtual ~DocManager() { }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
@ -86,7 +80,7 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsAccDocManager() { }
|
||||
DocManager() { }
|
||||
|
||||
/**
|
||||
* Initialize the manager.
|
||||
@ -99,8 +93,8 @@ protected:
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
nsAccDocManager(const nsAccDocManager&);
|
||||
nsAccDocManager& operator =(const nsAccDocManager&);
|
||||
DocManager(const DocManager&);
|
||||
DocManager& operator =(const DocManager&);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -160,4 +154,7 @@ private:
|
||||
DocAccessibleHashtable mDocAccessibleCache;
|
||||
};
|
||||
|
||||
#endif // nsAccDocManager_h_
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_a11_DocManager_h_
|
@ -21,9 +21,9 @@ CPPSRCS = \
|
||||
AccIterator.cpp \
|
||||
Filters.cpp \
|
||||
ARIAStateMap.cpp \
|
||||
DocManager.cpp \
|
||||
FocusManager.cpp \
|
||||
NotificationController.cpp \
|
||||
nsAccDocManager.cpp \
|
||||
nsAccessNode.cpp \
|
||||
nsARIAMap.cpp \
|
||||
nsCoreUtils.cpp \
|
||||
@ -48,7 +48,6 @@ endif
|
||||
|
||||
EXPORTS = \
|
||||
AccEvent.h \
|
||||
nsAccDocManager.h \
|
||||
nsAccessibilityService.h \
|
||||
nsAccessNode.h \
|
||||
$(NULL)
|
||||
@ -56,6 +55,7 @@ EXPORTS = \
|
||||
EXPORTS_NAMESPACES = mozilla/a11y
|
||||
|
||||
EXPORTS_mozilla/a11y = \
|
||||
DocManager.h \
|
||||
FocusManager.h \
|
||||
AccTypes.h \
|
||||
States.h \
|
||||
|
@ -125,7 +125,7 @@ ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
|
||||
bool nsAccessibilityService::gIsShutdown = true;
|
||||
|
||||
nsAccessibilityService::nsAccessibilityService() :
|
||||
nsAccDocManager(), FocusManager()
|
||||
DocManager(), FocusManager()
|
||||
{
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ nsAccessibilityService::~nsAccessibilityService()
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsAccessibilityService,
|
||||
nsAccDocManager,
|
||||
DocManager,
|
||||
nsIAccessibilityService,
|
||||
nsIAccessibleRetrieval,
|
||||
nsIObserver)
|
||||
@ -621,7 +621,7 @@ nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
|
||||
// caches. If we don't find it, and the given node is itself a document, check
|
||||
// our cache of document accessibles (document cache). Note usually shutdown
|
||||
// document accessibles are not stored in the document cache, however an
|
||||
// "unofficially" shutdown document (i.e. not from nsAccDocManager) can still
|
||||
// "unofficially" shutdown document (i.e. not from DocManager) can still
|
||||
// exist in the document cache.
|
||||
Accessible* accessible = FindAccessibleInCache(node);
|
||||
if (!accessible) {
|
||||
@ -975,7 +975,7 @@ bool
|
||||
nsAccessibilityService::Init()
|
||||
{
|
||||
// Initialize accessible document manager.
|
||||
if (!nsAccDocManager::Init())
|
||||
if (!DocManager::Init())
|
||||
return false;
|
||||
|
||||
// Add observers.
|
||||
@ -1026,7 +1026,7 @@ nsAccessibilityService::Shutdown()
|
||||
}
|
||||
|
||||
// Stop accessible document loader.
|
||||
nsAccDocManager::Shutdown();
|
||||
DocManager::Shutdown();
|
||||
|
||||
// Application is going to be closed, shutdown accessibility and mark
|
||||
// accessibility service as shutdown to prevent calls of its methods.
|
||||
|
@ -8,8 +8,7 @@
|
||||
|
||||
#include "nsIAccessibilityService.h"
|
||||
|
||||
#include "nsAccDocManager.h"
|
||||
|
||||
#include "mozilla/a11y/DocManager.h"
|
||||
#include "mozilla/a11y/FocusManager.h"
|
||||
|
||||
#include "nsIObserver.h"
|
||||
@ -64,12 +63,15 @@ bool ShouldA11yBeEnabled();
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
class nsAccessibilityService : public nsAccDocManager,
|
||||
class nsAccessibilityService : public mozilla::a11y::DocManager,
|
||||
public mozilla::a11y::FocusManager,
|
||||
public nsIAccessibilityService,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
typedef mozilla::a11y::Accessible Accessible;
|
||||
typedef mozilla::a11y::DocAccessible DocAccessible;
|
||||
|
||||
virtual ~nsAccessibilityService();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
@ -96,7 +96,7 @@ DocAccessible::
|
||||
if (!mDocument)
|
||||
return;
|
||||
|
||||
// nsAccDocManager creates document accessible when scrollable frame is
|
||||
// DocManager creates document accessible when scrollable frame is
|
||||
// available already, it should be safe time to add scroll listener.
|
||||
AddScrollListener();
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
|
||||
class nsAccDocManager;
|
||||
class nsAccessiblePivot;
|
||||
|
||||
class nsIScrollableView;
|
||||
@ -34,6 +33,7 @@ const uint32_t kDefaultCacheSize = 256;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class DocManager;
|
||||
class NotificationController;
|
||||
class RelatedAccIterator;
|
||||
template<class Class, class Arg>
|
||||
@ -319,7 +319,7 @@ protected:
|
||||
void NotifyOfLoad(uint32_t aLoadEventType);
|
||||
void NotifyOfLoading(bool aIsReloading);
|
||||
|
||||
friend class ::nsAccDocManager;
|
||||
friend class DocManager;
|
||||
|
||||
/**
|
||||
* Perform initial update (create accessible tree).
|
||||
|
@ -135,13 +135,13 @@ OuterDocAccessible::Shutdown()
|
||||
void
|
||||
OuterDocAccessible::InvalidateChildren()
|
||||
{
|
||||
// Do not invalidate children because nsAccDocManager is responsible for
|
||||
// Do not invalidate children because DocManager is responsible for
|
||||
// document accessible lifetime when DOM document is created or destroyed. If
|
||||
// DOM document isn't destroyed but its presshell is destroyed (for example,
|
||||
// when DOM node of outerdoc accessible is hidden), then outerdoc accessible
|
||||
// notifies nsAccDocManager about this. If presshell is created for existing
|
||||
// notifies DocManager about this. If presshell is created for existing
|
||||
// DOM document (for example when DOM node of outerdoc accessible is shown)
|
||||
// then allow nsAccDocManager to handle this case since the document
|
||||
// then allow DocManager to handle this case since the document
|
||||
// accessible is created and appended as a child when it's requested.
|
||||
|
||||
SetChildrenFlag(eChildrenUninitialized);
|
||||
|
@ -50,10 +50,7 @@ var gSimpleTraversalRoles =
|
||||
Ci.nsIAccessibleRole.ROLE_LINK,
|
||||
Ci.nsIAccessibleRole.ROLE_PAGETAB,
|
||||
Ci.nsIAccessibleRole.ROLE_GRAPHIC,
|
||||
// XXX: Find a better solution for ROLE_STATICTEXT.
|
||||
// It allows to filter list bullets but at the same time it
|
||||
// filters CSS generated content too as an unwanted side effect.
|
||||
// Ci.nsIAccessibleRole.ROLE_STATICTEXT,
|
||||
Ci.nsIAccessibleRole.ROLE_STATICTEXT,
|
||||
Ci.nsIAccessibleRole.ROLE_TEXT_LEAF,
|
||||
Ci.nsIAccessibleRole.ROLE_PUSHBUTTON,
|
||||
Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
|
||||
@ -95,6 +92,16 @@ this.TraversalRules = {
|
||||
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
|
||||
else
|
||||
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
|
||||
case Ci.nsIAccessibleRole.ROLE_STATICTEXT:
|
||||
{
|
||||
let parent = aAccessible.parent;
|
||||
// Ignore prefix static text in list items. They are typically bullets or numbers.
|
||||
if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
|
||||
parent.role == Ci.nsIAccessibleRole.ROLE_LISTITEM)
|
||||
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
|
||||
|
||||
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
|
||||
}
|
||||
default:
|
||||
// Ignore the subtree, if there is one. So that we don't land on
|
||||
// the same content that was already presented by its parent.
|
||||
|
@ -584,6 +584,9 @@ pref("network.activity.blipIntervalMilliseconds", 250);
|
||||
|
||||
pref("jsloader.reuseGlobal", true);
|
||||
|
||||
// Enable font inflation for browser tab content.
|
||||
pref("font.size.inflation.minTwips", 120);
|
||||
|
||||
// Enable freeing dirty pages when minimizing memory; this reduces memory
|
||||
// consumption when applications are sent to the background.
|
||||
pref("memory.free_dirty_pages", true);
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r167750"
|
||||
"clang_version": "r168304"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 56161789,
|
||||
"digest": "43a35be63f9ea1c73a1b22532b5484b131f0c25bdb6a2f39e31c968b6c3477f6640450cc8dab8e17df80f20e367b8cbc0a74986a4eefd7ac9b9adf2b0859e55e",
|
||||
"size": 56144782,
|
||||
"digest": "7e7dd6775d71d074cced8407fac82dc5e161a9034927bd059c84fc06da161da39d32bbd95ac9b6efdf550370fa351361bc476f0b327387dc8d503dc446a776d6",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
|
||||
|
||||
MOZ_SAFE_BROWSING=
|
||||
MOZ_SERVICES_COMMON=1
|
||||
MOZ_SERVICES_HEALTHREPORT=1
|
||||
MOZ_SERVICES_METRICS=1
|
||||
|
||||
MOZ_WEBSMS_BACKEND=1
|
||||
MOZ_DISABLE_DOMCRYPTO=1
|
||||
|
@ -483,6 +483,10 @@
|
||||
@BINPATH@/components/WeaveCrypto.manifest
|
||||
@BINPATH@/components/WeaveCrypto.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@BINPATH@/components/HealthReportComponents.manifest
|
||||
@BINPATH@/components/HealthReportService.js
|
||||
#endif
|
||||
@BINPATH@/components/TelemetryPing.js
|
||||
@BINPATH@/components/TelemetryPing.manifest
|
||||
@BINPATH@/components/Webapps.js
|
||||
@ -574,6 +578,9 @@
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
@BINPATH@/@PREF_DIR@/services-sync.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@BINPATH@/@PREF_DIR@/healthreport-prefs.js
|
||||
#endif
|
||||
@BINPATH@/greprefs.js
|
||||
@BINPATH@/defaults/autoconfig/platform.js
|
||||
@BINPATH@/defaults/autoconfig/prefcalls.js
|
||||
|
@ -3536,15 +3536,18 @@ function OpenBrowserWindow(options)
|
||||
var wintype = document.documentElement.getAttribute('windowtype');
|
||||
|
||||
var extraFeatures = "";
|
||||
var forcePrivate = false;
|
||||
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
|
||||
if (typeof options == "object" &&
|
||||
"private" in options &&
|
||||
options.private) {
|
||||
forcePrivate = typeof options == "object" && "private" in options && options.private;
|
||||
#else
|
||||
forcePrivate = gPrivateBrowsingUI.privateBrowsingEnabled;
|
||||
#endif
|
||||
|
||||
if (forcePrivate) {
|
||||
extraFeatures = ",private";
|
||||
// Force the new window to load about:privatebrowsing instead of the default home page
|
||||
defaultArgs = "about:privatebrowsing";
|
||||
}
|
||||
#endif
|
||||
|
||||
// if and only if the current window is a browser window and it has a document with a character
|
||||
// set, then extract the current charset menu setting from the current document and use it to
|
||||
|
@ -25,11 +25,15 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_privatebrowsing_geoprompt_page.html \
|
||||
browser_privatebrowsing_lastpbcontextexited.js \
|
||||
browser_privatebrowsing_localStorage.js \
|
||||
browser_privatebrowsing_localStorage_before_after.js \
|
||||
browser_privatebrowsing_localStorage_before_after_page.html \
|
||||
browser_privatebrowsing_localStorage_before_after_page2.html \
|
||||
browser_privatebrowsing_localStorage_page1.html \
|
||||
browser_privatebrowsing_localStorage_page2.html \
|
||||
browser_privatebrowsing_opendir.js \
|
||||
browser_privatebrowsing_openlocation.js \
|
||||
browser_privatebrowsing_openLocationLastURL.js \
|
||||
browser_privatebrowsing_placestitle.js \
|
||||
browser_privatebrowsing_popupblocker.js \
|
||||
browser_privatebrowsing_protocolhandler.js \
|
||||
browser_privatebrowsing_protocolhandler_page.html \
|
||||
@ -39,6 +43,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_privatebrowsing_windowtitle_page.html \
|
||||
browser_privatebrowsing_zoomrestore.js \
|
||||
popup.html \
|
||||
title.sjs \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -0,0 +1,66 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Ensure that a storage instance used by both private and public sessions at different times does not
|
||||
// allow any data to leak due to cached values.
|
||||
|
||||
// Step 1: Load browser_privatebrowsing_localStorage_before_after_page.html in a private tab, causing a storage
|
||||
// item to exist. Close the tab.
|
||||
// Step 2: Load the same page in a non-private tab, ensuring that the storage instance reports only one item
|
||||
// existing.
|
||||
|
||||
function test() {
|
||||
// initialization
|
||||
waitForExplicitFinish();
|
||||
let windowsToClose = [];
|
||||
let testURI = "about:blank";
|
||||
let prefix = 'http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/perwindow/';
|
||||
|
||||
function doTest(aIsPrivateMode, aWindow, aCallback) {
|
||||
aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
|
||||
if (aIsPrivateMode) {
|
||||
// do something when aIsPrivateMode is true
|
||||
is(aWindow.gBrowser.contentWindow.document.title, '1', "localStorage should contain 1 item");
|
||||
} else {
|
||||
// do something when aIsPrivateMode is false
|
||||
is(aWindow.gBrowser.contentWindow.document.title, 'null|0', 'localStorage should contain 0 items');
|
||||
}
|
||||
|
||||
aCallback();
|
||||
}, true);
|
||||
|
||||
aWindow.gBrowser.selectedBrowser.loadURI(testURI);
|
||||
}
|
||||
|
||||
function testOnWindow(aOptions, aCallback) {
|
||||
whenNewWindowLoaded(aOptions, function(aWin) {
|
||||
windowsToClose.push(aWin);
|
||||
// execute should only be called when need, like when you are opening
|
||||
// web pages on the test. If calling executeSoon() is not necesary, then
|
||||
// call whenNewWindowLoaded() instead of testOnWindow() on your test.
|
||||
executeSoon(function() aCallback(aWin));
|
||||
});
|
||||
};
|
||||
|
||||
// this function is called after calling finish() on the test.
|
||||
registerCleanupFunction(function() {
|
||||
windowsToClose.forEach(function(aWin) {
|
||||
aWin.close();
|
||||
});
|
||||
});
|
||||
|
||||
// test first when on private mode
|
||||
testOnWindow({private: true}, function(aWin) {
|
||||
testURI = prefix + 'browser_privatebrowsing_localStorage_before_after_page.html';
|
||||
doTest(true, aWin, function() {
|
||||
// then test when not on private mode
|
||||
testOnWindow({}, function(aWin) {
|
||||
testURI = prefix + 'browser_privatebrowsing_localStorage_before_after_page2.html';
|
||||
doTest(false, aWin, finish);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
localStorage.clear();
|
||||
localStorage.setItem('zzztest', 'zzzvalue');
|
||||
document.title = localStorage.length;
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,10 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
document.title = localStorage.getItem('zzztest', 'zzzvalue') + '|' + localStorage.length;
|
||||
localStorage.clear();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,109 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This test makes sure that the title of existing history entries does not
|
||||
// change inside a private window.
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
const TEST_URL = "http://mochi.test:8888/browser/browser/components/" +
|
||||
"privatebrowsing/test/browser/perwindow/title.sjs";
|
||||
let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
|
||||
|
||||
function waitForCleanup(aCallback) {
|
||||
// delete all cookies
|
||||
cm.removeAll();
|
||||
// delete all history items
|
||||
Services.obs.addObserver(function observeCH(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(observeCH, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback();
|
||||
}, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
let testNumber = 0;
|
||||
let historyObserver = {
|
||||
onTitleChanged: function(aURI, aPageTitle) {
|
||||
if (aURI.spec != TEST_URL)
|
||||
return;
|
||||
switch (++testNumber) {
|
||||
case 1:
|
||||
// The first time that the page is loaded
|
||||
is(aPageTitle, "No Cookie",
|
||||
"The page should be loaded without any cookie for the first time");
|
||||
openTestPage(selectedWin);
|
||||
break;
|
||||
case 2:
|
||||
// The second time that the page is loaded
|
||||
is(aPageTitle, "Cookie",
|
||||
"The page should be loaded with a cookie for the second time");
|
||||
waitForCleanup(function () {
|
||||
openTestPage(selectedWin);
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
// After clean up
|
||||
is(aPageTitle, "No Cookie",
|
||||
"The page should be loaded without any cookie again");
|
||||
testOnWindow(true, function(win) {
|
||||
whenPageLoad(win, function() {
|
||||
waitForCleanup(finish);
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
// Checks that opening the page in a private window should not fire a
|
||||
// title change.
|
||||
ok(false, "Title changed. Unexpected pass: " + testNumber);
|
||||
}
|
||||
},
|
||||
|
||||
onBeginUpdateBatch: function () {},
|
||||
onEndUpdateBatch: function () {},
|
||||
onVisit: function () {},
|
||||
onBeforeDeleteURI: function () {},
|
||||
onDeleteURI: function () {},
|
||||
onClearHistory: function () {},
|
||||
onPageChanged: function () {},
|
||||
onDeleteVisits: function() {},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver])
|
||||
};
|
||||
PlacesUtils.history.addObserver(historyObserver, false);
|
||||
|
||||
let selectedWin = null;
|
||||
let windowsToClose = [];
|
||||
registerCleanupFunction(function() {
|
||||
PlacesUtils.history.removeObserver(historyObserver);
|
||||
windowsToClose.forEach(function(win) {
|
||||
win.close();
|
||||
});
|
||||
});
|
||||
|
||||
function openTestPage(aWin) {
|
||||
aWin.gBrowser.selectedTab = aWin.gBrowser.addTab(TEST_URL);
|
||||
}
|
||||
|
||||
function whenPageLoad(aWin, aCallback) {
|
||||
aWin.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
aWin.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
aCallback();
|
||||
}, true);
|
||||
aWin.gBrowser.selectedBrowser.loadURI(TEST_URL);
|
||||
}
|
||||
|
||||
function testOnWindow(aPrivate, aCallback) {
|
||||
whenNewWindowLoaded({ private: aPrivate }, function(win) {
|
||||
selectedWin = win;
|
||||
windowsToClose.push(win);
|
||||
executeSoon(function() { aCallback(win) });
|
||||
});
|
||||
}
|
||||
|
||||
waitForCleanup(function() {
|
||||
testOnWindow(false, function(win) {
|
||||
openTestPage(win);
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This provides the tests with a page with different titles based on whether
|
||||
// a cookie is present or not.
|
||||
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
var cookie = "name=value";
|
||||
var title = "No Cookie";
|
||||
if (request.hasHeader("Cookie") && request.getHeader("Cookie") == cookie)
|
||||
title = "Cookie";
|
||||
else
|
||||
response.setHeader("Set-Cookie", cookie, false);
|
||||
|
||||
response.write("<html><head><title>");
|
||||
response.write(title);
|
||||
response.write("</title><body>test page</body></html>");
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r167750"
|
||||
"clang_version": "r168304"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 62553019,
|
||||
"digest": "31dd1ef281d0508bda0c470a29f244f062f42a4c521664dd1833f0f760c4d0cc0a222a8ba23063ad4cf50b678c2ee057519bd480e4a4f6804c3c7fb40f841a92",
|
||||
"size": 62536221,
|
||||
"digest": "a8381234d896ba2eeeef287b948f9d8ffc73bf4d4608ce74002eb666f1ac06d00047fd09b1b8f241c7160561b5dc7a40faf7f8bec94bb7939b9b77ba76af5967",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r167750"
|
||||
"clang_version": "r168304"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 62858526,
|
||||
"digest": "3c8280e001420eea4c352b05dfffda317ecb9c3be1eb23bda5cb16efebd4fe1b38f752b644acf33c6d34858ae01aa026cbb4c6f319fd6ee8d372517922063ad8",
|
||||
"size": 62877504,
|
||||
"digest": "837884b29c176e652b81e9cdaaeda34cf0bf41b7fe17a7f84ed30269ad7daedc9d72ba0d188b8f1551456f307f2dd72583daf99539e62403c0f2b5a83735658e",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r167750"
|
||||
"clang_version": "r168304"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 56161789,
|
||||
"digest": "43a35be63f9ea1c73a1b22532b5484b131f0c25bdb6a2f39e31c968b6c3477f6640450cc8dab8e17df80f20e367b8cbc0a74986a4eefd7ac9b9adf2b0859e55e",
|
||||
"size": 56144782,
|
||||
"digest": "7e7dd6775d71d074cced8407fac82dc5e161a9034927bd059c84fc06da161da39d32bbd95ac9b6efdf550370fa351361bc476f0b327387dc8d503dc446a776d6",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r167750"
|
||||
"clang_version": "r168304"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 56161789,
|
||||
"digest": "43a35be63f9ea1c73a1b22532b5484b131f0c25bdb6a2f39e31c968b6c3477f6640450cc8dab8e17df80f20e367b8cbc0a74986a4eefd7ac9b9adf2b0859e55e",
|
||||
"size": 56144782,
|
||||
"digest": "7e7dd6775d71d074cced8407fac82dc5e161a9034927bd059c84fc06da161da39d32bbd95ac9b6efdf550370fa351361bc476f0b327387dc8d503dc446a776d6",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ MOZ_SAFE_BROWSING=1
|
||||
MOZ_SERVICES_AITC=1
|
||||
MOZ_SERVICES_COMMON=1
|
||||
MOZ_SERVICES_CRYPTO=1
|
||||
MOZ_SERVICES_METRICS=1
|
||||
MOZ_SERVICES_NOTIFICATIONS=1
|
||||
MOZ_SERVICES_SYNC=1
|
||||
MOZ_APP_VERSION=$FIREFOX_VERSION
|
||||
|
@ -463,6 +463,10 @@
|
||||
@BINPATH@/components/AitcComponents.manifest
|
||||
@BINPATH@/components/Aitc.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@BINPATH@/components/HealthReportComponents.manifest
|
||||
@BINPATH@/components/HealthReportService.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_NOTIFICATIONS
|
||||
@BINPATH@/components/NotificationsComponents.manifest
|
||||
#endif
|
||||
@ -570,6 +574,9 @@
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
@BINPATH@/@PREF_DIR@/services-sync.js
|
||||
#endif
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
@BINPATH@/@PREF_DIR@/healthreport-prefs.js
|
||||
#endif
|
||||
@BINPATH@/greprefs.js
|
||||
@BINPATH@/defaults/autoconfig/platform.js
|
||||
@BINPATH@/defaults/autoconfig/prefcalls.js
|
||||
|
@ -978,27 +978,32 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
def checkForZombies(self, processLog):
|
||||
""" Look for hung processes """
|
||||
if not os.path.exists(processLog):
|
||||
self.log.info('INFO | automation.py | PID log not found: %s', processLog)
|
||||
else:
|
||||
self.log.info('INFO | automation.py | Reading PID log: %s', processLog)
|
||||
processList = []
|
||||
pidRE = re.compile(r'launched child process (\d+)$')
|
||||
processLogFD = open(processLog)
|
||||
for line in processLogFD:
|
||||
self.log.info(line.rstrip())
|
||||
m = pidRE.search(line)
|
||||
if m:
|
||||
processList.append(int(m.group(1)))
|
||||
processLogFD.close()
|
||||
self.log.info('Automation Error: PID log not found: %s', processLog)
|
||||
# Whilst no hung process was found, the run should still display as a failure
|
||||
return True
|
||||
|
||||
for processPID in processList:
|
||||
self.log.info("INFO | automation.py | Checking for orphan process with PID: %d", processPID)
|
||||
if self.isPidAlive(processPID):
|
||||
self.log.info("TEST-UNEXPECTED-FAIL | automation.py | child process %d still alive after shutdown", processPID)
|
||||
self.killPid(processPID)
|
||||
foundZombie = False
|
||||
self.log.info('INFO | automation.py | Reading PID log: %s', processLog)
|
||||
processList = []
|
||||
pidRE = re.compile(r'launched child process (\d+)$')
|
||||
processLogFD = open(processLog)
|
||||
for line in processLogFD:
|
||||
self.log.info(line.rstrip())
|
||||
m = pidRE.search(line)
|
||||
if m:
|
||||
processList.append(int(m.group(1)))
|
||||
processLogFD.close()
|
||||
|
||||
for processPID in processList:
|
||||
self.log.info("INFO | automation.py | Checking for orphan process with PID: %d", processPID)
|
||||
if self.isPidAlive(processPID):
|
||||
foundZombie = True
|
||||
self.log.info("TEST-UNEXPECTED-FAIL | automation.py | child process %d still alive after shutdown", processPID)
|
||||
self.killPid(processPID)
|
||||
return foundZombie
|
||||
|
||||
def checkForCrashes(self, profileDir, symbolsPath):
|
||||
automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen)
|
||||
return automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen)
|
||||
|
||||
def runApp(self, testURL, env, app, profileDir, extraArgs,
|
||||
runSSLTunnel = False, utilityPath = None,
|
||||
@ -1065,8 +1070,12 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
self.log.info("INFO | automation.py | Application ran for: %s", str(datetime.now() - startTime))
|
||||
|
||||
# Do a final check for zombie child processes.
|
||||
self.checkForZombies(processLog)
|
||||
self.checkForCrashes(profileDir, symbolsPath)
|
||||
zombieProcesses = self.checkForZombies(processLog)
|
||||
|
||||
crashed = self.checkForCrashes(profileDir, symbolsPath)
|
||||
|
||||
if crashed or zombieProcesses:
|
||||
status = 1
|
||||
|
||||
if os.path.exists(processLog):
|
||||
os.unlink(processLog)
|
||||
|
@ -146,7 +146,6 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None):
|
||||
if len(dumps) == 0:
|
||||
return False
|
||||
|
||||
foundCrash = False
|
||||
removeSymbolsPath = False
|
||||
|
||||
# If our symbols are at a remote URL, download them now
|
||||
@ -198,12 +197,11 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None):
|
||||
extra = os.path.splitext(d)[0] + ".extra"
|
||||
if os.path.exists(extra):
|
||||
os.remove(extra)
|
||||
foundCrash = True
|
||||
finally:
|
||||
if removeSymbolsPath:
|
||||
shutil.rmtree(symbolsPath)
|
||||
|
||||
return foundCrash
|
||||
return True
|
||||
|
||||
def getFullPath(directory, path):
|
||||
"Get an absolute path relative to 'directory'."
|
||||
|
@ -99,11 +99,12 @@ class B2GRemoteAutomation(Automation):
|
||||
# is in place.
|
||||
dumpDir = tempfile.mkdtemp()
|
||||
self._devicemanager.getDirectory(self._remoteProfile + '/minidumps/', dumpDir)
|
||||
automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen)
|
||||
crashed = automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen)
|
||||
try:
|
||||
shutil.rmtree(dumpDir)
|
||||
except:
|
||||
print "WARNING: unable to remove directory: %s" % (dumpDir)
|
||||
return crashed
|
||||
|
||||
def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False):
|
||||
# add b2g specific prefs
|
||||
|
@ -85,21 +85,22 @@ class RemoteAutomation(Automation):
|
||||
|
||||
def checkForCrashes(self, directory, symbolsPath):
|
||||
remoteCrashDir = self._remoteProfile + '/minidumps/'
|
||||
if self._devicemanager.dirExists(remoteCrashDir):
|
||||
dumpDir = tempfile.mkdtemp()
|
||||
self._devicemanager.getDirectory(remoteCrashDir, dumpDir)
|
||||
automationutils.checkForCrashes(dumpDir, symbolsPath,
|
||||
self.lastTestSeen)
|
||||
try:
|
||||
shutil.rmtree(dumpDir)
|
||||
except:
|
||||
print "WARNING: unable to remove directory: %s" % dumpDir
|
||||
else:
|
||||
if not self._devicemanager.dirExists(remoteCrashDir):
|
||||
# As of this writing, the minidumps directory is automatically
|
||||
# created when fennec (first) starts, so its lack of presence
|
||||
# is a hint that something went wrong.
|
||||
print "WARNING: No crash directory (%s) on remote " \
|
||||
"device" % remoteCrashDir
|
||||
print "Automation Error: No crash directory (%s) found on remote device" % remoteCrashDir
|
||||
# Whilst no crash was found, the run should still display as a failure
|
||||
return True
|
||||
dumpDir = tempfile.mkdtemp()
|
||||
self._devicemanager.getDirectory(remoteCrashDir, dumpDir)
|
||||
crashed = automationutils.checkForCrashes(dumpDir, symbolsPath,
|
||||
self.lastTestSeen)
|
||||
try:
|
||||
shutil.rmtree(dumpDir)
|
||||
except:
|
||||
print "WARNING: unable to remove directory: %s" % dumpDir
|
||||
return crashed
|
||||
|
||||
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
|
||||
# If remote profile is specified, use that instead
|
||||
|
@ -3,7 +3,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
llvm_revision = "167750"
|
||||
llvm_revision = "168304"
|
||||
moz_version = "moz0"
|
||||
|
||||
##############################################
|
||||
|
12
configure.in
12
configure.in
@ -8214,6 +8214,18 @@ if test -n "$MOZ_SERVICES_CRYPTO"; then
|
||||
AC_DEFINE(MOZ_SERVICES_CRYPTO)
|
||||
fi
|
||||
|
||||
dnl Build Firefox Health Reporter Service
|
||||
AC_SUBST(MOZ_SERVICES_HEALTHREPORT)
|
||||
if test -n "$MOZ_SERVICES_HEALTHREPORT"; then
|
||||
AC_DEFINE(MOZ_SERVICES_HEALTHREPORT)
|
||||
fi
|
||||
|
||||
dnl Build Services metrics component
|
||||
AC_SUBST(MOZ_SERVICES_METRICS)
|
||||
if test -n "$MOZ_SERVICES_METRICS"; then
|
||||
AC_DEFINE(MOZ_SERVICES_METRICS)
|
||||
fi
|
||||
|
||||
dnl Build Notifications if required
|
||||
AC_SUBST(MOZ_SERVICES_NOTIFICATIONS)
|
||||
if test -n "$MOZ_SERVICES_NOTIFICATIONS"; then
|
||||
|
@ -375,6 +375,8 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
MOZ_ASSERT(mAssertNextInsertOrAppendIndex == -1,
|
||||
"splitText failed to notify insert/append?");
|
||||
NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
|
||||
|
||||
nsINode* newRoot = nullptr;
|
||||
@ -383,6 +385,35 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
|
||||
uint32_t newStartOffset = 0;
|
||||
uint32_t newEndOffset = 0;
|
||||
|
||||
if (aInfo->mDetails &&
|
||||
aInfo->mDetails->mType == CharacterDataChangeInfo::Details::eSplit) {
|
||||
// If the splitted text node is immediately before a range boundary point
|
||||
// that refers to a child index (i.e. its parent is the boundary container)
|
||||
// then we need to increment the corresponding offset to account for the new
|
||||
// text node that will be inserted. If so, we need to prevent the next
|
||||
// ContentInserted or ContentAppended for this range from incrementing it
|
||||
// again (when the new text node is notified).
|
||||
nsINode* parentNode = aContent->GetParentNode();
|
||||
int32_t index = -1;
|
||||
if (parentNode == mEndParent && mEndOffset > 0 &&
|
||||
(index = parentNode->IndexOf(aContent)) + 1 == mEndOffset) {
|
||||
++mEndOffset;
|
||||
mEndOffsetWasIncremented = true;
|
||||
}
|
||||
if (parentNode == mStartParent && mStartOffset > 0 &&
|
||||
(index != -1 ? index : parentNode->IndexOf(aContent)) + 1 == mStartOffset) {
|
||||
++mStartOffset;
|
||||
mStartOffsetWasIncremented = true;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) {
|
||||
mAssertNextInsertOrAppendIndex =
|
||||
(mStartOffsetWasIncremented ? mStartOffset : mEndOffset) - 1;
|
||||
mAssertNextInsertOrAppendNode = aInfo->mDetails->mNextSibling;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If the changed node contains our start boundary and the change starts
|
||||
// before the boundary we'll need to adjust the offset.
|
||||
if (aContent == mStartParent &&
|
||||
@ -469,7 +500,27 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
|
||||
newRoot = IsValidBoundary(newEndNode);
|
||||
}
|
||||
}
|
||||
// When the removed text node's parent is one of our boundary nodes we may
|
||||
// need to adjust the offset to account for the removed node. However,
|
||||
// there will also be a ContentRemoved notification later so the only cases
|
||||
// we need to handle here is when the removed node is the text node after
|
||||
// the boundary. (The m*Offset > 0 check is an optimization - a boundary
|
||||
// point before the first child is never affected by normalize().)
|
||||
nsINode* parentNode = aContent->GetParentNode();
|
||||
if (parentNode == mStartParent && mStartOffset > 0 &&
|
||||
mStartOffset < parentNode->GetChildCount() &&
|
||||
removed == parentNode->GetChildAt(mStartOffset)) {
|
||||
newStartNode = aContent;
|
||||
newStartOffset = aInfo->mChangeStart;
|
||||
}
|
||||
if (parentNode == mEndParent && mEndOffset > 0 &&
|
||||
mEndOffset < parentNode->GetChildCount() &&
|
||||
removed == parentNode->GetChildAt(mEndOffset)) {
|
||||
newEndNode = aContent;
|
||||
newEndOffset = aInfo->mChangeEnd;
|
||||
}
|
||||
}
|
||||
|
||||
if (newStartNode || newEndNode) {
|
||||
if (!newStartNode) {
|
||||
newStartNode = mStartParent;
|
||||
@ -504,6 +555,17 @@ nsRange::ContentAppended(nsIDocument* aDocument,
|
||||
child = child->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) {
|
||||
MOZ_ASSERT(mAssertNextInsertOrAppendIndex == aNewIndexInContainer);
|
||||
MOZ_ASSERT(mAssertNextInsertOrAppendNode == aFirstNewContent);
|
||||
MOZ_ASSERT(aFirstNewContent->IsNodeOfType(nsINode::eTEXT));
|
||||
mStartOffsetWasIncremented = mEndOffsetWasIncremented = false;
|
||||
#ifdef DEBUG
|
||||
mAssertNextInsertOrAppendIndex = -1;
|
||||
mAssertNextInsertOrAppendNode = nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -517,10 +579,12 @@ nsRange::ContentInserted(nsIDocument* aDocument,
|
||||
nsINode* container = NODE_FROM(aContainer, aDocument);
|
||||
|
||||
// Adjust position if a sibling was inserted.
|
||||
if (container == mStartParent && aIndexInContainer < mStartOffset) {
|
||||
if (container == mStartParent && aIndexInContainer < mStartOffset &&
|
||||
!mStartOffsetWasIncremented) {
|
||||
++mStartOffset;
|
||||
}
|
||||
if (container == mEndParent && aIndexInContainer < mEndOffset) {
|
||||
if (container == mEndParent && aIndexInContainer < mEndOffset &&
|
||||
!mEndOffsetWasIncremented) {
|
||||
++mEndOffset;
|
||||
}
|
||||
if (container->IsSelectionDescendant() &&
|
||||
@ -528,6 +592,17 @@ nsRange::ContentInserted(nsIDocument* aDocument,
|
||||
MarkDescendants(aChild);
|
||||
aChild->SetDescendantOfCommonAncestorForRangeInSelection();
|
||||
}
|
||||
|
||||
if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) {
|
||||
MOZ_ASSERT(mAssertNextInsertOrAppendIndex == aIndexInContainer);
|
||||
MOZ_ASSERT(mAssertNextInsertOrAppendNode == aChild);
|
||||
MOZ_ASSERT(aChild->IsNodeOfType(nsINode::eTEXT));
|
||||
mStartOffsetWasIncremented = mEndOffsetWasIncremented = false;
|
||||
#ifdef DEBUG
|
||||
mAssertNextInsertOrAppendIndex = -1;
|
||||
mAssertNextInsertOrAppendNode = nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -538,6 +613,9 @@ nsRange::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
|
||||
MOZ_ASSERT(!mStartOffsetWasIncremented && !mEndOffsetWasIncremented &&
|
||||
mAssertNextInsertOrAppendIndex == -1,
|
||||
"splitText failed to notify insert/append?");
|
||||
|
||||
nsINode* container = NODE_FROM(aContainer, aDocument);
|
||||
bool gravitateStart = false;
|
||||
@ -581,6 +659,9 @@ nsRange::ContentRemoved(nsIDocument* aDocument,
|
||||
void
|
||||
nsRange::ParentChainChanged(nsIContent *aContent)
|
||||
{
|
||||
MOZ_ASSERT(!mStartOffsetWasIncremented && !mEndOffsetWasIncremented &&
|
||||
mAssertNextInsertOrAppendIndex == -1,
|
||||
"splitText failed to notify insert/append?");
|
||||
NS_ASSERTION(mRoot == aContent, "Wrong ParentChainChanged notification?");
|
||||
nsINode* newRoot = IsValidBoundary(mStartParent);
|
||||
NS_ASSERTION(newRoot, "No valid boundary or root found!");
|
||||
|
@ -30,6 +30,12 @@ public:
|
||||
, mIsDetached(false)
|
||||
, mMaySpanAnonymousSubtrees(false)
|
||||
, mInSelection(false)
|
||||
, mStartOffsetWasIncremented(false)
|
||||
, mEndOffsetWasIncremented(false)
|
||||
#ifdef DEBUG
|
||||
, mAssertNextInsertOrAppendIndex(-1)
|
||||
, mAssertNextInsertOrAppendNode(nullptr)
|
||||
#endif
|
||||
{}
|
||||
virtual ~nsRange();
|
||||
|
||||
@ -229,6 +235,12 @@ protected:
|
||||
bool mIsDetached;
|
||||
bool mMaySpanAnonymousSubtrees;
|
||||
bool mInSelection;
|
||||
bool mStartOffsetWasIncremented;
|
||||
bool mEndOffsetWasIncremented;
|
||||
#ifdef DEBUG
|
||||
int32_t mAssertNextInsertOrAppendIndex;
|
||||
nsINode* mAssertNextInsertOrAppendNode;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* nsRange_h___ */
|
||||
|
@ -593,6 +593,8 @@ MOCHITEST_FILES_B = \
|
||||
file_bug804395.jar \
|
||||
test_bug804395.html \
|
||||
test_bug809003.html \
|
||||
test_textnode_split_in_selection.html \
|
||||
test_textnode_normalize_in_selection.html \
|
||||
$(NULL)
|
||||
|
||||
# OOP tests don't work on Windows (bug 763081) or native-fennec
|
||||
|
201
content/base/test/test_textnode_normalize_in_selection.html
Normal file
201
content/base/test/test_textnode_normalize_in_selection.html
Normal file
@ -0,0 +1,201 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=804784
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 804784</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=804784">Mozilla Bug 804784</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 804784 **/
|
||||
|
||||
var sel = document.getSelection();
|
||||
var flush = true;
|
||||
var dry = true;
|
||||
var run = "";
|
||||
var empty_range;
|
||||
var empty_first_text_range;
|
||||
var empty_last_text_range;
|
||||
var full_range;
|
||||
|
||||
function check(range, expected, test)
|
||||
{
|
||||
is(""+range, expected, test);
|
||||
is(""+empty_range, "", "empty range test after: "+test);
|
||||
is(""+empty_first_text_range, "", "empty first text range test after: "+test);
|
||||
if (empty_last_text_range) is(""+empty_last_text_range, "", "empty last text range test after: "+test);
|
||||
is(""+full_range, full_range.startContainer.textContent, "full range test after: "+test);
|
||||
}
|
||||
|
||||
function newDiv()
|
||||
{
|
||||
var div = document.createElement('div');
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
div.appendChild(document.createTextNode(arguments[i]));
|
||||
}
|
||||
document.body.appendChild(div)
|
||||
empty_range = document.createRange();
|
||||
empty_range.setStart(div,0);
|
||||
empty_range.setEnd(div,0);
|
||||
var firstTextNode = div.childNodes[0];
|
||||
var lastTextNode = div.childNodes[div.childNodes.length - 1];
|
||||
empty_first_text_range = document.createRange();
|
||||
empty_first_text_range.setStart(firstTextNode,0);
|
||||
empty_first_text_range.setEnd(firstTextNode,0);
|
||||
empty_last_text_range = null;
|
||||
if (firstTextNode != lastTextNode) {
|
||||
empty_last_text_range = document.createRange();
|
||||
empty_last_text_range.setStart(lastTextNode,0);
|
||||
empty_last_text_range.setEnd(lastTextNode,0);
|
||||
}
|
||||
full_range = document.createRange();
|
||||
full_range.setStart(div,0);
|
||||
full_range.setEnd(div,div.childNodes.length);
|
||||
return div;
|
||||
}
|
||||
|
||||
function selEnd(div,child,index,s)
|
||||
{
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(start, index);
|
||||
r.setEnd(div, div.childNodes.length);
|
||||
if (!dry) div.normalize();
|
||||
check(r,s,run+" selEnd "+child+","+index);
|
||||
}
|
||||
|
||||
function selStart(div,child,index,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(div, 0);
|
||||
r.setEnd(start, index);
|
||||
if (!dry) div.normalize();
|
||||
check(r,s,run+" selStart "+child+","+index);
|
||||
}
|
||||
|
||||
function selMiddleStart(div,child,index,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(div, 1);
|
||||
r.setEnd(start, index);
|
||||
div.normalize();
|
||||
check(r,s,run+" selMiddleStart "+child+","+index);
|
||||
}
|
||||
|
||||
function selMiddleEnd(div,child,index,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(start, index);
|
||||
r.setEnd(div, 2);
|
||||
if (!dry) div.normalize();
|
||||
check(r,s,run+" selMiddleEnd "+child+","+index);
|
||||
}
|
||||
|
||||
function mergeBefore(div,child,index,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(div, 1);
|
||||
r.setEnd(start, index);
|
||||
if (!dry) div.normalize();
|
||||
check(r,s,run+" mergeBefore "+child+","+index);
|
||||
}
|
||||
|
||||
function runTests(s)
|
||||
{
|
||||
run = s+":";
|
||||
selEnd(newDiv('111'), 0,0,'111');
|
||||
selEnd(newDiv('111'), 0,1,'11');
|
||||
selEnd(newDiv('111'), 0,2,'1');
|
||||
selEnd(newDiv(''), 0,0,'');
|
||||
selEnd(newDiv('',''), 1,0,'');
|
||||
selEnd(newDiv('','',''), 1,0,'');
|
||||
selEnd(newDiv('111','222'), 0,1,'11222');
|
||||
selEnd(newDiv('111','222'), 0,2,'1222');
|
||||
selEnd(newDiv('111','222'), 1,1,'22');
|
||||
selEnd(newDiv('','222'), 1,2,'2');
|
||||
selEnd(newDiv('111',''), 0,1,'11');
|
||||
selEnd(newDiv('111','222'), 1,2,'2');
|
||||
selEnd(newDiv('111','222','333'), 1,1,'22333');
|
||||
selEnd(newDiv('111','222','333'), 1,2,'2333');
|
||||
selEnd(newDiv('111','','333'), 0,2,'1333');
|
||||
selEnd(newDiv('111','','333'), 1,0,'333');
|
||||
selEnd(newDiv('111','','333'), 2,0,'333');
|
||||
|
||||
selStart(newDiv('111'), 0,0,'');
|
||||
selStart(newDiv('111'), 0,1,'1');
|
||||
selStart(newDiv('111'), 0,2,'11');
|
||||
selStart(newDiv(''), 0,0,'');
|
||||
selStart(newDiv('111','222'), 0,1,'1');
|
||||
selStart(newDiv('111','222'), 0,2,'11');
|
||||
selStart(newDiv('111','222'), 1,1,'1112');
|
||||
selStart(newDiv('111','222'), 1,2,'11122');
|
||||
selStart(newDiv('111',''), 1,0,'111');
|
||||
selStart(newDiv('111',''), 0,2,'11');
|
||||
selStart(newDiv('111','222','333'), 1,1,'1112');
|
||||
selStart(newDiv('111','222','333'), 1,2,'11122');
|
||||
selStart(newDiv('111','222','333'), 1,2,'11122');
|
||||
selStart(newDiv('111','','333'), 1,0,'111');
|
||||
|
||||
selMiddleStart(newDiv('111','222','333'), 1,1,'2');
|
||||
selMiddleStart(newDiv('111','222','333'), 1,2,'22');
|
||||
selMiddleStart(newDiv('111','222','333'), 2,1,'2223');
|
||||
selMiddleStart(newDiv('111','222','333'), 2,2,'22233');
|
||||
selMiddleStart(newDiv('111','','333'), 2,2,'33');
|
||||
selMiddleStart(newDiv('111','222',''), 2,0,'222');
|
||||
|
||||
selMiddleEnd(newDiv('111','222','333'), 0,1,'11222');
|
||||
selMiddleEnd(newDiv('111','222','333'), 0,2,'1222');
|
||||
selMiddleEnd(newDiv('111','222','333'), 1,1,'22');
|
||||
selMiddleEnd(newDiv('111','222','333'), 1,2,'2');
|
||||
selMiddleEnd(newDiv('111','','333'), 1,0,'');
|
||||
selMiddleEnd(newDiv('','222','333'), 0,0,'222');
|
||||
|
||||
mergeBefore(newDiv('111','222'), 1,1,'2');
|
||||
mergeBefore(newDiv('111','222','333'), 1,2,'22');
|
||||
mergeBefore(newDiv('111','222','333'), 2,1,'2223');
|
||||
mergeBefore(newDiv('111','222','333'), 2,2,'22233');
|
||||
mergeBefore(newDiv('111','','333'), 2,0,'');
|
||||
mergeBefore(newDiv('111','','333'), 2,2,'33');
|
||||
}
|
||||
|
||||
function boom()
|
||||
{
|
||||
runTests("dry run"); // this is to verify the result strings without normalize()
|
||||
dry = false;
|
||||
flush = false;
|
||||
runTests("no flush");
|
||||
flush = true;
|
||||
runTests("flush");
|
||||
}
|
||||
|
||||
boom();
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
221
content/base/test/test_textnode_split_in_selection.html
Normal file
221
content/base/test/test_textnode_split_in_selection.html
Normal file
@ -0,0 +1,221 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=803924
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 803924</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=803924">Mozilla Bug 803924</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 803924 **/
|
||||
|
||||
var sel = document.getSelection();
|
||||
var flush = true;
|
||||
var dry = true;
|
||||
var run = "";
|
||||
var empty_range;
|
||||
var empty_first_text_range;
|
||||
var empty_last_text_range;
|
||||
var full_range;
|
||||
|
||||
function check(range, expected, test)
|
||||
{
|
||||
is(""+range, expected, test);
|
||||
is(""+empty_range, "", "empty range test after: "+test);
|
||||
is(""+empty_first_text_range, "", "empty first text range test after: "+test);
|
||||
if (empty_last_text_range) is(""+empty_last_text_range, "", "empty last text range test after: "+test);
|
||||
is(""+full_range, full_range.startContainer.textContent, "full range test after: "+test);
|
||||
}
|
||||
|
||||
function newDiv()
|
||||
{
|
||||
var div = document.createElement('div');
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
div.appendChild(document.createTextNode(arguments[i]));
|
||||
}
|
||||
document.body.appendChild(div)
|
||||
empty_range = document.createRange();
|
||||
empty_range.setStart(div,0);
|
||||
empty_range.setEnd(div,0);
|
||||
var firstTextNode = div.childNodes[0];
|
||||
var lastTextNode = div.childNodes[div.childNodes.length - 1];
|
||||
empty_first_text_range = document.createRange();
|
||||
empty_first_text_range.setStart(firstTextNode,0);
|
||||
empty_first_text_range.setEnd(firstTextNode,0);
|
||||
empty_last_text_range = null;
|
||||
if (firstTextNode != lastTextNode) {
|
||||
empty_last_text_range = document.createRange();
|
||||
empty_last_text_range.setStart(lastTextNode,0);
|
||||
empty_last_text_range.setEnd(lastTextNode,0);
|
||||
}
|
||||
full_range = document.createRange();
|
||||
full_range.setStart(div,0);
|
||||
full_range.setEnd(div,div.childNodes.length);
|
||||
return div;
|
||||
}
|
||||
|
||||
function selEnd(div,child,index,split,s)
|
||||
{
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(start, index);
|
||||
r.setEnd(div, div.childNodes.length);
|
||||
if (!dry) start.splitText(split);
|
||||
check(r,s,run+" selEnd "+child+","+index+","+split);
|
||||
}
|
||||
|
||||
function selStart(div,child,index,split,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(div, 0);
|
||||
r.setEnd(start, index);
|
||||
if (!dry) start.splitText(split);
|
||||
check(r,s,run+" selStart "+child+","+index+","+split);
|
||||
}
|
||||
|
||||
function selMiddleStart(div,child,index,split,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(div, 1);
|
||||
r.setEnd(start, index);
|
||||
if (!dry) start.splitText(split);
|
||||
check(r,s,run+" selMiddleStart "+child+","+index+","+split);
|
||||
}
|
||||
|
||||
function selMiddleEnd(div,child,index,split,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(start, index);
|
||||
r.setEnd(div, 2);
|
||||
if (!dry) start.splitText(split);
|
||||
check(r,s,run+" selMiddleEnd "+child+","+index+","+split);
|
||||
}
|
||||
|
||||
function splitBefore(div,child,index,split,s)
|
||||
{
|
||||
if (flush) document.body.getClientRects();
|
||||
var start = div.childNodes[child];
|
||||
var r = document.createRange();
|
||||
sel.addRange(r);
|
||||
r.setStart(div, 1);
|
||||
r.setEnd(start, index);
|
||||
if (!dry) div.childNodes[0].splitText(split);
|
||||
check(r,s,run+" splitBefore "+child+","+index+","+split);
|
||||
}
|
||||
|
||||
function runTests(s)
|
||||
{
|
||||
run = s+":";
|
||||
selEnd(newDiv('111'), 0,0,0,'111');
|
||||
selEnd(newDiv('111'), 0,0,1,'111');
|
||||
selEnd(newDiv('111'), 0,0,3,'111');
|
||||
selEnd(newDiv(''), 0,0,0,'');
|
||||
selEnd(newDiv('111'), 0,1,0,'11');
|
||||
selEnd(newDiv('111'), 0,2,1,'1');
|
||||
selEnd(newDiv('111'), 0,1,3,'11');
|
||||
selEnd(newDiv('111','222'), 0,1,0,'11222');
|
||||
selEnd(newDiv('111','222'), 0,2,1,'1222');
|
||||
selEnd(newDiv('111','222'), 0,1,3,'11222');
|
||||
selEnd(newDiv('111','222'), 1,1,0,'22');
|
||||
selEnd(newDiv('111','222'), 1,2,1,'2');
|
||||
selEnd(newDiv('','222'), 1,1,1,'22');
|
||||
selEnd(newDiv('','222'), 0,0,0,'222');
|
||||
selEnd(newDiv('111',''), 0,1,0,'11');
|
||||
selEnd(newDiv('111','222'), 1,1,3,'22');
|
||||
selEnd(newDiv('111','222','333'), 1,1,0,'22333');
|
||||
selEnd(newDiv('111','222','333'), 1,2,1,'2333');
|
||||
selEnd(newDiv('111','222','333'), 1,1,3,'22333');
|
||||
selEnd(newDiv('111','222',''), 1,1,3,'22');
|
||||
selEnd(newDiv('111','','333'), 0,1,3,'11333');
|
||||
|
||||
selStart(newDiv('111'), 0,0,0,'');
|
||||
selStart(newDiv('111'), 0,0,1,'');
|
||||
selStart(newDiv('111'), 0,0,3,'');
|
||||
selStart(newDiv('111'), 0,1,0,'1');
|
||||
selStart(newDiv('111'), 0,2,1,'11');
|
||||
selStart(newDiv('111'), 0,1,3,'1');
|
||||
selStart(newDiv(''), 0,0,0,'');
|
||||
selStart(newDiv('111','222'), 0,1,0,'1');
|
||||
selStart(newDiv('111','222'), 0,2,1,'11');
|
||||
selStart(newDiv('111','222'), 0,1,3,'1');
|
||||
selStart(newDiv('111','222'), 1,1,0,'1112');
|
||||
selStart(newDiv('111','222'), 1,2,1,'11122');
|
||||
selStart(newDiv('111','222'), 1,1,3,'1112');
|
||||
selStart(newDiv('','222'), 1,1,2,'2');
|
||||
selStart(newDiv('','222'), 0,0,0,'');
|
||||
selStart(newDiv('111',''), 1,0,0,'111');
|
||||
selStart(newDiv('111','222','333'), 1,1,0,'1112');
|
||||
selStart(newDiv('111','222','333'), 1,2,1,'11122');
|
||||
selStart(newDiv('111','222','333'), 1,1,3,'1112');
|
||||
selStart(newDiv('111','','333'), 1,0,0,'111');
|
||||
selStart(newDiv('111','222',''), 1,1,3,'1112');
|
||||
|
||||
selMiddleStart(newDiv('111','222','333'), 1,1,0,'2');
|
||||
selMiddleStart(newDiv('111','222','333'), 1,2,1,'22');
|
||||
selMiddleStart(newDiv('111','222','333'), 1,1,3,'2');
|
||||
selMiddleStart(newDiv('111','222','333'), 2,1,0,'2223');
|
||||
selMiddleStart(newDiv('111','222','333'), 2,2,1,'22233');
|
||||
selMiddleStart(newDiv('111','222','333'), 2,1,3,'2223');
|
||||
selMiddleStart(newDiv('111','','333'), 2,1,2,'3');
|
||||
selMiddleStart(newDiv('111','','333'), 1,0,0,'');
|
||||
|
||||
selMiddleEnd(newDiv('111','222','333'), 0,1,0,'11222');
|
||||
selMiddleEnd(newDiv('111','222','333'), 0,2,1,'1222');
|
||||
selMiddleEnd(newDiv('111','222','333'), 0,1,3,'11222');
|
||||
selMiddleEnd(newDiv('111','222','333'), 1,1,0,'22');
|
||||
selMiddleEnd(newDiv('111','222','333'), 1,2,1,'2');
|
||||
selMiddleEnd(newDiv('111','222','333'), 1,1,3,'22');
|
||||
selMiddleEnd(newDiv('111','','333'), 0,1,2,'11');
|
||||
selMiddleEnd(newDiv('111','','333'), 0,1,3,'11');
|
||||
selMiddleEnd(newDiv('111','','333'), 1,0,0,'');
|
||||
|
||||
splitBefore(newDiv('111','222','333'), 1,1,0,'2');
|
||||
splitBefore(newDiv('111','222','333'), 1,2,1,'22');
|
||||
splitBefore(newDiv('111','222','333'), 1,1,3,'2');
|
||||
splitBefore(newDiv('111','222','333'), 2,1,0,'2223');
|
||||
splitBefore(newDiv('111','222','333'), 2,2,1,'22233');
|
||||
splitBefore(newDiv('111','222','333'), 2,1,3,'2223');
|
||||
splitBefore(newDiv('','222','333'), 1,1,0,'2');
|
||||
splitBefore(newDiv('','','333'), 1,0,0,'');
|
||||
splitBefore(newDiv('','222',''), 2,0,0,'222');
|
||||
splitBefore(newDiv('111','','333'), 2,1,2,'3');
|
||||
}
|
||||
|
||||
function boom()
|
||||
{
|
||||
runTests("dry run"); // this is to verify the result strings without splitText()
|
||||
dry = false;
|
||||
flush = false;
|
||||
runTests("no flush");
|
||||
flush = true;
|
||||
runTests("flush");
|
||||
}
|
||||
|
||||
boom();
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -85,100 +85,5 @@ CoerceDouble(jsval v, double* d)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
static bool
|
||||
JSValToMatrixElts(JSContext* cx, const jsval& val,
|
||||
double* (&elts)[N], nsresult* rv)
|
||||
{
|
||||
JSObject* obj;
|
||||
uint32_t length;
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(val) ||
|
||||
!(obj = JSVAL_TO_OBJECT(val)) ||
|
||||
!JS_GetArrayLength(cx, obj, &length) ||
|
||||
N != length) {
|
||||
// Not an array-like thing or wrong size
|
||||
*rv = NS_ERROR_INVALID_ARG;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < N; ++i) {
|
||||
jsval elt;
|
||||
double d;
|
||||
if (!JS_GetElement(cx, obj, i, &elt)) {
|
||||
*rv = NS_ERROR_FAILURE;
|
||||
return false;
|
||||
}
|
||||
if (!CoerceDouble(elt, &d)) {
|
||||
*rv = NS_ERROR_INVALID_ARG;
|
||||
return false;
|
||||
}
|
||||
if (!FloatValidate(d)) {
|
||||
// This is weird, but it's the behavior of SetTransform()
|
||||
*rv = NS_OK;
|
||||
return false;
|
||||
}
|
||||
*elts[i] = d;
|
||||
}
|
||||
|
||||
*rv = NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSValToMatrix(JSContext* cx, const jsval& val, gfxMatrix* matrix, nsresult* rv)
|
||||
{
|
||||
double* elts[] = { &matrix->xx, &matrix->yx, &matrix->xy, &matrix->yy,
|
||||
&matrix->x0, &matrix->y0 };
|
||||
return JSValToMatrixElts(cx, val, elts, rv);
|
||||
}
|
||||
|
||||
bool
|
||||
JSValToMatrix(JSContext* cx, const jsval& val, Matrix* matrix, nsresult* rv)
|
||||
{
|
||||
gfxMatrix m;
|
||||
if (!JSValToMatrix(cx, val, &m, rv))
|
||||
return false;
|
||||
*matrix = Matrix(Float(m.xx), Float(m.yx), Float(m.xy), Float(m.yy),
|
||||
Float(m.x0), Float(m.y0));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
static nsresult
|
||||
MatrixEltsToJSVal(/*const*/ jsval (&elts)[N], JSContext* cx, jsval* val)
|
||||
{
|
||||
JSObject* obj = JS_NewArrayObject(cx, N, elts);
|
||||
if (!obj) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*val = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MatrixToJSVal(const gfxMatrix& matrix, JSContext* cx, jsval* val)
|
||||
{
|
||||
jsval elts[] = {
|
||||
DOUBLE_TO_JSVAL(matrix.xx), DOUBLE_TO_JSVAL(matrix.yx),
|
||||
DOUBLE_TO_JSVAL(matrix.xy), DOUBLE_TO_JSVAL(matrix.yy),
|
||||
DOUBLE_TO_JSVAL(matrix.x0), DOUBLE_TO_JSVAL(matrix.y0)
|
||||
};
|
||||
return MatrixEltsToJSVal(elts, cx, val);
|
||||
}
|
||||
|
||||
nsresult
|
||||
MatrixToJSVal(const Matrix& matrix, JSContext* cx, jsval* val)
|
||||
{
|
||||
jsval elts[] = {
|
||||
DOUBLE_TO_JSVAL(matrix._11), DOUBLE_TO_JSVAL(matrix._12),
|
||||
DOUBLE_TO_JSVAL(matrix._21), DOUBLE_TO_JSVAL(matrix._22),
|
||||
DOUBLE_TO_JSVAL(matrix._31), DOUBLE_TO_JSVAL(matrix._32)
|
||||
};
|
||||
return MatrixEltsToJSVal(elts, cx, val);
|
||||
}
|
||||
|
||||
} // namespace CanvasUtils
|
||||
} // namespace mozilla
|
||||
|
@ -49,18 +49,6 @@ void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
|
||||
// succeeded.
|
||||
bool CoerceDouble(jsval v, double* d);
|
||||
|
||||
// Return true iff the conversion succeeded, false otherwise. *rv is
|
||||
// the value to return to script if this returns false.
|
||||
bool JSValToMatrix(JSContext* cx, const jsval& val,
|
||||
gfxMatrix* matrix, nsresult* rv);
|
||||
bool JSValToMatrix(JSContext* cx, const jsval& val,
|
||||
gfx::Matrix* matrix, nsresult* rv);
|
||||
|
||||
nsresult MatrixToJSVal(const gfxMatrix& matrix,
|
||||
JSContext* cx, jsval* val);
|
||||
nsresult MatrixToJSVal(const gfx::Matrix& matrix,
|
||||
JSContext* cx, jsval* val);
|
||||
|
||||
/* Float validation stuff */
|
||||
#define VALIDATE(_f) if (!NS_finite(_f)) return false
|
||||
|
||||
|
@ -55,6 +55,7 @@ CPPSRCS += \
|
||||
WebGLExtensionTextureFilterAnisotropic.cpp \
|
||||
WebGLExtensionTextureFloat.cpp \
|
||||
WebGLFramebuffer.cpp \
|
||||
WebGLObjectModel.cpp \
|
||||
WebGLProgram.cpp \
|
||||
WebGLRenderbuffer.cpp \
|
||||
WebGLShader.cpp \
|
||||
|
@ -3,11 +3,57 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
WebGLBuffer::WebGLBuffer(WebGLContext *context)
|
||||
: WebGLContextBoundObject(context)
|
||||
, mHasEverBeenBound(false)
|
||||
, mByteLength(0)
|
||||
, mTarget(LOCAL_GL_NONE)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->gl->fGenBuffers(1, &mGLName);
|
||||
mContext->mBuffers.insertBack(this);
|
||||
}
|
||||
|
||||
WebGLBuffer::~WebGLBuffer() {
|
||||
DeleteOnce();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLBuffer::Delete() {
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->gl->fDeleteBuffers(1, &mGLName);
|
||||
mByteLength = 0;
|
||||
mCache = nullptr;
|
||||
LinkedListElement<WebGLBuffer>::remove(); // remove from mContext->mBuffers
|
||||
}
|
||||
|
||||
void
|
||||
WebGLBuffer::SetTarget(GLenum target) {
|
||||
mTarget = target;
|
||||
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
mCache = new WebGLElementArrayCache;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLBuffer::ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) {
|
||||
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
return mCache->BufferData(ptr, buffer_size_in_bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) {
|
||||
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
mCache->BufferSubData(pos, ptr, update_size_in_bytes);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
WebGLBuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
|
||||
return dom::WebGLBufferBinding::Wrap(cx, scope, this, triedToWrap);
|
||||
|
74
content/canvas/src/WebGLBuffer.h
Normal file
74
content/canvas/src/WebGLBuffer.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef WEBGLBUFFER_H_
|
||||
#define WEBGLBUFFER_H_
|
||||
|
||||
#include "WebGLElementArrayCache.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLBuffer MOZ_FINAL
|
||||
: public nsISupports
|
||||
, public WebGLRefCountedObject<WebGLBuffer>
|
||||
, public LinkedListElement<WebGLBuffer>
|
||||
, public WebGLContextBoundObject
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
WebGLBuffer(WebGLContext *context);
|
||||
|
||||
~WebGLBuffer();
|
||||
|
||||
void Delete();
|
||||
|
||||
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
|
||||
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
return aMallocSizeOf(this) + sizeOfCache;
|
||||
}
|
||||
|
||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||
GLuint GLName() const { return mGLName; }
|
||||
GLuint ByteLength() const { return mByteLength; }
|
||||
GLenum Target() const { return mTarget; }
|
||||
|
||||
void SetByteLength(GLuint byteLength) { mByteLength = byteLength; }
|
||||
|
||||
void SetTarget(GLenum target);
|
||||
|
||||
bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes);
|
||||
|
||||
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
|
||||
|
||||
bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
|
||||
return mCache->Validate(type, max_allowed, first, count);
|
||||
}
|
||||
|
||||
WebGLContext *GetParentObject() const {
|
||||
return Context();
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer)
|
||||
|
||||
protected:
|
||||
|
||||
WebGLuint mGLName;
|
||||
bool mHasEverBeenBound;
|
||||
GLuint mByteLength;
|
||||
GLenum mTarget;
|
||||
|
||||
nsAutoPtr<WebGLElementArrayCache> mCache;
|
||||
};
|
||||
}
|
||||
#endif //WEBGLBUFFER_H_
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLExtensions.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
|
||||
|
@ -6,6 +6,10 @@
|
||||
#ifndef WEBGLCONTEXT_H_
|
||||
#define WEBGLCONTEXT_H_
|
||||
|
||||
#include "WebGLElementArrayCache.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLBuffer.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <vector>
|
||||
|
||||
@ -42,8 +46,6 @@
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
||||
#include "WebGLElementArrayCache.h"
|
||||
|
||||
/*
|
||||
* Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=686732
|
||||
@ -62,30 +64,16 @@
|
||||
#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
|
||||
#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
|
||||
|
||||
// Manual reflection of WebIDL typedefs
|
||||
typedef uint32_t WebGLenum;
|
||||
typedef uint32_t WebGLbitfield;
|
||||
typedef int32_t WebGLint;
|
||||
typedef int32_t WebGLsizei;
|
||||
typedef int64_t WebGLsizeiptr;
|
||||
typedef int64_t WebGLintptr;
|
||||
typedef uint32_t WebGLuint;
|
||||
typedef float WebGLfloat;
|
||||
typedef float WebGLclampf;
|
||||
typedef bool WebGLboolean;
|
||||
|
||||
class nsIPropertyBag;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLTexture;
|
||||
class WebGLBuffer;
|
||||
class WebGLProgram;
|
||||
class WebGLShader;
|
||||
class WebGLFramebuffer;
|
||||
class WebGLRenderbuffer;
|
||||
class WebGLUniformLocation;
|
||||
class WebGLContext;
|
||||
class WebGLRenderbuffer;
|
||||
struct WebGLVertexAttribData;
|
||||
class WebGLMemoryPressureObserver;
|
||||
class WebGLRectangleObject;
|
||||
@ -163,246 +151,6 @@ inline bool is_pot_assuming_nonnegative(WebGLsizei x)
|
||||
return x && (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
/* Each WebGL object class WebGLFoo wants to:
|
||||
* - inherit WebGLRefCountedObject<WebGLFoo>
|
||||
* - implement a Delete() method
|
||||
* - have its destructor call DeleteOnce()
|
||||
*
|
||||
* This base class provides two features to WebGL object types:
|
||||
* 1. support for OpenGL object reference counting
|
||||
* 2. support for OpenGL deletion statuses
|
||||
*
|
||||
***** 1. OpenGL object reference counting *****
|
||||
*
|
||||
* WebGL objects such as WebGLTexture's really have two different refcounts:
|
||||
* the XPCOM refcount, that is directly exposed to JavaScript, and the OpenGL
|
||||
* refcount.
|
||||
*
|
||||
* For example, when in JavaScript one does: var newname = existingTexture;
|
||||
* that increments the XPCOM refcount, but doesn't affect the OpenGL refcount.
|
||||
* When one attaches the texture to a framebuffer object, that does increment
|
||||
* its OpenGL refcount (and also its XPCOM refcount, to prevent the regular
|
||||
* XPCOM refcounting mechanism from destroying objects prematurely).
|
||||
*
|
||||
* The actual OpenGL refcount is opaque to us (it's internal to the OpenGL
|
||||
* implementation) but is affects the WebGL semantics that we have to implement:
|
||||
* for example, a WebGLTexture that is attached to a WebGLFramebuffer must not
|
||||
* be actually deleted, even if deleteTexture has been called on it, and even
|
||||
* if JavaScript doesn't have references to it anymore. We can't just rely on
|
||||
* OpenGL to keep alive the underlying OpenGL texture for us, for a variety of
|
||||
* reasons, most importantly: we'd need to know when OpenGL objects are actually
|
||||
* deleted, and OpenGL doesn't notify us about that, so we would have to query
|
||||
* status very often with glIsXxx calls which isn't practical.
|
||||
*
|
||||
* This means that we have to keep track of the OpenGL refcount ourselves,
|
||||
* in addition to the XPCOM refcount.
|
||||
*
|
||||
* This class implements such a refcount, see the mWebGLRefCnt
|
||||
* member. In order to avoid name clashes (with regular XPCOM refcounting)
|
||||
* in the derived class, we prefix members with 'WebGL', whence the names
|
||||
* WebGLAddRef, WebGLRelease, etc.
|
||||
*
|
||||
* In practice, WebGLAddRef and WebGLRelease are only called from the
|
||||
* WebGLRefPtr class.
|
||||
*
|
||||
***** 2. OpenGL deletion statuses *****
|
||||
*
|
||||
* In OpenGL, an object can go through 3 different deletion statuses during its
|
||||
* lifetime, which correspond to the 3 enum values for DeletionStatus in this class:
|
||||
* - the Default status, which it has from its creation to when the
|
||||
* suitable glDeleteXxx function is called on it;
|
||||
* - the DeleteRequested status, which is has from when the suitable glDeleteXxx
|
||||
* function is called on it to when it is no longer referenced by other OpenGL
|
||||
* objects. For example, a texture that is attached to a non-current FBO
|
||||
* will enter that status when glDeleteTexture is called on it. For objects
|
||||
* with that status, GL_DELETE_STATUS queries return true, but glIsXxx
|
||||
* functions still return true.
|
||||
* - the Deleted status, which is the status of objects on which the
|
||||
* suitable glDeleteXxx function has been called, and that are not referenced
|
||||
* by other OpenGL objects.
|
||||
*
|
||||
* This state is stored in the mDeletionStatus member of this class.
|
||||
*
|
||||
* When the GL refcount hits zero, if the status is DeleteRequested then we call
|
||||
* the Delete() method on the derived class and the status becomes Deleted. This is
|
||||
* what the MaybeDelete() function does.
|
||||
*
|
||||
* The DeleteOnce() function implemented here is a helper to ensure that we don't
|
||||
* call Delete() twice on the same object. Since the derived class' destructor
|
||||
* needs to call DeleteOnce() which calls Delete(), we can't allow either to be
|
||||
* virtual. Strictly speaking, we could let them be virtual if the derived class
|
||||
* were final, but that would be impossible to enforce and would lead to strange
|
||||
* bugs if it were subclassed.
|
||||
*
|
||||
* This WebGLRefCountedObject class takes the Derived type
|
||||
* as template parameter, as a means to allow DeleteOnce to call Delete()
|
||||
* on the Derived class, without either method being virtual. This is a common
|
||||
* C++ pattern known as the "curiously recursive template pattern (CRTP)".
|
||||
*/
|
||||
template<typename Derived>
|
||||
class WebGLRefCountedObject
|
||||
{
|
||||
public:
|
||||
enum DeletionStatus { Default, DeleteRequested, Deleted };
|
||||
|
||||
WebGLRefCountedObject()
|
||||
: mDeletionStatus(Default)
|
||||
{ }
|
||||
|
||||
~WebGLRefCountedObject() {
|
||||
NS_ABORT_IF_FALSE(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects");
|
||||
NS_ABORT_IF_FALSE(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()");
|
||||
}
|
||||
|
||||
// called by WebGLRefPtr
|
||||
void WebGLAddRef() {
|
||||
++mWebGLRefCnt;
|
||||
}
|
||||
|
||||
// called by WebGLRefPtr
|
||||
void WebGLRelease() {
|
||||
NS_ABORT_IF_FALSE(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero");
|
||||
--mWebGLRefCnt;
|
||||
MaybeDelete();
|
||||
}
|
||||
|
||||
// this is the function that WebGL.deleteXxx() functions want to call
|
||||
void RequestDelete() {
|
||||
if (mDeletionStatus == Default)
|
||||
mDeletionStatus = DeleteRequested;
|
||||
MaybeDelete();
|
||||
}
|
||||
|
||||
bool IsDeleted() const {
|
||||
return mDeletionStatus == Deleted;
|
||||
}
|
||||
|
||||
bool IsDeleteRequested() const {
|
||||
return mDeletionStatus != Default;
|
||||
}
|
||||
|
||||
void DeleteOnce() {
|
||||
if (mDeletionStatus != Deleted) {
|
||||
static_cast<Derived*>(this)->Delete();
|
||||
mDeletionStatus = Deleted;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void MaybeDelete() {
|
||||
if (mWebGLRefCnt == 0 &&
|
||||
mDeletionStatus == DeleteRequested)
|
||||
{
|
||||
DeleteOnce();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
nsAutoRefCnt mWebGLRefCnt;
|
||||
DeletionStatus mDeletionStatus;
|
||||
};
|
||||
|
||||
/* This WebGLRefPtr class is meant to be used for references between WebGL objects.
|
||||
* For example, a WebGLProgram holds WebGLRefPtr's to the WebGLShader's attached
|
||||
* to it.
|
||||
*
|
||||
* Why the need for a separate refptr class? The only special thing that WebGLRefPtr
|
||||
* does is that it increments and decrements the WebGL refcount of
|
||||
* WebGLRefCountedObject's, in addition to incrementing and decrementing the
|
||||
* usual XPCOM refcount.
|
||||
*
|
||||
* This means that by using a WebGLRefPtr instead of a nsRefPtr, you ensure that
|
||||
* the WebGL refcount is incremented, which means that the object will be kept
|
||||
* alive by this reference even if the matching webgl.deleteXxx() function is
|
||||
* called on it.
|
||||
*/
|
||||
template<typename T>
|
||||
class WebGLRefPtr
|
||||
{
|
||||
public:
|
||||
WebGLRefPtr()
|
||||
: mRawPtr(0)
|
||||
{ }
|
||||
|
||||
WebGLRefPtr(const WebGLRefPtr<T>& aSmartPtr)
|
||||
: mRawPtr(aSmartPtr.mRawPtr)
|
||||
{
|
||||
AddRefOnPtr(mRawPtr);
|
||||
}
|
||||
|
||||
WebGLRefPtr(T *aRawPtr)
|
||||
: mRawPtr(aRawPtr)
|
||||
{
|
||||
AddRefOnPtr(mRawPtr);
|
||||
}
|
||||
|
||||
~WebGLRefPtr() {
|
||||
ReleasePtr(mRawPtr);
|
||||
}
|
||||
|
||||
WebGLRefPtr<T>&
|
||||
operator=(const WebGLRefPtr<T>& rhs)
|
||||
{
|
||||
assign_with_AddRef(rhs.mRawPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
WebGLRefPtr<T>&
|
||||
operator=(T* rhs)
|
||||
{
|
||||
assign_with_AddRef(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return static_cast<T*>(mRawPtr);
|
||||
}
|
||||
|
||||
operator T*() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator->()!");
|
||||
return get();
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator*()!");
|
||||
return *get();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void AddRefOnPtr(T* rawPtr) {
|
||||
if (rawPtr) {
|
||||
rawPtr->WebGLAddRef();
|
||||
rawPtr->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
static void ReleasePtr(T* rawPtr) {
|
||||
if (rawPtr) {
|
||||
rawPtr->WebGLRelease(); // must be done first before Release(), as Release() might actually destroy the object
|
||||
rawPtr->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void assign_with_AddRef(T* rawPtr) {
|
||||
AddRefOnPtr(rawPtr);
|
||||
assign_assuming_AddRef(rawPtr);
|
||||
}
|
||||
|
||||
void assign_assuming_AddRef(T* newPtr) {
|
||||
T* oldPtr = mRawPtr;
|
||||
mRawPtr = newPtr;
|
||||
ReleasePtr(oldPtr);
|
||||
}
|
||||
|
||||
protected:
|
||||
T *mRawPtr;
|
||||
};
|
||||
|
||||
// this class is a mixin for GL objects that have dimensions
|
||||
// that we need to track.
|
||||
class WebGLRectangleObject
|
||||
@ -1463,29 +1211,6 @@ ToSupports(WebGLContext* context)
|
||||
return static_cast<nsICanvasRenderingContextInternal*>(context);
|
||||
}
|
||||
|
||||
// This class is a mixin for objects that are tied to a specific
|
||||
// context (which is to say, all of them). They provide initialization
|
||||
// as well as comparison with the current context.
|
||||
class WebGLContextBoundObject
|
||||
{
|
||||
public:
|
||||
WebGLContextBoundObject(WebGLContext *context) {
|
||||
mContext = context;
|
||||
mContextGeneration = context->Generation();
|
||||
}
|
||||
|
||||
bool IsCompatibleWithContext(WebGLContext *other) {
|
||||
return mContext == other &&
|
||||
mContextGeneration == other->Generation();
|
||||
}
|
||||
|
||||
WebGLContext *Context() const { return mContext; }
|
||||
|
||||
protected:
|
||||
WebGLContext *mContext;
|
||||
uint32_t mContextGeneration;
|
||||
};
|
||||
|
||||
struct WebGLVertexAttribData {
|
||||
// note that these initial values are what GL initializes vertex attribs to
|
||||
WebGLVertexAttribData()
|
||||
@ -1531,90 +1256,6 @@ struct WebGLVertexAttribData {
|
||||
}
|
||||
};
|
||||
|
||||
class WebGLBuffer MOZ_FINAL
|
||||
: public nsISupports
|
||||
, public WebGLRefCountedObject<WebGLBuffer>
|
||||
, public LinkedListElement<WebGLBuffer>
|
||||
, public WebGLContextBoundObject
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
WebGLBuffer(WebGLContext *context)
|
||||
: WebGLContextBoundObject(context)
|
||||
, mHasEverBeenBound(false)
|
||||
, mByteLength(0)
|
||||
, mTarget(LOCAL_GL_NONE)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->gl->fGenBuffers(1, &mGLName);
|
||||
mContext->mBuffers.insertBack(this);
|
||||
}
|
||||
|
||||
~WebGLBuffer() {
|
||||
DeleteOnce();
|
||||
}
|
||||
|
||||
void Delete() {
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->gl->fDeleteBuffers(1, &mGLName);
|
||||
mByteLength = 0;
|
||||
mCache = nullptr;
|
||||
LinkedListElement<WebGLBuffer>::removeFrom(mContext->mBuffers);
|
||||
}
|
||||
|
||||
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
|
||||
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
return aMallocSizeOf(this) + sizeOfCache;
|
||||
}
|
||||
|
||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||
GLuint GLName() const { return mGLName; }
|
||||
GLuint ByteLength() const { return mByteLength; }
|
||||
GLenum Target() const { return mTarget; }
|
||||
|
||||
void SetByteLength(GLuint byteLength) { mByteLength = byteLength; }
|
||||
|
||||
void SetTarget(GLenum target) {
|
||||
mTarget = target;
|
||||
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
mCache = new WebGLElementArrayCache;
|
||||
}
|
||||
|
||||
bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) {
|
||||
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
return mCache->BufferData(ptr, buffer_size_in_bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) {
|
||||
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
mCache->BufferSubData(pos, ptr, update_size_in_bytes);
|
||||
}
|
||||
|
||||
bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
|
||||
return mCache->Validate(type, max_allowed, first, count);
|
||||
}
|
||||
|
||||
WebGLContext *GetParentObject() const {
|
||||
return Context();
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer)
|
||||
|
||||
protected:
|
||||
|
||||
WebGLuint mGLName;
|
||||
bool mHasEverBeenBound;
|
||||
GLuint mByteLength;
|
||||
GLenum mTarget;
|
||||
|
||||
nsAutoPtr<WebGLElementArrayCache> mCache;
|
||||
};
|
||||
|
||||
// NOTE: When this class is switched to new DOM bindings, update the (then-slow)
|
||||
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
|
||||
@ -3467,22 +3108,4 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
||||
aCallback.NoteXPCOMChild(aField.buf);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& aField)
|
||||
{
|
||||
aField = nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
||||
mozilla::WebGLRefPtr<T>& aField,
|
||||
const char* aName,
|
||||
uint32_t aFlags = 0)
|
||||
{
|
||||
CycleCollectionNoteEdgeName(aCallback, aName, aFlags);
|
||||
aCallback.NoteXPCOMChild(aField);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
19
content/canvas/src/WebGLObjectModel.cpp
Normal file
19
content/canvas/src/WebGLObjectModel.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext *context) {
|
||||
mContext = context;
|
||||
mContextGeneration = context->Generation();
|
||||
}
|
||||
bool
|
||||
WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext *other) {
|
||||
return mContext == other &&
|
||||
mContextGeneration == other->Generation();
|
||||
}
|
306
content/canvas/src/WebGLObjectModel.h
Normal file
306
content/canvas/src/WebGLObjectModel.h
Normal file
@ -0,0 +1,306 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef WEBGLOBJECTMODEL_H_
|
||||
#define WEBGLOBJECTMODEL_H_
|
||||
|
||||
#include "nsCycleCollectionNoteChild.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
|
||||
// Manual reflection of WebIDL typedefs
|
||||
typedef uint32_t WebGLenum;
|
||||
typedef uint32_t WebGLbitfield;
|
||||
typedef int32_t WebGLint;
|
||||
typedef int32_t WebGLsizei;
|
||||
typedef int64_t WebGLsizeiptr;
|
||||
typedef int64_t WebGLintptr;
|
||||
typedef uint32_t WebGLuint;
|
||||
typedef float WebGLfloat;
|
||||
typedef float WebGLclampf;
|
||||
typedef bool WebGLboolean;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLBuffer;
|
||||
class WebGLContext;
|
||||
|
||||
/* Each WebGL object class WebGLFoo wants to:
|
||||
* - inherit WebGLRefCountedObject<WebGLFoo>
|
||||
* - implement a Delete() method
|
||||
* - have its destructor call DeleteOnce()
|
||||
*
|
||||
* This base class provides two features to WebGL object types:
|
||||
* 1. support for OpenGL object reference counting
|
||||
* 2. support for OpenGL deletion statuses
|
||||
*
|
||||
***** 1. OpenGL object reference counting *****
|
||||
*
|
||||
* WebGL objects such as WebGLTexture's really have two different refcounts:
|
||||
* the XPCOM refcount, that is directly exposed to JavaScript, and the OpenGL
|
||||
* refcount.
|
||||
*
|
||||
* For example, when in JavaScript one does: var newname = existingTexture;
|
||||
* that increments the XPCOM refcount, but doesn't affect the OpenGL refcount.
|
||||
* When one attaches the texture to a framebuffer object, that does increment
|
||||
* its OpenGL refcount (and also its XPCOM refcount, to prevent the regular
|
||||
* XPCOM refcounting mechanism from destroying objects prematurely).
|
||||
*
|
||||
* The actual OpenGL refcount is opaque to us (it's internal to the OpenGL
|
||||
* implementation) but is affects the WebGL semantics that we have to implement:
|
||||
* for example, a WebGLTexture that is attached to a WebGLFramebuffer must not
|
||||
* be actually deleted, even if deleteTexture has been called on it, and even
|
||||
* if JavaScript doesn't have references to it anymore. We can't just rely on
|
||||
* OpenGL to keep alive the underlying OpenGL texture for us, for a variety of
|
||||
* reasons, most importantly: we'd need to know when OpenGL objects are actually
|
||||
* deleted, and OpenGL doesn't notify us about that, so we would have to query
|
||||
* status very often with glIsXxx calls which isn't practical.
|
||||
*
|
||||
* This means that we have to keep track of the OpenGL refcount ourselves,
|
||||
* in addition to the XPCOM refcount.
|
||||
*
|
||||
* This class implements such a refcount, see the mWebGLRefCnt
|
||||
* member. In order to avoid name clashes (with regular XPCOM refcounting)
|
||||
* in the derived class, we prefix members with 'WebGL', whence the names
|
||||
* WebGLAddRef, WebGLRelease, etc.
|
||||
*
|
||||
* In practice, WebGLAddRef and WebGLRelease are only called from the
|
||||
* WebGLRefPtr class.
|
||||
*
|
||||
***** 2. OpenGL deletion statuses *****
|
||||
*
|
||||
* In OpenGL, an object can go through 3 different deletion statuses during its
|
||||
* lifetime, which correspond to the 3 enum values for DeletionStatus in this class:
|
||||
* - the Default status, which it has from its creation to when the
|
||||
* suitable glDeleteXxx function is called on it;
|
||||
* - the DeleteRequested status, which is has from when the suitable glDeleteXxx
|
||||
* function is called on it to when it is no longer referenced by other OpenGL
|
||||
* objects. For example, a texture that is attached to a non-current FBO
|
||||
* will enter that status when glDeleteTexture is called on it. For objects
|
||||
* with that status, GL_DELETE_STATUS queries return true, but glIsXxx
|
||||
* functions still return true.
|
||||
* - the Deleted status, which is the status of objects on which the
|
||||
* suitable glDeleteXxx function has been called, and that are not referenced
|
||||
* by other OpenGL objects.
|
||||
*
|
||||
* This state is stored in the mDeletionStatus member of this class.
|
||||
*
|
||||
* When the GL refcount hits zero, if the status is DeleteRequested then we call
|
||||
* the Delete() method on the derived class and the status becomes Deleted. This is
|
||||
* what the MaybeDelete() function does.
|
||||
*
|
||||
* The DeleteOnce() function implemented here is a helper to ensure that we don't
|
||||
* call Delete() twice on the same object. Since the derived class' destructor
|
||||
* needs to call DeleteOnce() which calls Delete(), we can't allow either to be
|
||||
* virtual. Strictly speaking, we could let them be virtual if the derived class
|
||||
* were final, but that would be impossible to enforce and would lead to strange
|
||||
* bugs if it were subclassed.
|
||||
*
|
||||
* This WebGLRefCountedObject class takes the Derived type
|
||||
* as template parameter, as a means to allow DeleteOnce to call Delete()
|
||||
* on the Derived class, without either method being virtual. This is a common
|
||||
* C++ pattern known as the "curiously recursive template pattern (CRTP)".
|
||||
*/
|
||||
template<typename Derived>
|
||||
class WebGLRefCountedObject
|
||||
{
|
||||
public:
|
||||
enum DeletionStatus { Default, DeleteRequested, Deleted };
|
||||
|
||||
WebGLRefCountedObject()
|
||||
: mDeletionStatus(Default)
|
||||
{ }
|
||||
|
||||
~WebGLRefCountedObject() {
|
||||
NS_ABORT_IF_FALSE(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects");
|
||||
NS_ABORT_IF_FALSE(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()");
|
||||
}
|
||||
|
||||
// called by WebGLRefPtr
|
||||
void WebGLAddRef() {
|
||||
++mWebGLRefCnt;
|
||||
}
|
||||
|
||||
// called by WebGLRefPtr
|
||||
void WebGLRelease() {
|
||||
NS_ABORT_IF_FALSE(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero");
|
||||
--mWebGLRefCnt;
|
||||
MaybeDelete();
|
||||
}
|
||||
|
||||
// this is the function that WebGL.deleteXxx() functions want to call
|
||||
void RequestDelete() {
|
||||
if (mDeletionStatus == Default)
|
||||
mDeletionStatus = DeleteRequested;
|
||||
MaybeDelete();
|
||||
}
|
||||
|
||||
bool IsDeleted() const {
|
||||
return mDeletionStatus == Deleted;
|
||||
}
|
||||
|
||||
bool IsDeleteRequested() const {
|
||||
return mDeletionStatus != Default;
|
||||
}
|
||||
|
||||
void DeleteOnce() {
|
||||
if (mDeletionStatus != Deleted) {
|
||||
static_cast<Derived*>(this)->Delete();
|
||||
mDeletionStatus = Deleted;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void MaybeDelete() {
|
||||
if (mWebGLRefCnt == 0 &&
|
||||
mDeletionStatus == DeleteRequested)
|
||||
{
|
||||
DeleteOnce();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
nsAutoRefCnt mWebGLRefCnt;
|
||||
DeletionStatus mDeletionStatus;
|
||||
};
|
||||
|
||||
/* This WebGLRefPtr class is meant to be used for references between WebGL objects.
|
||||
* For example, a WebGLProgram holds WebGLRefPtr's to the WebGLShader's attached
|
||||
* to it.
|
||||
*
|
||||
* Why the need for a separate refptr class? The only special thing that WebGLRefPtr
|
||||
* does is that it increments and decrements the WebGL refcount of
|
||||
* WebGLRefCountedObject's, in addition to incrementing and decrementing the
|
||||
* usual XPCOM refcount.
|
||||
*
|
||||
* This means that by using a WebGLRefPtr instead of a nsRefPtr, you ensure that
|
||||
* the WebGL refcount is incremented, which means that the object will be kept
|
||||
* alive by this reference even if the matching webgl.deleteXxx() function is
|
||||
* called on it.
|
||||
*/
|
||||
template<typename T>
|
||||
class WebGLRefPtr
|
||||
{
|
||||
public:
|
||||
WebGLRefPtr()
|
||||
: mRawPtr(0)
|
||||
{ }
|
||||
|
||||
WebGLRefPtr(const WebGLRefPtr<T>& aSmartPtr)
|
||||
: mRawPtr(aSmartPtr.mRawPtr)
|
||||
{
|
||||
AddRefOnPtr(mRawPtr);
|
||||
}
|
||||
|
||||
WebGLRefPtr(T *aRawPtr)
|
||||
: mRawPtr(aRawPtr)
|
||||
{
|
||||
AddRefOnPtr(mRawPtr);
|
||||
}
|
||||
|
||||
~WebGLRefPtr() {
|
||||
ReleasePtr(mRawPtr);
|
||||
}
|
||||
|
||||
WebGLRefPtr<T>&
|
||||
operator=(const WebGLRefPtr<T>& rhs)
|
||||
{
|
||||
assign_with_AddRef(rhs.mRawPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
WebGLRefPtr<T>&
|
||||
operator=(T* rhs)
|
||||
{
|
||||
assign_with_AddRef(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return static_cast<T*>(mRawPtr);
|
||||
}
|
||||
|
||||
operator T*() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator->()!");
|
||||
return get();
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator*()!");
|
||||
return *get();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void AddRefOnPtr(T* rawPtr) {
|
||||
if (rawPtr) {
|
||||
rawPtr->WebGLAddRef();
|
||||
rawPtr->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
static void ReleasePtr(T* rawPtr) {
|
||||
if (rawPtr) {
|
||||
rawPtr->WebGLRelease(); // must be done first before Release(), as Release() might actually destroy the object
|
||||
rawPtr->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void assign_with_AddRef(T* rawPtr) {
|
||||
AddRefOnPtr(rawPtr);
|
||||
assign_assuming_AddRef(rawPtr);
|
||||
}
|
||||
|
||||
void assign_assuming_AddRef(T* newPtr) {
|
||||
T* oldPtr = mRawPtr;
|
||||
mRawPtr = newPtr;
|
||||
ReleasePtr(oldPtr);
|
||||
}
|
||||
|
||||
protected:
|
||||
T *mRawPtr;
|
||||
};
|
||||
|
||||
// This class is a mixin for objects that are tied to a specific
|
||||
// context (which is to say, all of them). They provide initialization
|
||||
// as well as comparison with the current context.
|
||||
class WebGLContextBoundObject
|
||||
{
|
||||
public:
|
||||
WebGLContextBoundObject(WebGLContext *context);
|
||||
|
||||
bool IsCompatibleWithContext(WebGLContext *other);
|
||||
|
||||
WebGLContext *Context() const { return mContext; }
|
||||
|
||||
protected:
|
||||
WebGLContext *mContext;
|
||||
uint32_t mContextGeneration;
|
||||
};
|
||||
|
||||
}// namespace mozilla
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& aField)
|
||||
{
|
||||
aField = nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
||||
mozilla::WebGLRefPtr<T>& aField,
|
||||
const char* aName,
|
||||
uint32_t aFlags = 0)
|
||||
{
|
||||
CycleCollectionNoteEdgeName(aCallback, aName, aFlags);
|
||||
aCallback.NoteXPCOMChild(aField);
|
||||
}
|
||||
|
||||
#endif
|
@ -256,6 +256,8 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData)
|
||||
/* virtual */ void
|
||||
BodyRule::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out);
|
||||
fputs("[body rule] {}\n", out);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -81,6 +81,7 @@ MOCHITEST_FILES = \
|
||||
test_delay_load.html \
|
||||
test_error_on_404.html \
|
||||
test_info_leak.html \
|
||||
test_invalid_reject.html \
|
||||
test_load.html \
|
||||
test_load_candidates.html \
|
||||
test_load_same_resource.html \
|
||||
@ -246,6 +247,16 @@ MOCHITEST_FILES += \
|
||||
# Other files
|
||||
MOCHITEST_FILES += \
|
||||
bogus.duh \
|
||||
invalid-m0c0.opus \
|
||||
invalid-m0c3.opus \
|
||||
invalid-m1c0.opus \
|
||||
invalid-m1c9.opus \
|
||||
invalid-m2c0.opus \
|
||||
invalid-m2c1.opus \
|
||||
invalid-cmap-short.opus \
|
||||
invalid-cmap-s0c0.opus \
|
||||
invalid-cmap-s0c2.opus \
|
||||
invalid-cmap-s1c2.opus \
|
||||
$(NULL)
|
||||
|
||||
# These tests contain backend-specific tests. Try to write backend
|
||||
|
BIN
content/media/test/invalid-cmap-s0c0.opus
Normal file
BIN
content/media/test/invalid-cmap-s0c0.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-cmap-s0c2.opus
Normal file
BIN
content/media/test/invalid-cmap-s0c2.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-cmap-s1c2.opus
Normal file
BIN
content/media/test/invalid-cmap-s1c2.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-cmap-short.opus
Normal file
BIN
content/media/test/invalid-cmap-short.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-m0c0.opus
Normal file
BIN
content/media/test/invalid-m0c0.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-m0c3.opus
Normal file
BIN
content/media/test/invalid-m0c3.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-m1c0.opus
Normal file
BIN
content/media/test/invalid-m1c0.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-m1c9.opus
Normal file
BIN
content/media/test/invalid-m1c9.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-m2c0.opus
Normal file
BIN
content/media/test/invalid-m2c0.opus
Normal file
Binary file not shown.
BIN
content/media/test/invalid-m2c1.opus
Normal file
BIN
content/media/test/invalid-m2c1.opus
Normal file
Binary file not shown.
@ -167,6 +167,20 @@ var gSnifferTests = [
|
||||
{ name:"bogus.duh", type:"bogus/duh" }
|
||||
];
|
||||
|
||||
// Files we must reject as invalid.
|
||||
var gInvalidTests = [
|
||||
{ name:"invalid-m0c0.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-m0c3.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-m1c0.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-m1c9.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-m2c0.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-m2c1.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-cmap-short.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"},
|
||||
{ name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"},
|
||||
];
|
||||
|
||||
// Converts a path/filename to a file:// URI which we can load from disk.
|
||||
// Optionally checks whether the file actually exists on disk at the location
|
||||
// we've specified.
|
||||
|
52
content/media/test/test_invalid_reject.html
Normal file
52
content/media/test/test_invalid_reject.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Test rejection of invalid files</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function startTest(test, token) {
|
||||
var v = document.createElement('video');
|
||||
manager.started(token);
|
||||
|
||||
// Set up event handlers. Seeing any of these is a failure.
|
||||
function badEvent(type) { return function(e) {
|
||||
ok(false, test.name + " should not fire '" + type + "' event");
|
||||
}};
|
||||
var events = [
|
||||
'loadedmetadata', 'load',
|
||||
'canplay', 'canplaythrough',
|
||||
'playing'
|
||||
];
|
||||
events.forEach( function(e) {
|
||||
v.addEventListener(e, badEvent(e));
|
||||
});
|
||||
|
||||
// Seeing a decoder error is a success.
|
||||
v.addEventListener("error", function(e) {
|
||||
is(v.error.code, v.error.MEDIA_ERR_DECODE,
|
||||
"decoder should reject " + test.name);
|
||||
manager.finished(token);
|
||||
});
|
||||
|
||||
// Now try to load and play the file, which should result in the
|
||||
// error event handler above being called, terminating the test.
|
||||
document.body.appendChild(v);
|
||||
v.src = test.name;
|
||||
v.play();
|
||||
}
|
||||
|
||||
manager.runTests(gInvalidTests, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -21,13 +21,11 @@ using namespace mozilla::dom;
|
||||
/*static*/ nsSMILCSSValueType nsSMILCSSValueType::sSingleton;
|
||||
|
||||
struct ValueWrapper {
|
||||
ValueWrapper(nsCSSProperty aPropID, const nsStyleAnimation::Value& aValue,
|
||||
nsPresContext* aPresContext) :
|
||||
mPropID(aPropID), mCSSValue(aValue), mPresContext(aPresContext) {}
|
||||
ValueWrapper(nsCSSProperty aPropID, const nsStyleAnimation::Value& aValue) :
|
||||
mPropID(aPropID), mCSSValue(aValue) {}
|
||||
|
||||
nsCSSProperty mPropID;
|
||||
nsStyleAnimation::Value mCSSValue;
|
||||
nsPresContext* mPresContext;
|
||||
};
|
||||
|
||||
// Helper "zero" values of various types
|
||||
@ -194,7 +192,6 @@ nsSMILCSSValueType::IsEqual(const nsSMILValue& aLeft,
|
||||
// Both non-null
|
||||
NS_WARN_IF_FALSE(leftWrapper != rightWrapper,
|
||||
"Two nsSMILValues with matching ValueWrapper ptr");
|
||||
// mPresContext doesn't really matter for equality comparison
|
||||
return (leftWrapper->mPropID == rightWrapper->mPropID &&
|
||||
leftWrapper->mCSSValue == rightWrapper->mCSSValue);
|
||||
}
|
||||
@ -247,7 +244,7 @@ nsSMILCSSValueType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
|
||||
// Handle barely-initialized "zero" destination.
|
||||
if (!destWrapper) {
|
||||
aDest.mU.mPtr = destWrapper =
|
||||
new ValueWrapper(property, *destValue, valueToAddWrapper->mPresContext);
|
||||
new ValueWrapper(property, *destValue);
|
||||
}
|
||||
|
||||
return nsStyleAnimation::Add(property,
|
||||
@ -311,8 +308,7 @@ nsSMILCSSValueType::Interpolate(const nsSMILValue& aStartVal,
|
||||
if (nsStyleAnimation::Interpolate(endWrapper->mPropID,
|
||||
*startCSSValue, *endCSSValue,
|
||||
aUnitDistance, resultValue)) {
|
||||
aResult.mU.mPtr = new ValueWrapper(endWrapper->mPropID, resultValue,
|
||||
endWrapper->mPresContext);
|
||||
aResult.mU.mPtr = new ValueWrapper(endWrapper->mPropID, resultValue);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -399,7 +395,7 @@ nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID,
|
||||
if (ValueFromStringHelper(aPropID, aTargetElement, presContext,
|
||||
aString, parsedValue, aIsContextSensitive)) {
|
||||
sSingleton.Init(aValue);
|
||||
aValue.mU.mPtr = new ValueWrapper(aPropID, parsedValue, presContext);
|
||||
aValue.mU.mPtr = new ValueWrapper(aPropID, parsedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,6 +408,6 @@ nsSMILCSSValueType::ValueToString(const nsSMILValue& aValue,
|
||||
"Unexpected SMIL value type");
|
||||
const ValueWrapper* wrapper = ExtractValueWrapper(aValue);
|
||||
return !wrapper ||
|
||||
nsStyleAnimation::UncomputeValue(wrapper->mPropID, wrapper->mPresContext,
|
||||
nsStyleAnimation::UncomputeValue(wrapper->mPropID,
|
||||
wrapper->mCSSValue, aString);
|
||||
}
|
||||
|
@ -258,16 +258,38 @@ let Activities = {
|
||||
};
|
||||
|
||||
let matchFunc = function matchFunc(aResult) {
|
||||
// Bug 773383: arrays of strings / regexp.
|
||||
for (let prop in aResult.description.filters) {
|
||||
if (Array.isArray(aResult.description.filters[prop])) {
|
||||
if (aResult.description.filters[prop].indexOf(aMsg.options.data[prop]) == -1) {
|
||||
return false;
|
||||
|
||||
function matchFuncValue(aValue, aFilter) {
|
||||
// Bug 805822 - Regexp support for MozActivity
|
||||
|
||||
let values = Array.isArray(aValue) ? aValue : [aValue];
|
||||
let filters = Array.isArray(aFilter) ? aFilter : [aFilter];
|
||||
|
||||
// At least 1 value must match.
|
||||
let ret = false;
|
||||
values.forEach(function(value) {
|
||||
if (filters.indexOf(value) != -1) {
|
||||
ret = true;
|
||||
}
|
||||
} else if (aResult.description.filters[prop] !== aMsg.options.data[prop] ) {
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// For any incoming property.
|
||||
for (let prop in aMsg.options.data) {
|
||||
|
||||
// If this is unknown for the app, this app must be excluded.
|
||||
if (!(prop in aResult.description.filters)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, let's check the value against the filter.
|
||||
if (!matchFuncValue(aMsg.options.data[prop], aResult.description.filters[prop])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -1104,6 +1104,7 @@ this.DOMApplicationRegistry = {
|
||||
appObject.localId = localId;
|
||||
appObject.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true, true).path;
|
||||
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
|
||||
dir.permissions = FileUtils.PERMS_DIRECTORY;
|
||||
let manFile = dir.clone();
|
||||
manFile.append(manifestName);
|
||||
let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest;
|
||||
@ -1180,6 +1181,7 @@ this.DOMApplicationRegistry = {
|
||||
let zipFile = FileUtils.getFile("TmpD", ["webapps", aId, "application.zip"], true);
|
||||
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
|
||||
zipFile.moveTo(dir, "application.zip");
|
||||
zipFile.permissions = FileUtils.PERMS_FILE;
|
||||
let tmpDir = FileUtils.getDir("TmpD", ["webapps", aId], true, true);
|
||||
try {
|
||||
tmpDir.remove(true);
|
||||
|
@ -475,13 +475,16 @@ public:
|
||||
// non-wrapper-cached object using WebIDL bindings. "value" must implement a
|
||||
// WrapObject() method taking a JSContext and a scope.
|
||||
template <class T>
|
||||
inline bool
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp)
|
||||
{
|
||||
JSObject* obj = value->GetWrapper();
|
||||
if (obj && js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) {
|
||||
*vp = JS::ObjectValue(*obj);
|
||||
return true;
|
||||
JSObject* obj = value->GetWrapperPreserveColor();
|
||||
if (obj) {
|
||||
xpc_UnmarkNonNullGrayObject(obj);
|
||||
if (js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)) {
|
||||
*vp = JS::ObjectValue(*obj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
|
@ -23,6 +23,7 @@ MOCHITEST_FILES := \
|
||||
test_Range-extractContents.html.json \
|
||||
test_Range-intersectsNode.html.json \
|
||||
test_Range-isPointInRange.html.json \
|
||||
test_Range-mutations.html.json \
|
||||
test_Range-set.html.json \
|
||||
test_interfaces.html.json \
|
||||
$(NULL)
|
||||
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"paras[0].firstChild.splitText(1), with unselected range on paras[0] from 0 to 1": true,
|
||||
"paras[0].firstChild.splitText(1), with selected range on paras[0] from 0 to 1": true,
|
||||
"paras[0].firstChild.splitText(1), with unselected range collapsed at (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(1), with selected range collapsed at (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(1), with unselected range from (paras[0].firstChild, 1) to (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(1), with selected range from (paras[0].firstChild, 1) to (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(2), with unselected range from (paras[0].firstChild, 1) to (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(2), with selected range from (paras[0].firstChild, 1) to (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(3), with unselected range from (paras[0].firstChild, 1) to (paras[0], 1)": true,
|
||||
"paras[0].firstChild.splitText(3), with selected range from (paras[0].firstChild, 1) to (paras[0], 1)": true
|
||||
}
|
@ -32,9 +32,17 @@ const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
const crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(Ci.nsICrashReporter);
|
||||
const oldServerPref = Services.prefs.getCharPref("toolkit.crashreporter.pluginHangSubmitURL");
|
||||
const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
|
||||
|
||||
const serverPrefName = "toolkit.crashreporter.pluginHangSubmitURL";
|
||||
|
||||
var oldServerPref;
|
||||
try {
|
||||
oldServerPref = Services.prefs.getCharPref(serverPrefName);
|
||||
}
|
||||
catch(e) {
|
||||
}
|
||||
|
||||
const oldTimeoutPref = Services.prefs.getIntPref("dom.ipc.plugins.timeoutSecs");
|
||||
|
||||
var testObserver = {
|
||||
@ -81,7 +89,12 @@ var testObserver = {
|
||||
env.set("MOZ_CRASHREPORTER_NO_REPORT", "1");
|
||||
|
||||
// Finally re-set prefs
|
||||
Services.prefs.setCharPref("toolkit.crashreporter.pluginHangSubmitURL", oldServerPref);
|
||||
if (oldServerPref === undefined) {
|
||||
Services.prefs.clearUserPref(serverPrefName);
|
||||
}
|
||||
else {
|
||||
Services.prefs.setCharPref(serverPrefName, oldServerPref);
|
||||
}
|
||||
Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", oldTimeoutPref);
|
||||
SimpleTest.finish();
|
||||
},
|
||||
|
@ -9503,69 +9503,73 @@
|
||||
< sonofabitch
|
||||
---
|
||||
> sonofabitch/!
|
||||
44371a50184
|
||||
44346a50159
|
||||
> spelled
|
||||
44348a50162
|
||||
> spelt
|
||||
44371a50186
|
||||
> spick/S!
|
||||
44383c50196
|
||||
44383c50198
|
||||
< spik/S
|
||||
---
|
||||
> spik/S!
|
||||
46106a51920
|
||||
46106a51922
|
||||
> syllabi
|
||||
46160c51974
|
||||
46160c51976
|
||||
< synch/GMD
|
||||
---
|
||||
> synch/GMDS
|
||||
46167d51980
|
||||
46167d51982
|
||||
< synchs
|
||||
46203,46204c52016,52017
|
||||
46203,46204c52018,52019
|
||||
< sysadmin/S
|
||||
< sysop/S
|
||||
---
|
||||
> sysadmin/MS
|
||||
> sysop/MS
|
||||
46752a52566
|
||||
46752a52568
|
||||
> terabit/MS
|
||||
46753a52568,52569
|
||||
46753a52570,52571
|
||||
> terahertz/M
|
||||
> terapixel/MS
|
||||
46817a52634
|
||||
46817a52636
|
||||
> testcase/MS
|
||||
46831a52649
|
||||
46831a52651
|
||||
> testsuite/MS
|
||||
46925a52744
|
||||
46925a52746
|
||||
> theremin/MS
|
||||
47755a53575
|
||||
47755a53577
|
||||
> transfect/DSMG
|
||||
47774a53595,53596
|
||||
47774a53597,53598
|
||||
> transgenderism
|
||||
> transgene/MS
|
||||
47951c53773
|
||||
47951c53775
|
||||
< triage/M
|
||||
---
|
||||
> triage/MG
|
||||
48869a54692
|
||||
48869a54694
|
||||
> unlikeable
|
||||
49211c55034
|
||||
49211c55036
|
||||
< vagina/M
|
||||
---
|
||||
> vagina/MS
|
||||
49368,49369c55191
|
||||
49368,49369c55193
|
||||
< velour's
|
||||
< velours's
|
||||
---
|
||||
> velour/MS
|
||||
49478a55301
|
||||
49478a55303
|
||||
> vertices
|
||||
50148a55972
|
||||
50148a55974
|
||||
> weaponize/DSG
|
||||
50260,50261d56083
|
||||
50260,50261d56085
|
||||
< werwolf/M
|
||||
< werwolves
|
||||
50728c56550
|
||||
50728c56552
|
||||
< women
|
||||
---
|
||||
> women/M
|
||||
50794c56616
|
||||
50794c56618
|
||||
< wop/S!
|
||||
---
|
||||
> wop/MS!
|
||||
|
@ -1,4 +1,4 @@
|
||||
57438
|
||||
57440
|
||||
0/nm
|
||||
0th/pt
|
||||
1/n1
|
||||
@ -50500,8 +50500,10 @@ spellbinder/M
|
||||
spellbound
|
||||
spellchecker/S
|
||||
spelldown/SM
|
||||
spelled
|
||||
speller/M
|
||||
spelling/M
|
||||
spelt
|
||||
spelunker/MS
|
||||
spelunking/M
|
||||
spend/BSRZG
|
||||
|
@ -2525,8 +2525,8 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
|
||||
// If we have all the data we don't want to waste cpu time doing
|
||||
// a progressive decode
|
||||
mDecoder = new nsJPEGDecoder(*this, observer,
|
||||
mHasBeenDecoded ? Decoder::DecodeStyle::SEQUENTIAL :
|
||||
Decoder::DecodeStyle::PROGRESSIVE);
|
||||
mHasBeenDecoded ? Decoder::SEQUENTIAL :
|
||||
Decoder::PROGRESSIVE);
|
||||
break;
|
||||
case eDecoderType_bmp:
|
||||
mDecoder = new nsBMPDecoder(*this, observer);
|
||||
|
@ -36,26 +36,11 @@ const size_t ChunkShift = 20;
|
||||
const size_t ChunkSize = size_t(1) << ChunkShift;
|
||||
const size_t ChunkMask = ChunkSize - 1;
|
||||
|
||||
const size_t CellShift = 3;
|
||||
const size_t CellSize = size_t(1) << CellShift;
|
||||
const size_t CellMask = CellSize - 1;
|
||||
|
||||
/* These are magic constants derived from actual offsets in gc/Heap.h. */
|
||||
const size_t ChunkMarkBitmapOffset = 1032376;
|
||||
const size_t ChunkMarkBitmapBits = 129024;
|
||||
|
||||
/*
|
||||
* Live objects are marked black. How many other additional colors are available
|
||||
* depends on the size of the GCThing. Objects marked gray are eligible for
|
||||
* cycle collection.
|
||||
*/
|
||||
static const uint32_t BLACK = 0;
|
||||
static const uint32_t GRAY = 1;
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
namespace shadow {
|
||||
|
||||
struct ArenaHeader
|
||||
@ -63,39 +48,7 @@ struct ArenaHeader
|
||||
JSCompartment *compartment;
|
||||
};
|
||||
|
||||
struct Compartment
|
||||
{
|
||||
bool needsBarrier_;
|
||||
|
||||
Compartment() : needsBarrier_(false) {}
|
||||
};
|
||||
|
||||
} /* namespace shadow */
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
static inline uintptr_t *
|
||||
GetGCThingMarkBitmap(const void *thing)
|
||||
{
|
||||
uintptr_t addr = uintptr_t(thing);
|
||||
addr &= ~js::gc::ChunkMask;
|
||||
addr |= js::gc::ChunkMarkBitmapOffset;
|
||||
return reinterpret_cast<uintptr_t *>(addr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
GetGCThingMarkWordAndMask(const void *thing, uint32_t color,
|
||||
uintptr_t **wordp, uintptr_t *maskp)
|
||||
{
|
||||
uintptr_t addr = uintptr_t(thing);
|
||||
size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color;
|
||||
JS_ASSERT(bit < js::gc::ChunkMarkBitmapBits);
|
||||
uintptr_t *bitmap = GetGCThingMarkBitmap(thing);
|
||||
*maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD);
|
||||
*wordp = &bitmap[bit / JS_BITS_PER_WORD];
|
||||
}
|
||||
|
||||
static inline shadow::ArenaHeader *
|
||||
GetGCThingArena(void *thing)
|
||||
@ -105,16 +58,11 @@ GetGCThingArena(void *thing)
|
||||
return reinterpret_cast<shadow::ArenaHeader *>(addr);
|
||||
}
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
||||
static inline JSCompartment *
|
||||
GetGCThingCompartment(void *thing)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
return js::gc::GetGCThingArena(thing)->compartment;
|
||||
return GetGCThingArena(thing)->compartment;
|
||||
}
|
||||
|
||||
static inline JSCompartment *
|
||||
@ -123,21 +71,6 @@ GetObjectCompartment(JSObject *obj)
|
||||
return GetGCThingCompartment(obj);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
GCThingIsMarkedGray(void *thing)
|
||||
{
|
||||
uintptr_t *word, mask;
|
||||
js::gc::GetGCThingMarkWordAndMask(thing, js::gc::GRAY, &word, &mask);
|
||||
return *word & mask;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsIncrementalBarrierNeededOnGCThing(void *thing)
|
||||
{
|
||||
JSCompartment *comp = GetGCThingCompartment(thing);
|
||||
return reinterpret_cast<shadow::Compartment *>(comp)->needsBarrier_;
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_heap_api_h___ */
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
using namespace js;
|
||||
|
||||
#ifndef TRACE_LOG_DIR
|
||||
# if defined(_WIN32)
|
||||
# define TRACE_LOG_DIR ""
|
||||
@ -20,11 +22,9 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
#if defined(__i386__)
|
||||
static __inline__ uint64_t
|
||||
rdtsc(void)
|
||||
js::rdtsc(void)
|
||||
{
|
||||
uint64_t x;
|
||||
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
|
||||
@ -32,7 +32,7 @@ rdtsc(void)
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
static __inline__ uint64_t
|
||||
rdtsc(void)
|
||||
js::rdtsc(void)
|
||||
{
|
||||
unsigned hi, lo;
|
||||
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
@ -40,7 +40,7 @@ rdtsc(void)
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
static __inline__ uint64_t
|
||||
rdtsc(void)
|
||||
js::rdtsc(void)
|
||||
{
|
||||
uint64_t result=0;
|
||||
uint32_t upper, lower,tmp;
|
||||
@ -242,19 +242,19 @@ TraceLogging::releaseDefaultLogger()
|
||||
|
||||
/* Helper functions for asm calls */
|
||||
void
|
||||
TraceLog(TraceLogging* logger, TraceLogging::Type type, JSScript* script)
|
||||
js::TraceLog(TraceLogging* logger, TraceLogging::Type type, JSScript* script)
|
||||
{
|
||||
logger->log(type, script);
|
||||
}
|
||||
|
||||
void
|
||||
TraceLog(TraceLogging* logger, const char* log)
|
||||
js::TraceLog(TraceLogging* logger, const char* log)
|
||||
{
|
||||
logger->log(log);
|
||||
}
|
||||
|
||||
void
|
||||
TraceLog(TraceLogging* logger, TraceLogging::Type type)
|
||||
js::TraceLog(TraceLogging* logger, TraceLogging::Type type)
|
||||
{
|
||||
logger->log(type);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "jsprf.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "builtin/TestingFunctions.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
|
||||
#include "vm/Stack-inl.h"
|
||||
@ -925,12 +926,8 @@ static JSFunctionSpecWithHelp TestingFunctions[] = {
|
||||
JS_FS_HELP_END
|
||||
};
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
DefineTestingFunctions(JSContext *cx, HandleObject obj)
|
||||
js::DefineTestingFunctions(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return JS_DefineFunctionsWithHelp(cx, obj, TestingFunctions);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -6464,7 +6464,7 @@ Parser::atomNode(ParseNodeKind kind, JSOp op)
|
||||
// them, so we don't wait for a long time for compression to finish at the
|
||||
// end of compilation.
|
||||
const size_t HUGE_STRING = 50000;
|
||||
if (sct && kind == PNK_STRING && node->pn_atom->length() >= HUGE_STRING)
|
||||
if (sct && sct->active() && kind == PNK_STRING && node->pn_atom->length() >= HUGE_STRING)
|
||||
sct->abort();
|
||||
|
||||
return node;
|
||||
|
@ -34,6 +34,14 @@ struct Arena;
|
||||
struct ArenaHeader;
|
||||
struct Chunk;
|
||||
|
||||
/*
|
||||
* Live objects are marked black. How many other additional colors are available
|
||||
* depends on the size of the GCThing. Objects marked gray are eligible for
|
||||
* cycle collection.
|
||||
*/
|
||||
static const uint32_t BLACK = 0;
|
||||
static const uint32_t GRAY = 1;
|
||||
|
||||
/* The GC allocation kinds. */
|
||||
enum AllocKind {
|
||||
FINALIZE_OBJECT0,
|
||||
@ -77,6 +85,10 @@ static const size_t MAX_BACKGROUND_FINALIZE_KINDS = FINALIZE_LIMIT - FINALIZE_OB
|
||||
*/
|
||||
struct Cell
|
||||
{
|
||||
static const size_t CellShift = 3;
|
||||
static const size_t CellSize = size_t(1) << CellShift;
|
||||
static const size_t CellMask = CellSize - 1;
|
||||
|
||||
inline uintptr_t address() const;
|
||||
inline ArenaHeader *arenaHeader() const;
|
||||
inline Chunk *chunk() const;
|
||||
@ -104,7 +116,7 @@ const static uint32_t FreeCommittedArenasThreshold = (32 << 20) / ArenaSize;
|
||||
* accessing the bitmap. In addition this allows to use some bits for colored
|
||||
* marking during the cycle GC.
|
||||
*/
|
||||
const size_t ArenaCellCount = size_t(1) << (ArenaShift - CellShift);
|
||||
const size_t ArenaCellCount = size_t(1) << (ArenaShift - Cell::CellShift);
|
||||
const size_t ArenaBitmapBits = ArenaCellCount;
|
||||
const size_t ArenaBitmapBytes = ArenaBitmapBits / 8;
|
||||
const size_t ArenaBitmapWords = ArenaBitmapBits / JS_BITS_PER_WORD;
|
||||
@ -133,7 +145,7 @@ const size_t ArenaBitmapWords = ArenaBitmapBits / JS_BITS_PER_WORD;
|
||||
* fully used.
|
||||
*
|
||||
* Also only for the last span (|last| & 1)! = 0 as all allocation sizes are
|
||||
* multiples of CellSize.
|
||||
* multiples of Cell::CellSize.
|
||||
*/
|
||||
struct FreeSpan
|
||||
{
|
||||
@ -250,7 +262,7 @@ struct FreeSpan
|
||||
|
||||
/* See comments before FreeSpan for details. */
|
||||
MOZ_ALWAYS_INLINE void *allocate(size_t thingSize) {
|
||||
JS_ASSERT(thingSize % CellSize == 0);
|
||||
JS_ASSERT(thingSize % Cell::CellSize == 0);
|
||||
checkSpan();
|
||||
uintptr_t thing = first;
|
||||
if (thing < last) {
|
||||
@ -271,7 +283,7 @@ struct FreeSpan
|
||||
|
||||
/* A version of allocate when we know that the span is not empty. */
|
||||
MOZ_ALWAYS_INLINE void *infallibleAllocate(size_t thingSize) {
|
||||
JS_ASSERT(thingSize % CellSize == 0);
|
||||
JS_ASSERT(thingSize % Cell::CellSize == 0);
|
||||
checkSpan();
|
||||
uintptr_t thing = first;
|
||||
if (thing < last) {
|
||||
@ -319,7 +331,7 @@ struct FreeSpan
|
||||
return;
|
||||
}
|
||||
size_t spanLength = last - first + 1;
|
||||
JS_ASSERT(spanLength % CellSize == 0);
|
||||
JS_ASSERT(spanLength % Cell::CellSize == 0);
|
||||
|
||||
/* Start and end must belong to the same arena. */
|
||||
JS_ASSERT((first & ~ArenaMask) == arenaAddr);
|
||||
@ -329,7 +341,7 @@ struct FreeSpan
|
||||
/* The span is not the last and we have more spans to follow. */
|
||||
JS_ASSERT(first <= last);
|
||||
size_t spanLengthWithoutOneThing = last - first;
|
||||
JS_ASSERT(spanLengthWithoutOneThing % CellSize == 0);
|
||||
JS_ASSERT(spanLengthWithoutOneThing % Cell::CellSize == 0);
|
||||
|
||||
JS_ASSERT((first & ~ArenaMask) == arenaAddr);
|
||||
|
||||
@ -339,7 +351,7 @@ struct FreeSpan
|
||||
* storing useless empty span reference.
|
||||
*/
|
||||
size_t beforeTail = ArenaSize - (last & ArenaMask);
|
||||
JS_ASSERT(beforeTail >= sizeof(FreeSpan) + CellSize);
|
||||
JS_ASSERT(beforeTail >= sizeof(FreeSpan) + Cell::CellSize);
|
||||
|
||||
FreeSpan *next = reinterpret_cast<FreeSpan *>(last);
|
||||
|
||||
@ -537,7 +549,7 @@ struct Arena
|
||||
}
|
||||
|
||||
static size_t thingsPerArena(size_t thingSize) {
|
||||
JS_ASSERT(thingSize % CellSize == 0);
|
||||
JS_ASSERT(thingSize % Cell::CellSize == 0);
|
||||
|
||||
/* We should be able to fit FreeSpan in any GC thing. */
|
||||
JS_ASSERT(thingSize >= sizeof(FreeSpan));
|
||||
@ -587,14 +599,6 @@ struct ChunkInfo
|
||||
/* Free arenas are linked together with aheader.next. */
|
||||
ArenaHeader *freeArenasHead;
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
/*
|
||||
* Calculating sizes and offsets is simpler if sizeof(ChunkInfo) is
|
||||
* architecture-independent.
|
||||
*/
|
||||
char padding[12];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decommitted arenas are tracked by a bitmap in the chunk header. We use
|
||||
* this offset to start our search iteration close to a decommitted arena
|
||||
@ -652,10 +656,7 @@ struct ChunkBitmap
|
||||
uintptr_t bitmap[ArenaBitmapWords * ArenasPerChunk];
|
||||
|
||||
MOZ_ALWAYS_INLINE void getMarkWordAndMask(const Cell *cell, uint32_t color,
|
||||
uintptr_t **wordp, uintptr_t *maskp)
|
||||
{
|
||||
GetGCThingMarkWordAndMask(cell, color, wordp, maskp);
|
||||
}
|
||||
uintptr_t **wordp, uintptr_t *maskp);
|
||||
|
||||
MOZ_ALWAYS_INLINE bool isMarked(const Cell *cell, uint32_t color) {
|
||||
uintptr_t *word, mask;
|
||||
@ -707,7 +708,6 @@ struct ChunkBitmap
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(ArenaBitmapBytes * ArenasPerChunk == sizeof(ChunkBitmap));
|
||||
JS_STATIC_ASSERT(js::gc::ChunkMarkBitmapBits == ArenaBitmapBits * ArenasPerChunk);
|
||||
|
||||
typedef BitArray<ArenasPerChunk> PerArenaBitmap;
|
||||
|
||||
@ -810,13 +810,12 @@ struct Chunk
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(Chunk) == ChunkSize);
|
||||
JS_STATIC_ASSERT(js::gc::ChunkMarkBitmapOffset == offsetof(Chunk, bitmap));
|
||||
|
||||
inline uintptr_t
|
||||
Cell::address() const
|
||||
{
|
||||
uintptr_t addr = uintptr_t(this);
|
||||
JS_ASSERT(addr % CellSize == 0);
|
||||
JS_ASSERT(addr % Cell::CellSize == 0);
|
||||
JS_ASSERT(Chunk::withinArenasRange(addr));
|
||||
return addr;
|
||||
}
|
||||
@ -920,12 +919,22 @@ ArenaHeader::unsetAllocDuringSweep()
|
||||
auxNextLink = 0;
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE void
|
||||
ChunkBitmap::getMarkWordAndMask(const Cell *cell, uint32_t color,
|
||||
uintptr_t **wordp, uintptr_t *maskp)
|
||||
{
|
||||
size_t bit = (cell->address() & ChunkMask) / Cell::CellSize + color;
|
||||
JS_ASSERT(bit < ArenaBitmapBits * ArenasPerChunk);
|
||||
*maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD);
|
||||
*wordp = &bitmap[bit / JS_BITS_PER_WORD];
|
||||
}
|
||||
|
||||
static void
|
||||
AssertValidColor(const void *thing, uint32_t color)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
ArenaHeader *aheader = reinterpret_cast<const Cell *>(thing)->arenaHeader();
|
||||
JS_ASSERT_IF(color, color < aheader->getThingSize() / CellSize);
|
||||
JS_ASSERT_IF(color, color < aheader->getThingSize() / Cell::CellSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -941,7 +950,7 @@ Chunk *
|
||||
Cell::chunk() const
|
||||
{
|
||||
uintptr_t addr = uintptr_t(this);
|
||||
JS_ASSERT(addr % CellSize == 0);
|
||||
JS_ASSERT(addr % Cell::CellSize == 0);
|
||||
addr &= ~(ChunkSize - 1);
|
||||
return reinterpret_cast<Chunk *>(addr);
|
||||
}
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include "ion/IonCode.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
using mozilla::DebugOnly;
|
||||
|
||||
void * const js::NullPtr::constNullValue = NULL;
|
||||
@ -53,9 +56,6 @@ void * const js::NullPtr::constNullValue = NULL;
|
||||
* scanning functions, but they don't push onto an explicit stack.
|
||||
*/
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
static inline void
|
||||
PushMarkStack(GCMarker *gcmarker, JSXML *thing);
|
||||
@ -79,6 +79,22 @@ PushMarkStack(GCMarker *gcmarker, JSString *thing);
|
||||
static inline void
|
||||
PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing);
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
static void MarkChildren(JSTracer *trc, JSString *str);
|
||||
static void MarkChildren(JSTracer *trc, JSScript *script);
|
||||
static void MarkChildren(JSTracer *trc, Shape *shape);
|
||||
static void MarkChildren(JSTracer *trc, BaseShape *base);
|
||||
static void MarkChildren(JSTracer *trc, types::TypeObject *type);
|
||||
static void MarkChildren(JSTracer *trc, ion::IonCode *code);
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
static void MarkChildren(JSTracer *trc, JSXML *xml);
|
||||
#endif
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
/*** Object Marking ***/
|
||||
|
||||
template<typename T>
|
||||
@ -104,7 +120,7 @@ CheckMarkedThing(JSTracer *trc, T *thing)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
static void
|
||||
MarkInternal(JSTracer *trc, T **thingp)
|
||||
{
|
||||
JS_ASSERT(thingp);
|
||||
@ -143,6 +159,9 @@ MarkUnbarriered(JSTracer *trc, T **thingp, const char *name)
|
||||
MarkInternal(trc, thingp);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
Mark(JSTracer *trc, EncapsulatedPtr<T> *thing, const char *name)
|
||||
@ -151,6 +170,9 @@ Mark(JSTracer *trc, EncapsulatedPtr<T> *thing, const char *name)
|
||||
MarkInternal(trc, thing->unsafeGet());
|
||||
}
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
template <typename T>
|
||||
static void
|
||||
MarkRoot(JSTracer *trc, T **thingp, const char *name)
|
||||
@ -185,6 +207,9 @@ MarkRootRange(JSTracer *trc, size_t len, T **vec, const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
template <typename T>
|
||||
static bool
|
||||
IsMarked(T **thingp)
|
||||
@ -215,22 +240,26 @@ Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name)
|
||||
MarkUnbarriered<type>(trc, thingp, name); \
|
||||
} \
|
||||
\
|
||||
void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *vec, const char *name) \
|
||||
void \
|
||||
Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *vec, const char *name) \
|
||||
{ \
|
||||
MarkRange<type>(trc, len, vec, name); \
|
||||
} \
|
||||
\
|
||||
void Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *name) \
|
||||
void \
|
||||
Mark##base##RootRange(JSTracer *trc, size_t len, type **vec, const char *name) \
|
||||
{ \
|
||||
MarkRootRange<type>(trc, len, vec, name); \
|
||||
} \
|
||||
\
|
||||
bool Is##base##Marked(type **thingp) \
|
||||
bool \
|
||||
Is##base##Marked(type **thingp) \
|
||||
{ \
|
||||
return IsMarked<type>(thingp); \
|
||||
} \
|
||||
\
|
||||
bool Is##base##Marked(EncapsulatedPtr<type> *thingp) \
|
||||
bool \
|
||||
Is##base##Marked(EncapsulatedPtr<type> *thingp) \
|
||||
{ \
|
||||
return IsMarked<type>(thingp->unsafeGet()); \
|
||||
}
|
||||
@ -251,15 +280,18 @@ DeclMarkerImpl(String, JSString)
|
||||
DeclMarkerImpl(String, JSFlatString)
|
||||
DeclMarkerImpl(String, JSLinearString)
|
||||
DeclMarkerImpl(String, PropertyName)
|
||||
DeclMarkerImpl(TypeObject, types::TypeObject)
|
||||
DeclMarkerImpl(TypeObject, js::types::TypeObject)
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
DeclMarkerImpl(XML, JSXML)
|
||||
#endif
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
/*** Externally Typed Marking ***/
|
||||
|
||||
void
|
||||
MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
gc::MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(thingp);
|
||||
JS_ASSERT(*thingp);
|
||||
@ -294,7 +326,7 @@ MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MarkGCThingInternal(JSTracer *trc, void **thingp, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
@ -305,14 +337,14 @@ MarkGCThingInternal(JSTracer *trc, void **thingp, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name)
|
||||
gc::MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name)
|
||||
{
|
||||
JS_ROOT_MARKING_ASSERT(trc);
|
||||
MarkGCThingInternal(trc, thingp, name);
|
||||
}
|
||||
|
||||
void
|
||||
MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name)
|
||||
gc::MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name)
|
||||
{
|
||||
MarkGCThingInternal(trc, thingp, name);
|
||||
}
|
||||
@ -339,14 +371,14 @@ MarkIdInternal(JSTracer *trc, jsid *id)
|
||||
}
|
||||
|
||||
void
|
||||
MarkId(JSTracer *trc, EncapsulatedId *id, const char *name)
|
||||
gc::MarkId(JSTracer *trc, EncapsulatedId *id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdInternal(trc, id->unsafeGet());
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRoot(JSTracer *trc, jsid *id, const char *name)
|
||||
gc::MarkIdRoot(JSTracer *trc, jsid *id, const char *name)
|
||||
{
|
||||
JS_ROOT_MARKING_ASSERT(trc);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
@ -354,14 +386,14 @@ MarkIdRoot(JSTracer *trc, jsid *id, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name)
|
||||
gc::MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkIdInternal(trc, id);
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name)
|
||||
gc::MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
@ -370,7 +402,7 @@ MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
gc::MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
{
|
||||
JS_ROOT_MARKING_ASSERT(trc);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
@ -400,14 +432,14 @@ MarkValueInternal(JSTracer *trc, Value *v)
|
||||
}
|
||||
|
||||
void
|
||||
MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name)
|
||||
gc::MarkValue(JSTracer *trc, EncapsulatedValue *v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v->unsafeGet());
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRoot(JSTracer *trc, Value *v, const char *name)
|
||||
gc::MarkValueRoot(JSTracer *trc, Value *v, const char *name)
|
||||
{
|
||||
JS_ROOT_MARKING_ASSERT(trc);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
@ -415,7 +447,7 @@ MarkValueRoot(JSTracer *trc, Value *v, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name)
|
||||
gc::MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name)
|
||||
{
|
||||
JS_ROOT_MARKING_ASSERT(trc);
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
@ -431,7 +463,7 @@ MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name)
|
||||
gc::MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
@ -440,7 +472,7 @@ MarkValueRange(JSTracer *trc, size_t len, EncapsulatedValue *vec, const char *na
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
|
||||
gc::MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
|
||||
{
|
||||
JS_ROOT_MARKING_ASSERT(trc);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
@ -450,7 +482,7 @@ MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
|
||||
}
|
||||
|
||||
bool
|
||||
IsValueMarked(Value *v)
|
||||
gc::IsValueMarked(Value *v)
|
||||
{
|
||||
JS_ASSERT(v->isMarkable());
|
||||
bool rv;
|
||||
@ -469,14 +501,14 @@ IsValueMarked(Value *v)
|
||||
/*** Slot Marking ***/
|
||||
|
||||
void
|
||||
MarkSlot(JSTracer *trc, HeapSlot *s, const char *name)
|
||||
gc::MarkSlot(JSTracer *trc, HeapSlot *s, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, s->unsafeGet());
|
||||
}
|
||||
|
||||
void
|
||||
MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name)
|
||||
gc::MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
@ -485,7 +517,7 @@ MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots)
|
||||
gc::MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots)
|
||||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
for (uint32_t i = start; i < (start + nslots); ++i) {
|
||||
@ -495,7 +527,7 @@ MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots)
|
||||
}
|
||||
|
||||
void
|
||||
MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char *name)
|
||||
gc::MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char *name)
|
||||
{
|
||||
if (IS_GC_MARKING_TRACER(trc) && !(*obj)->compartment()->isCollecting())
|
||||
return;
|
||||
@ -504,7 +536,7 @@ MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char
|
||||
}
|
||||
|
||||
void
|
||||
MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const char *name)
|
||||
gc::MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const char *name)
|
||||
{
|
||||
if (IS_GC_MARKING_TRACER(trc) && !(*script)->compartment()->isCollecting())
|
||||
return;
|
||||
@ -513,7 +545,7 @@ MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const ch
|
||||
}
|
||||
|
||||
void
|
||||
MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name)
|
||||
gc::MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name)
|
||||
{
|
||||
if (s->isMarkable()) {
|
||||
Cell *cell = (Cell *)s->toGCThing();
|
||||
@ -527,21 +559,21 @@ MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name)
|
||||
/*** Special Marking ***/
|
||||
|
||||
void
|
||||
MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name)
|
||||
gc::MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkInternal(trc, thingp->unsafeGet());
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name)
|
||||
gc::MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
bool
|
||||
IsCellMarked(Cell **thingp)
|
||||
gc::IsCellMarked(Cell **thingp)
|
||||
{
|
||||
return IsMarked<Cell>(thingp);
|
||||
}
|
||||
@ -593,9 +625,6 @@ PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing)
|
||||
gcmarker->pushType(thing);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSScript *script);
|
||||
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, JSScript *thing)
|
||||
{
|
||||
@ -623,7 +652,7 @@ PushMarkStack(GCMarker *gcmarker, Shape *thing)
|
||||
ScanShape(gcmarker, thing);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PushMarkStack(GCMarker *gcmarker, ion::IonCode *thing)
|
||||
{
|
||||
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
|
||||
@ -789,13 +818,13 @@ PushMarkStack(GCMarker *gcmarker, JSString *str)
|
||||
}
|
||||
|
||||
void
|
||||
MarkChildren(JSTracer *trc, JSObject *obj)
|
||||
gc::MarkChildren(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
obj->markChildren(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSString *str)
|
||||
gc::MarkChildren(JSTracer *trc, JSString *str)
|
||||
{
|
||||
if (str->hasBase())
|
||||
str->markBase(trc);
|
||||
@ -804,19 +833,19 @@ MarkChildren(JSTracer *trc, JSString *str)
|
||||
}
|
||||
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSScript *script)
|
||||
gc::MarkChildren(JSTracer *trc, JSScript *script)
|
||||
{
|
||||
script->markChildren(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, Shape *shape)
|
||||
gc::MarkChildren(JSTracer *trc, Shape *shape)
|
||||
{
|
||||
shape->markChildren(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, BaseShape *base)
|
||||
gc::MarkChildren(JSTracer *trc, BaseShape *base)
|
||||
{
|
||||
base->markChildren(trc);
|
||||
}
|
||||
@ -829,7 +858,7 @@ MarkChildren(JSTracer *trc, BaseShape *base)
|
||||
* marked only if it isn't the same as prevParent, which will be
|
||||
* updated to the current shape's parent.
|
||||
*/
|
||||
inline void
|
||||
static inline void
|
||||
MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent)
|
||||
{
|
||||
JS_ASSERT(base);
|
||||
@ -870,7 +899,7 @@ MarkCycleCollectorChildren(JSTracer *trc, BaseShape *base, JSObject **prevParent
|
||||
* parent pointer will only be marked once.
|
||||
*/
|
||||
void
|
||||
MarkCycleCollectorChildren(JSTracer *trc, Shape *shape)
|
||||
gc::MarkCycleCollectorChildren(JSTracer *trc, Shape *shape)
|
||||
{
|
||||
JSObject *prevParent = NULL;
|
||||
do {
|
||||
@ -909,7 +938,7 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type)
|
||||
}
|
||||
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, types::TypeObject *type)
|
||||
gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
|
||||
{
|
||||
unsigned count = type->getPropertyCount();
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
@ -933,8 +962,8 @@ MarkChildren(JSTracer *trc, types::TypeObject *type)
|
||||
MarkObject(trc, &type->interpretedFunction, "type_function");
|
||||
}
|
||||
|
||||
void
|
||||
MarkChildren(JSTracer *trc, ion::IonCode *code)
|
||||
static void
|
||||
gc::MarkChildren(JSTracer *trc, ion::IonCode *code)
|
||||
{
|
||||
#ifdef JS_ION
|
||||
code->trace(trc);
|
||||
@ -943,14 +972,14 @@ MarkChildren(JSTracer *trc, ion::IonCode *code)
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
static void
|
||||
MarkChildren(JSTracer *trc, JSXML *xml)
|
||||
gc::MarkChildren(JSTracer *trc, JSXML *xml)
|
||||
{
|
||||
js_TraceXML(trc, xml);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
static void
|
||||
PushArenaTyped(GCMarker *gcmarker, ArenaHeader *aheader)
|
||||
{
|
||||
for (CellIterUnderGC i(aheader); !i.done(); i.next())
|
||||
@ -958,7 +987,7 @@ PushArenaTyped(GCMarker *gcmarker, ArenaHeader *aheader)
|
||||
}
|
||||
|
||||
void
|
||||
PushArena(GCMarker *gcmarker, ArenaHeader *aheader)
|
||||
gc::PushArena(GCMarker *gcmarker, ArenaHeader *aheader)
|
||||
{
|
||||
switch (MapAllocToTraceKind(aheader->getAllocKind())) {
|
||||
case JSTRACE_OBJECT:
|
||||
@ -997,10 +1026,6 @@ PushArena(GCMarker *gcmarker, ArenaHeader *aheader)
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace gc */
|
||||
|
||||
using namespace js::gc;
|
||||
|
||||
struct SlotArrayLayout
|
||||
{
|
||||
union {
|
||||
@ -1118,7 +1143,7 @@ GCMarker::processMarkStackOther(SliceBudget &budget, uintptr_t tag, uintptr_t ad
|
||||
if (tag == TypeTag) {
|
||||
ScanTypeObject(this, reinterpret_cast<types::TypeObject *>(addr));
|
||||
} else if (tag == SavedValueArrayTag) {
|
||||
JS_ASSERT(!(addr & CellMask));
|
||||
JS_ASSERT(!(addr & Cell::CellMask));
|
||||
JSObject *obj = reinterpret_cast<JSObject *>(addr);
|
||||
HeapValue *vp, *end;
|
||||
if (restoreValueArray(obj, (void **)&vp, (void **)&end))
|
||||
@ -1183,7 +1208,7 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
|
||||
|
||||
if (tag == ValueArrayTag) {
|
||||
JS_STATIC_ASSERT(ValueArrayTag == 0);
|
||||
JS_ASSERT(!(addr & CellMask));
|
||||
JS_ASSERT(!(addr & Cell::CellMask));
|
||||
obj = reinterpret_cast<JSObject *>(addr);
|
||||
uintptr_t addr2 = stack.pop();
|
||||
uintptr_t addr3 = stack.pop();
|
||||
@ -1325,7 +1350,7 @@ GCMarker::drainMarkStack(SliceBudget &budget)
|
||||
}
|
||||
|
||||
void
|
||||
TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
js::TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case JSTRACE_OBJECT:
|
||||
@ -1365,12 +1390,10 @@ TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
}
|
||||
|
||||
void
|
||||
CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
js::CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
void *tmp = thing;
|
||||
MarkKind(trc, &tmp, kind);
|
||||
JS_ASSERT(tmp == thing);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -7,17 +7,16 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/Utility.h"
|
||||
#include "gc/Memory.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
/* Unused memory decommiting requires the arena size match the page size. */
|
||||
extern const size_t PageSize;
|
||||
extern const size_t ArenaSize;
|
||||
static bool
|
||||
DecommitEnabled()
|
||||
{
|
||||
@ -31,7 +30,7 @@ DecommitEnabled()
|
||||
static size_t AllocationGranularity = 0;
|
||||
|
||||
void
|
||||
InitMemorySubsystem()
|
||||
gc::InitMemorySubsystem()
|
||||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
@ -43,7 +42,7 @@ InitMemorySubsystem()
|
||||
}
|
||||
|
||||
void *
|
||||
MapAlignedPages(size_t size, size_t alignment)
|
||||
gc::MapAlignedPages(size_t size, size_t alignment)
|
||||
{
|
||||
JS_ASSERT(size >= alignment);
|
||||
JS_ASSERT(size % alignment == 0);
|
||||
@ -86,13 +85,13 @@ MapAlignedPages(size_t size, size_t alignment)
|
||||
}
|
||||
|
||||
void
|
||||
UnmapPages(void *p, size_t size)
|
||||
gc::UnmapPages(void *p, size_t size)
|
||||
{
|
||||
JS_ALWAYS_TRUE(VirtualFree(p, 0, MEM_RELEASE));
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesUnused(void *p, size_t size)
|
||||
gc::MarkPagesUnused(void *p, size_t size)
|
||||
{
|
||||
if (!DecommitEnabled())
|
||||
return false;
|
||||
@ -103,14 +102,14 @@ MarkPagesUnused(void *p, size_t size)
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesInUse(void *p, size_t size)
|
||||
gc::MarkPagesInUse(void *p, size_t size)
|
||||
{
|
||||
JS_ASSERT(uintptr_t(p) % PageSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
GetPageFaultCount()
|
||||
gc::GetPageFaultCount()
|
||||
{
|
||||
PROCESS_MEMORY_COUNTERS pmc;
|
||||
if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
|
||||
@ -127,12 +126,12 @@ GetPageFaultCount()
|
||||
#define OS2_MAX_RECURSIONS 16
|
||||
|
||||
void
|
||||
InitMemorySubsystem()
|
||||
gc::InitMemorySubsystem()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
UnmapPages(void *addr, size_t size)
|
||||
gc::UnmapPages(void *addr, size_t size)
|
||||
{
|
||||
if (!DosFreeMem(addr))
|
||||
return;
|
||||
@ -153,7 +152,7 @@ UnmapPages(void *addr, size_t size)
|
||||
}
|
||||
|
||||
static void *
|
||||
MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions)
|
||||
gc::MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions)
|
||||
{
|
||||
if (++recursions >= OS2_MAX_RECURSIONS)
|
||||
return NULL;
|
||||
@ -194,7 +193,7 @@ MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions)
|
||||
}
|
||||
|
||||
void *
|
||||
MapAlignedPages(size_t size, size_t alignment)
|
||||
gc::MapAlignedPages(size_t size, size_t alignment)
|
||||
{
|
||||
JS_ASSERT(size >= alignment);
|
||||
JS_ASSERT(size % alignment == 0);
|
||||
@ -230,21 +229,21 @@ MapAlignedPages(size_t size, size_t alignment)
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesUnused(void *p, size_t size)
|
||||
gc::MarkPagesUnused(void *p, size_t size)
|
||||
{
|
||||
JS_ASSERT(uintptr_t(p) % PageSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesInUse(void *p, size_t size)
|
||||
gc::MarkPagesInUse(void *p, size_t size)
|
||||
{
|
||||
JS_ASSERT(uintptr_t(p) % PageSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
GetPageFaultCount()
|
||||
gc::GetPageFaultCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -259,12 +258,12 @@ GetPageFaultCount()
|
||||
#endif
|
||||
|
||||
void
|
||||
InitMemorySubsystem()
|
||||
gc::InitMemorySubsystem()
|
||||
{
|
||||
}
|
||||
|
||||
void *
|
||||
MapAlignedPages(size_t size, size_t alignment)
|
||||
gc::MapAlignedPages(size_t size, size_t alignment)
|
||||
{
|
||||
JS_ASSERT(size >= alignment);
|
||||
JS_ASSERT(size % alignment == 0);
|
||||
@ -281,27 +280,27 @@ MapAlignedPages(size_t size, size_t alignment)
|
||||
}
|
||||
|
||||
void
|
||||
UnmapPages(void *p, size_t size)
|
||||
gc::UnmapPages(void *p, size_t size)
|
||||
{
|
||||
JS_ALWAYS_TRUE(0 == munmap((caddr_t)p, size));
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesUnused(void *p, size_t size)
|
||||
gc::MarkPagesUnused(void *p, size_t size)
|
||||
{
|
||||
JS_ASSERT(uintptr_t(p) % PageSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesInUse(void *p, size_t size)
|
||||
gc::MarkPagesInUse(void *p, size_t size)
|
||||
{
|
||||
JS_ASSERT(uintptr_t(p) % PageSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
GetPageFaultCount()
|
||||
gc::GetPageFaultCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -314,7 +313,7 @@ GetPageFaultCount()
|
||||
#include <unistd.h>
|
||||
|
||||
void
|
||||
InitMemorySubsystem()
|
||||
gc::InitMemorySubsystem()
|
||||
{
|
||||
if (size_t(sysconf(_SC_PAGESIZE)) != PageSize) {
|
||||
fprintf(stderr,"SpiderMonkey compiled with incorrect page size; please update js/public/HeapAPI.h.\n");
|
||||
@ -323,7 +322,7 @@ InitMemorySubsystem()
|
||||
}
|
||||
|
||||
void *
|
||||
MapAlignedPages(size_t size, size_t alignment)
|
||||
gc::MapAlignedPages(size_t size, size_t alignment)
|
||||
{
|
||||
JS_ASSERT(size >= alignment);
|
||||
JS_ASSERT(size % alignment == 0);
|
||||
@ -360,13 +359,13 @@ MapAlignedPages(size_t size, size_t alignment)
|
||||
}
|
||||
|
||||
void
|
||||
UnmapPages(void *p, size_t size)
|
||||
gc::UnmapPages(void *p, size_t size)
|
||||
{
|
||||
JS_ALWAYS_TRUE(0 == munmap(p, size));
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesUnused(void *p, size_t size)
|
||||
gc::MarkPagesUnused(void *p, size_t size)
|
||||
{
|
||||
if (!DecommitEnabled())
|
||||
return false;
|
||||
@ -377,14 +376,14 @@ MarkPagesUnused(void *p, size_t size)
|
||||
}
|
||||
|
||||
bool
|
||||
MarkPagesInUse(void *p, size_t size)
|
||||
gc::MarkPagesInUse(void *p, size_t size)
|
||||
{
|
||||
JS_ASSERT(uintptr_t(p) % PageSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
GetPageFaultCount()
|
||||
gc::GetPageFaultCount()
|
||||
{
|
||||
struct rusage usage;
|
||||
int err = getrusage(RUSAGE_SELF, &usage);
|
||||
@ -396,6 +395,3 @@ GetPageFaultCount()
|
||||
#else
|
||||
#error "Memory mapping functions are not defined for your OS."
|
||||
#endif
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
@ -22,13 +22,13 @@
|
||||
|
||||
#include "gc/Barrier-inl.h"
|
||||
|
||||
namespace js {
|
||||
namespace gcstats {
|
||||
using namespace js;
|
||||
using namespace js::gcstats;
|
||||
|
||||
/* Except for the first and last, slices of less than 42ms are not reported. */
|
||||
static const int64_t SLICE_MIN_REPORT_TIME = 42 * PRMJ_USEC_PER_MSEC;
|
||||
|
||||
class StatisticsSerializer
|
||||
class gcstats::StatisticsSerializer
|
||||
{
|
||||
typedef Vector<char, 128, SystemAllocPolicy> CharBuffer;
|
||||
CharBuffer buf_;
|
||||
@ -682,6 +682,3 @@ Statistics::computeMMU(int64_t window)
|
||||
|
||||
return double(window - gcMax) / window;
|
||||
}
|
||||
|
||||
} /* namespace gcstats */
|
||||
} /* namespace js */
|
||||
|
@ -13,8 +13,7 @@
|
||||
#include "gc/StoreBuffer.h"
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
using namespace js::gc;
|
||||
|
||||
/*** MonoTypeBuffer ***/
|
||||
|
||||
@ -265,7 +264,4 @@ template class StoreBuffer::MonoTypeBuffer<StoreBuffer::SlotEdge>;
|
||||
template class StoreBuffer::RelocatableMonoTypeBuffer<StoreBuffer::ValueEdge>;
|
||||
template class StoreBuffer::RelocatableMonoTypeBuffer<StoreBuffer::CellPtrEdge>;
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* JSGC_GENERATIONAL */
|
||||
|
@ -50,7 +50,7 @@ using namespace js::ion;
|
||||
IonOptions ion::js_IonOptions;
|
||||
|
||||
// Assert that IonCode is gc::Cell aligned.
|
||||
JS_STATIC_ASSERT(sizeof(IonCode) % gc::CellSize == 0);
|
||||
JS_STATIC_ASSERT(sizeof(IonCode) % gc::Cell::CellSize == 0);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
static bool IonTLSInitialized = false;
|
||||
|
@ -470,6 +470,29 @@ NextInstructionHasFixedUses(LBlock *block, LInstruction *ins)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true iff ins has a def/temp reusing the input allocation.
|
||||
static bool
|
||||
IsInputReused(LInstruction *ins, LUse *use)
|
||||
{
|
||||
for (size_t i = 0; i < ins->numDefs(); i++) {
|
||||
if (ins->getDef(i)->policy() == LDefinition::MUST_REUSE_INPUT &&
|
||||
ins->getOperand(ins->getDef(i)->getReusedInput())->toUse() == use)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ins->numTemps(); i++) {
|
||||
if (ins->getTemp(i)->policy() == LDefinition::MUST_REUSE_INPUT &&
|
||||
ins->getOperand(ins->getTemp(i)->getReusedInput())->toUse() == use)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -618,6 +641,9 @@ LinearScanAllocator::buildLivenessInfo()
|
||||
}
|
||||
}
|
||||
|
||||
DebugOnly<bool> hasUseRegister = false;
|
||||
DebugOnly<bool> hasUseRegisterAtStart = false;
|
||||
|
||||
for (LInstruction::InputIterator alloc(**ins); alloc.more(); alloc.next()) {
|
||||
if (alloc->isUse()) {
|
||||
LUse *use = alloc->toUse();
|
||||
@ -637,6 +663,20 @@ LinearScanAllocator::buildLivenessInfo()
|
||||
for (size_t i = 0; i < ins->numTemps(); i++)
|
||||
JS_ASSERT(vregs[ins->getTemp(i)].isDouble() != vregs[use].isDouble());
|
||||
}
|
||||
|
||||
// If there are both useRegisterAtStart(x) and useRegister(y)
|
||||
// uses, we may assign the same register to both operands due to
|
||||
// interval splitting (bug 772830). Don't allow this for now.
|
||||
if (use->policy() == LUse::REGISTER) {
|
||||
if (use->usedAtStart()) {
|
||||
if (!IsInputReused(*ins, use))
|
||||
hasUseRegisterAtStart = true;
|
||||
} else {
|
||||
hasUseRegister = true;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ASSERT(!(hasUseRegister && hasUseRegisterAtStart));
|
||||
#endif
|
||||
|
||||
CodePosition to;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "jsalloc.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
namespace js {
|
||||
using namespace js;
|
||||
|
||||
void *
|
||||
TempAllocPolicy::onOutOfMemory(void *p, size_t nbytes)
|
||||
@ -21,5 +21,3 @@ TempAllocPolicy::reportAllocOverflow() const
|
||||
{
|
||||
js_ReportAllocationOverflow(cx);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -13,9 +13,8 @@
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
using mozilla::DebugOnly;
|
||||
|
||||
namespace js {
|
||||
namespace analyze {
|
||||
using namespace js;
|
||||
using namespace js::analyze;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Bytecode
|
||||
@ -23,7 +22,7 @@ namespace analyze {
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc)
|
||||
analyze::PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc)
|
||||
{
|
||||
RootedScript script(cx, scriptArg);
|
||||
|
||||
@ -36,7 +35,7 @@ PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc)
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool
|
||||
static inline bool
|
||||
IsJumpOpcode(JSOp op)
|
||||
{
|
||||
uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
|
||||
@ -2129,6 +2128,3 @@ ScriptAnalysis::assertMatchingDebugMode()
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
} /* namespace analyze */
|
||||
} /* namespace js */
|
||||
|
@ -57,6 +57,7 @@ CPPSRCS = \
|
||||
testScriptInfo.cpp \
|
||||
testScriptObject.cpp \
|
||||
testSetProperty.cpp \
|
||||
testSourcePolicy.cpp \
|
||||
testStringBuffer.cpp \
|
||||
testTrap.cpp \
|
||||
testTypedArrays.cpp \
|
||||
|
23
js/src/jsapi-tests/testSourcePolicy.cpp
Normal file
23
js/src/jsapi-tests/testSourcePolicy.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
BEGIN_TEST(testBug795104)
|
||||
{
|
||||
JS::CompileOptions opts(cx);
|
||||
opts.setSourcePolicy(JS::CompileOptions::NO_SOURCE);
|
||||
const size_t strLen = 60002;
|
||||
char *s = static_cast<char *>(JS_malloc(cx, strLen));
|
||||
CHECK(s);
|
||||
s[0] = '"';
|
||||
memset(s + 1, 'x', strLen - 2);
|
||||
s[strLen - 1] = '"';
|
||||
CHECK(JS::Evaluate(cx, global, opts, s, strLen, NULL));
|
||||
CHECK(JS::CompileFunction(cx, global, opts, "f", 0, NULL, s, strLen));
|
||||
JS_free(cx, s);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testBug795104)
|
@ -680,49 +680,43 @@ static JSBool js_NewRuntimeWasCalled = JS_FALSE;
|
||||
/*
|
||||
* Thread Local Storage slot for storing the runtime for a thread.
|
||||
*/
|
||||
namespace js {
|
||||
mozilla::ThreadLocal<PerThreadData *> TlsPerThreadData;
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
mozilla::ThreadLocal<PerThreadData *> js::TlsPerThreadData;
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_FRIEND_API(void)
|
||||
EnterAssertNoGCScope()
|
||||
JS::EnterAssertNoGCScope()
|
||||
{
|
||||
++TlsPerThreadData.get()->gcAssertNoGCDepth;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
LeaveAssertNoGCScope()
|
||||
JS::LeaveAssertNoGCScope()
|
||||
{
|
||||
--TlsPerThreadData.get()->gcAssertNoGCDepth;
|
||||
JS_ASSERT(TlsPerThreadData.get()->gcAssertNoGCDepth >= 0);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
InNoGCScope()
|
||||
JS::InNoGCScope()
|
||||
{
|
||||
return TlsPerThreadData.get()->gcAssertNoGCDepth > 0;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
NeedRelaxedRootChecks()
|
||||
JS::NeedRelaxedRootChecks()
|
||||
{
|
||||
return TlsPerThreadData.get()->gcRelaxRootChecks;
|
||||
}
|
||||
#else
|
||||
JS_FRIEND_API(void) EnterAssertNoGCScope() {}
|
||||
JS_FRIEND_API(void) LeaveAssertNoGCScope() {}
|
||||
JS_FRIEND_API(bool) InNoGCScope() { return false; }
|
||||
JS_FRIEND_API(bool) NeedRelaxedRootChecks() { return false; }
|
||||
JS_FRIEND_API(void) JS::EnterAssertNoGCScope() {}
|
||||
JS_FRIEND_API(void) JS::LeaveAssertNoGCScope() {}
|
||||
JS_FRIEND_API(bool) JS::InNoGCScope() { return false; }
|
||||
JS_FRIEND_API(bool) JS::NeedRelaxedRootChecks() { return false; }
|
||||
#endif
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
static const JSSecurityCallbacks NullSecurityCallbacks = { };
|
||||
|
||||
js::PerThreadData::PerThreadData(JSRuntime *runtime)
|
||||
PerThreadData::PerThreadData(JSRuntime *runtime)
|
||||
: runtime_(runtime)
|
||||
#ifdef DEBUG
|
||||
, gcRelaxRootChecks(false)
|
||||
@ -5478,16 +5472,20 @@ JS_CompileFunction(JSContext *cx, JSObject *objArg, const char *name,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, unsigned indent)
|
||||
JS_DecompileScript(JSContext *cx, JSScript *scriptArg, const char *name, unsigned indent)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
RootedScript script(cx, scriptArg);
|
||||
RootedFunction fun(cx, script->function());
|
||||
if (fun)
|
||||
return JS_DecompileFunction(cx, fun, indent);
|
||||
return script->sourceData(cx);
|
||||
bool haveSource = script->scriptSource()->hasSourceData();
|
||||
if (!haveSource && !JSScript::loadSource(cx, script, &haveSource))
|
||||
return NULL;
|
||||
return haveSource ? script->sourceData(cx) : js_NewStringCopyZ(cx, "[no source]");
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
@ -5766,10 +5764,8 @@ JS_CallFunctionValue(JSContext *cx, JSObject *objArg, jsval fval, unsigned argc,
|
||||
return Invoke(cx, ObjectOrNullValue(obj), fval, argc, argv, rval);
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
Call(JSContext *cx, jsval thisv, jsval fval, unsigned argc, jsval *argv, jsval *rval)
|
||||
JS::Call(JSContext *cx, jsval thisv, jsval fval, unsigned argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
@ -5779,8 +5775,6 @@ Call(JSContext *cx, jsval thisv, jsval fval, unsigned argc, jsval *argv, jsval *
|
||||
return Invoke(cx, thisv, fval, argc, argv, rval);
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_New(JSContext *cx, JSObject *ctorArg, unsigned argc, jsval *argv)
|
||||
{
|
||||
@ -7102,8 +7096,6 @@ JS_CallOnce(JSCallOnceType *once, JSInitCallback func)
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag)
|
||||
: down(cx->runtime->autoGCRooters), tag(tag), stackTop(&cx->runtime->autoGCRooters)
|
||||
{
|
||||
@ -7113,7 +7105,7 @@ AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag)
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_PUBLIC_API(void)
|
||||
AssertArgumentsAreSane(JSContext *cx, const JS::Value &value)
|
||||
JS::AssertArgumentsAreSane(JSContext *cx, const JS::Value &value)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
@ -7121,8 +7113,6 @@ AssertArgumentsAreSane(JSContext *cx, const JS::Value &value)
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
} // namespace JS
|
||||
|
||||
JS_PUBLIC_API(void *)
|
||||
JS_EncodeScript(JSContext *cx, JSRawScript scriptArg, uint32_t *lengthp)
|
||||
{
|
||||
|
@ -120,10 +120,8 @@ using mozilla::ArrayLength;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::PointerRangeSize;
|
||||
|
||||
namespace js {
|
||||
|
||||
JSBool
|
||||
GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp)
|
||||
js::GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp)
|
||||
{
|
||||
if (obj->isArray()) {
|
||||
*lengthp = obj->getArrayLength();
|
||||
@ -170,7 +168,7 @@ GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp)
|
||||
*
|
||||
*/
|
||||
JS_FRIEND_API(bool)
|
||||
StringIsArrayIndex(JSLinearString *str, uint32_t *indexp)
|
||||
js::StringIsArrayIndex(JSLinearString *str, uint32_t *indexp)
|
||||
{
|
||||
const jschar *s = str->chars();
|
||||
uint32_t length = str->length();
|
||||
@ -207,7 +205,7 @@ StringIsArrayIndex(JSLinearString *str, uint32_t *indexp)
|
||||
}
|
||||
|
||||
Shape *
|
||||
GetDenseArrayShape(JSContext *cx, HandleObject globalObj)
|
||||
js::GetDenseArrayShape(JSContext *cx, HandleObject globalObj)
|
||||
{
|
||||
JS_ASSERT(globalObj);
|
||||
|
||||
@ -219,8 +217,6 @@ GetDenseArrayShape(JSContext *cx, HandleObject globalObj)
|
||||
gc::FINALIZE_OBJECT0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElementsHint)
|
||||
{
|
||||
@ -364,8 +360,6 @@ GetElement(JSContext *cx, HandleObject obj, IndexType index, JSBool *hole, Mutab
|
||||
return DoGetElement(cx, obj, index, hole, vp);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
static bool
|
||||
GetElementsSlow(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
|
||||
{
|
||||
@ -378,7 +372,7 @@ GetElementsSlow(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
|
||||
}
|
||||
|
||||
bool
|
||||
GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
|
||||
js::GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
|
||||
{
|
||||
if (aobj->isDenseArray() && length <= aobj->getDenseArrayInitializedLength() &&
|
||||
!js_PrototypeHasIndexedProperties(aobj)) {
|
||||
@ -402,8 +396,6 @@ GetElements(JSContext *cx, HandleObject aobj, uint32_t length, Value *vp)
|
||||
return GetElementsSlow(cx, aobj, length, vp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the value of the property at the given index to v assuming v is rooted.
|
||||
*/
|
||||
@ -984,12 +976,10 @@ array_defineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, H
|
||||
return array_defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
/* non-static for direct definition of array elements within the engine */
|
||||
JSBool
|
||||
array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
js::array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
if (!obj->isDenseArray())
|
||||
return baseops::DefineElement(cx, obj, index, value, getter, setter, attrs);
|
||||
@ -1023,8 +1013,6 @@ array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue
|
||||
return baseops::DefineElement(cx, obj, index, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
static JSBool
|
||||
array_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
@ -1108,12 +1096,10 @@ array_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
/* non-static for direct deletion of array elements within the engine */
|
||||
JSBool
|
||||
array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
MutableHandleValue rval, JSBool strict)
|
||||
js::array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue rval,
|
||||
JSBool strict)
|
||||
{
|
||||
if (!obj->isDenseArray())
|
||||
return baseops::DeleteElement(cx, obj, index, rval, strict);
|
||||
@ -1130,8 +1116,6 @@ array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
static JSBool
|
||||
array_deleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
|
||||
MutableHandleValue rval, JSBool strict)
|
||||
@ -3615,7 +3599,6 @@ js_InitArrayClass(JSContext *cx, HandleObject obj)
|
||||
/*
|
||||
* Array allocation functions.
|
||||
*/
|
||||
namespace js {
|
||||
|
||||
static inline bool
|
||||
EnsureNewArrayElements(JSContext *cx, JSObject *obj, uint32_t length)
|
||||
@ -3692,19 +3675,19 @@ NewArray(JSContext *cx, uint32_t length, RawObject protoArg)
|
||||
}
|
||||
|
||||
JSObject * JS_FASTCALL
|
||||
NewDenseEmptyArray(JSContext *cx, RawObject proto /* = NULL */)
|
||||
js::NewDenseEmptyArray(JSContext *cx, RawObject proto /* = NULL */)
|
||||
{
|
||||
return NewArray<false>(cx, 0, proto);
|
||||
}
|
||||
|
||||
JSObject * JS_FASTCALL
|
||||
NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */)
|
||||
js::NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */)
|
||||
{
|
||||
return NewArray<true>(cx, length, proto);
|
||||
}
|
||||
|
||||
JSObject * JS_FASTCALL
|
||||
NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */)
|
||||
js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */)
|
||||
{
|
||||
return NewArray<false>(cx, length, proto);
|
||||
}
|
||||
@ -3722,7 +3705,8 @@ mjit::stubs::NewDenseUnallocatedArray(VMFrame &f, uint32_t length)
|
||||
#endif
|
||||
|
||||
JSObject *
|
||||
NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset, RawObject proto /* = NULL */)
|
||||
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset,
|
||||
RawObject proto /* = NULL */)
|
||||
{
|
||||
JSObject* obj = NewArray<true>(cx, length, proto);
|
||||
if (!obj)
|
||||
@ -3741,7 +3725,8 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t e
|
||||
|
||||
// values must point at already-rooted Value objects
|
||||
JSObject *
|
||||
NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, RawObject proto /* = NULL */)
|
||||
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values,
|
||||
RawObject proto /* = NULL */)
|
||||
{
|
||||
JSObject* obj = NewArray<true>(cx, length, proto);
|
||||
if (!obj)
|
||||
@ -3758,7 +3743,7 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, RawObje
|
||||
}
|
||||
|
||||
JSObject *
|
||||
NewSlowEmptyArray(JSContext *cx)
|
||||
js::NewSlowEmptyArray(JSContext *cx)
|
||||
{
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &SlowArrayClass));
|
||||
if (!obj || !AddLengthProperty(cx, obj))
|
||||
@ -3768,8 +3753,6 @@ NewSlowEmptyArray(JSContext *cx)
|
||||
return obj;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
#ifdef DEBUG
|
||||
JSBool
|
||||
js_ArrayInfo(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
@ -371,10 +371,8 @@ js::AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavi
|
||||
return AtomizeInline(cx, &chars, length, ib);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
|
||||
js::IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
|
||||
{
|
||||
JS_ASSERT(index > JSID_INT_MAX);
|
||||
|
||||
@ -390,8 +388,6 @@ IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
bool
|
||||
js::InternNonIntElementId(JSContext *cx, JSObject *obj, const Value &idval,
|
||||
jsid *idp, MutableHandleValue vp)
|
||||
|
@ -94,6 +94,9 @@ BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr<T> end)
|
||||
return end;
|
||||
}
|
||||
|
||||
bool
|
||||
IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp);
|
||||
|
||||
inline bool
|
||||
IndexToId(JSContext *cx, uint32_t index, jsid *idp)
|
||||
{
|
||||
@ -104,7 +107,6 @@ IndexToId(JSContext *cx, uint32_t index, jsid *idp)
|
||||
return true;
|
||||
}
|
||||
|
||||
extern bool IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp);
|
||||
return IndexToIdSlow(cx, index, idp);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
#include "jsboolinlines.h"
|
||||
#include "jsinferinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
@ -192,17 +193,15 @@ js_BooleanToString(JSContext *cx, JSBool b)
|
||||
return b ? cx->runtime->atomState.true_ : cx->runtime->atomState.false_;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
ToBooleanSlow(const Value &v)
|
||||
js::ToBooleanSlow(const Value &v)
|
||||
{
|
||||
JS_ASSERT(v.isString());
|
||||
return v.toString()->length() != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp)
|
||||
js::BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp)
|
||||
{
|
||||
InvokeArgsGuard ag;
|
||||
if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
|
||||
@ -214,7 +213,3 @@ BooleanGetPrimitiveValueSlow(JSContext *cx, JSObject &obj, Value *vp)
|
||||
*vp = ag.rval();
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
bool BooleanGetPrimitiveValueSlow(JSContext *, JSObject &, Value *);
|
||||
|
||||
inline bool
|
||||
BooleanGetPrimitiveValue(JSContext *cx, JSObject &obj, Value *vp)
|
||||
{
|
||||
@ -21,7 +23,6 @@ BooleanGetPrimitiveValue(JSContext *cx, JSObject &obj, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
extern bool BooleanGetPrimitiveValueSlow(JSContext *, JSObject &, Value *);
|
||||
return BooleanGetPrimitiveValueSlow(cx, obj, vp);
|
||||
}
|
||||
|
||||
|
@ -120,12 +120,10 @@ SwapBytes(uint64_t u)
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp,
|
||||
const JSStructuredCloneCallbacks *cb, void *cbClosure,
|
||||
jsval transferable)
|
||||
js::WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp,
|
||||
const JSStructuredCloneCallbacks *cb, void *cbClosure,
|
||||
jsval transferable)
|
||||
{
|
||||
SCOutput out(cx);
|
||||
JSStructuredCloneWriter w(out, cb, cbClosure, transferable);
|
||||
@ -133,8 +131,8 @@ WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nby
|
||||
}
|
||||
|
||||
bool
|
||||
ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp,
|
||||
const JSStructuredCloneCallbacks *cb, void *cbClosure)
|
||||
js::ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp,
|
||||
const JSStructuredCloneCallbacks *cb, void *cbClosure)
|
||||
{
|
||||
SCInput in(cx, data, nbytes);
|
||||
|
||||
@ -146,7 +144,7 @@ ReadStructuredClone(JSContext *cx, uint64_t *data, size_t nbytes, Value *vp,
|
||||
}
|
||||
|
||||
bool
|
||||
ClearStructuredClone(const uint64_t *data, size_t nbytes)
|
||||
js::ClearStructuredClone(const uint64_t *data, size_t nbytes)
|
||||
{
|
||||
const uint64_t *point = data;
|
||||
const uint64_t *end = data + nbytes / 8;
|
||||
@ -171,8 +169,7 @@ ClearStructuredClone(const uint64_t *data, size_t nbytes)
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes,
|
||||
bool *hasTransferable)
|
||||
js::StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes, bool *hasTransferable)
|
||||
{
|
||||
*hasTransferable = false;
|
||||
|
||||
@ -187,8 +184,6 @@ StructuredCloneHasTransferObjects(const uint64_t *data, size_t nbytes,
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
static inline uint64_t
|
||||
PairToUInt64(uint32_t tag, uint32_t data)
|
||||
{
|
||||
|
@ -541,8 +541,6 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode)
|
||||
js_delete(cx);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
AutoResolving::alreadyStartedSlow() const
|
||||
{
|
||||
@ -556,8 +554,6 @@ AutoResolving::alreadyStartedSlow() const
|
||||
return false;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
static void
|
||||
ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
JSErrorCallback callback, void *userRef)
|
||||
@ -754,11 +750,9 @@ js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap)
|
||||
return warning;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
|
||||
void
|
||||
ReportUsageError(JSContext *cx, HandleObject callee, const char *msg)
|
||||
js::ReportUsageError(JSContext *cx, HandleObject callee, const char *msg)
|
||||
{
|
||||
const char *usageStr = "usage";
|
||||
PropertyName *usageAtom = Atomize(cx, usageStr, strlen(usageStr))->asPropertyName();
|
||||
@ -784,8 +778,8 @@ ReportUsageError(JSContext *cx, HandleObject callee, const char *msg)
|
||||
}
|
||||
|
||||
bool
|
||||
PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report,
|
||||
bool reportWarnings)
|
||||
js::PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report,
|
||||
bool reportWarnings)
|
||||
{
|
||||
if (!report) {
|
||||
fprintf(file, "%s\n", message);
|
||||
@ -855,8 +849,6 @@ PrintError(JSContext *cx, FILE *file, const char *message, JSErrorReport *report
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* The arguments from ap need to be packaged up into an array and stored
|
||||
* into the report struct.
|
||||
@ -1610,8 +1602,6 @@ JSContext::mark(JSTracer *trc)
|
||||
MarkValueRoot(trc, &iterValue, "iterValue");
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
|
||||
AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx)
|
||||
@ -1629,5 +1619,3 @@ AutoCheckRequestDepth::~AutoCheckRequestDepth()
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace JS
|
||||
|
@ -385,8 +385,6 @@ CallNativeImpl(JSContext *cx, NativeImpl impl, const CallArgs &args)
|
||||
return ok;
|
||||
}
|
||||
|
||||
extern JSBool CallOrConstructBoundFunction(JSContext *, unsigned, js::Value *);
|
||||
|
||||
STATIC_PRECONDITION(ubound(args.argv_) >= argc)
|
||||
JS_ALWAYS_INLINE bool
|
||||
CallJSNativeConstructor(JSContext *cx, Native native, const CallArgs &args)
|
||||
|
@ -50,6 +50,7 @@ JSCompartment::JSCompartment(JSRuntime *rt)
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
gcStoreBuffer(&gcNursery),
|
||||
#endif
|
||||
needsBarrier_(false),
|
||||
ionUsingBarriers_(false),
|
||||
gcScheduled(false),
|
||||
gcState(NoGC),
|
||||
|
@ -116,7 +116,7 @@ namespace js {
|
||||
class AutoDebugModeGC;
|
||||
}
|
||||
|
||||
struct JSCompartment : private JS::shadow::Compartment
|
||||
struct JSCompartment
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSPrincipals *principals;
|
||||
@ -156,6 +156,7 @@ struct JSCompartment : private JS::shadow::Compartment
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool needsBarrier_;
|
||||
bool ionUsingBarriers_;
|
||||
public:
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace js {
|
||||
namespace crash {
|
||||
using namespace js;
|
||||
using namespace js::crash;
|
||||
|
||||
const static int stack_snapshot_max_size = 32768;
|
||||
|
||||
@ -139,6 +139,9 @@ GetStack(uint64_t *stack, uint64_t *stack_len, CrashRegisters *regs, char *buffe
|
||||
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
namespace crash {
|
||||
|
||||
class Stack : private CrashStack
|
||||
{
|
||||
public:
|
||||
@ -206,6 +209,9 @@ Ring::copyBytes(void *data, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace crash */
|
||||
} /* namespace js */
|
||||
|
||||
static bool gInitialized;
|
||||
|
||||
static Stack gGCStack(JS_CRASH_STACK_GC);
|
||||
@ -213,32 +219,26 @@ static Stack gErrorStack(JS_CRASH_STACK_ERROR);
|
||||
static Ring gRingBuffer(JS_CRASH_RING);
|
||||
|
||||
void
|
||||
SnapshotGCStack()
|
||||
js::crash::SnapshotGCStack()
|
||||
{
|
||||
if (gInitialized)
|
||||
gGCStack.snapshot();
|
||||
}
|
||||
|
||||
void
|
||||
SnapshotErrorStack()
|
||||
js::crash::SnapshotErrorStack()
|
||||
{
|
||||
if (gInitialized)
|
||||
gErrorStack.snapshot();
|
||||
}
|
||||
|
||||
void
|
||||
SaveCrashData(uint64_t tag, void *ptr, size_t size)
|
||||
js::crash::SaveCrashData(uint64_t tag, void *ptr, size_t size)
|
||||
{
|
||||
if (gInitialized)
|
||||
gRingBuffer.push(tag, ptr, size);
|
||||
}
|
||||
|
||||
} /* namespace crash */
|
||||
} /* namespace js */
|
||||
|
||||
using namespace js;
|
||||
using namespace js::crash;
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_EnumerateDiagnosticMemoryRegions(JSEnumerateDiagnosticMemoryCallback callback)
|
||||
{
|
||||
|
@ -70,10 +70,8 @@ JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug)
|
||||
rt->debugMode = !!debug;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
JSTrapStatus
|
||||
ScriptDebugPrologue(JSContext *cx, StackFrame *fp)
|
||||
js::ScriptDebugPrologue(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
JS_ASSERT(fp == cx->fp());
|
||||
|
||||
@ -106,7 +104,7 @@ ScriptDebugPrologue(JSContext *cx, StackFrame *fp)
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg)
|
||||
js::ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg)
|
||||
{
|
||||
JS_ASSERT(fp == cx->fp());
|
||||
JSBool ok = okArg;
|
||||
@ -124,8 +122,6 @@ ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg)
|
||||
return Debugger::onLeaveFrame(cx, ok);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
JS_SetDebugModeForAllCompartments(JSContext *cx, JSBool debug)
|
||||
{
|
||||
|
@ -875,10 +875,8 @@ js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
|
||||
return errorString;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
JS_FRIEND_API(const jschar*)
|
||||
GetErrorTypeName(JSContext* cx, int16_t exnType)
|
||||
js::GetErrorTypeName(JSContext* cx, int16_t exnType)
|
||||
{
|
||||
/*
|
||||
* JSEXN_INTERNALERR returns null to prevent that "InternalError: "
|
||||
@ -893,8 +891,6 @@ GetErrorTypeName(JSContext* cx, int16_t exnType)
|
||||
return ClassName(key, cx)->chars();
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
|
||||
/* For use below... get character strings for error name and exception name */
|
||||
static struct exnname { char *name; char *exception; } errortoexnname[] = {
|
||||
|
@ -502,6 +502,7 @@ js::SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback)
|
||||
* sufficient data has been harvested.
|
||||
*/
|
||||
|
||||
// Defined in jsxml.cpp.
|
||||
extern size_t sE4XObjectsCreated;
|
||||
|
||||
JS_FRIEND_API(size_t)
|
||||
@ -511,6 +512,7 @@ JS_GetE4XObjectsCreated(JSContext *)
|
||||
}
|
||||
|
||||
namespace js {
|
||||
// Defined in vm/GlobalObject.cpp.
|
||||
extern size_t sSetProtoCalled;
|
||||
}
|
||||
|
||||
@ -520,6 +522,7 @@ JS_SetProtoCalled(JSContext *)
|
||||
return sSetProtoCalled;
|
||||
}
|
||||
|
||||
// Defined in jsiter.cpp.
|
||||
extern size_t sCustomIteratorCount;
|
||||
|
||||
JS_FRIEND_API(size_t)
|
||||
@ -546,6 +549,13 @@ js::TraceWeakMaps(WeakMapTracer *trc)
|
||||
WatchpointMap::traceAll(trc);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::GCThingIsMarkedGray(void *thing)
|
||||
{
|
||||
JS_ASSERT(thing);
|
||||
return reinterpret_cast<gc::Cell *>(thing)->isMarked(gc::GRAY);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSGCTraceKind)
|
||||
js::GCThingTraceKind(void *thing)
|
||||
{
|
||||
@ -710,29 +720,27 @@ js::DumpHeapComplete(JSRuntime *rt, FILE *fp)
|
||||
fflush(dtrc.output);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
JS_FRIEND_API(const JSStructuredCloneCallbacks *)
|
||||
GetContextStructuredCloneCallbacks(JSContext *cx)
|
||||
js::GetContextStructuredCloneCallbacks(JSContext *cx)
|
||||
{
|
||||
return cx->runtime->structuredCloneCallbacks;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSVersion)
|
||||
VersionSetMoarXML(JSVersion version, bool enable)
|
||||
js::VersionSetMoarXML(JSVersion version, bool enable)
|
||||
{
|
||||
return enable ? JSVersion(uint32_t(version) | VersionFlags::MOAR_XML)
|
||||
: JSVersion(uint32_t(version) & ~VersionFlags::MOAR_XML);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
CanCallContextDebugHandler(JSContext *cx)
|
||||
js::CanCallContextDebugHandler(JSContext *cx)
|
||||
{
|
||||
return !!cx->runtime->debugHooks.debuggerHandler;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSTrapStatus)
|
||||
CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval)
|
||||
js::CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval)
|
||||
{
|
||||
if (!cx->runtime->debugHooks.debuggerHandler)
|
||||
return JSTRAP_RETURN;
|
||||
@ -743,51 +751,51 @@ CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
void *
|
||||
GetOwnerThread(const JSContext *cx)
|
||||
js::GetOwnerThread(const JSContext *cx)
|
||||
{
|
||||
return cx->runtime->ownerThread();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
ContextHasOutstandingRequests(const JSContext *cx)
|
||||
js::ContextHasOutstandingRequests(const JSContext *cx)
|
||||
{
|
||||
return cx->outstandingRequests > 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(JSCompartment *)
|
||||
GetContextCompartment(const JSContext *cx)
|
||||
js::GetContextCompartment(const JSContext *cx)
|
||||
{
|
||||
return cx->compartment;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
HasUnrootedGlobal(const JSContext *cx)
|
||||
js::HasUnrootedGlobal(const JSContext *cx)
|
||||
{
|
||||
return cx->hasRunOption(JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg)
|
||||
js::SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg)
|
||||
{
|
||||
rt->activityCallback = cb;
|
||||
rt->activityCallbackArg = arg;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsContextRunningJS(JSContext *cx)
|
||||
js::IsContextRunningJS(JSContext *cx)
|
||||
{
|
||||
return !cx->stack.empty();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(const CompartmentVector&)
|
||||
GetRuntimeCompartments(JSRuntime *rt)
|
||||
js::GetRuntimeCompartments(JSRuntime *rt)
|
||||
{
|
||||
return rt->compartments;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(GCSliceCallback)
|
||||
SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
|
||||
js::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
|
||||
{
|
||||
GCSliceCallback old = rt->gcSliceCallback;
|
||||
rt->gcSliceCallback = callback;
|
||||
@ -795,7 +803,7 @@ SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
WasIncrementalGC(JSRuntime *rt)
|
||||
js::WasIncrementalGC(JSRuntime *rt)
|
||||
{
|
||||
return rt->gcIsIncremental;
|
||||
}
|
||||
@ -813,7 +821,7 @@ GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const
|
||||
}
|
||||
|
||||
JS_FRIEND_API(AnalysisPurgeCallback)
|
||||
SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback)
|
||||
js::SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback)
|
||||
{
|
||||
AnalysisPurgeCallback old = rt->analysisPurgeCallback;
|
||||
rt->analysisPurgeCallback = callback;
|
||||
@ -821,7 +829,7 @@ SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback)
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
NotifyDidPaint(JSRuntime *rt)
|
||||
js::NotifyDidPaint(JSRuntime *rt)
|
||||
{
|
||||
if (rt->gcZeal() == gc::ZealFrameVerifierPreValue) {
|
||||
gc::VerifyBarriers(rt, gc::PreBarrierVerifier);
|
||||
@ -847,38 +855,50 @@ NotifyDidPaint(JSRuntime *rt)
|
||||
rt->gcInterFrameGC = false;
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalGCEnabled(JSRuntime *rt)
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalGCEnabled(JSRuntime *rt)
|
||||
{
|
||||
return rt->gcIncrementalEnabled && rt->gcMode == JSGC_MODE_INCREMENTAL;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt)
|
||||
js::IsIncrementalGCInProgress(JSRuntime *rt)
|
||||
{
|
||||
return (rt->gcIncrementalState != gc::NO_INCREMENTAL && !rt->gcVerifyPreData);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableIncrementalGC(JSRuntime *rt)
|
||||
JS_FRIEND_API(void)
|
||||
js::DisableIncrementalGC(JSRuntime *rt)
|
||||
{
|
||||
rt->gcIncrementalEnabled = false;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt)
|
||||
js::IsIncrementalBarrierNeeded(JSRuntime *rt)
|
||||
{
|
||||
return (rt->gcIncrementalState == gc::MARK && !rt->isHeapBusy());
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext *cx)
|
||||
js::IsIncrementalBarrierNeeded(JSContext *cx)
|
||||
{
|
||||
return IsIncrementalBarrierNeeded(cx->runtime);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalReferenceBarrier(void *ptr)
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalBarrierNeededOnObject(RawObject obj)
|
||||
{
|
||||
return obj->compartment()->needsBarrier();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalBarrierNeededOnScript(JSScript *script)
|
||||
{
|
||||
return script->compartment()->needsBarrier();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::IncrementalReferenceBarrier(void *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
@ -905,20 +925,20 @@ IncrementalReferenceBarrier(void *ptr)
|
||||
JS_NOT_REACHED("invalid trace kind");
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalValueBarrier(const Value &v)
|
||||
JS_FRIEND_API(void)
|
||||
js::IncrementalValueBarrier(const Value &v)
|
||||
{
|
||||
HeapValue::writeBarrierPre(v);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PokeGC(JSRuntime *rt)
|
||||
JS_FRIEND_API(void)
|
||||
js::PokeGC(JSRuntime *rt)
|
||||
{
|
||||
rt->gcPoke = true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
GetTestingFunctions(JSContext *cx)
|
||||
js::GetTestingFunctions(JSContext *cx)
|
||||
{
|
||||
RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
|
||||
if (!obj)
|
||||
@ -931,32 +951,31 @@ GetTestingFunctions(JSContext *cx)
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size,
|
||||
uint32_t max)
|
||||
js::SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size, uint32_t max)
|
||||
{
|
||||
rt->spsProfiler.setProfilingStack(stack, size, max);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled)
|
||||
js::EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled)
|
||||
{
|
||||
rt->spsProfiler.enable(enabled);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(jsbytecode*)
|
||||
ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip)
|
||||
js::ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip)
|
||||
{
|
||||
return rt->spsProfiler.ipToPC(script, size_t(ip));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks)
|
||||
js::SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks)
|
||||
{
|
||||
rt->DOMcallbacks = callbacks;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(const DOMCallbacks *)
|
||||
GetDOMCallbacks(JSRuntime *rt)
|
||||
js::GetDOMCallbacks(JSRuntime *rt)
|
||||
{
|
||||
return rt->DOMcallbacks;
|
||||
}
|
||||
@ -965,22 +984,20 @@ static void *gListBaseHandlerFamily = NULL;
|
||||
static uint32_t gListBaseExpandoSlot = 0;
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot)
|
||||
js::SetListBaseInformation(void *listBaseHandlerFamily, uint32_t listBaseExpandoSlot)
|
||||
{
|
||||
gListBaseHandlerFamily = listBaseHandlerFamily;
|
||||
gListBaseExpandoSlot = listBaseExpandoSlot;
|
||||
}
|
||||
|
||||
void *
|
||||
GetListBaseHandlerFamily()
|
||||
js::GetListBaseHandlerFamily()
|
||||
{
|
||||
return gListBaseHandlerFamily;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetListBaseExpandoSlot()
|
||||
js::GetListBaseExpandoSlot()
|
||||
{
|
||||
return gListBaseExpandoSlot;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user