Merge m-c to fx-team a=merge

This commit is contained in:
Wes Kocher 2014-09-23 16:51:05 -07:00
commit 25d3579892
340 changed files with 75943 additions and 1847 deletions

View File

@ -85,7 +85,7 @@ ApplicationAccessibleWrap::Name(nsString& aName)
// Firefox or Thunderbird) like IA2 does. Thus let's return an application
// name as accessible name that was used to get a branding name (for example,
// Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
GetAppName(aName);
AppName(aName);
return eNameOK;
}

View File

@ -79,19 +79,16 @@ getDocumentAttributesCB(AtkDocument *aDocument)
GSList* attributes = nullptr;
DocAccessible* document = accWrap->AsDoc();
nsAutoString aURL;
nsresult rv = document->GetURL(aURL);
if (NS_SUCCEEDED(rv))
attributes = prependToList(attributes, kDocUrlName, aURL);
document->URL(aURL);
attributes = prependToList(attributes, kDocUrlName, aURL);
nsAutoString aW3CDocType;
rv = document->GetDocType(aW3CDocType);
if (NS_SUCCEEDED(rv))
attributes = prependToList(attributes, kDocTypeName, aW3CDocType);
document->GetDocType(aW3CDocType);
attributes = prependToList(attributes, kDocTypeName, aW3CDocType);
nsAutoString aMimeType;
rv = document->GetMimeType(aMimeType);
if (NS_SUCCEEDED(rv))
attributes = prependToList(attributes, kMimeTypeName, aMimeType);
document->MimeType(aMimeType);
attributes = prependToList(attributes, kMimeTypeName, aMimeType);
return attributes;
}
@ -110,9 +107,9 @@ getDocumentAttributeValueCB(AtkDocument *aDocument,
if (!strcasecmp(aAttrName, kDocTypeName))
rv = document->GetDocType(attrValue);
else if (!strcasecmp(aAttrName, kDocUrlName))
rv = document->GetURL(attrValue);
document->URL(attrValue);
else if (!strcasecmp(aAttrName, kMimeTypeName))
rv = document->GetMimeType(attrValue);
document->MimeType(attrValue);
else
return nullptr;

View File

@ -128,64 +128,6 @@ ApplicationAccessible::Bounds() const
return nsIntRect();
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleApplication
NS_IMETHODIMP
ApplicationAccessible::GetAppName(nsAString& aName)
{
aName.Truncate();
if (!mAppInfo)
return NS_ERROR_FAILURE;
nsAutoCString cname;
nsresult rv = mAppInfo->GetName(cname);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(cname, aName);
return NS_OK;
}
NS_IMETHODIMP
ApplicationAccessible::GetAppVersion(nsAString& aVersion)
{
aVersion.Truncate();
if (!mAppInfo)
return NS_ERROR_FAILURE;
nsAutoCString cversion;
nsresult rv = mAppInfo->GetVersion(cversion);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(cversion, aVersion);
return NS_OK;
}
NS_IMETHODIMP
ApplicationAccessible::GetPlatformName(nsAString& aName)
{
aName.AssignLiteral("Gecko");
return NS_OK;
}
NS_IMETHODIMP
ApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
{
aVersion.Truncate();
if (!mAppInfo)
return NS_ERROR_FAILURE;
nsAutoCString cversion;
nsresult rv = mAppInfo->GetPlatformVersion(cversion);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(cversion, aVersion);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// Accessible public methods

View File

@ -9,7 +9,7 @@
#define mozilla_a11y_ApplicationAccessible_h__
#include "AccessibleWrap.h"
#include "nsIAccessibleApplication.h"
#include "xpcAccessibleApplication.h"
#include "nsIMutableArray.h"
#include "nsIXULAppInfo.h"
@ -28,7 +28,7 @@ namespace a11y {
*/
class ApplicationAccessible : public AccessibleWrap,
public nsIAccessibleApplication
public xpcAccessibleApplication
{
public:
@ -37,9 +37,6 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleApplication
NS_DECL_NSIACCESSIBLEAPPLICATION
// Accessible
virtual void Shutdown();
virtual nsIntRect Bounds() const MOZ_OVERRIDE;
@ -63,6 +60,33 @@ public:
// ActionAccessible
virtual KeyBinding AccessKey() const;
// ApplicationAccessible
void AppName(nsAString& aName) const
{
nsAutoCString cname;
mAppInfo->GetName(cname);
AppendUTF8toUTF16(cname, aName);
}
void AppVersion(nsAString& aVersion) const
{
nsAutoCString cversion;
mAppInfo->GetVersion(cversion);
AppendUTF8toUTF16(cversion, aVersion);
}
void PlatformName(nsAString& aName) const
{
aName.AssignLiteral("Gecko");
}
void PlatformVersion(nsAString& aVersion) const
{
nsAutoCString cversion;
mAppInfo->GetPlatformVersion(cversion);
AppendUTF8toUTF16(cversion, aVersion);
}
protected:
virtual ~ApplicationAccessible() {}

View File

@ -9,6 +9,7 @@
#include "DocAccessible.h"
#include "nsAccessibilityService.h"
#include "nsAccessiblePivot.h"
#include "NotificationController.h"
#include "States.h"
#include "nsIScrollableFrame.h"
@ -20,6 +21,16 @@
namespace mozilla {
namespace a11y {
inline nsIAccessiblePivot*
DocAccessible::VirtualCursor()
{
if (!mVirtualCursor) {
mVirtualCursor = new nsAccessiblePivot(this);
mVirtualCursor->AddObserver(this);
}
return mVirtualCursor;
}
inline void
DocAccessible::FireDelayedEvent(AccEvent* aEvent)
{

View File

@ -40,7 +40,6 @@
#include "nsIURI.h"
#include "nsIWebNavigation.h"
#include "nsFocusManager.h"
#include "nsNameSpaceManager.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/EventStates.h"
@ -76,7 +75,7 @@ static const uint32_t kRelationAttrsLen = ArrayLength(kRelationAttrs);
DocAccessible::
DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
nsIPresShell* aPresShell) :
HyperTextAccessibleWrap(aRootContent, this),
HyperTextAccessibleWrap(aRootContent, this), xpcAccessibleDocument(),
// XXX aaronl should we use an algorithm for the initial cache size?
mAccessibleCache(kDefaultCacheLength),
mNodeToAccessibleMap(kDefaultCacheLength),
@ -175,12 +174,12 @@ DocAccessible::Name(nsString& aName)
Accessible::Name(aName);
}
if (aName.IsEmpty()) {
GetTitle(aName); // Try title element
Title(aName); // Try title element
}
if (aName.IsEmpty()) { // Last resort: use URL
GetURL(aName);
URL(aName);
}
return eNameOK;
}
@ -323,174 +322,6 @@ DocAccessible::TakeFocus()
nsFocusManager::MOVEFOCUS_ROOT, 0, getter_AddRefs(newFocus));
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleDocument
NS_IMETHODIMP
DocAccessible::GetURL(nsAString& aURL)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsISupports> container = mDocumentNode->GetContainer();
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(container));
nsAutoCString theURL;
if (webNav) {
nsCOMPtr<nsIURI> pURI;
webNav->GetCurrentURI(getter_AddRefs(pURI));
if (pURI)
pURI->GetSpec(theURL);
}
CopyUTF8toUTF16(theURL, aURL);
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetTitle(nsAString& aTitle)
{
if (!mDocumentNode) {
return NS_ERROR_FAILURE;
}
nsString title;
mDocumentNode->GetTitle(title);
aTitle = title;
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetMimeType(nsAString& aMimeType)
{
if (!mDocumentNode) {
return NS_ERROR_FAILURE;
}
return mDocumentNode->GetContentType(aMimeType);
}
NS_IMETHODIMP
DocAccessible::GetDocType(nsAString& aDocType)
{
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
if (xulDoc) {
aDocType.AssignLiteral("window"); // doctype not implemented for XUL at time of writing - causes assertion
return NS_OK;
} else
#endif
if (mDocumentNode) {
dom::DocumentType* docType = mDocumentNode->GetDoctype();
if (docType) {
return docType->GetPublicId(aDocType);
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
DocAccessible::GetNameSpaceURIForID(int16_t aNameSpaceID, nsAString& aNameSpaceURI)
{
if (mDocumentNode) {
nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance();
if (nameSpaceManager)
return nameSpaceManager->GetNameSpaceURI(aNameSpaceID, aNameSpaceURI);
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
DocAccessible::GetWindowHandle(void** aWindow)
{
NS_ENSURE_ARG_POINTER(aWindow);
*aWindow = GetNativeWindow();
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetWindow(nsIDOMWindow** aDOMWin)
{
*aDOMWin = nullptr;
if (!mDocumentNode) {
return NS_ERROR_FAILURE; // Accessible is Shutdown()
}
*aDOMWin = mDocumentNode->GetWindow();
if (!*aDOMWin)
return NS_ERROR_FAILURE; // No DOM Window
NS_ADDREF(*aDOMWin);
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetDOMDocument(nsIDOMDocument** aDOMDocument)
{
NS_ENSURE_ARG_POINTER(aDOMDocument);
*aDOMDocument = nullptr;
if (mDocumentNode)
CallQueryInterface(mDocumentNode, aDOMDocument);
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetParentDocument(nsIAccessibleDocument** aDocument)
{
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nullptr;
if (!IsDefunct())
NS_IF_ADDREF(*aDocument = ParentDocument());
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetChildDocumentCount(uint32_t* aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
if (!IsDefunct())
*aCount = ChildDocumentCount();
return NS_OK;
}
NS_IMETHODIMP
DocAccessible::GetChildDocumentAt(uint32_t aIndex,
nsIAccessibleDocument** aDocument)
{
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nullptr;
if (IsDefunct())
return NS_OK;
NS_IF_ADDREF(*aDocument = GetChildDocumentAt(aIndex));
return *aDocument ? NS_OK : NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
DocAccessible::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
{
NS_ENSURE_ARG_POINTER(aVirtualCursor);
*aVirtualCursor = nullptr;
if (IsDefunct())
return NS_ERROR_FAILURE;
if (!mVirtualCursor) {
mVirtualCursor = new nsAccessiblePivot(this);
mVirtualCursor->AddObserver(this);
}
NS_ADDREF(*aVirtualCursor = mVirtualCursor);
return NS_OK;
}
// HyperTextAccessible method
already_AddRefed<nsIEditor>
DocAccessible::GetEditor() const
@ -520,6 +351,37 @@ DocAccessible::GetEditor() const
}
// DocAccessible public method
void
DocAccessible::URL(nsAString& aURL) const
{
nsCOMPtr<nsISupports> container = mDocumentNode->GetContainer();
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(container));
nsAutoCString theURL;
if (webNav) {
nsCOMPtr<nsIURI> pURI;
webNav->GetCurrentURI(getter_AddRefs(pURI));
if (pURI)
pURI->GetSpec(theURL);
}
CopyUTF8toUTF16(theURL, aURL);
}
void
DocAccessible::DocType(nsAString& aType) const
{
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
if (xulDoc) {
aType.AssignLiteral("window"); // doctype not implemented for XUL at time of writing - causes assertion
return;
}
#endif
dom::DocumentType* docType = mDocumentNode->GetDoctype();
if (docType)
docType->GetPublicId(aType);
}
Accessible*
DocAccessible::GetAccessible(nsINode* aNode) const
{

View File

@ -6,7 +6,7 @@
#ifndef mozilla_a11y_DocAccessible_h__
#define mozilla_a11y_DocAccessible_h__
#include "nsIAccessibleDocument.h"
#include "xpcAccessibleDocument.h"
#include "nsIAccessiblePivot.h"
#include "AccEvent.h"
@ -38,7 +38,7 @@ template<class Class, class Arg>
class TNotification;
class DocAccessible : public HyperTextAccessibleWrap,
public nsIAccessibleDocument,
public xpcAccessibleDocument,
public nsIDocumentObserver,
public nsIObserver,
public nsIScrollPositionListener,
@ -48,8 +48,6 @@ class DocAccessible : public HyperTextAccessibleWrap,
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocAccessible, Accessible)
NS_DECL_NSIACCESSIBLEDOCUMENT
NS_DECL_NSIOBSERVER
NS_DECL_NSIACCESSIBLEPIVOTOBSERVER
@ -96,6 +94,31 @@ public:
// DocAccessible
/**
* Return document URL.
*/
void URL(nsAString& aURL) const;
/**
* Return DOM document title.
*/
void Title(nsString& aTitle) const { mDocumentNode->GetTitle(aTitle); }
/**
* Return DOM document mime type.
*/
void MimeType(nsAString& aType) const { mDocumentNode->GetContentType(aType); }
/**
* Return DOM document type.
*/
void DocType(nsAString& aType) const;
/**
* Return virtual cursor associated with the document.
*/
nsIAccessiblePivot* VirtualCursor();
/**
* Return presentation shell for this document accessible.
*/
@ -105,7 +128,7 @@ public:
* Return the presentation shell's context.
*/
nsPresContext* PresContext() const { return mPresShell->GetPresContext(); }
/**
* Return true if associated DOM document was loaded and isn't unloading.
*/

View File

@ -146,33 +146,20 @@ ImageAccessible::DoAction(uint8_t aIndex)
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleImage
// ImageAccessible
NS_IMETHODIMP
ImageAccessible::GetImagePosition(uint32_t aCoordType, int32_t* aX, int32_t* aY)
nsIntPoint
ImageAccessible::Position(uint32_t aCoordType)
{
NS_ENSURE_ARG_POINTER(aX);
NS_ENSURE_ARG_POINTER(aY);
nsIntRect rect = Bounds();
*aX = rect.x;
*aY = rect.y;
nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
return NS_OK;
nsAccUtils::ConvertScreenCoordsTo(&rect.x, &rect.y, aCoordType, this);
return rect.TopLeft();
}
NS_IMETHODIMP
ImageAccessible::GetImageSize(int32_t* aWidth, int32_t* aHeight)
nsIntSize
ImageAccessible::Size()
{
NS_ENSURE_ARG_POINTER(aWidth);
NS_ENSURE_ARG_POINTER(aHeight);
nsIntRect rect = Bounds();
*aWidth = rect.width;
*aHeight = rect.height;
return NS_OK;
return Bounds().Size();
}
// Accessible

View File

@ -7,7 +7,7 @@
#define mozilla_a11y_ImageAccessible_h__
#include "BaseAccessibles.h"
#include "nsIAccessibleImage.h"
#include "xpcAccessibleImage.h"
class nsGenericHTMLElement;
@ -20,7 +20,7 @@ namespace a11y {
* - support basic state
*/
class ImageAccessible : public LinkableAccessible,
public nsIAccessibleImage
public xpcAccessibleImage
{
public:
ImageAccessible(nsIContent* aContent, DocAccessible* aDoc);
@ -28,9 +28,6 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleImage
NS_DECL_NSIACCESSIBLEIMAGE
// Accessible
virtual a11y::role NativeRole() MOZ_OVERRIDE;
virtual uint64_t NativeState() MOZ_OVERRIDE;
@ -41,6 +38,10 @@ public:
virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) MOZ_OVERRIDE;
virtual bool DoAction(uint8_t aIndex) MOZ_OVERRIDE;
// ImageAccessible
nsIntPoint Position(uint32_t aCoordType);
nsIntSize Size();
protected:
virtual ~ImageAccessible();

View File

@ -5,10 +5,8 @@
#include "nsISupports.idl"
interface nsIAccessible;
interface nsIAccessiblePivot;
interface nsIDOMDocument;
interface nsIDOMNode;
interface nsIDOMWindow;
/**
@ -18,11 +16,10 @@ interface nsIDOMWindow;
* there is an nsIAccessibleDocument for each document
* whether it is XUL, HTML or whatever.
* You can QueryInterface to nsIAccessibleDocument from the nsIAccessible for
* the root node of a document. You can also get one from
* nsIAccessible::GetAccessibleDocument() or
* nsIAccessibleEvent::GetAccessibleDocument()
* the root node of a document or you can get one from
* nsIAccessible::GetDocument().
*/
[scriptable, uuid(fe5b3886-2b6a-491a-80cd-a3e6342c451d)]
[scriptable, uuid(c80f6600-3210-4893-8f71-fde381ca39c9)]
interface nsIAccessibleDocument : nsISupports
{
/**
@ -55,17 +52,6 @@ interface nsIAccessibleDocument : nsISupports
*/
readonly attribute nsIDOMWindow window;
/**
* The namespace for each ID that is handed back.
*/
AString getNameSpaceURIForID(in short nameSpaceID);
/**
* The window handle for the OS window the document is being displayed in.
* For example, in Windows you can static cast it to an HWND.
*/
[noscript] readonly attribute voidPtr windowHandle;
/**
* Return the parent document accessible.
*/
@ -84,5 +70,6 @@ interface nsIAccessibleDocument : nsISupports
/**
* Return the child document accessible at the given index.
*/
[binaryname(ScriptableGetChildDocumentAt)]
nsIAccessibleDocument getChildDocumentAt(in unsigned long index);
};

View File

@ -79,10 +79,7 @@ ApplicationAccessibleWrap::get_appName(BSTR* aName)
return CO_E_OBJNOTCONNECTED;
nsAutoString name;
nsresult rv = GetAppName(name);
if (NS_FAILED(rv))
return GetHRESULT(rv);
AppName(name);
if (name.IsEmpty())
return S_FALSE;
@ -106,10 +103,7 @@ ApplicationAccessibleWrap::get_appVersion(BSTR* aVersion)
return CO_E_OBJNOTCONNECTED;
nsAutoString version;
nsresult rv = GetAppVersion(version);
if (NS_FAILED(rv))
return GetHRESULT(rv);
AppVersion(version);
if (version.IsEmpty())
return S_FALSE;
@ -131,10 +125,7 @@ ApplicationAccessibleWrap::get_toolkitName(BSTR* aName)
return CO_E_OBJNOTCONNECTED;
nsAutoString name;
nsresult rv = GetPlatformName(name);
if (NS_FAILED(rv))
return GetHRESULT(rv);
PlatformName(name);
if (name.IsEmpty())
return S_FALSE;
@ -158,10 +149,7 @@ ApplicationAccessibleWrap::get_toolkitVersion(BSTR* aVersion)
return CO_E_OBJNOTCONNECTED;
nsAutoString version;
nsresult rv = GetPlatformVersion(version);
if (NS_FAILED(rv))
return GetHRESULT(rv);
PlatformVersion(version);
if (version.IsEmpty())
return S_FALSE;

View File

@ -61,16 +61,16 @@ DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue)
// If document is being used to create a widget, don't use the URL hack
roles::Role role = Role();
if (role != roles::DOCUMENT && role != roles::APPLICATION &&
role != roles::DIALOG && role != roles::ALERT)
if (role != roles::DOCUMENT && role != roles::APPLICATION &&
role != roles::DIALOG && role != roles::ALERT)
return hr;
nsAutoString URL;
nsresult rv = GetURL(URL);
if (URL.IsEmpty())
nsAutoString url;
URL(url);
if (url.IsEmpty())
return S_FALSE;
*aValue = ::SysAllocStringLen(URL.get(), URL.Length());
*aValue = ::SysAllocStringLen(url.get(), url.Length());
return *aValue ? S_OK : E_OUTOFMEMORY;
A11Y_TRYBLOCK_END

View File

@ -8,6 +8,8 @@
#include "ISimpleDOMDocument_i.c"
#include "nsNameSpaceManager.h"
using namespace mozilla;
using namespace mozilla::a11y;
@ -32,10 +34,7 @@ sdnDocAccessible::get_URL(BSTR __RPC_FAR* aURL)
return CO_E_OBJNOTCONNECTED;
nsAutoString URL;
nsresult rv = mAccessible->GetURL(URL);
if (NS_FAILED(rv))
return E_FAIL;
mAccessible->URL(URL);
if (URL.IsEmpty())
return S_FALSE;
@ -58,10 +57,7 @@ sdnDocAccessible::get_title(BSTR __RPC_FAR* aTitle)
return CO_E_OBJNOTCONNECTED;
nsAutoString title;
nsresult rv = mAccessible->GetTitle(title);
if (NS_FAILED(rv))
return E_FAIL;
mAccessible->Title(title);
*aTitle = ::SysAllocStringLen(title.get(), title.Length());
return *aTitle ? S_OK : E_OUTOFMEMORY;
@ -137,9 +133,9 @@ sdnDocAccessible::get_nameSpaceURIForID(short aNameSpaceID,
return E_INVALIDARG; // -1 is kNameSpaceID_Unknown
nsAutoString nameSpaceURI;
nsresult rv = mAccessible->GetNameSpaceURIForID(aNameSpaceID, nameSpaceURI);
if (NS_FAILED(rv))
return E_FAIL;
nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance();
if (nameSpaceManager)
nameSpaceManager->GetNameSpaceURI(aNameSpaceID, nameSpaceURI);
if (nameSpaceURI.IsEmpty())
return S_FALSE;

View File

@ -6,6 +6,7 @@
EXPORTS += [
'xpcAccessible.h',
'xpcAccessibleDocument.h',
'xpcAccessibleHyperLink.h',
'xpcAccessibleHyperText.h',
'xpcAccessibleSelectable.h',
@ -15,8 +16,11 @@ EXPORTS += [
UNIFIED_SOURCES += [
'nsAccessibleRelation.cpp',
'xpcAccessible.cpp',
'xpcAccessibleApplication.cpp',
'xpcAccessibleDocument.cpp',
'xpcAccessibleHyperLink.cpp',
'xpcAccessibleHyperText.cpp',
'xpcAccessibleImage.cpp',
'xpcAccessibleSelectable.cpp',
'xpcAccessibleTable.cpp',
'xpcAccessibleTableCell.cpp',

View File

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "xpcAccessibleApplication.h"
#include "ApplicationAccessible.h"
using namespace mozilla::a11y;
NS_IMETHODIMP
xpcAccessibleApplication::GetAppName(nsAString& aName)
{
aName.Truncate();
if (static_cast<ApplicationAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<ApplicationAccessible*>(this)->AppName(aName);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleApplication::GetAppVersion(nsAString& aVersion)
{
aVersion.Truncate();
if (static_cast<ApplicationAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<ApplicationAccessible*>(this)->AppVersion(aVersion);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleApplication::GetPlatformName(nsAString& aName)
{
aName.Truncate();
if (static_cast<ApplicationAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<ApplicationAccessible*>(this)->PlatformName(aName);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleApplication::GetPlatformVersion(nsAString& aVersion)
{
aVersion.Truncate();
if (static_cast<ApplicationAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<ApplicationAccessible*>(this)->PlatformVersion(aVersion);
return NS_OK;
}

View File

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 mozilla_a11y_xpcAccessibleApplication_h_
#define mozilla_a11y_xpcAccessibleApplication_h_
#include "nsIAccessibleApplication.h"
class nsIAccessible;
namespace mozilla {
namespace a11y {
class xpcAccessibleApplication : public nsIAccessibleApplication
{
public:
NS_IMETHOD GetAppName(nsAString& aName) MOZ_FINAL;
NS_IMETHOD GetAppVersion(nsAString& aVersion) MOZ_FINAL;
NS_IMETHOD GetPlatformName(nsAString& aName) MOZ_FINAL;
NS_IMETHOD GetPlatformVersion(nsAString& aVersion) MOZ_FINAL;
private:
xpcAccessibleApplication() { }
friend class ApplicationAccessible;
xpcAccessibleApplication(const xpcAccessibleApplication&) MOZ_DELETE;
xpcAccessibleApplication& operator =(const xpcAccessibleApplication&) MOZ_DELETE;
};
} // namespace a11y
} // namespace mozilla
#endif

View File

@ -0,0 +1,135 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "xpcAccessibleDocument.h"
#include "DocAccessible-inl.h"
#include "nsIDOMDocument.h"
using namespace mozilla::a11y;
NS_IMETHODIMP
xpcAccessibleDocument::GetURL(nsAString& aURL)
{
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<DocAccessible*>(this)->URL(aURL);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetTitle(nsAString& aTitle)
{
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
nsAutoString title;
static_cast<DocAccessible*>(this)->Title(title);
aTitle = title;
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetMimeType(nsAString& aType)
{
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<DocAccessible*>(this)->MimeType(aType);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetDocType(nsAString& aType)
{
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
static_cast<DocAccessible*>(this)->DocType(aType);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetDOMDocument(nsIDOMDocument** aDOMDocument)
{
NS_ENSURE_ARG_POINTER(aDOMDocument);
*aDOMDocument = nullptr;
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
if (static_cast<DocAccessible*>(this)->DocumentNode())
CallQueryInterface(static_cast<DocAccessible*>(this)->DocumentNode(), aDOMDocument);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetWindow(nsIDOMWindow** aDOMWindow)
{
NS_ENSURE_ARG_POINTER(aDOMWindow);
*aDOMWindow = nullptr;
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aDOMWindow = static_cast<DocAccessible*>(this)->DocumentNode()->GetWindow());
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetParentDocument(nsIAccessibleDocument** aDocument)
{
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nullptr;
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aDocument = static_cast<DocAccessible*>(this)->ParentDocument());
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetChildDocumentCount(uint32_t* aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
*aCount = static_cast<DocAccessible*>(this)->ChildDocumentCount();
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleDocument::ScriptableGetChildDocumentAt(uint32_t aIndex,
nsIAccessibleDocument** aDocument)
{
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nullptr;
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aDocument = static_cast<DocAccessible*>(this)->GetChildDocumentAt(aIndex));
return *aDocument ? NS_OK : NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
xpcAccessibleDocument::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
{
NS_ENSURE_ARG_POINTER(aVirtualCursor);
*aVirtualCursor = nullptr;
if (static_cast<DocAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
NS_ADDREF(*aVirtualCursor = static_cast<DocAccessible*>(this)->VirtualCursor());
return NS_OK;
}

View File

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 mozilla_a11y_xpcAccessibleDocument_h_
#define mozilla_a11y_xpcAccessibleDocument_h_
#include "nsIAccessibleDocument.h"
namespace mozilla {
namespace a11y {
class xpcAccessibleDocument : public nsIAccessibleDocument
{
public:
NS_IMETHOD GetURL(nsAString& aURL) MOZ_FINAL;
NS_IMETHOD GetTitle(nsAString& aTitle) MOZ_FINAL;
NS_IMETHOD GetMimeType(nsAString& aType) MOZ_FINAL;
NS_IMETHOD GetDocType(nsAString& aType) MOZ_FINAL;
NS_IMETHOD GetDOMDocument(nsIDOMDocument** aDOMDocument) MOZ_FINAL;
NS_IMETHOD GetWindow(nsIDOMWindow** aDOMWindow) MOZ_FINAL;
NS_IMETHOD GetParentDocument(nsIAccessibleDocument** aDocument) MOZ_FINAL;
NS_IMETHOD GetChildDocumentCount(uint32_t* aCount) MOZ_FINAL;
NS_IMETHOD ScriptableGetChildDocumentAt(uint32_t aIndex,
nsIAccessibleDocument** aDocument) MOZ_FINAL;
NS_IMETHOD GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor) MOZ_FINAL;
private:
friend class DocAccessible;
xpcAccessibleDocument() { }
xpcAccessibleDocument(const xpcAccessibleDocument&) MOZ_DELETE;
xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) MOZ_DELETE;
};
} // namespace a11y
} // namespace mozilla
#endif

View File

@ -0,0 +1,44 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "xpcAccessibleImage.h"
#include "ImageAccessible.h"
using namespace mozilla::a11y;
NS_IMETHODIMP
xpcAccessibleImage::GetImagePosition(uint32_t aCoordType, int32_t* aX, int32_t* aY)
{
NS_ENSURE_ARG_POINTER(aX);
*aX = 0;
NS_ENSURE_ARG_POINTER(aY);
*aY = 0;
if (static_cast<ImageAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
nsIntPoint point = static_cast<ImageAccessible*>(this)->Position(aCoordType);
*aX = point.x; *aY = point.y;
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleImage::GetImageSize(int32_t* aWidth, int32_t* aHeight)
{
NS_ENSURE_ARG_POINTER(aWidth);
*aWidth = 0;
NS_ENSURE_ARG_POINTER(aHeight);
*aHeight = 0;
if (static_cast<ImageAccessible*>(this)->IsDefunct())
return NS_ERROR_FAILURE;
nsIntSize size = static_cast<ImageAccessible*>(this)->Size();
*aWidth = size.width;
*aHeight = size.height;
return NS_OK;
}

View File

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 mozilla_a11y_xpcAccessibleImage_h_
#define mozilla_a11y_xpcAccessibleImage_h_
#include "nsIAccessibleImage.h"
namespace mozilla {
namespace a11y {
class xpcAccessibleImage : public nsIAccessibleImage
{
public:
NS_IMETHOD GetImagePosition(uint32_t aCoordType,
int32_t* aX, int32_t* aY) MOZ_FINAL;
NS_IMETHOD GetImageSize(int32_t* aWidth, int32_t* aHeight) MOZ_FINAL;
private:
friend class ImageAccessible;
xpcAccessibleImage() { }
xpcAccessibleImage(const xpcAccessibleImage&) MOZ_DELETE;
xpcAccessibleImage& operator =(const xpcAccessibleImage&) MOZ_DELETE;
};
} // namespace a11y
} // namespace mozilla
#endif

View File

@ -738,7 +738,8 @@ let DoCommandHelper = {
handleEvent: function docommand_handleEvent(cmd) {
if (this._event) {
shell.sendEvent(this._event.target, 'mozdocommand', { cmd: cmd });
Services.obs.notifyObservers({ wrappedJSObject: this._event.target },
'copypaste-docommand', cmd);
this._event = null;
}
}

View File

@ -15,9 +15,9 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>

View File

@ -19,8 +19,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>

View File

@ -17,8 +17,8 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>

View File

@ -15,9 +15,9 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>

View File

@ -19,8 +19,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>

View File

@ -15,9 +15,9 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>

View File

@ -17,8 +17,8 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "6890cdf5807b0c9a4341b97ee39fd692dc95fd0c",
"revision": "aa27f131a40f855892c6ed638e05b6d0ef92aece",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,8 +17,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>

View File

@ -15,8 +15,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>

View File

@ -17,8 +17,8 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f3e998242fb9a857cf50f5bf3a02304a530ea617"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>

View File

@ -17,8 +17,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="37b8a812c642ca616bf9457cb9b71e45261cdfa8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b81855b6b67f285d6f27a4f8c1cfe2e0387ea57c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ff6dbb006e4e60edba697639aa2a2a199b07069b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>

View File

@ -508,8 +508,11 @@ class Automation(object):
else:
env['MOZ_CRASHREPORTER_DISABLE'] = '1'
# Crash on non-local network connections.
env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1'
# Crash on non-local network connections by default.
# MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
# enable non-local connections for the purposes of local testing. Don't
# override the user's choice here. See bug 1049688.
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
env['GNOME_DISABLE_CRASH_DIALOG'] = '1'
env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1'

View File

@ -432,8 +432,11 @@ def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=N
else:
env['MOZ_CRASHREPORTER_DISABLE'] = '1'
# Crash on non-local network connections.
env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1'
# Crash on non-local network connections by default.
# MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
# enable non-local connections for the purposes of local testing. Don't
# override the user's choice here. See bug 1049688.
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
# Set WebRTC logging in case it is not set yet
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')

View File

@ -74,8 +74,11 @@ class RemoteAutomation(Automation):
else:
env['MOZ_CRASHREPORTER_DISABLE'] = '1'
# Crash on non-local network connections.
env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1'
# Crash on non-local network connections by default.
# MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
# enable non-local connections for the purposes of local testing.
# Don't override the user's choice here. See bug 1049688.
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
return env

View File

@ -670,3 +670,4 @@ VFY_End
VFY_Update
VFY_VerifyDataDirect
VFY_VerifyDataWithAlgorithmID
_SGN_VerifyPKCS1DigestInfo

View File

@ -1242,6 +1242,7 @@ nsCSPContext::Write(nsIObjectOutputStream* aStream)
nsAutoString polStr;
for (uint32_t p = 0; p < mPolicies.Length(); p++) {
polStr.Truncate();
mPolicies[p]->toString(polStr);
aStream->WriteWStringZ(polStr.get());
aStream->WriteBoolean(mPolicies[p]->getReportOnlyFlag());

View File

@ -512,6 +512,7 @@ BrowserElementChild.prototype = {
debug('Got iconchanged: (' + e.target.href + ')');
let icon = { href: e.target.href };
this._maybeCopyAttribute(e.target, icon, 'sizes');
this._maybeCopyAttribute(e.target, icon, 'rel');
sendAsyncMsg('iconchange', icon);
},

View File

@ -85,6 +85,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
Services.obs.addObserver(this, 'ask-children-to-exit-fullscreen', /* ownsWeak = */ true);
Services.obs.addObserver(this, 'oop-frameloader-crashed', /* ownsWeak = */ true);
Services.obs.addObserver(this, 'copypaste-docommand', /* ownsWeak = */ true);
let defineMethod = function(name, fn) {
XPCNativeWrapper.unwrap(self._frameElement)[name] = function() {
@ -169,14 +170,6 @@ function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
/* wantsUntrusted = */ false);
}
this._doCommandHandlerBinder = this._doCommandHandler.bind(this);
this._frameElement.addEventListener('mozdocommand',
this._doCommandHandlerBinder,
/* useCapture = */ false,
/* wantsUntrusted = */ false);
Services.obs.addObserver(this, 'ipc:browser-destroyed', /* ownsWeak = */ true);
this._window._browserElementParents.set(this, null);
// Insert ourself into the prompt service.
@ -498,11 +491,6 @@ BrowserElementParent.prototype = {
this._frameElement.dispatchEvent(evt);
},
_doCommandHandler: function(e) {
e.stopPropagation();
this._sendAsyncMsg('do-command', { command: e.detail.cmd });
},
_createEvent: function(evtName, detail, cancelable) {
// This will have to change if we ever want to send a CustomEvent with null
// detail. For now, it's OK.
@ -926,11 +914,9 @@ BrowserElementParent.prototype = {
}
Services.obs.removeObserver(this, 'remote-browser-frame-shown');
}
case 'ipc:browser-destroyed':
if (this._isAlive() && subject == this._frameLoader) {
Services.obs.removeObserver(this, 'ipc:browser-destroyed');
this._frameElement.removeEventListener('mozdocommand',
this._doCommandHandlerBinder)
case 'copypaste-docommand':
if (this._isAlive() && this._frameElement.isEqualNode(subject.wrappedJSObject)) {
this._sendAsyncMsg('do-command', { command: data });
}
break;
default:

View File

@ -8,6 +8,7 @@ SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.setSelectionChangeEnabledPref(true);
browserElementTestHelpers.addPermission();
const { Services } = SpecialPowers.Cu.import('resource://gre/modules/Services.jsm');
var gTextarea = null;
var mm;
var iframe;
@ -60,10 +61,8 @@ function runTest() {
}
function doCommand(cmd) {
let doc = iframe.ownerDocument;
let event = doc.createEvent('CustomEvent');
event.initCustomEvent('mozdocommand', true, true, { cmd: cmd });
SpecialPowers.wrap(iframe).dispatchEvent(event);
Services.obs.notifyObservers({wrappedJSObject: iframe},
'copypaste-docommand', cmd);
}
function dispatchTest(e) {

View File

@ -100,6 +100,7 @@ function runTest() {
iframe1.src = createHtml(createLink('testapple1', '100x100', 'apple-touch-icon'));
} else if (numIconChanges == 8) {
is(e.detail.href, 'http://example.com/testapple1.png');
is(e.detail.rel, 'apple-touch-icon');
is(e.detail.sizes, '100x100');
SimpleTest.finish();
} else {

View File

@ -4622,6 +4622,7 @@ CanvasPath::AddPath(CanvasPath& aCanvasPath, const Optional<NonNull<SVGMatrix>>&
}
}
EnsurePathBuilder(); // in case a path is added to itself
tempPath->StreamToSink(mPathBuilder);
}

View File

@ -93,7 +93,7 @@ namespace gfx {
class SourceSurface;
}
WebGLTexelFormat GetWebGLTexelFormat(GLenum format, GLenum type);
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format, TexType type);
void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
@ -221,7 +221,7 @@ public:
*/
static const char *EnumName(GLenum glenum);
bool IsTextureFormatCompressed(GLenum format);
bool IsTextureFormatCompressed(TexInternalFormat format);
void DummyFramebufferOperation(const char *info);
@ -1093,7 +1093,7 @@ protected:
bool ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func);
bool ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
GLint level, GLint internalFormat,
GLint level, GLenum internalFormat,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
GLint border, GLenum format, GLenum type,
@ -1120,7 +1120,7 @@ protected:
uint32_t byteLength, WebGLTexImageFunc func);
static uint32_t GetBitsPerTexel(GLenum format, GLenum type);
static uint32_t GetBitsPerTexel(TexInternalFormat format, TexType type);
void Invalidate();
void DestroyResourcesAndContext();

View File

@ -595,7 +595,7 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
tex->DoDeferredImageInitialization(texImageTarget, level);
}
return CopyTexSubImage2D_base(texImageTarget, level, imageInfo.WebGLFormat(), xoffset, yoffset, x, y, width, height, true);
return CopyTexSubImage2D_base(texImageTarget, level, imageInfo.WebGLFormat().get(), xoffset, yoffset, x, y, width, height, true);
}
@ -900,7 +900,7 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
if (!tex->IsFirstImagePowerOfTwo())
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
GLenum webGLFormat = tex->ImageInfoAt(imageTarget, 0).WebGLFormat();
TexInternalFormat webGLFormat = tex->ImageInfoAt(imageTarget, 0).WebGLFormat();
if (IsTextureFormatCompressed(webGLFormat))
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
@ -1177,7 +1177,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
const GLenum webGLFormat =
const TexInternalFormat webGLFormat =
fba.Texture()->ImageInfoBase().WebGLFormat();
return (webGLFormat == LOCAL_GL_SRGB ||
webGLFormat == LOCAL_GL_SRGB_ALPHA) ?
@ -1219,9 +1219,9 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
return JS::NumberValue(uint32_t(LOCAL_GL_NONE));
uint32_t ret = LOCAL_GL_NONE;
GLenum type = fba.Texture()->ImageInfoAt(fba.ImageTarget(),
fba.MipLevel()).WebGLType();
switch (type) {
TexType type = fba.Texture()->ImageInfoAt(fba.ImageTarget(),
fba.MipLevel()).WebGLType();
switch (type.get()) {
case LOCAL_GL_UNSIGNED_BYTE:
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
@ -2409,7 +2409,7 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
bool hasExtensions = IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float) &&
IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float);
if (!hasExtensions)
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target);
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
break;
}
case LOCAL_GL_RGB32F:
@ -2417,7 +2417,7 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
bool hasExtensions = IsExtensionEnabled(WebGLExtensionID::OES_texture_float) &&
IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float);
if (!hasExtensions)
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target);
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
break;
}
default:
@ -4032,12 +4032,12 @@ BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize)
}
WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum internalformat, GLenum type)
WebGLTexelFormat mozilla::GetWebGLTexelFormat(TexInternalFormat internalformat, TexType type)
{
//
// WEBGL_depth_texture
if (internalformat == LOCAL_GL_DEPTH_COMPONENT) {
switch (type) {
switch (type.get()) {
case LOCAL_GL_UNSIGNED_SHORT:
return WebGLTexelFormat::D16;
case LOCAL_GL_UNSIGNED_INT:
@ -4048,7 +4048,7 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum internalformat, GLenum type
}
if (internalformat == LOCAL_GL_DEPTH_STENCIL) {
switch (type) {
switch (type.get()) {
case LOCAL_GL_UNSIGNED_INT_24_8_EXT:
return WebGLTexelFormat::D24S8;
}
@ -4069,7 +4069,7 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum internalformat, GLenum type
}
if (type == LOCAL_GL_UNSIGNED_BYTE) {
switch (internalformat) {
switch (internalformat.get()) {
case LOCAL_GL_RGBA:
case LOCAL_GL_SRGB_ALPHA_EXT:
return WebGLTexelFormat::RGBA8;
@ -4089,7 +4089,7 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum internalformat, GLenum type
if (type == LOCAL_GL_FLOAT) {
// OES_texture_float
switch (internalformat) {
switch (internalformat.get()) {
case LOCAL_GL_RGBA:
case LOCAL_GL_RGBA32F:
return WebGLTexelFormat::RGBA32F;
@ -4110,7 +4110,7 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum internalformat, GLenum type
MOZ_CRASH("Invalid WebGL texture format/type?");
} else if (type == LOCAL_GL_HALF_FLOAT_OES) {
// OES_texture_half_float
switch (internalformat) {
switch (internalformat.get()) {
case LOCAL_GL_RGBA:
case LOCAL_GL_RGBA16F:
return WebGLTexelFormat::RGBA16F;
@ -4132,7 +4132,7 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum internalformat, GLenum type
}
}
switch (type) {
switch (type.get()) {
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
return WebGLTexelFormat::RGBA4444;
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:

View File

@ -31,7 +31,7 @@ namespace mozilla {
using namespace gl;
bool
IsGLDepthFormat(GLenum webGLFormat)
IsGLDepthFormat(TexInternalFormat webGLFormat)
{
return (webGLFormat == LOCAL_GL_DEPTH_COMPONENT ||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
@ -39,14 +39,14 @@ IsGLDepthFormat(GLenum webGLFormat)
}
bool
IsGLDepthStencilFormat(GLenum webGLFormat)
IsGLDepthStencilFormat(TexInternalFormat webGLFormat)
{
return (webGLFormat == LOCAL_GL_DEPTH_STENCIL ||
webGLFormat == LOCAL_GL_DEPTH24_STENCIL8);
}
bool
FormatHasAlpha(GLenum webGLFormat)
FormatHasAlpha(TexInternalFormat webGLFormat)
{
return webGLFormat == LOCAL_GL_RGBA ||
webGLFormat == LOCAL_GL_LUMINANCE_ALPHA ||
@ -76,11 +76,11 @@ TexImageTargetToTexTarget(TexImageTarget texImageTarget)
}
}
GLComponents::GLComponents(GLenum format)
GLComponents::GLComponents(TexInternalFormat format)
{
mComponents = 0;
switch (format) {
switch (format.get()) {
case LOCAL_GL_RGBA:
case LOCAL_GL_RGBA4:
case LOCAL_GL_RGBA8:
@ -118,91 +118,99 @@ GLComponents::IsSubsetOf(const GLComponents& other) const
}
/**
* Convert WebGL/ES format and type into GL format and GL internal
* Convert WebGL/ES format and type into GL internal
* format valid for underlying driver.
*/
void
DriverFormatsFromFormatAndType(GLContext* gl, GLenum webGLFormat, GLenum webGLType,
DriverFormatsFromFormatAndType(GLContext* gl, TexInternalFormat webGLInternalFormat, TexType webGLType,
GLenum* out_driverInternalFormat, GLenum* out_driverFormat)
{
MOZ_ASSERT(out_driverInternalFormat, "out_driverInternalFormat can't be nullptr.");
MOZ_ASSERT(out_driverFormat, "out_driverFormat can't be nullptr.");
if (!out_driverInternalFormat || !out_driverFormat)
return;
MOZ_ASSERT(out_driverInternalFormat);
MOZ_ASSERT(out_driverFormat);
// ES2 requires that format == internalformat; floating-point is
// indicated purely by the type that's loaded. For desktop GL, we
// have to specify a floating point internal format.
if (gl->IsGLES()) {
*out_driverInternalFormat = webGLFormat;
*out_driverFormat = webGLFormat;
*out_driverFormat = *out_driverInternalFormat = webGLInternalFormat.get();
return;
}
GLenum format = webGLFormat;
GLenum internalFormat = LOCAL_GL_NONE;
GLenum format = LOCAL_GL_NONE;
if (format == LOCAL_GL_DEPTH_COMPONENT) {
if (webGLInternalFormat == LOCAL_GL_DEPTH_COMPONENT) {
format = LOCAL_GL_DEPTH_COMPONENT;
if (webGLType == LOCAL_GL_UNSIGNED_SHORT)
internalFormat = LOCAL_GL_DEPTH_COMPONENT16;
else if (webGLType == LOCAL_GL_UNSIGNED_INT)
internalFormat = LOCAL_GL_DEPTH_COMPONENT32;
} else if (format == LOCAL_GL_DEPTH_STENCIL) {
} else if (webGLInternalFormat == LOCAL_GL_DEPTH_STENCIL) {
format = LOCAL_GL_DEPTH_STENCIL;
if (webGLType == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
} else {
switch (webGLType) {
switch (webGLType.get()) {
case LOCAL_GL_UNSIGNED_BYTE:
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
internalFormat = format;
format = internalFormat = webGLInternalFormat.get();
break;
case LOCAL_GL_FLOAT:
switch (format) {
switch (webGLInternalFormat.get()) {
case LOCAL_GL_RGBA:
format = LOCAL_GL_RGBA;
internalFormat = LOCAL_GL_RGBA32F;
break;
case LOCAL_GL_RGB:
format = LOCAL_GL_RGB;
internalFormat = LOCAL_GL_RGB32F;
break;
case LOCAL_GL_ALPHA:
format = LOCAL_GL_ALPHA;
internalFormat = LOCAL_GL_ALPHA32F_ARB;
break;
case LOCAL_GL_LUMINANCE:
format = LOCAL_GL_LUMINANCE;
internalFormat = LOCAL_GL_LUMINANCE32F_ARB;
break;
case LOCAL_GL_LUMINANCE_ALPHA:
format = LOCAL_GL_LUMINANCE_ALPHA;
internalFormat = LOCAL_GL_LUMINANCE_ALPHA32F_ARB;
break;
}
break;
case LOCAL_GL_HALF_FLOAT_OES:
switch (format) {
switch (webGLInternalFormat.get()) {
case LOCAL_GL_RGBA:
format = LOCAL_GL_RGBA;
internalFormat = LOCAL_GL_RGBA16F;
break;
case LOCAL_GL_RGB:
format = LOCAL_GL_RGB;
internalFormat = LOCAL_GL_RGB16F;
break;
case LOCAL_GL_ALPHA:
format = LOCAL_GL_ALPHA;
internalFormat = LOCAL_GL_ALPHA16F_ARB;
break;
case LOCAL_GL_LUMINANCE:
format = LOCAL_GL_LUMINANCE;
internalFormat = LOCAL_GL_LUMINANCE16F_ARB;
break;
case LOCAL_GL_LUMINANCE_ALPHA:
format = LOCAL_GL_LUMINANCE_ALPHA;
internalFormat = LOCAL_GL_LUMINANCE_ALPHA16F_ARB;
break;
}
@ -218,20 +226,19 @@ DriverFormatsFromFormatAndType(GLContext* gl, GLenum webGLFormat, GLenum webGLTy
// format -> internalformat
// GL_RGB GL_SRGB_EXT
// GL_RGBA GL_SRGB_ALPHA_EXT
switch (format) {
switch (webGLInternalFormat.get()) {
case LOCAL_GL_SRGB:
internalFormat = format;
format = LOCAL_GL_RGB;
internalFormat = LOCAL_GL_SRGB;
break;
case LOCAL_GL_SRGB_ALPHA:
internalFormat = format;
format = LOCAL_GL_RGBA;
internalFormat = LOCAL_GL_SRGB_ALPHA;
break;
}
}
MOZ_ASSERT(format != LOCAL_GL_NONE && internalFormat != LOCAL_GL_NONE,
MOZ_ASSERT(webGLInternalFormat != LOCAL_GL_NONE && internalFormat != LOCAL_GL_NONE,
"Coding mistake -- bad format/type passed?");
*out_driverInternalFormat = internalFormat;
@ -239,13 +246,14 @@ DriverFormatsFromFormatAndType(GLContext* gl, GLenum webGLFormat, GLenum webGLTy
}
GLenum
DriverTypeFromType(GLContext* gl, GLenum webGLType)
DriverTypeFromType(GLContext* gl, TexType webGLType)
{
GLenum type = webGLType.get();
if (gl->IsGLES())
return webGLType;
return type;
// convert type for half float if not on GLES2
GLenum type = webGLType;
if (type == LOCAL_GL_HALF_FLOAT_OES) {
if (gl->IsSupported(gl::GLFeature::texture_half_float)) {
return LOCAL_GL_HALF_FLOAT;
@ -254,7 +262,7 @@ DriverTypeFromType(GLContext* gl, GLenum webGLType)
}
}
return webGLType;
return type;
}
void
@ -484,9 +492,9 @@ WebGLContext::EnumName(GLenum glenum)
bool
WebGLContext::IsTextureFormatCompressed(GLenum format)
WebGLContext::IsTextureFormatCompressed(TexInternalFormat format)
{
switch (format) {
switch (format.get()) {
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:

View File

@ -13,12 +13,12 @@
namespace mozilla {
bool IsGLDepthFormat(GLenum webGLFormat);
bool IsGLDepthStencilFormat(GLenum webGLFormat);
bool FormatHasAlpha(GLenum webGLFormat);
void DriverFormatsFromFormatAndType(gl::GLContext* gl, GLenum webGLFormat, GLenum webGLType,
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
bool IsGLDepthStencilFormat(TexInternalFormat webGLFormat);
bool FormatHasAlpha(TexInternalFormat webGLFormat);
void DriverFormatsFromFormatAndType(gl::GLContext* gl, TexInternalFormat webGLFormat, TexType webGLType,
GLenum* out_driverInternalFormat, GLenum* out_driverFormat);
GLenum DriverTypeFromType(gl::GLContext* gl, GLenum webGLType);
GLenum DriverTypeFromType(gl::GLContext* gl, TexType webGLType);
// For use with the different texture calls, i.e.
// TexImage2D, CopyTex[Sub]Image2D, ...
@ -51,7 +51,7 @@ struct GLComponents
: mComponents(0)
{ }
explicit GLComponents(GLenum aFormat);
explicit GLComponents(TexInternalFormat aFormat);
// Returns true iff other has all (or more) of
// the components present in this GLComponents

View File

@ -1039,13 +1039,8 @@ WebGLContext::ValidateTexSubImageSize(GLint xoffset, GLint yoffset, GLint /*zoff
* ValidateTexImageFormatAndType().
*/
uint32_t
WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
WebGLContext::GetBitsPerTexel(TexInternalFormat format, TexType type)
{
// If there is no defined format or type, we're not taking up any memory
if (!format || !type) {
return 0;
}
/* Known fixed-sized types */
if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
@ -1058,7 +1053,7 @@ WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
return 32;
int bitsPerComponent = 0;
switch (type) {
switch (type.get()) {
case LOCAL_GL_UNSIGNED_BYTE:
bitsPerComponent = 8;
break;
@ -1079,7 +1074,7 @@ WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
break;
}
switch (format) {
switch (format.get()) {
// Uncompressed formats
case LOCAL_GL_ALPHA:
case LOCAL_GL_LUMINANCE:
@ -1309,7 +1304,7 @@ WebGLContext::ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func)
// TODO: Texture dims is here for future expansion in WebGL 2.0
bool
WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
GLint level, GLint internalFormat,
GLint level, GLenum internalFormat,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
GLint border, GLenum format, GLenum type,
@ -1339,7 +1334,7 @@ WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
* (e.g., GL_FLOAT requires GL_OES_texture_float) are filtered
* elsewhere.
*/
if ((GLint) format != internalFormat) {
if (format != internalFormat) {
ErrorInvalidOperation("%s: format does not match internalformat", info);
return false;
}

View File

@ -64,17 +64,23 @@ WebGLFramebuffer::Attachment::IsDeleteRequested() const
: false;
}
bool
WebGLFramebuffer::Attachment::IsDefined() const
{
return Renderbuffer() ||
(Texture() && Texture()->HasImageInfoAt(ImageTarget(), 0));
}
bool
WebGLFramebuffer::Attachment::HasAlpha() const
{
MOZ_ASSERT(HasImage());
GLenum format = 0;
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
format = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLFormat();
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLFormat());
else if (Renderbuffer())
format = Renderbuffer()->InternalFormat();
return FormatHasAlpha(format);
return FormatHasAlpha(Renderbuffer()->InternalFormat());
else return false;
}
GLenum
@ -88,7 +94,7 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
return imgInfo.WebGLFormat();
return imgInfo.WebGLFormat().get();
}
if (attachment.Renderbuffer())
@ -102,7 +108,7 @@ WebGLFramebuffer::Attachment::IsReadableFloat() const
{
const WebGLTexture* tex = Texture();
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
GLenum type = tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLType();
GLenum type = tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLType().get();
switch (type) {
case LOCAL_GL_FLOAT:
case LOCAL_GL_HALF_FLOAT_OES:
@ -322,7 +328,7 @@ WebGLFramebuffer::Attachment::IsComplete() const
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
const WebGLTexture::ImageInfo& imageInfo =
Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
GLenum webGLFormat = imageInfo.WebGLFormat();
GLenum webGLFormat = imageInfo.WebGLFormat().get();
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
return IsValidFBOTextureDepthFormat(webGLFormat);

View File

@ -49,9 +49,7 @@ public:
explicit Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
~Attachment();
bool IsDefined() const {
return Texture() || Renderbuffer();
}
bool IsDefined() const;
bool IsDeleteRequested() const;

View File

@ -17,13 +17,13 @@
// To create a new type from a set of GLenums do the following:
//
// STRONG_GLENUM_BEGIN(TypeName)
// Enum1,
// Enum2,
// STRONG_GLENUM_VALUE(ENUM1),
// STRONG_GLENUM_VALUE(ENUM2),
// ...
// STRONG_GLENUM_END()
//
// where TypeName is the name you want to give the type. Now simply use TypeName
// instead of GLenum.
// instead of GLenum. The enum values must be given without GL_ prefix.
//
// ~~~~~~~~~~~~~~~~
// Important Notes:
@ -33,10 +33,10 @@
// when using constants. For example we want to make sure that GL_ENUM_X is
// a valid value for the type in code like:
//
// if (myNewType == LOCAL_GL_SOME_ENUM)
// if (myNewType == STRONG_GLENUM_VALUE(SOME_ENUM))
// ...
//
// The operators will assert that LOCAL_GL_SOME_ENUM is a value that myNewType
// The operators will assert that STRONG_GLENUM_VALUE(SOME_ENUM) is a value that myNewType
// can have.
//
// ----
@ -47,7 +47,7 @@
//
// Definitely XXX - DO NOT DO - XXX:
//
// if (myNewType.get() == LOCAL_GL_SOME_ENUM)
// if (myNewType.get() == STRONG_GLENUM_VALUE(SOME_ENUM))
// ...
//
// As that undermines the debug checks that were implemented in the ==, and !=
@ -77,76 +77,268 @@
// is an attempt at fixing this by providing a small wrapper around GLenum that
// validates its values.
//
#ifdef DEBUG
// Comparison between STRONG_GLENUM's vs. enum classes
// ===================================================
//
// The present STRONG_GLENUM's differ from ordinary enum classes
// in that they assert at runtime that their values are legal, and in that they
// allow implicit conversion from integers to STRONG_GLENUM's but disallow
// implicit conversion from STRONG_GLENUM's to integers (enum classes are the opposite).
//
// When to use GLenum's vs. STRONG_GLENUM's vs. enum classes
// =========================================================
//
// Rule of thumb:
// * For unchecked GLenum constants, such as WebGL method parameters that haven't been
// validated yet, use GLenum.
// * For already-validated GLenum constants, use STRONG_GLENUM's.
// * For custom constants that aren't GL enum values, use enum classes.
template<size_t N>
static bool
IsValueInArr(GLenum value, const GLenum (&arr)[N])
template<typename Details>
class StrongGLenum MOZ_FINAL
{
for (size_t i = 0; i < N; ++i) {
if (value == arr[i])
return true;
private:
static const GLenum NonexistantGLenum = 0xdeaddead;
GLenum mValue;
static void AssertOnceThatEnumValuesAreSorted()
{
#ifdef DEBUG
static bool alreadyChecked = false;
if (alreadyChecked) {
return;
}
for (size_t i = 1; i < Details::valuesCount(); i++) {
MOZ_ASSERT(Details::values()[i] > Details::values()[i - 1],
"GLenum values should be sorted in ascending order");
}
alreadyChecked = true;
#endif
}
return false;
public:
StrongGLenum(const StrongGLenum& other)
: mValue(other.mValue)
{
AssertOnceThatEnumValuesAreSorted();
}
StrongGLenum()
#ifdef DEBUG
: mValue(NonexistantGLenum)
#endif
{
AssertOnceThatEnumValuesAreSorted();
}
StrongGLenum(GLenum val)
: mValue(val)
{
AssertOnceThatEnumValuesAreSorted();
MOZ_ASSERT(IsValueLegal(mValue));
}
GLenum get() const {
MOZ_ASSERT(mValue != NonexistantGLenum);
return mValue;
}
bool operator==(const StrongGLenum& other) const {
return get() == other.get();
}
bool operator!=(const StrongGLenum& other) const {
return get() != other.get();
}
static bool IsValueLegal(GLenum value) {
if (value > UINT16_MAX) {
return false;
}
return std::binary_search(Details::values(),
Details::values() + Details::valuesCount(),
uint16_t(value));
}
};
template<typename Details>
bool operator==(GLenum a, StrongGLenum<Details> b)
{
return a == b.get();
}
#endif
template<typename Details>
bool operator!=(GLenum a, StrongGLenum<Details> b)
{
return a != b.get();
}
#define STRONG_GLENUM_BEGIN(NAME) \
class NAME { \
private: \
GLenum mValue; \
public: \
MOZ_CONSTEXPR NAME(const NAME& other) \
: mValue(other.mValue) { } \
\
bool operator==(const NAME& other) const { \
return mValue == other.mValue; \
} \
\
bool operator!=(const NAME& other) const { \
return mValue != other.mValue; \
} \
\
GLenum get() const { \
MOZ_ASSERT(mValue != LOCAL_GL_NONE); \
return mValue; \
} \
\
NAME(GLenum val) \
: mValue(val) \
{ \
const GLenum validValues[] = {
template<typename Details>
bool operator==(StrongGLenum<Details> a, GLenum b)
{
return a.get() == b;
}
#define STRONG_GLENUM_END() \
}; \
(void)validValues; \
MOZ_ASSERT(IsValueInArr(mValue, validValues)); \
} \
};
template<typename Details>
bool operator!=(StrongGLenum<Details> a, GLenum b)
{
return a.get() != b;
}
#define STRONG_GLENUM_BEGIN(NAME) \
const uint16_t NAME##Values[] = {
#define STRONG_GLENUM_VALUE(VALUE) LOCAL_GL_##VALUE
#define STRONG_GLENUM_END(NAME) \
}; \
struct NAME##Details { \
static size_t valuesCount() { return MOZ_ARRAY_LENGTH(NAME##Values); } \
static const uint16_t* values() { return NAME##Values; } \
}; \
typedef StrongGLenum<NAME##Details> NAME;
/******************************************************************************
* Add your types after this comment
*****************************************************************************/
STRONG_GLENUM_BEGIN(TexImageTarget)
LOCAL_GL_NONE,
LOCAL_GL_TEXTURE_2D,
LOCAL_GL_TEXTURE_3D,
LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X,
LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
STRONG_GLENUM_END()
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(TEXTURE_2D),
STRONG_GLENUM_VALUE(TEXTURE_3D),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP_POSITIVE_X),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP_NEGATIVE_X),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP_POSITIVE_Y),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP_NEGATIVE_Y),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP_POSITIVE_Z),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP_NEGATIVE_Z),
STRONG_GLENUM_END(TexImageTarget)
STRONG_GLENUM_BEGIN(TexTarget)
LOCAL_GL_NONE,
LOCAL_GL_TEXTURE_2D,
LOCAL_GL_TEXTURE_3D,
LOCAL_GL_TEXTURE_CUBE_MAP,
STRONG_GLENUM_END()
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(TEXTURE_2D),
STRONG_GLENUM_VALUE(TEXTURE_3D),
STRONG_GLENUM_VALUE(TEXTURE_CUBE_MAP),
STRONG_GLENUM_END(TexTarget)
STRONG_GLENUM_BEGIN(TexType)
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(BYTE),
STRONG_GLENUM_VALUE(UNSIGNED_BYTE),
STRONG_GLENUM_VALUE(SHORT),
STRONG_GLENUM_VALUE(UNSIGNED_SHORT),
STRONG_GLENUM_VALUE(INT),
STRONG_GLENUM_VALUE(UNSIGNED_INT),
STRONG_GLENUM_VALUE(FLOAT),
STRONG_GLENUM_VALUE(HALF_FLOAT),
STRONG_GLENUM_VALUE(UNSIGNED_SHORT_4_4_4_4),
STRONG_GLENUM_VALUE(UNSIGNED_SHORT_5_5_5_1),
STRONG_GLENUM_VALUE(UNSIGNED_SHORT_5_6_5),
STRONG_GLENUM_VALUE(UNSIGNED_INT_2_10_10_10_REV),
STRONG_GLENUM_VALUE(UNSIGNED_INT_24_8),
STRONG_GLENUM_VALUE(UNSIGNED_INT_10F_11F_11F_REV),
STRONG_GLENUM_VALUE(UNSIGNED_INT_5_9_9_9_REV),
STRONG_GLENUM_VALUE(HALF_FLOAT_OES),
STRONG_GLENUM_VALUE(FLOAT_32_UNSIGNED_INT_24_8_REV),
STRONG_GLENUM_END(TexType)
STRONG_GLENUM_BEGIN(TexFormat)
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(DEPTH_COMPONENT),
STRONG_GLENUM_VALUE(RED),
STRONG_GLENUM_VALUE(ALPHA),
STRONG_GLENUM_VALUE(RGB),
STRONG_GLENUM_VALUE(RGBA),
STRONG_GLENUM_VALUE(LUMINANCE),
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA),
STRONG_GLENUM_VALUE(RG),
STRONG_GLENUM_VALUE(SRGB),
STRONG_GLENUM_VALUE(SRGB_ALPHA),
STRONG_GLENUM_VALUE(RG_INTEGER),
STRONG_GLENUM_VALUE(DEPTH_STENCIL),
STRONG_GLENUM_VALUE(RED_INTEGER),
STRONG_GLENUM_VALUE(RGB_INTEGER),
STRONG_GLENUM_VALUE(RGBA_INTEGER),
STRONG_GLENUM_END(TexFormat)
STRONG_GLENUM_BEGIN(TexInternalFormat)
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(DEPTH_COMPONENT),
STRONG_GLENUM_VALUE(ALPHA),
STRONG_GLENUM_VALUE(RGB),
STRONG_GLENUM_VALUE(RGBA),
STRONG_GLENUM_VALUE(LUMINANCE),
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA),
STRONG_GLENUM_VALUE(RGB8),
STRONG_GLENUM_VALUE(RGBA4),
STRONG_GLENUM_VALUE(RGB5_A1),
STRONG_GLENUM_VALUE(RGBA8),
STRONG_GLENUM_VALUE(RGB10_A2),
STRONG_GLENUM_VALUE(DEPTH_COMPONENT16),
STRONG_GLENUM_VALUE(DEPTH_COMPONENT24),
STRONG_GLENUM_VALUE(R8),
STRONG_GLENUM_VALUE(RG8),
STRONG_GLENUM_VALUE(R16F),
STRONG_GLENUM_VALUE(R32F),
STRONG_GLENUM_VALUE(RG16F),
STRONG_GLENUM_VALUE(RG32F),
STRONG_GLENUM_VALUE(R8I),
STRONG_GLENUM_VALUE(R8UI),
STRONG_GLENUM_VALUE(R16I),
STRONG_GLENUM_VALUE(R16UI),
STRONG_GLENUM_VALUE(R32I),
STRONG_GLENUM_VALUE(R32UI),
STRONG_GLENUM_VALUE(RG8I),
STRONG_GLENUM_VALUE(RG8UI),
STRONG_GLENUM_VALUE(RG16I),
STRONG_GLENUM_VALUE(RG16UI),
STRONG_GLENUM_VALUE(RG32I),
STRONG_GLENUM_VALUE(RG32UI),
STRONG_GLENUM_VALUE(COMPRESSED_RGB_S3TC_DXT1_EXT),
STRONG_GLENUM_VALUE(COMPRESSED_RGBA_S3TC_DXT1_EXT),
STRONG_GLENUM_VALUE(COMPRESSED_RGBA_S3TC_DXT3_EXT),
STRONG_GLENUM_VALUE(COMPRESSED_RGBA_S3TC_DXT5_EXT),
STRONG_GLENUM_VALUE(DEPTH_STENCIL),
STRONG_GLENUM_VALUE(ATC_RGBA_INTERPOLATED_ALPHA),
STRONG_GLENUM_VALUE(RGBA32F),
STRONG_GLENUM_VALUE(RGB32F),
STRONG_GLENUM_VALUE(RGBA16F),
STRONG_GLENUM_VALUE(RGB16F),
STRONG_GLENUM_VALUE(DEPTH24_STENCIL8),
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_4BPPV1),
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_2BPPV1),
STRONG_GLENUM_VALUE(COMPRESSED_RGBA_PVRTC_4BPPV1),
STRONG_GLENUM_VALUE(COMPRESSED_RGBA_PVRTC_2BPPV1),
STRONG_GLENUM_VALUE(R11F_G11F_B10F),
STRONG_GLENUM_VALUE(RGB9_E5),
STRONG_GLENUM_VALUE(SRGB),
STRONG_GLENUM_VALUE(SRGB8),
STRONG_GLENUM_VALUE(SRGB_ALPHA),
STRONG_GLENUM_VALUE(SRGB8_ALPHA8),
STRONG_GLENUM_VALUE(ATC_RGB),
STRONG_GLENUM_VALUE(ATC_RGBA_EXPLICIT_ALPHA),
STRONG_GLENUM_VALUE(DEPTH_COMPONENT32F),
STRONG_GLENUM_VALUE(DEPTH32F_STENCIL8),
STRONG_GLENUM_VALUE(RGB565),
STRONG_GLENUM_VALUE(ETC1_RGB8_OES),
STRONG_GLENUM_VALUE(RGBA32UI),
STRONG_GLENUM_VALUE(RGB32UI),
STRONG_GLENUM_VALUE(RGBA16UI),
STRONG_GLENUM_VALUE(RGB16UI),
STRONG_GLENUM_VALUE(RGBA8UI),
STRONG_GLENUM_VALUE(RGB8UI),
STRONG_GLENUM_VALUE(RGBA32I),
STRONG_GLENUM_VALUE(RGB32I),
STRONG_GLENUM_VALUE(RGBA16I),
STRONG_GLENUM_VALUE(RGB16I),
STRONG_GLENUM_VALUE(RGBA8I),
STRONG_GLENUM_VALUE(RGB8I),
STRONG_GLENUM_VALUE(R8_SNORM),
STRONG_GLENUM_VALUE(RG8_SNORM),
STRONG_GLENUM_VALUE(RGB8_SNORM),
STRONG_GLENUM_VALUE(RGBA8_SNORM),
STRONG_GLENUM_VALUE(RGB10_A2UI),
STRONG_GLENUM_END(TexInternalFormat)
#endif

View File

@ -138,7 +138,7 @@ WebGLTexture::Bind(TexTarget aTexTarget) {
void
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight,
GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus)
TexInternalFormat aFormat, TexType aType, WebGLImageDataStatus aStatus)
{
MOZ_ASSERT(TexImageTargetToTexTarget(aTexImageTarget) == mTarget);
if (TexImageTargetToTexTarget(aTexImageTarget) != mTarget)
@ -459,7 +459,7 @@ ClearByMask(WebGLContext* context, GLbitfield mask)
static bool
ClearWithTempFB(WebGLContext* context, GLuint tex,
TexImageTarget texImageTarget, GLint level,
GLenum baseInternalFormat,
TexInternalFormat baseInternalFormat,
GLsizei width, GLsizei height)
{
if (texImageTarget != LOCAL_GL_TEXTURE_2D)
@ -472,7 +472,7 @@ ClearWithTempFB(WebGLContext* context, GLuint tex,
gl::ScopedBindFramebuffer autoFB(gl, fb.FB());
GLbitfield mask = 0;
switch (baseInternalFormat) {
switch (baseInternalFormat.get()) {
case LOCAL_GL_LUMINANCE:
case LOCAL_GL_LUMINANCE_ALPHA:
case LOCAL_GL_ALPHA:
@ -542,8 +542,8 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
mContext->MakeContextCurrent();
// Try to clear with glCLear.
GLenum format = imageInfo.mWebGLFormat;
GLenum type = imageInfo.mWebGLType;
TexInternalFormat format = imageInfo.mWebGLFormat;
TexType type = imageInfo.mWebGLType;
WebGLTexelFormat texelformat = GetWebGLTexelFormat(format, type);
bool cleared = ClearWithTempFB(mContext, GLName(),

View File

@ -74,8 +74,8 @@ public:
ImageInfo(GLsizei width,
GLsizei height,
GLenum webGLFormat,
GLenum webGLType,
TexInternalFormat webGLFormat,
TexType webGLType,
WebGLImageDataStatus status)
: WebGLRectangleObject(width, height)
, mWebGLFormat(webGLFormat)
@ -114,16 +114,16 @@ public:
* It can be converted to a value to be passed to driver with
* DriverFormatsFromFormatAndType().
*/
GLenum WebGLFormat() const { return mWebGLFormat; }
TexInternalFormat WebGLFormat() const { return mWebGLFormat; }
/*! This is the type passed from JS to WebGL.
* It can be converted to a value to be passed to driver with
* DriverTypeFromType().
*/
GLenum WebGLType() const { return mWebGLType; }
TexType WebGLType() const { return mWebGLType; }
protected:
GLenum mWebGLFormat; //!< This is the WebGL/GLES format
GLenum mWebGLType; //!< This is the WebGL/GLES type
TexInternalFormat mWebGLFormat; //!< This is the WebGL/GLES format
TexType mWebGLType; //!< This is the WebGL/GLES type
WebGLImageDataStatus mImageDataStatus;
friend class WebGLTexture;
@ -225,7 +225,7 @@ public:
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight,
GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus);
TexInternalFormat aFormat, TexType aType, WebGLImageDataStatus aStatus);
void SetMinFilter(GLenum aMinFilter) {
mMinFilter = aMinFilter;

View File

@ -378,6 +378,8 @@ function test_addpath_canvas() {
shouldThrow(ctx, "p5.addPath(null, m)");
shouldThrow(ctx, "p5.addPath([], m)");
shouldThrow(ctx, "p5.addPath({}, m)");
p5 = p5.addPath(p5);
}
</script>

View File

@ -741,7 +741,7 @@ NetworkManager.prototype = {
#endif
},
_requestCount: 0,
_usbTetheringRequestCount: 0,
handle: function(aName, aResult) {
switch(aName) {
@ -776,12 +776,17 @@ NetworkManager.prototype = {
if (this._oldUsbTetheringEnabledState === this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("No changes for SETTINGS_USB_ENABLED flag. Nothing to do.");
this.handlePendingWifiTetheringRequest();
break;
}
this._requestCount++;
if (this._requestCount === 1) {
this.handleUSBTetheringToggle(aResult);
this._usbTetheringRequestCount++;
if (this._usbTetheringRequestCount === 1) {
if (this._wifiTetheringRequestOngoing) {
debug('USB tethering request is blocked by ongoing wifi tethering request.');
} else {
this.handleLastUsbTetheringRequest();
}
}
break;
};
@ -819,24 +824,31 @@ NetworkManager.prototype = {
// External and internal interface name.
_tetheringInterface: null,
handleLastRequest: function() {
if (this._requestCount === 1) {
this._requestCount = 0;
handleLastUsbTetheringRequest: function() {
debug('handleLastUsbTetheringRequest... ' + this._usbTetheringRequestCount);
if (this._usbTetheringRequestCount === 0) {
if (this.wantConnectionEvent) {
if (this.tetheringSettings[SETTINGS_USB_ENABLED]) {
this.wantConnectionEvent.call(this);
}
this.wantConnectionEvent = null;
}
this.handlePendingWifiTetheringRequest();
return;
}
if (this._requestCount > 1) {
// Set this._requestCount to 1 to prevent from subsequent usb tethering toggles
// triggering |handleUSBTetheringToggle|.
this._requestCount = 1;
this.handleUSBTetheringToggle(this.tetheringSettings[SETTINGS_USB_ENABLED]);
this.wantConnectionEvent = null;
// Cancel the accumlated count to 1 since we only care about the
// last state.
this._usbTetheringRequestCount = 1;
this.handleUSBTetheringToggle(this.tetheringSettings[SETTINGS_USB_ENABLED]);
this.wantConnectionEvent = null;
},
handlePendingWifiTetheringRequest: function() {
if (this._pendingWifiTetheringRequestArgs) {
this.setWifiTethering.apply(this, this._pendingWifiTetheringRequestArgs);
this._pendingWifiTetheringRequestArgs = null;
}
},
@ -932,14 +944,16 @@ NetworkManager.prototype = {
(this._usbTetheringAction === TETHERING_STATE_ONGOING ||
this._usbTetheringAction === TETHERING_STATE_ACTIVE)) {
debug("Usb tethering already connecting/connected.");
this._requestCount = 0;
this._usbTetheringRequestCount = 0;
this.handlePendingWifiTetheringRequest();
return;
}
if (!enable &&
this._usbTetheringAction === TETHERING_STATE_IDLE) {
debug("Usb tethering already disconnected.");
this._requestCount = 0;
this._usbTetheringRequestCount = 0;
this.handlePendingWifiTetheringRequest();
return;
}
@ -1034,16 +1048,21 @@ NetworkManager.prototype = {
debug("setWifiTethering: " + (msg ? msg : "success"));
if (callback) {
callback.wifiTetheringEnabledChange(msg);
// Callback asynchronously to avoid netsted toggling.
Services.tm.currentThread.dispatch(() => {
callback.wifiTetheringEnabledChange(msg);
}, Ci.nsIThread.DISPATCH_NORMAL);
}
},
_wifiTetheringRequestOngoing: false,
enableWifiTethering: function(enable, config, callback) {
// Fill in config's required fields.
config.ifname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
config.internalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
config.externalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface;
this._wifiTetheringRequestOngoing = true;
gNetworkService.setWifiTethering(enable, config, (function(error) {
#ifdef MOZ_B2G_RIL
// Disconnect dun on error or when wifi tethering is disabled.
@ -1053,10 +1072,17 @@ NetworkManager.prototype = {
}
#endif
let resetSettings = error;
debug('gNetworkService.setWifiTethering finished');
this.notifyError(resetSettings, callback, error);
this._wifiTetheringRequestOngoing = false;
if (this._usbTetheringRequestCount > 0) {
debug('Perform pending USB tethering requests.');
this.handleLastUsbTetheringRequest();
}
}).bind(this));
},
_pendingWifiTetheringRequestArgs: null,
// Enable/disable WiFi tethering by sending commands to netd.
setWifiTethering: function(enable, network, config, callback) {
debug("setWifiTethering: " + enable);
@ -1070,6 +1096,16 @@ NetworkManager.prototype = {
return;
}
if (this._usbTetheringRequestCount > 0) {
// If there's still pending usb tethering request, save
// the request params and redo |setWifiTethering| on
// usb tethering task complete.
debug('USB tethering request is being processed. Queue this wifi tethering request.');
this._pendingWifiTetheringRequestArgs = Array.prototype.slice.call(arguments);
debug('Pending args: ' + JSON.stringify(this._pendingWifiTetheringRequestArgs));
return;
}
if (!enable) {
this.enableWifiTethering(false, config, callback);
return;
@ -1143,20 +1179,24 @@ NetworkManager.prototype = {
this._tetheringInterface[TETHERING_TYPE_USB],
this.usbTetheringResultReport.bind(this, enable));
} else {
this.usbTetheringResultReport("Failed to set usb function");
this.usbTetheringResultReport(enable, "enableUsbRndisResult failure");
throw new Error("failed to set USB Function to adb");
}
},
usbTetheringResultReport: function(enable, error) {
this._usbTetheringRequestCount--;
let settingsLock = gSettingsService.createLock();
debug('usbTetheringResultReport callback. enable: ' + enable + ', error: ' + error);
// Disable tethering settings when fail to enable it.
if (error) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
settingsLock.set("tethering.usb.enabled", false, null);
// Skip others request when we found an error.
this._requestCount = 0;
this._usbTetheringRequestCount = 0;
this._usbTetheringAction = TETHERING_STATE_IDLE;
#ifdef MOZ_B2G_RIL
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
@ -1174,7 +1214,8 @@ NetworkManager.prototype = {
}
#endif
}
this.handleLastRequest();
this.handleLastUsbTetheringRequest();
}
},

View File

@ -1,4 +1,4 @@
57239
57240
0/nm
0th/pt
1/n1
@ -22255,6 +22255,7 @@ characterless
charade/SM
charbroil/GDS
charcoal/MS
charcuterie
chard/M
chardonnay/SM
charge/EAMGDS

View File

@ -76,7 +76,7 @@ public:
HRESULT hr = mDT->mDevice->CreateTexture2D(&desc, nullptr, byRef(tmpTexture));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateTexture2D failure " << size << " Code: " << hr;
gfxCriticalError() << "[D2D] CreateTexture2D failure " << size << " Code: " << hexa(hr);
// Crash debug builds but try to recover in release builds.
MOZ_ASSERT(false);
return;
@ -93,7 +93,7 @@ public:
&props, byRef(mOldSurfBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateSharedBitmap failure " << size << " Code: " << hr;
gfxCriticalError() << "[D2D] CreateSharedBitmap failure " << size << " Code: " << hexa(hr);
// Crash debug builds but try to recover in release builds.
MOZ_ASSERT(false);
return;
@ -241,7 +241,7 @@ DrawTargetD2D::Flush()
HRESULT hr = mRT->Flush();
if (FAILED(hr)) {
gfxWarning() << "Error reported when trying to flush D2D rendertarget. Code: " << hr;
gfxWarning() << "Error reported when trying to flush D2D rendertarget. Code: " << hexa(hr);
}
// We no longer depend on any target.
@ -471,7 +471,7 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
HRESULT hr = mDevice->CreateRenderTargetView(mTempTexture, nullptr, byRef(mTempRTView));
if (FAILED(hr)) {
gfxWarning() << "Failure to create RenderTargetView. Code: " << hr;
gfxWarning() << "Failure to create RenderTargetView. Code: " << hexa(hr);
return;
}
}
@ -532,7 +532,7 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(mipTexture));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateTexture2D failure " << aSurface->GetSize() << " Code: " << hr;
gfxCriticalError() << "[D2D] CreateTexture2D failure " << aSurface->GetSize() << " Code: " << hexa(hr);
return;
}
@ -559,7 +559,7 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(tmpDSTexture));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D] CreateTexture2D failure " << dsSize << " Code: " << hr;
gfxCriticalError() << "[D2D] CreateTexture2D failure " << dsSize << " Code: " << hexa(hr);
return;
}
@ -1268,14 +1268,14 @@ DrawTargetD2D::CreatePathBuilder(FillRule aFillRule) const
HRESULT hr = factory()->CreatePathGeometry(byRef(path));
if (FAILED(hr)) {
gfxWarning() << "Failed to create Direct2D Path Geometry. Code: " << hr;
gfxWarning() << "Failed to create Direct2D Path Geometry. Code: " << hexa(hr);
return nullptr;
}
RefPtr<ID2D1GeometrySink> sink;
hr = path->Open(byRef(sink));
if (FAILED(hr)) {
gfxWarning() << "Failed to access Direct2D Path Geometry. Code: " << hr;
gfxWarning() << "Failed to access Direct2D Path Geometry. Code: " << hexa(hr);
return nullptr;
}
@ -1305,7 +1305,7 @@ DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops, E
delete [] stops;
if (FAILED(hr)) {
gfxWarning() << "Failed to create GradientStopCollection. Code: " << hr;
gfxWarning() << "Failed to create GradientStopCollection. Code: " << hexa(hr);
return nullptr;
}
@ -1362,7 +1362,7 @@ DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(mTexture));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hr;
gfxCriticalError() << "Failed to init Direct2D DrawTarget. Size: " << mSize << " Code: " << hexa(hr);
return false;
}
@ -1432,7 +1432,7 @@ DrawTargetD2D::InitD3D10Data()
hr = createD3DEffect((void*)d2deffect, sizeof(d2deffect), 0, mDevice, nullptr, byRef(mPrivateData->mEffect));
if (FAILED(hr)) {
gfxWarning() << "Failed to initialize Direct2D required effects. Code: " << hr;
gfxWarning() << "Failed to initialize Direct2D required effects. Code: " << hexa(hr);
return false;
}
@ -1454,7 +1454,7 @@ DrawTargetD2D::InitD3D10Data()
byRef(mPrivateData->mInputLayout));
if (FAILED(hr)) {
gfxWarning() << "Failed to initialize Direct2D required InputLayout. Code: " << hr;
gfxWarning() << "Failed to initialize Direct2D required InputLayout. Code: " << hexa(hr);
return false;
}
@ -1466,7 +1466,7 @@ DrawTargetD2D::InitD3D10Data()
hr = mDevice->CreateBuffer(&bufferDesc, &data, byRef(mPrivateData->mVB));
if (FAILED(hr)) {
gfxWarning() << "Failed to initialize Direct2D required VertexBuffer. Code: " << hr;
gfxWarning() << "Failed to initialize Direct2D required VertexBuffer. Code: " << hexa(hr);
return false;
}
@ -1771,7 +1771,7 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
mDevice->CopyResource(tmpTexture, mTexture);
if (FAILED(hr)) {
gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hr;
gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hexa(hr);
return;
}
@ -1780,7 +1780,7 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
hr = mDevice->CreateShaderResourceView(tmpTexture, nullptr, byRef(mBckSRView));
if (FAILED(hr)) {
gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hr;
gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hexa(hr);
return;
}
@ -2005,21 +2005,21 @@ DrawTargetD2D::EnsureViews()
if (FAILED(hr)) {
gfxWarning() << *this << "Failed to create temporary texture for rendertarget. Size: "
<< mSize << " Code: " << hr;
<< mSize << " Code: " << hexa(hr);
return;
}
hr = mDevice->CreateShaderResourceView(mTempTexture, nullptr, byRef(mSRView));
if (FAILED(hr)) {
gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hr;
gfxWarning() << *this << "Failed to create shader resource view for temp texture. Code: " << hexa(hr);
return;
}
hr = mDevice->CreateRenderTargetView(mTexture, nullptr, byRef(mRTView));
if (FAILED(hr)) {
gfxWarning() << *this << "Failed to create rendertarget view for temp texture. Code: " << hr;
gfxWarning() << *this << "Failed to create rendertarget view for temp texture. Code: " << hexa(hr);
}
}

View File

@ -620,7 +620,7 @@ DrawTargetD2D1::CreateSourceSurfaceFromData(unsigned char *aData,
byRef(bitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << aSize << " Code: " << hr;
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << aSize << " Code: " << hexa(hr);
}
if (!bitmap) {
@ -649,14 +649,14 @@ DrawTargetD2D1::CreatePathBuilder(FillRule aFillRule) const
HRESULT hr = factory()->CreatePathGeometry(byRef(path));
if (FAILED(hr)) {
gfxWarning() << *this << ": Failed to create Direct2D Path Geometry. Code: " << hr;
gfxWarning() << *this << ": Failed to create Direct2D Path Geometry. Code: " << hexa(hr);
return nullptr;
}
RefPtr<ID2D1GeometrySink> sink;
hr = path->Open(byRef(sink));
if (FAILED(hr)) {
gfxWarning() << *this << ": Failed to access Direct2D Path Geometry. Code: " << hr;
gfxWarning() << *this << ": Failed to access Direct2D Path Geometry. Code: " << hexa(hr);
return nullptr;
}
@ -691,7 +691,7 @@ DrawTargetD2D1::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops,
delete [] stops;
if (FAILED(hr)) {
gfxWarning() << *this << ": Failed to create GradientStopCollection. Code: " << hr;
gfxWarning() << *this << ": Failed to create GradientStopCollection. Code: " << hexa(hr);
return nullptr;
}
@ -712,7 +712,7 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
if (FAILED(hr)) {
gfxWarning() << *this << ": Error " << hr << " failed to initialize new DeviceContext.";
gfxWarning() << *this << ": Error " << hexa(hr) << " failed to initialize new DeviceContext.";
return false;
}
@ -732,7 +732,7 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
hr = mDC->CreateBitmapFromDxgiSurface(dxgiSurface, props, (ID2D1Bitmap1**)byRef(mBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: " << hr;
gfxCriticalError() << "[D2D1.1] CreateBitmapFromDxgiSurface failure Code: " << hexa(hr);
return false;
}
@ -748,7 +748,7 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mTempBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << mSize << " Code: " << hr;
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << mSize << " Code: " << hexa(hr);
return false;
}
@ -766,7 +766,7 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
if (FAILED(hr)) {
gfxWarning() << *this << ": Error " << hr << " failed to initialize new DeviceContext.";
gfxWarning() << *this << ": Error " << hexa(hr) << " failed to initialize new DeviceContext.";
return false;
}
@ -786,7 +786,7 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
mDC->CreateBitmap(D2DIntSize(aSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << *this << ": Error " << hr << " failed to create new CommandList.";
gfxWarning() << *this << ": Error " << hexa(hr) << " failed to create new CommandList.";
return false;
}
@ -1283,7 +1283,7 @@ DrawTargetD2D1::OptimizeSourceSurface(SourceSurface* aSurface) const
byRef(bitmap));
if (FAILED(hr)) {
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << data->GetSize() << " Code: " << hr;
gfxCriticalError() << "[D2D1.1] CreateBitmap failure " << data->GetSize() << " Code: " << hexa(hr);
}
data->Unmap();

View File

@ -535,7 +535,7 @@ FilterNodeD2D1::Create(DrawTarget* aDT, ID2D1DeviceContext *aDC, FilterType aTyp
hr = aDC->CreateEffect(GetCLDIDForFilterType(aType), byRef(effect));
if (FAILED(hr)) {
gfxWarning() << "Failed to create effect for FilterType: " << hr;
gfxWarning() << "Failed to create effect for FilterType: " << hexa(hr);
return nullptr;
}

View File

@ -10,7 +10,9 @@
#include <sstream>
#include <stdio.h>
#if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
#include "nsDebug.h"
#endif
#include "Point.h"
#include "BaseRect.h"
#include "Matrix.h"
@ -69,7 +71,11 @@ struct BasicLogger
}
#else
if (aLevel >= sGfxLogLevel) {
#if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
printf_stderr("%s", aString.c_str());
#else
printf("%s", aString.c_str());
#endif
}
#endif
}
@ -101,6 +107,14 @@ MOZ_BEGIN_ENUM_CLASS(LogOptions, int)
NoNewline = 0x01
MOZ_END_ENUM_CLASS(LogOptions)
template<typename T>
struct Hexa {
Hexa(T aVal) : mVal(aVal) {}
T mVal;
};
template<typename T>
Hexa<T> hexa(T val) { return Hexa<T>(val); }
template<int L, typename Logger = BasicLogger>
class Log
{
@ -145,7 +159,9 @@ public:
{ mMessage << "Rect" << aRect; return *this; }
Log &operator<<(const Matrix& aMatrix)
{ mMessage << "Matrix(" << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << ")"; return *this; }
template<typename T>
Log &operator<<(Hexa<T> aHex)
{ mMessage << "0x" << std::hex << aHex.mVal << std::dec; return *this; }
private:

View File

@ -299,7 +299,7 @@ PathBuilderD2D::Finish()
HRESULT hr = mSink->Close();
if (FAILED(hr)) {
gfxDebug() << "Failed to close PathSink. Code: " << hr;
gfxDebug() << "Failed to close PathSink. Code: " << hexa(hr);
return nullptr;
}
@ -319,14 +319,14 @@ PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule)
HRESULT hr = DrawTargetD2D::factory()->CreatePathGeometry(byRef(path));
if (FAILED(hr)) {
gfxWarning() << "Failed to create PathGeometry. Code: " << hr;
gfxWarning() << "Failed to create PathGeometry. Code: " << hexa(hr);
return nullptr;
}
RefPtr<ID2D1GeometrySink> sink;
hr = path->Open(byRef(sink));
if (FAILED(hr)) {
gfxWarning() << "Failed to open Geometry for writing. Code: " << hr;
gfxWarning() << "Failed to open Geometry for writing. Code: " << hexa(hr);
return nullptr;
}
@ -367,7 +367,7 @@ PathD2D::StreamToSink(PathSink *aSink) const
D2D1::IdentityMatrix(), &sink);
if (FAILED(hr)) {
gfxWarning() << "Failed to stream D2D path to sink. Code: " << hr;
gfxWarning() << "Failed to stream D2D path to sink. Code: " << hexa(hr);
return;
}
}
@ -418,7 +418,7 @@ PathD2D::GetBounds(const Matrix &aTransform) const
Rect bounds = ToRect(d2dBounds);
if (FAILED(hr) || !bounds.IsFinite()) {
gfxWarning() << "Failed to get stroked bounds for path. Code: " << hr;
gfxWarning() << "Failed to get stroked bounds for path. Code: " << hexa(hr);
return Rect();
}
@ -438,7 +438,7 @@ PathD2D::GetStrokedBounds(const StrokeOptions &aStrokeOptions,
Rect bounds = ToRect(d2dBounds);
if (FAILED(hr) || !bounds.IsFinite()) {
gfxWarning() << "Failed to get stroked bounds for path. Code: " << hr;
gfxWarning() << "Failed to get stroked bounds for path. Code: " << hexa(hr);
return Rect();
}

View File

@ -382,7 +382,7 @@ RadialGradientEffectD2D1::CreateGradientTexture()
HRESULT hr = mEffectContext->CreateResourceTexture(nullptr, &props, &textureData.front(), &stride, 4096 * 4, byRef(tex));
if (FAILED(hr)) {
gfxWarning() << "Failed to create resource texture: " << hr;
gfxWarning() << "Failed to create resource texture: " << hexa(hr);
}
return tex.forget();

View File

@ -72,14 +72,14 @@ SourceSurfaceD2D::InitFromData(unsigned char *aData,
hr = aRT->CreateBitmap(D2DIntSize(aSize), props, byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr;
gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hexa(hr);
return false;
}
hr = mBitmap->CopyFromMemory(nullptr, aData, aStride);
if (FAILED(hr)) {
gfxWarning() << "Failed to copy data to D2D bitmap. Code: " << hr;
gfxWarning() << "Failed to copy data to D2D bitmap. Code: " << hexa(hr);
return false;
}
@ -101,7 +101,7 @@ SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
hr = aTexture->QueryInterface((IDXGISurface**)&surf);
if (FAILED(hr)) {
gfxWarning() << "Failed to QI texture to surface. Code: " << hr;
gfxWarning() << "Failed to QI texture to surface. Code: " << hexa(hr);
return false;
}
@ -115,7 +115,7 @@ SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create SharedBitmap. Code: " << hr;
gfxWarning() << "Failed to create SharedBitmap. Code: " << hexa(hr);
return false;
}
@ -150,14 +150,14 @@ DataSourceSurfaceD2D::DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface)
HRESULT hr = aSourceSurface->mDevice->CreateTexture2D(&desc, nullptr,
byRef(sourceTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create texture. Code: " << hr;
gfxWarning() << "Failed to create texture. Code: " << hexa(hr);
return;
}
RefPtr<IDXGISurface> dxgiSurface;
hr = sourceTexture->QueryInterface((IDXGISurface**)byRef(dxgiSurface));
if (FAILED(hr)) {
gfxWarning() << "Failed to create DXGI surface. Code: " << hr;
gfxWarning() << "Failed to create DXGI surface. Code: " << hexa(hr);
return;
}
@ -170,7 +170,7 @@ DataSourceSurfaceD2D::DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface)
&rtProps,
byRef(renderTarget));
if (FAILED(hr)) {
gfxWarning() << "Failed to create render target. Code: " << hr;
gfxWarning() << "Failed to create render target. Code: " << hexa(hr);
return;
}
@ -189,7 +189,7 @@ DataSourceSurfaceD2D::DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface)
}
hr = renderTarget->EndDraw();
if (FAILED(hr)) {
gfxWarning() << "Failed to draw bitmap. Code: " << hr;
gfxWarning() << "Failed to draw bitmap. Code: " << hexa(hr);
return;
}
@ -198,7 +198,7 @@ DataSourceSurfaceD2D::DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface)
desc.BindFlags = 0;
hr = aSourceSurface->mDevice->CreateTexture2D(&desc, nullptr, byRef(mTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create staging texture. Code: " << hr;
gfxWarning() << "Failed to create staging texture. Code: " << hexa(hr);
mTexture = nullptr;
return;
}
@ -273,7 +273,7 @@ DataSourceSurfaceD2D::Map(MapType aMapType, MappedSurface *aMappedSurface)
HRESULT hr = mTexture->Map(0, mapType, 0, &map);
if (FAILED(hr)) {
gfxWarning() << "Texture map failed with code: " << hr;
gfxWarning() << "Texture map failed with code: " << hexa(hr);
return false;
}
@ -306,7 +306,7 @@ DataSourceSurfaceD2D::EnsureMappedTexture()
HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mData);
if (FAILED(hr)) {
gfxWarning() << "Failed to map texture. Code: " << hr;
gfxWarning() << "Failed to map texture. Code: " << hexa(hr);
mTexture = nullptr;
} else {
mMapped = true;

View File

@ -67,7 +67,7 @@ SourceSurfaceD2DTarget::GetDataSurface()
HRESULT hr = Factory::GetDirect3D10Device()->CreateTexture2D(&desc, nullptr, byRef(dataSurf->mTexture));
if (FAILED(hr)) {
gfxDebug() << "Failed to create staging texture for SourceSurface. Code: " << hr;
gfxDebug() << "Failed to create staging texture for SourceSurface. Code: " << hexa(hr);
return nullptr;
}
Factory::GetDirect3D10Device()->CopyResource(dataSurf->mTexture, mTexture);
@ -94,7 +94,7 @@ SourceSurfaceD2DTarget::GetSRView()
HRESULT hr = Factory::GetDirect3D10Device()->CreateShaderResourceView(mTexture, nullptr, byRef(mSRView));
if (FAILED(hr)) {
gfxWarning() << "Failed to create ShaderResourceView. Code: " << hr;
gfxWarning() << "Failed to create ShaderResourceView. Code: " << hexa(hr);
}
return mSRView;
@ -143,7 +143,7 @@ SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
hr = mTexture->QueryInterface((IDXGISurface**)byRef(surf));
if (FAILED(hr)) {
gfxWarning() << "Failed to query interface texture to DXGISurface. Code: " << hr;
gfxWarning() << "Failed to query interface texture to DXGISurface. Code: " << hexa(hr);
return nullptr;
}
@ -157,7 +157,7 @@ SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed in CreateBitmap. Code: " << hr;
gfxWarning() << "Failed in CreateBitmap. Code: " << hexa(hr);
return nullptr;
}
@ -276,7 +276,7 @@ DataSourceSurfaceD2DTarget::Map(MapType aMapType, MappedSurface *aMappedSurface)
HRESULT hr = mTexture->Map(0, mapType, 0, &map);
if (FAILED(hr)) {
gfxWarning() << "Texture map failed with code: " << hr;
gfxWarning() << "Texture map failed with code: " << hexa(hr);
return false;
}
@ -304,7 +304,7 @@ DataSourceSurfaceD2DTarget::EnsureMapped()
if (!mMapped) {
HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mMap);
if (FAILED(hr)) {
gfxWarning() << "Failed to map texture to memory. Code: " << hr;
gfxWarning() << "Failed to map texture to memory. Code: " << hexa(hr);
return;
}
mMapped = true;

View File

@ -288,7 +288,7 @@ TextureClientD3D11::Unlock()
HRESULT hr = device->CreateTexture2D(&desc, nullptr, byRef(tex));
if (FAILED(hr)) {
gfx::gfxCriticalError() << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << hr;
gfx::gfxCriticalError() << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
return;
}
@ -375,7 +375,7 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
}
if (FAILED(hr)) {
gfx::gfxCriticalError() << "[D3D11] CreateTexture2D failure " << aSize << " Code: " << hr;
gfx::gfxCriticalError() << "[D3D11] CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
return false;
}

View File

@ -19,32 +19,6 @@
#include "js/CallArgs.h"
#include "js/TypeDecls.h"
class JSAtom;
struct JSFreeOp;
namespace js {
class InterpreterFrame;
class FrameIter;
class ScriptSource;
}
namespace JS {
extern JS_PUBLIC_API(char *)
FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps);
} // namespace JS
# ifdef JS_DEBUG
JS_FRIEND_API(void) js_DumpValue(const JS::Value &val);
JS_FRIEND_API(void) js_DumpId(jsid id);
JS_FRIEND_API(void) js_DumpInterpreterFrame(JSContext *cx, js::InterpreterFrame *start = nullptr);
# endif
JS_FRIEND_API(void)
js_DumpBacktrace(JSContext *cx);
typedef enum JSTrapStatus {
JSTRAP_ERROR,
JSTRAP_CONTINUE,
@ -53,23 +27,11 @@ typedef enum JSTrapStatus {
JSTRAP_LIMIT
} JSTrapStatus;
extern JS_PUBLIC_API(JSString *)
JS_DecompileScript(JSContext *cx, JS::HandleScript script, const char *name, unsigned indent);
/************************************************************************/
// Raw JSScript* because this needs to be callable from a signal handler.
extern JS_PUBLIC_API(unsigned)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
extern JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, unsigned lineno);
extern JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JS::HandleFunction fun);
/************************************************************************/
extern JS_PUBLIC_API(const char *)
@ -81,26 +43,4 @@ JS_GetScriptSourceMap(JSContext *cx, JSScript *script);
extern JS_PUBLIC_API(unsigned)
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
extern JS_PUBLIC_API(unsigned)
JS_GetScriptLineExtent(JSContext *cx, JSScript *script);
/************************************************************************/
/**
* Add various profiling-related functions as properties of the given object.
*/
extern JS_PUBLIC_API(bool)
JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj);
/* Defined in vm/Debugger.cpp. */
extern JS_PUBLIC_API(bool)
JS_DefineDebuggerObject(JSContext *cx, JS::HandleObject obj);
extern JS_PUBLIC_API(void)
JS_DumpPCCounts(JSContext *cx, JS::HandleScript script);
extern JS_PUBLIC_API(void)
JS_DumpCompartmentPCCounts(JSContext *cx);
#endif /* js_OldDebugAPI_h */

View File

@ -419,10 +419,8 @@ static const JSFunctionSpec profiling_functions[] = {
#endif
JS_PUBLIC_API(bool)
JS_DefineProfilingFunctions(JSContext *cx, JSObject *objArg)
JS_DefineProfilingFunctions(JSContext *cx, HandleObject obj)
{
RootedObject obj(cx, objArg);
assertSameCompartment(cx, obj);
#ifdef MOZ_PROFILING
return JS_DefineFunctions(cx, obj, profiling_functions);

View File

@ -870,6 +870,25 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
// Stolen from jsmath.cpp
static const uint64_t RNG_MULTIPLIER = 0x5DEECE66DLL;
static const uint64_t RNG_MASK = (1LL << 48) - 1;
static bool
SetSavedStacksRNGState(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.requireAtLeast(cx, "setSavedStacksRNGState", 1))
return false;
int32_t seed;
if (!ToInt32(cx, args[0], &seed))
return false;
cx->compartment()->savedStacks().setRNGState((seed ^ RNG_MULTIPLIER) & RNG_MASK);
return true;
}
static bool
GetSavedFrameCount(JSContext *cx, unsigned argc, jsval *vp)
{
@ -2057,6 +2076,10 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
" then you can provide an extra argument with some specific traceable\n"
" thing to count.\n"),
JS_FN_HELP("setSavedStacksRNGState", SetSavedStacksRNGState, 1, 0,
"setSavedStacksRNGState(seed)",
" Set this compartment's SavedStacks' RNG state.\n"),
JS_FN_HELP("getSavedFrameCount", GetSavedFrameCount, 0, 0,
"getSavedFrameCount()",
" Return the number of SavedFrame instances stored in this compartment's\n"

View File

@ -1320,7 +1320,7 @@ NativeRegExpMacroAssembler::CheckSpecialCharacterClass(char16_t type, Label* on_
bool
NativeRegExpMacroAssembler::CanReadUnaligned()
{
#if defined(JS_CODEGEN_MIPS)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
return false;
#else
return true;

View File

@ -0,0 +1,21 @@
// Test that setting Debugger.Memory.prototype.allocationSamplingProbability to
// a bad number throws.
load(libdir + "asserts.js");
const root = newGlobal();
const dbg = new Debugger();
const wrappedRoot = dbg.addDebuggee(root);
// Out of range.
assertThrowsInstanceOf(() => dbg.memory.allocationSamplingProbability = -1,
TypeError);
assertThrowsInstanceOf(() => dbg.memory.allocationSamplingProbability = 2,
TypeError);
// In range
dbg.memory.allocationSamplingProbability = 0;
dbg.memory.allocationSamplingProbability = 1;
dbg.memory.allocationSamplingProbability = .5;

View File

@ -0,0 +1,36 @@
// Test that we only sample about allocationSamplingProbability * 100 percent of
// allocations.
const root = newGlobal();
const dbg = new Debugger();
const wrappedRoot = dbg.addDebuggee(root);
root.eval(`
objs = [];
objs.push(new Object);
`);
root.eval("" + function makeSomeAllocations() {
for (var i = 0; i < 100; i++) {
objs.push(new Object);
}
});
function measure(P, expected) {
root.setSavedStacksRNGState(Number.MAX_SAFE_INTEGER - 1);
dbg.memory.allocationSamplingProbability = P;
root.makeSomeAllocations();
assertEq(dbg.memory.drainAllocationsLog().length, expected);
}
dbg.memory.trackingAllocationSites = true;
// These are the sample counts that were correct when this test was last
// updated; changes to SpiderMonkey may occasionally cause changes
// here. Anything that is within a plausible range for the given sampling
// probability is fine.
measure(0.0, 0);
measure(1.0, 100);
measure(0.1, 9);
measure(0.5, 51);

View File

@ -379,6 +379,33 @@ struct BaselineStackBuilder
}
};
// Ensure that all value locations are readable from the SnapshotIterator.
// Remove RInstructionResults from the JitActivation if the frame got recovered
// ahead of the bailout.
class SnapshotIteratorForBailout : public SnapshotIterator
{
RInstructionResults results_;
public:
SnapshotIteratorForBailout(const IonBailoutIterator &iter)
: SnapshotIterator(iter),
results_()
{
}
// Take previously computed result out of the activation, or compute the
// results of all recover instructions contained in the snapshot.
bool init(JSContext *cx, JitActivation *activation) {
activation->maybeTakeIonFrameRecovery(fp_, &results_);
if (!results_.isInitialized() && !computeInstructionResults(cx, &results_))
return false;
MOZ_ASSERT(results_.isInitialized());
instructionResults_ = &results_;
return true;
}
};
static inline bool
IsInlinableFallback(ICFallbackStub *icEntry)
{
@ -1343,10 +1370,8 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIt
return BAILOUT_RETURN_FATAL_ERROR;
JitSpew(JitSpew_BaselineBailouts, " Incoming frame ptr = %p", builder.startFrame());
AutoValueVector instructionResults(cx);
SnapshotIterator snapIter(iter);
if (!snapIter.initIntructionResults(instructionResults))
SnapshotIteratorForBailout snapIter(iter);
if (!snapIter.init(cx, activation))
return BAILOUT_RETURN_FATAL_ERROR;
#ifdef TRACK_SNAPSHOTS
@ -1380,12 +1405,8 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIt
jsbytecode *topCallerPC = nullptr;
while (true) {
if (!snapIter.instruction()->isResumePoint()) {
if (!snapIter.instruction()->recover(cx, snapIter))
return BAILOUT_RETURN_FATAL_ERROR;
snapIter.nextInstruction();
continue;
}
// Skip recover instructions as they are already recovered by |initInstructionResults|.
snapIter.settleOnFrame();
if (frameNo > 0) {
TraceLogStartEvent(logger, TraceLogCreateTextId(logger, scr));

View File

@ -444,6 +444,16 @@ class CompileInfo
// would have to be executed and that they cannot be removed even if they
// are unused.
bool isObservableSlot(uint32_t slot) const {
if (isObservableFrameSlot(slot))
return true;
if (isObservableArgumentSlot(slot))
return true;
return false;
}
bool isObservableFrameSlot(uint32_t slot) const {
if (!funMaybeLazy())
return false;
@ -458,6 +468,13 @@ class CompileInfo
if (hasArguments() && (slot == scopeChainSlot() || slot == argsObjSlot()))
return true;
return false;
}
bool isObservableArgumentSlot(uint32_t slot) const {
if (!funMaybeLazy())
return false;
// Function.arguments can be used to access all arguments in non-strict
// scripts, so we can't optimize out any arguments.
if ((hasArguments() || !script()->strict()) &&
@ -469,6 +486,19 @@ class CompileInfo
return false;
}
// Returns true if a slot can be recovered before or during a bailout. A
// definition which can be observed and recovered, implies that this
// definition can be optimized away as long as we can compute its values.
bool isRecoverableOperand(uint32_t slot) const {
if (isObservableFrameSlot(slot))
return false;
if (needsArgsObj() && isObservableArgumentSlot(slot))
return false;
return true;
}
private:
unsigned nimplicit_;
unsigned nargs_;

View File

@ -2904,6 +2904,17 @@ jit::Invalidate(JSContext *cx, const Vector<types::RecompileInfo> &invalid, bool
cancelOffThread);
}
bool
jit::IonScript::invalidate(JSContext *cx, bool resetUses, const char *reason)
{
JitSpew(JitSpew_IonInvalidate, " Invalidate IonScript %p: %s", this, reason);
Vector<types::RecompileInfo> list(cx);
if (!list.append(recompileInfo()))
return false;
Invalidate(cx, list, resetUses, true);
return true;
}
bool
jit::Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetUses,
bool cancelOffThread)

View File

@ -582,6 +582,10 @@ struct IonScript
bool invalidated() const {
return refcount_ != 0;
}
// Invalidate the current compilation.
bool invalidate(JSContext *cx, bool resetUses, const char *reason);
size_t refcount() const {
return refcount_;
}

View File

@ -1284,6 +1284,7 @@ MarkJitActivation(JSTracer *trc, const JitActivationIterator &activations)
#endif
activation->markRematerializedFrames(trc);
activation->markIonRecovery(trc);
for (JitFrameIterator frames(activations); !frames.done(); ++frames) {
switch (frames.type()) {
@ -1436,6 +1437,79 @@ OsiIndex::returnPointDisplacement() const
return callPointDisplacement_ + Assembler::PatchWrite_NearCallSize();
}
RInstructionResults::RInstructionResults()
: results_(nullptr),
fp_(nullptr)
{
}
RInstructionResults::RInstructionResults(RInstructionResults&& src)
: results_(mozilla::Move(src.results_)),
fp_(src.fp_)
{
src.fp_ = nullptr;
}
RInstructionResults&
RInstructionResults::operator=(RInstructionResults&& rhs)
{
MOZ_ASSERT(&rhs != this, "self-moves are prohibited");
this->~RInstructionResults();
new(this) RInstructionResults(mozilla::Move(rhs));
return *this;
}
RInstructionResults::~RInstructionResults()
{
// results_ is freed by the UniquePtr.
}
bool
RInstructionResults::init(JSContext *cx, uint32_t numResults, IonJSFrameLayout *fp)
{
if (numResults) {
results_ = cx->make_unique<Values>();
if (!results_ || !results_->growBy(numResults))
return false;
Value guard = MagicValue(JS_ION_BAILOUT);
for (size_t i = 0; i < numResults; i++)
(*results_)[i].init(guard);
}
fp_ = fp;
return true;
}
bool
RInstructionResults::isInitialized() const
{
MOZ_ASSERT_IF(results_, fp_);
return fp_;
}
IonJSFrameLayout *
RInstructionResults::frame() const
{
MOZ_ASSERT(isInitialized());
return fp_;
}
RelocatableValue&
RInstructionResults::operator [](size_t index)
{
return (*results_)[index];
}
void
RInstructionResults::trace(JSTracer *trc)
{
// Note: The vector necessary exists, otherwise this object would not have
// been stored on the activation from where the trace function is called.
gc::MarkValueRange(trc, results_->length(), results_->begin(), "ion-recover-results");
}
SnapshotIterator::SnapshotIterator(IonScript *ionScript, SnapshotOffset snapshotOffset,
IonJSFrameLayout *fp, const MachineState &machine)
: snapshot_(ionScript->snapshots(),
@ -1699,24 +1773,91 @@ SnapshotIterator::skipInstruction()
}
bool
SnapshotIterator::initIntructionResults(AutoValueVector &results)
SnapshotIterator::initInstructionResults(MaybeReadFallback &fallback)
{
MOZ_ASSERT(recover_.numInstructionsRead() == 1);
MOZ_ASSERT(fallback.canRecoverResults());
JSContext *cx = fallback.maybeCx;
// The last instruction will always be a resume point, no need to allocate
// space for it.
// If there is only one resume point in the list of instructions, then there
// is no instruction to recover, and thus no need to register any results.
if (recover_.numInstructions() == 1)
return true;
MOZ_ASSERT(recover_.numInstructions() > 1);
IonJSFrameLayout *fp = fallback.frame->jsFrame();
RInstructionResults *results = fallback.activation->maybeIonFrameRecovery(fp);
if (!results) {
// We do not have the result yet, which means that an observable stack
// slot is requested. As we do not want to bailout every time for the
// same reason, we need to recompile without optimizing away the
// observable stack slots. The script would later be recompiled to have
// support for Argument objects.
if (!ionScript_->invalidate(cx, /* resetUses = */ false, "Observe recovered instruction."))
return false;
// Register the list of result on the activation. We need to do that
// before we initialize the list such as if any recover instruction
// cause a GC, we can ensure that the results are properly traced by the
// activation.
RInstructionResults tmp;
if (!fallback.activation->registerIonFrameRecovery(fallback.frame->jsFrame(),
mozilla::Move(tmp)))
return false;
results = fallback.activation->maybeIonFrameRecovery(fp);
// Start a new snapshot at the beginning of the JitFrameIterator. This
// SnapshotIterator is used for evaluating the content of all recover
// instructions. The result is then saved on the JitActivation.
SnapshotIterator s(*fallback.frame);
if (!s.computeInstructionResults(cx, results)) {
// If the evaluation failed because of OOMs, then we discard the
// current set of result that we collected so far.
fallback.activation->maybeTakeIonFrameRecovery(fp, &tmp);
return false;
}
}
MOZ_ASSERT(results->isInitialized());
instructionResults_ = results;
return true;
}
bool
SnapshotIterator::computeInstructionResults(JSContext *cx, RInstructionResults *results) const
{
MOZ_ASSERT(!results->isInitialized());
MOZ_ASSERT(recover_.numInstructionsRead() == 1);
// The last instruction will always be a resume point.
size_t numResults = recover_.numInstructions() - 1;
if (!results.reserve(numResults))
return false;
if (!results->isInitialized()) {
if (!results->init(cx, numResults, fp_))
return false;
for (size_t i = 0; i < numResults; i++)
results.infallibleAppend(MagicValue(JS_ION_BAILOUT));
// No need to iterate over the only resume point.
if (!numResults) {
MOZ_ASSERT(results->isInitialized());
return true;
}
instructionResults_ = &results;
// Fill with the results of recover instructions.
SnapshotIterator s(*this);
s.instructionResults_ = results;
while (s.moreInstructions()) {
// Skip resume point and only interpret recover instructions.
if (s.instruction()->isResumePoint()) {
s.skipInstruction();
continue;
}
if (!s.instruction()->recover(cx, s))
return false;
s.nextInstruction();
}
}
MOZ_ASSERT(results->isInitialized());
return true;
}
@ -1725,7 +1866,7 @@ SnapshotIterator::storeInstructionResult(Value v)
{
uint32_t currIns = recover_.numInstructionsRead() - 1;
MOZ_ASSERT((*instructionResults_)[currIns].isMagic(JS_ION_BAILOUT));
(*instructionResults_)[currIns].set(v);
(*instructionResults_)[currIns] = v;
}
Value
@ -1751,6 +1892,28 @@ SnapshotIterator::nextFrame()
settleOnFrame();
}
Value
SnapshotIterator::maybeReadAllocByIndex(size_t index)
{
while (index--) {
JS_ASSERT(moreAllocations());
skip();
}
Value s;
{
// This MaybeReadFallback method cannot GC.
JS::AutoSuppressGCAnalysis nogc;
MaybeReadFallback fallback(UndefinedValue());
s = maybeRead(fallback);
}
while (moreAllocations())
skip();
return s;
}
IonScript *
JitFrameIterator::ionScript() const
{
@ -2124,6 +2287,7 @@ InlineFrameIterator::dump() const
}
SnapshotIterator si = snapshotIterator();
MaybeReadFallback fallback(UndefinedValue());
fprintf(stderr, " slots: %u\n", si.numAllocations() - 1);
for (unsigned i = 0; i < si.numAllocations() - 1; i++) {
if (isFunction) {
@ -2136,7 +2300,7 @@ InlineFrameIterator::dump() const
else {
if (i - 2 == callee()->nargs() && numActualArgs() > callee()->nargs()) {
DumpOp d(callee()->nargs());
unaliasedForEachActual(GetJSContextFromJitCode(), d, ReadFrame_Overflown);
unaliasedForEachActual(GetJSContextFromJitCode(), d, ReadFrame_Overflown, fallback);
}
fprintf(stderr, " slot %d: ", int(i - 2 - callee()->nargs()));
@ -2144,7 +2308,7 @@ InlineFrameIterator::dump() const
} else
fprintf(stderr, " slot %u: ", i);
#ifdef DEBUG
js_DumpValue(si.maybeRead());
js_DumpValue(si.maybeRead(fallback));
#else
fprintf(stderr, "?\n");
#endif

View File

@ -266,7 +266,77 @@ class JitFrameIterator
#endif
};
class IonJSFrameLayout;
class RInstructionResults
{
// Vector of results of recover instructions.
typedef mozilla::Vector<RelocatableValue, 1, SystemAllocPolicy> Values;
mozilla::UniquePtr<Values, JS::DeletePolicy<Values> > results_;
// The frame pointer is used as a key to check if the current frame already
// bailed out.
IonJSFrameLayout *fp_;
public:
RInstructionResults();
RInstructionResults(RInstructionResults&& src);
RInstructionResults& operator=(RInstructionResults&& rhs);
~RInstructionResults();
bool init(JSContext *cx, uint32_t numResults, IonJSFrameLayout *fp);
bool isInitialized() const;
IonJSFrameLayout *frame() const;
RelocatableValue& operator[](size_t index);
void trace(JSTracer *trc);
};
struct MaybeReadFallback
{
enum NoGCValue {
NoGC_UndefinedValue,
NoGC_MagicOptimizedOut
};
JSContext *maybeCx;
JitActivation *activation;
JitFrameIterator *frame;
const NoGCValue unreadablePlaceholder_;
MaybeReadFallback(const Value &placeholder = UndefinedValue())
: maybeCx(nullptr),
activation(nullptr),
frame(nullptr),
unreadablePlaceholder_(noGCPlaceholder(placeholder))
{
}
MaybeReadFallback(JSContext *cx, JitActivation *activation, JitFrameIterator *frame)
: maybeCx(cx),
activation(activation),
frame(frame),
unreadablePlaceholder_(NoGC_UndefinedValue)
{
}
bool canRecoverResults() { return maybeCx; }
Value unreadablePlaceholder() const {
if (unreadablePlaceholder_ == NoGC_MagicOptimizedOut)
return MagicValue(JS_OPTIMIZED_OUT);
return UndefinedValue();
}
NoGCValue noGCPlaceholder(Value v) const {
if (v.isMagic(JS_OPTIMIZED_OUT))
return NoGC_MagicOptimizedOut;
return NoGC_UndefinedValue;
}
};
class RResumePoint;
@ -274,12 +344,13 @@ class RResumePoint;
// to innermost frame).
class SnapshotIterator
{
protected:
SnapshotReader snapshot_;
RecoverReader recover_;
IonJSFrameLayout *fp_;
MachineState machine_;
IonScript *ionScript_;
AutoValueVector *instructionResults_;
RInstructionResults *instructionResults_;
private:
// Read a spilled register from the machine state.
@ -335,6 +406,10 @@ class SnapshotIterator
int32_t readOuterNumActualArgs() const;
// Used by recover instruction to store the value back into the instruction
// results array.
void storeInstructionResult(Value v);
public:
// Exhibits frame properties contained in the snapshot.
uint32_t pcOffset() const;
@ -367,13 +442,16 @@ class SnapshotIterator
return recover_.moreInstructions();
}
protected:
// Register a vector used for storing the results of the evaluation of
// recover instructions. This vector should be registered before the
// beginning of the iteration. This function is in charge of allocating
// enough space for all instructions results, and return false iff it fails.
bool initIntructionResults(AutoValueVector &results);
bool initInstructionResults(MaybeReadFallback &fallback);
void storeInstructionResult(Value v);
// This function is used internally for computing the result of the recover
// instructions.
bool computeInstructionResults(JSContext *cx, RInstructionResults *results) const;
public:
// Handle iterating over frames of the snapshots.
@ -399,13 +477,23 @@ class SnapshotIterator
Value read() {
return allocationValue(readAllocation());
}
Value maybeRead(const Value &placeholder = UndefinedValue(), bool silentFailure = false) {
Value maybeRead(MaybeReadFallback &fallback) {
RValueAllocation a = readAllocation();
if (allocationReadable(a))
return allocationValue(a);
if (!silentFailure)
warnUnreadableAllocation();
return placeholder;
if (fallback.canRecoverResults()) {
if (!initInstructionResults(fallback))
return fallback.unreadablePlaceholder();
if (allocationReadable(a))
return allocationValue(a);
MOZ_ASSERT_UNREACHABLE("All allocations should be readable.");
}
return fallback.unreadablePlaceholder();
}
void readCommonFrameSlots(Value *scopeChain, Value *rval) {
@ -423,8 +511,7 @@ class SnapshotIterator
template <class Op>
void readFunctionFrameArgs(Op &op, ArgumentsObject **argsObj, Value *thisv,
unsigned start, unsigned end, JSScript *script,
const Value &unreadablePlaceholder = UndefinedValue(),
bool silentFailure = false)
MaybeReadFallback &fallback)
{
// Assumes that the common frame arguments have already been read.
if (script->argumentsHasVarBinding()) {
@ -452,24 +539,14 @@ class SnapshotIterator
// We are not always able to read values from the snapshots, some values
// such as non-gc things may still be live in registers and cause an
// error while reading the machine state.
Value v = maybeRead(unreadablePlaceholder, silentFailure);
Value v = maybeRead(fallback);
op(v);
}
}
Value maybeReadAllocByIndex(size_t index) {
while (index--) {
JS_ASSERT(moreAllocations());
skip();
}
Value s = maybeRead(/* placeholder = */ UndefinedValue(), true);
while (moreAllocations())
skip();
return s;
}
// Iterate over all the allocations and return only the value of the
// allocation located at one index.
Value maybeReadAllocByIndex(size_t index);
#ifdef TRACK_SNAPSHOTS
void spewBailingFrom() const {
@ -540,8 +617,7 @@ class InlineFrameIterator
JSObject **scopeChain, Value *rval,
ArgumentsObject **argsObj, Value *thisv,
ReadFrameArgsBehavior behavior,
const Value &unreadablePlaceholder = UndefinedValue(),
bool silentFailure = false) const
MaybeReadFallback &fallback) const
{
SnapshotIterator s(si_);
@ -560,10 +636,8 @@ class InlineFrameIterator
// Get the non overflown arguments, which are taken from the inlined
// frame, because it will have the updated value when JSOP_SETARG is
// done.
if (behavior != ReadFrame_Overflown) {
s.readFunctionFrameArgs(argOp, argsObj, thisv, 0, nformal, script(),
unreadablePlaceholder, silentFailure);
}
if (behavior != ReadFrame_Overflown)
s.readFunctionFrameArgs(argOp, argsObj, thisv, 0, nformal, script(), fallback);
if (behavior != ReadFrame_Formals) {
if (more()) {
@ -592,7 +666,7 @@ class InlineFrameIterator
parent_s.readCommonFrameSlots(nullptr, nullptr);
parent_s.readFunctionFrameArgs(argOp, nullptr, nullptr,
nformal, nactual, it.script(),
unreadablePlaceholder, silentFailure);
fallback);
} else {
// There is no parent frame to this inlined frame, we can read
// from the frame's Value vector directly.
@ -611,16 +685,17 @@ class InlineFrameIterator
// recovering slots.
//
// FIXME bug 1029963.
localOp(s.maybeRead(unreadablePlaceholder, silentFailure));
localOp(s.maybeRead(fallback));
}
}
template <class Op>
void unaliasedForEachActual(ThreadSafeContext *cx, Op op,
ReadFrameArgsBehavior behavior) const
ReadFrameArgsBehavior behavior,
MaybeReadFallback &fallback) const
{
Nop nop;
readFrameArgsAndLocals(cx, op, nop, nullptr, nullptr, nullptr, nullptr, behavior);
readFrameArgsAndLocals(cx, op, nop, nullptr, nullptr, nullptr, nullptr, behavior, fallback);
}
JSScript *script() const {

View File

@ -501,7 +501,7 @@ MDefinition::hasLiveDefUses() const
return true;
} else {
MOZ_ASSERT(ins->isResumePoint());
if (ins->toResumePoint()->isObservableOperand(*i))
if (!ins->toResumePoint()->isRecoverableOperand(*i))
return true;
}
}
@ -2708,6 +2708,12 @@ MResumePoint::isObservableOperand(size_t index) const
return block()->info().isObservableSlot(index);
}
bool
MResumePoint::isRecoverableOperand(MUse *u) const
{
return block()->info().isRecoverableOperand(indexOf(u));
}
MDefinition *
MToInt32::foldsTo(TempAllocator &alloc)
{

View File

@ -10796,6 +10796,7 @@ class MResumePoint MOZ_FINAL :
bool isObservableOperand(MUse *u) const;
bool isObservableOperand(size_t index) const;
bool isRecoverableOperand(MUse *u) const;
MDefinition *getOperand(size_t index) const {
return operands_[index].producer();

View File

@ -38,9 +38,10 @@ RematerializedFrame::RematerializedFrame(ThreadSafeContext *cx, uint8_t *top,
script_(iter.script())
{
CopyValueToRematerializedFrame op(slots_);
MaybeReadFallback fallback(MagicValue(JS_OPTIMIZED_OUT));
iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &returnValue_,
&argsObj_, &thisValue_, ReadFrame_Actuals,
MagicValue(JS_OPTIMIZED_OUT), /* silentFailure = */ true);
fallback);
}
/* static */ RematerializedFrame *

View File

@ -146,8 +146,8 @@ IsObjectEscaped(MInstruction *ins)
MNode *consumer = (*i)->consumer();
if (!consumer->isDefinition()) {
// Cannot optimize if it is observable from fun.arguments or others.
if (consumer->toResumePoint()->isObservableOperand(*i)) {
JitSpewDef(JitSpew_Escape, "Object is observable\n", ins);
if (!consumer->toResumePoint()->isRecoverableOperand(*i)) {
JitSpewDef(JitSpew_Escape, "Observable object cannot be recovered\n", ins);
return true;
}
continue;
@ -525,8 +525,8 @@ IsArrayEscaped(MInstruction *ins)
MNode *consumer = (*i)->consumer();
if (!consumer->isDefinition()) {
// Cannot optimize if it is observable from fun.arguments or others.
if (consumer->toResumePoint()->isObservableOperand(*i)) {
JitSpewDef(JitSpew_Escape, "Array is observable\n", ins);
if (!consumer->toResumePoint()->isRecoverableOperand(*i)) {
JitSpewDef(JitSpew_Escape, "Observable array cannot be recovered\n", ins);
return true;
}
continue;

View File

@ -2527,7 +2527,7 @@ Simulator::decodeType01(SimInstruction *instr)
int32_t value = get_register(rt);
switch (instr->bits(22,21)) {
case 0:
writeW(address, rt, instr);
writeW(address, value, instr);
break;
case 1: {
MOZ_ASSERT((rt % 2) == 0);

View File

@ -22,7 +22,6 @@ catch (e) \n\
}\n\
//@ sourceMappingURL=http://example.com/path/to/source-map.json";
// Bug 670958 - fix JS_GetScriptLineExtent, among others
BEGIN_TEST(testScriptInfo)
{
unsigned startLine = 1000;
@ -33,9 +32,7 @@ BEGIN_TEST(testScriptInfo)
CHECK(JS_CompileScript(cx, global, code, strlen(code), options, &script));
CHECK(script);
jsbytecode *start = JS_LineNumberToPC(cx, script, startLine);
CHECK_EQUAL(JS_GetScriptBaseLineNumber(cx, script), startLine);
CHECK_EQUAL(JS_PCToLineNumber(cx, script, start), startLine);
CHECK(strcmp(JS_GetScriptFilename(script), __FILE__) == 0);
const char16_t *sourceMap = JS_GetScriptSourceMap(cx, script);
CHECK(sourceMap);

View File

@ -1814,6 +1814,17 @@ CurrentGlobalOrNull(JSContext *cx);
extern JS_PUBLIC_API(JSObject *)
JS_InitReflect(JSContext *cx, JS::HandleObject global);
/*
* Add various profiling-related functions as properties of the given object.
* Defined in builtin/Profilers.cpp.
*/
extern JS_PUBLIC_API(bool)
JS_DefineProfilingFunctions(JSContext *cx, JS::HandleObject obj);
/* Defined in vm/Debugger.cpp. */
extern JS_PUBLIC_API(bool)
JS_DefineDebuggerObject(JSContext *cx, JS::HandleObject obj);
#ifdef JS_HAS_CTYPES
/*
* Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'

View File

@ -14,6 +14,7 @@
#include "jscompartment.h"
#include "jsgc.h"
#include "jsobj.h"
#include "jsprf.h"
#include "jsproxy.h"
#include "jswatchpoint.h"
#include "jsweakmap.h"
@ -22,6 +23,7 @@
#include "builtin/TestingFunctions.h"
#include "proxy/DeadObjectProxy.h"
#include "vm/ArgumentsObject.h"
#include "vm/WrapperObject.h"
#include "jsobjinlines.h"
@ -601,6 +603,12 @@ JS_GetCustomIteratorCount(JSContext *cx)
return sCustomIteratorCount;
}
JS_FRIEND_API(unsigned)
JS_PCToLineNumber(JSScript *script, jsbytecode *pc)
{
return PCToLineNumber(script, pc);
}
JS_FRIEND_API(bool)
JS_IsDeadWrapper(JSObject *obj)
{
@ -710,6 +718,219 @@ js_DumpObject(JSObject *obj)
#endif
static const char *
FormatValue(JSContext *cx, const Value &vArg, JSAutoByteString &bytes)
{
RootedValue v(cx, vArg);
/*
* We could use Maybe<AutoCompartment> here, but G++ can't quite follow
* that, and warns about uninitialized members being used in the
* destructor.
*/
RootedString str(cx);
if (v.isObject()) {
AutoCompartment ac(cx, &v.toObject());
str = ToString<CanGC>(cx, v);
} else {
str = ToString<CanGC>(cx, v);
}
if (!str)
return nullptr;
const char *buf = bytes.encodeLatin1(cx, str);
if (!buf)
return nullptr;
const char *found = strstr(buf, "function ");
if (found && (found - buf <= 2))
return "[function]";
return buf;
}
static char *
FormatFrame(JSContext *cx, const NonBuiltinScriptFrameIter &iter, char *buf, int num,
bool showArgs, bool showLocals, bool showThisProps)
{
JS_ASSERT(!cx->isExceptionPending());
RootedScript script(cx, iter.script());
jsbytecode* pc = iter.pc();
RootedObject scopeChain(cx, iter.scopeChain());
JSAutoCompartment ac(cx, scopeChain);
const char *filename = script->filename();
unsigned lineno = PCToLineNumber(script, pc);
RootedFunction fun(cx, iter.maybeCallee());
RootedString funname(cx);
if (fun)
funname = fun->atom();
RootedValue thisVal(cx);
if (iter.hasUsableAbstractFramePtr() && iter.computeThis(cx)) {
thisVal = iter.computedThisValue();
}
// print the frame number and function name
if (funname) {
JSAutoByteString funbytes;
buf = JS_sprintf_append(buf, "%d %s(", num, funbytes.encodeLatin1(cx, funname));
} else if (fun) {
buf = JS_sprintf_append(buf, "%d anonymous(", num);
} else {
buf = JS_sprintf_append(buf, "%d <TOP LEVEL>", num);
}
if (!buf)
return buf;
if (showArgs && iter.hasArgs()) {
BindingVector bindings(cx);
if (fun && fun->isInterpreted()) {
if (!FillBindingVector(script, &bindings))
return buf;
}
bool first = true;
for (unsigned i = 0; i < iter.numActualArgs(); i++) {
RootedValue arg(cx);
if (i < iter.numFormalArgs() && script->formalIsAliased(i)) {
for (AliasedFormalIter fi(script); ; fi++) {
if (fi.frameIndex() == i) {
arg = iter.callObj().aliasedVar(fi);
break;
}
}
} else if (script->argsObjAliasesFormals() && iter.hasArgsObj()) {
arg = iter.argsObj().arg(i);
} else {
arg = iter.unaliasedActual(i, DONT_CHECK_ALIASING);
}
JSAutoByteString valueBytes;
const char *value = FormatValue(cx, arg, valueBytes);
JSAutoByteString nameBytes;
const char *name = nullptr;
if (i < bindings.length()) {
name = nameBytes.encodeLatin1(cx, bindings[i].name());
if (!buf)
return nullptr;
}
if (value) {
buf = JS_sprintf_append(buf, "%s%s%s%s%s%s",
!first ? ", " : "",
name ? name :"",
name ? " = " : "",
arg.isString() ? "\"" : "",
value ? value : "?unknown?",
arg.isString() ? "\"" : "");
if (!buf)
return buf;
first = false;
} else {
buf = JS_sprintf_append(buf, " <Failed to get argument while inspecting stack frame>\n");
if (!buf)
return buf;
cx->clearPendingException();
}
}
}
// print filename and line number
buf = JS_sprintf_append(buf, "%s [\"%s\":%d]\n",
fun ? ")" : "",
filename ? filename : "<unknown>",
lineno);
if (!buf)
return buf;
// Note: Right now we don't dump the local variables anymore, because
// that is hard to support across all the JITs etc.
// print the value of 'this'
if (showLocals) {
if (!thisVal.isUndefined()) {
JSAutoByteString thisValBytes;
RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal));
const char *str = nullptr;
if (thisValStr &&
(str = thisValBytes.encodeLatin1(cx, thisValStr)))
{
buf = JS_sprintf_append(buf, " this = %s\n", str);
if (!buf)
return buf;
} else {
buf = JS_sprintf_append(buf, " <failed to get 'this' value>\n");
cx->clearPendingException();
}
}
}
if (showThisProps && thisVal.isObject()) {
RootedObject obj(cx, &thisVal.toObject());
AutoIdVector keys(cx);
if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &keys)) {
cx->clearPendingException();
return buf;
}
RootedId id(cx);
for (size_t i = 0; i < keys.length(); i++) {
RootedId id(cx, keys[i]);
RootedValue key(cx, IdToValue(id));
RootedValue v(cx);
if (!JSObject::getGeneric(cx, obj, obj, id, &v)) {
buf = JS_sprintf_append(buf, " <Failed to fetch property while inspecting stack frame>\n");
cx->clearPendingException();
continue;
}
JSAutoByteString nameBytes;
JSAutoByteString valueBytes;
const char *name = FormatValue(cx, key, nameBytes);
const char *value = FormatValue(cx, v, valueBytes);
if (name && value) {
buf = JS_sprintf_append(buf, " this.%s = %s%s%s\n",
name,
v.isString() ? "\"" : "",
value,
v.isString() ? "\"" : "");
if (!buf)
return buf;
} else {
buf = JS_sprintf_append(buf, " <Failed to format values while inspecting stack frame>\n");
cx->clearPendingException();
}
}
}
JS_ASSERT(!cx->isExceptionPending());
return buf;
}
JS_FRIEND_API(char *)
JS::FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps)
{
int num = 0;
for (NonBuiltinScriptFrameIter i(cx); !i.done(); ++i) {
buf = FormatFrame(cx, i, buf, num, showArgs, showLocals, showThisProps);
num++;
}
if (!num)
buf = JS_sprintf_append(buf, "JavaScript stack is empty\n");
return buf;
}
struct DumpHeapTracer : public JSTracer
{
FILE *output;

View File

@ -54,6 +54,7 @@ class Heap;
namespace js {
class JS_FRIEND_API(BaseProxyHandler);
class InterpreterFrame;
} /* namespace js */
extern JS_FRIEND_API(void)
@ -87,6 +88,10 @@ JS_GetCustomIteratorCount(JSContext *cx);
extern JS_FRIEND_API(bool)
JS_NondeterministicGetWeakMapKeys(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject ret);
// Raw JSScript* because this needs to be callable from a signal handler.
extern JS_FRIEND_API(unsigned)
JS_PCToLineNumber(JSScript *script, jsbytecode *pc);
/*
* Determine whether the given object is backed by a DeadObjectProxy.
*
@ -194,8 +199,29 @@ js_DumpObject(JSObject *obj);
extern JS_FRIEND_API(void)
js_DumpChars(const char16_t *s, size_t n);
extern JS_FRIEND_API(void)
js_DumpValue(const JS::Value &val);
extern JS_FRIEND_API(void)
js_DumpId(jsid id);
extern JS_FRIEND_API(void)
js_DumpInterpreterFrame(JSContext *cx, js::InterpreterFrame *start = nullptr);
#endif
extern JS_FRIEND_API(void)
js_DumpBacktrace(JSContext *cx);
namespace JS {
// Exposed for DumpJSStack
extern JS_FRIEND_API(char *)
FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps);
} // namespace JS
/*
* Copies all own properties from |obj| to |target|. |obj| must be a "native"
* object (that is to say, normal-ish - not an Array or a Proxy).

View File

@ -742,6 +742,9 @@ random_generateSeed()
* do, so just mix in the fd error code and the current time.
*/
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
perror("FITZGEN: error opening /dev/urandom: ");
}
MOZ_ASSERT(fd >= 0, "Can't open /dev/urandom");
if (fd >= 0) {
(void)read(fd, seed.u8, mozilla::ArrayLength(seed.u8));

View File

@ -6486,7 +6486,7 @@ js_DumpBacktrace(JSContext *cx)
size_t depth = 0;
for (ScriptFrameIter i(cx); !i.done(); ++i, ++depth) {
const char *filename = JS_GetScriptFilename(i.script());
unsigned line = JS_PCToLineNumber(cx, i.script(), i.pc());
unsigned line = PCToLineNumber(i.script(), i.pc());
JSScript *script = i.script();
sprinter.printf("#%d %14p %s:%d (%p @ %d)\n",
depth, (i.isJit() ? 0 : i.interpFrame()), filename, line,

View File

@ -28,6 +28,7 @@
#include "jstypes.h"
#include "jsutil.h"
#include "asmjs/AsmJSModule.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/SourceNotes.h"
#include "js/CharacterEncoding.h"
@ -276,6 +277,53 @@ js_DumpPCCounts(JSContext *cx, HandleScript script, js::Sprinter *sp)
}
}
void
js::DumpCompartmentPCCounts(JSContext *cx)
{
for (ZoneCellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
RootedScript script(cx, i.get<JSScript>());
if (script->compartment() != cx->compartment())
continue;
if (script->hasScriptCounts()) {
Sprinter sprinter(cx);
if (!sprinter.init())
return;
fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename(), (int) script->lineno());
js_DumpPCCounts(cx, script, &sprinter);
fputs(sprinter.string(), stdout);
fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename(), (int) script->lineno());
}
}
for (unsigned thingKind = FINALIZE_OBJECT0; thingKind < FINALIZE_OBJECT_LIMIT; thingKind++) {
for (ZoneCellIter i(cx->zone(), (AllocKind) thingKind); !i.done(); i.next()) {
JSObject *obj = i.get<JSObject>();
if (obj->compartment() != cx->compartment())
continue;
if (obj->is<AsmJSModuleObject>()) {
AsmJSModule &module = obj->as<AsmJSModuleObject>().module();
Sprinter sprinter(cx);
if (!sprinter.init())
return;
fprintf(stdout, "--- Asm.js Module ---\n");
for (size_t i = 0; i < module.numFunctionCounts(); i++) {
jit::IonScriptCounts *counts = module.functionCounts(i);
DumpIonScriptCounts(&sprinter, counts);
}
fputs(sprinter.string(), stdout);
fprintf(stdout, "--- END Asm.js Module ---\n");
}
}
}
}
/////////////////////////////////////////////////////////////////////
// Bytecode Parser
/////////////////////////////////////////////////////////////////////
@ -892,7 +940,7 @@ js_Disassemble1(JSContext *cx, HandleScript script, jsbytecode *pc,
ptrdiff_t len = (ptrdiff_t) cs->length;
Sprint(sp, "%05u:", loc);
if (lines)
Sprint(sp, "%4u", JS_PCToLineNumber(cx, script, pc));
Sprint(sp, "%4u", PCToLineNumber(script, pc));
Sprint(sp, " %s", js_CodeName[op]);
switch (JOF_TYPE(cs->format)) {

View File

@ -839,6 +839,9 @@ namespace js {
namespace jit { struct IonScriptCounts; }
void
DumpIonScriptCounts(js::Sprinter *sp, jit::IonScriptCounts *ionCounts);
void
DumpCompartmentPCCounts(JSContext *cx);
}
#endif /* jsopcode_h */

View File

@ -1788,7 +1788,7 @@ LineToPC(JSContext *cx, unsigned argc, jsval *vp)
if (!ToUint32(cx, args.get(lineArg), &lineno))
return false;
jsbytecode *pc = JS_LineNumberToPC(cx, script, lineno);
jsbytecode *pc = js_LineNumberToPC(script, lineno);
if (!pc)
return false;
args.rval().setInt32(script->pcToOffset(pc));
@ -1805,7 +1805,7 @@ PCToLine(JSContext *cx, unsigned argc, jsval *vp)
if (!GetScriptAndPCArgs(cx, args.length(), args.array(), &script, &i))
return false;
lineno = JS_PCToLineNumber(cx, script, script->offsetToPC(i));
lineno = PCToLineNumber(script, script->offsetToPC(i));
if (!lineno)
return false;
args.rval().setInt32(lineno);
@ -2234,7 +2234,7 @@ DisassWithSrc(JSContext *cx, unsigned argc, jsval *vp)
}
/* burn the leading lines */
line2 = JS_PCToLineNumber(cx, script, pc);
line2 = PCToLineNumber(script, pc);
for (line1 = 0; line1 < line2 - 1; line1++) {
char *tmp = fgets(linebuf, LINE_BUF_LEN, file);
if (!tmp) {
@ -2246,7 +2246,7 @@ DisassWithSrc(JSContext *cx, unsigned argc, jsval *vp)
bupline = 0;
while (pc < end) {
line2 = JS_PCToLineNumber(cx, script, pc);
line2 = PCToLineNumber(script, pc);
if (line2 < line1) {
if (bupline != line2) {
@ -2678,7 +2678,7 @@ EvalInFrame(JSContext *cx, unsigned argc, jsval *vp)
{
AutoCompartment ac(cx, env);
ok = EvaluateInEnv(cx, env, thisv, frame, stableChars.twoByteRange(), fpscript->filename(),
JS_PCToLineNumber(cx, fpscript, fi.pc()), args.rval());
PCToLineNumber(fpscript, fi.pc()), args.rval());
}
return ok;
}
@ -5821,7 +5821,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
int result = ProcessArgs(cx, glob, op);
if (enableDisassemblyDumps)
JS_DumpCompartmentPCCounts(cx);
js::DumpCompartmentPCCounts(cx);
if (!op->getBoolOption("no-js-cache-per-process")) {
if (jsCacheAsmJSPath) {

View File

@ -193,8 +193,8 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
if (!data)
return nullptr;
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp),
shape, type);
RootedObject obj(cx);
obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp), shape, type);
if (!obj) {
js_free(data);
return nullptr;
@ -204,15 +204,21 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
data->callee.init(ObjectValue(*callee.get()));
data->script = script;
/* Copy [0, numArgs) into data->slots. */
// Initialize with dummy UndefinedValue, and attach it to the argument
// object such as the GC can trace ArgumentsData as they are recovered.
HeapValue *dst = data->args, *dstEnd = data->args + numArgs;
for (HeapValue *iter = dst; iter != dstEnd; iter++)
iter->init(UndefinedValue());
obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
/* Copy [0, numArgs) into data->slots. */
copy.copyArgs(cx, dst, numArgs);
data->deletedBits = reinterpret_cast<size_t *>(dstEnd);
ClearAllBitArrayElements(data->deletedBits, numDeletedWords);
obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT));
obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
copy.maybeForwardToCallObject(obj, data);

View File

@ -343,9 +343,18 @@ Breakpoint::nextInSite()
/*** Debugger hook dispatch **********************************************************************/
Debugger::Debugger(JSContext *cx, JSObject *dbg)
: object(dbg), uncaughtExceptionHook(nullptr), enabled(true), trackingAllocationSites(false),
allocationsLogLength(0), maxAllocationsLogLength(DEFAULT_MAX_ALLOCATIONS_LOG_LENGTH),
frames(cx->runtime()), scripts(cx), sources(cx), objects(cx), environments(cx)
: object(dbg),
uncaughtExceptionHook(nullptr),
enabled(true),
trackingAllocationSites(false),
allocationSamplingProbability(1.0),
allocationsLogLength(0),
maxAllocationsLogLength(DEFAULT_MAX_ALLOCATIONS_LOG_LENGTH),
frames(cx->runtime()),
scripts(cx),
sources(cx),
objects(cx),
environments(cx)
{
assertSameCompartment(cx, dbg);
@ -3296,7 +3305,7 @@ DebuggerScript_getOffsetLine(JSContext *cx, unsigned argc, Value *vp)
size_t offset;
if (!ScriptOffset(cx, script, args[0], &offset))
return false;
unsigned lineno = JS_PCToLineNumber(cx, script, script->offsetToPC(offset));
unsigned lineno = PCToLineNumber(script, script->offsetToPC(offset));
args.rval().setNumber(lineno);
return true;
}

View File

@ -165,6 +165,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
{
friend class Breakpoint;
friend class DebuggerMemory;
friend class SavedStacks;
friend class mozilla::LinkedListElement<Debugger>;
friend bool (::JS_DefineDebuggerObject)(JSContext *cx, JS::HandleObject obj);
friend bool SavedStacksMetadataCallback(JSContext *cx, JSObject **pmetadata);
@ -209,6 +210,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
typedef mozilla::LinkedList<AllocationSite> AllocationSiteList;
bool trackingAllocationSites;
double allocationSamplingProbability;
AllocationSiteList allocationsLog;
size_t allocationsLogLength;
size_t maxAllocationsLogLength;

View File

@ -246,6 +246,36 @@ DebuggerMemory::setMaxAllocationsLogLength(JSContext *cx, unsigned argc, Value *
return true;
}
/* static */ bool
DebuggerMemory::getAllocationSamplingProbability(JSContext *cx, unsigned argc, Value *vp)
{
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get allocationSamplingProbability)", args, memory);
args.rval().setDouble(memory->getDebugger()->allocationSamplingProbability);
return true;
}
/* static */ bool
DebuggerMemory::setAllocationSamplingProbability(JSContext *cx, unsigned argc, Value *vp)
{
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set allocationSamplingProbability)", args, memory);
if (!args.requireAtLeast(cx, "(set allocationSamplingProbability)", 1))
return false;
double probability;
if (!ToNumber(cx, args[0], &probability))
return false;
if (probability < 0.0 || probability > 1.0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
"(set allocationSamplingProbability)'s parameter",
"not a number between 0 and 1");
return false;
}
memory->getDebugger()->allocationSamplingProbability = probability;
args.rval().setUndefined();
return true;
}
/* Debugger.Memory.prototype.takeCensus */
@ -751,6 +781,7 @@ DebuggerMemory::takeCensus(JSContext *cx, unsigned argc, Value *vp)
/* static */ const JSPropertySpec DebuggerMemory::properties[] = {
JS_PSGS("trackingAllocationSites", getTrackingAllocationSites, setTrackingAllocationSites, 0),
JS_PSGS("maxAllocationsLogLength", getMaxAllocationsLogLength, setMaxAllocationsLogLength, 0),
JS_PSGS("allocationSamplingProbability", getAllocationSamplingProbability, setAllocationSamplingProbability, 0),
JS_PS_END
};

View File

@ -40,6 +40,8 @@ class DebuggerMemory : public JSObject {
static bool getTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp);
static bool setMaxAllocationsLogLength(JSContext*cx, unsigned argc, Value *vp);
static bool getMaxAllocationsLogLength(JSContext*cx, unsigned argc, Value *vp);
static bool setAllocationSamplingProbability(JSContext*cx, unsigned argc, Value *vp);
static bool getAllocationSamplingProbability(JSContext*cx, unsigned argc, Value *vp);
// Function properties of Debugger.Memory.prototype.
static bool takeCensus(JSContext *cx, unsigned argc, Value *vp);

View File

@ -22,7 +22,6 @@
#include "jsstr.h"
#include "jstypes.h"
#include "asmjs/AsmJSModule.h"
#include "frontend/SourceNotes.h"
#include "vm/Debugger.h"
#include "vm/Shape.h"
@ -110,18 +109,6 @@ js::DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
/************************************************************************/
JS_PUBLIC_API(unsigned)
JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
{
return js::PCToLineNumber(script, pc);
}
JS_PUBLIC_API(jsbytecode *)
JS_LineNumberToPC(JSContext *cx, JSScript *script, unsigned lineno)
{
return js_LineNumberToPC(script, lineno);
}
JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, HandleFunction fun)
{
@ -158,272 +145,3 @@ JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
{
return script->lineno();
}
/***************************************************************************/
extern JS_PUBLIC_API(void)
JS_DumpPCCounts(JSContext *cx, HandleScript script)
{
JS_ASSERT(script->hasScriptCounts());
Sprinter sprinter(cx);
if (!sprinter.init())
return;
fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename(), (int) script->lineno());
js_DumpPCCounts(cx, script, &sprinter);
fputs(sprinter.string(), stdout);
fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename(), (int) script->lineno());
}
JS_PUBLIC_API(void)
JS_DumpCompartmentPCCounts(JSContext *cx)
{
for (ZoneCellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
RootedScript script(cx, i.get<JSScript>());
if (script->compartment() != cx->compartment())
continue;
if (script->hasScriptCounts())
JS_DumpPCCounts(cx, script);
}
for (unsigned thingKind = FINALIZE_OBJECT0; thingKind < FINALIZE_OBJECT_LIMIT; thingKind++) {
for (ZoneCellIter i(cx->zone(), (AllocKind) thingKind); !i.done(); i.next()) {
JSObject *obj = i.get<JSObject>();
if (obj->compartment() != cx->compartment())
continue;
if (obj->is<AsmJSModuleObject>()) {
AsmJSModule &module = obj->as<AsmJSModuleObject>().module();
Sprinter sprinter(cx);
if (!sprinter.init())
return;
fprintf(stdout, "--- Asm.js Module ---\n");
for (size_t i = 0; i < module.numFunctionCounts(); i++) {
jit::IonScriptCounts *counts = module.functionCounts(i);
DumpIonScriptCounts(&sprinter, counts);
}
fputs(sprinter.string(), stdout);
fprintf(stdout, "--- END Asm.js Module ---\n");
}
}
}
}
static const char *
FormatValue(JSContext *cx, const Value &vArg, JSAutoByteString &bytes)
{
RootedValue v(cx, vArg);
/*
* We could use Maybe<AutoCompartment> here, but G++ can't quite follow
* that, and warns about uninitialized members being used in the
* destructor.
*/
RootedString str(cx);
if (v.isObject()) {
AutoCompartment ac(cx, &v.toObject());
str = ToString<CanGC>(cx, v);
} else {
str = ToString<CanGC>(cx, v);
}
if (!str)
return nullptr;
const char *buf = bytes.encodeLatin1(cx, str);
if (!buf)
return nullptr;
const char *found = strstr(buf, "function ");
if (found && (found - buf <= 2))
return "[function]";
return buf;
}
static char *
FormatFrame(JSContext *cx, const NonBuiltinScriptFrameIter &iter, char *buf, int num,
bool showArgs, bool showLocals, bool showThisProps)
{
JS_ASSERT(!cx->isExceptionPending());
RootedScript script(cx, iter.script());
jsbytecode* pc = iter.pc();
RootedObject scopeChain(cx, iter.scopeChain());
JSAutoCompartment ac(cx, scopeChain);
const char *filename = script->filename();
unsigned lineno = PCToLineNumber(script, pc);
RootedFunction fun(cx, iter.maybeCallee());
RootedString funname(cx);
if (fun)
funname = fun->atom();
RootedValue thisVal(cx);
if (iter.hasUsableAbstractFramePtr() && iter.computeThis(cx)) {
thisVal = iter.computedThisValue();
}
// print the frame number and function name
if (funname) {
JSAutoByteString funbytes;
buf = JS_sprintf_append(buf, "%d %s(", num, funbytes.encodeLatin1(cx, funname));
} else if (fun) {
buf = JS_sprintf_append(buf, "%d anonymous(", num);
} else {
buf = JS_sprintf_append(buf, "%d <TOP LEVEL>", num);
}
if (!buf)
return buf;
if (showArgs && iter.hasArgs()) {
BindingVector bindings(cx);
if (fun && fun->isInterpreted()) {
if (!FillBindingVector(script, &bindings))
return buf;
}
bool first = true;
for (unsigned i = 0; i < iter.numActualArgs(); i++) {
RootedValue arg(cx);
if (i < iter.numFormalArgs() && script->formalIsAliased(i)) {
for (AliasedFormalIter fi(script); ; fi++) {
if (fi.frameIndex() == i) {
arg = iter.callObj().aliasedVar(fi);
break;
}
}
} else if (script->argsObjAliasesFormals() && iter.hasArgsObj()) {
arg = iter.argsObj().arg(i);
} else {
arg = iter.unaliasedActual(i, DONT_CHECK_ALIASING);
}
JSAutoByteString valueBytes;
const char *value = FormatValue(cx, arg, valueBytes);
JSAutoByteString nameBytes;
const char *name = nullptr;
if (i < bindings.length()) {
name = nameBytes.encodeLatin1(cx, bindings[i].name());
if (!buf)
return nullptr;
}
if (value) {
buf = JS_sprintf_append(buf, "%s%s%s%s%s%s",
!first ? ", " : "",
name ? name :"",
name ? " = " : "",
arg.isString() ? "\"" : "",
value ? value : "?unknown?",
arg.isString() ? "\"" : "");
if (!buf)
return buf;
first = false;
} else {
buf = JS_sprintf_append(buf, " <Failed to get argument while inspecting stack frame>\n");
if (!buf)
return buf;
cx->clearPendingException();
}
}
}
// print filename and line number
buf = JS_sprintf_append(buf, "%s [\"%s\":%d]\n",
fun ? ")" : "",
filename ? filename : "<unknown>",
lineno);
if (!buf)
return buf;
// Note: Right now we don't dump the local variables anymore, because
// that is hard to support across all the JITs etc.
// print the value of 'this'
if (showLocals) {
if (!thisVal.isUndefined()) {
JSAutoByteString thisValBytes;
RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal));
const char *str = nullptr;
if (thisValStr &&
(str = thisValBytes.encodeLatin1(cx, thisValStr)))
{
buf = JS_sprintf_append(buf, " this = %s\n", str);
if (!buf)
return buf;
} else {
buf = JS_sprintf_append(buf, " <failed to get 'this' value>\n");
cx->clearPendingException();
}
}
}
if (showThisProps && thisVal.isObject()) {
RootedObject obj(cx, &thisVal.toObject());
AutoIdVector keys(cx);
if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &keys)) {
cx->clearPendingException();
return buf;
}
RootedId id(cx);
for (size_t i = 0; i < keys.length(); i++) {
RootedId id(cx, keys[i]);
RootedValue key(cx, IdToValue(id));
RootedValue v(cx);
if (!JSObject::getGeneric(cx, obj, obj, id, &v)) {
buf = JS_sprintf_append(buf, " <Failed to fetch property while inspecting stack frame>\n");
cx->clearPendingException();
continue;
}
JSAutoByteString nameBytes;
JSAutoByteString valueBytes;
const char *name = FormatValue(cx, key, nameBytes);
const char *value = FormatValue(cx, v, valueBytes);
if (name && value) {
buf = JS_sprintf_append(buf, " this.%s = %s%s%s\n",
name,
v.isString() ? "\"" : "",
value,
v.isString() ? "\"" : "");
if (!buf)
return buf;
} else {
buf = JS_sprintf_append(buf, " <Failed to format values while inspecting stack frame>\n");
cx->clearPendingException();
}
}
}
JS_ASSERT(!cx->isExceptionPending());
return buf;
}
JS_PUBLIC_API(char *)
JS::FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps)
{
int num = 0;
for (NonBuiltinScriptFrameIter i(cx); !i.done(); ++i) {
buf = FormatFrame(cx, i, buf, num, showArgs, showLocals, showThisProps);
num++;
}
if (!num)
buf = JS_sprintf_append(buf, "JavaScript stack is empty\n");
return buf;
}

View File

@ -9,10 +9,13 @@
#include "mozilla/Attributes.h"
#include <math.h>
#include "jsapi.h"
#include "jscompartment.h"
#include "jsfriendapi.h"
#include "jshashutil.h"
#include "jsmath.h"
#include "jsnum.h"
#include "gc/Marking.h"
@ -703,6 +706,31 @@ SavedStacks::getLocation(JSContext *cx, const FrameIter &iter, MutableHandleLoca
return true;
}
void
SavedStacks::chooseSamplingProbability(JSContext *cx)
{
GlobalObject::DebuggerVector *dbgs = cx->global()->getDebuggers();
if (!dbgs || dbgs->empty())
return;
Debugger *allocationTrackingDbg = nullptr;
mozilla::DebugOnly<Debugger **> begin = dbgs->begin();
for (Debugger **dbgp = dbgs->begin(); dbgp < dbgs->end(); dbgp++) {
// The set of debuggers had better not change while we're iterating,
// such that the vector gets reallocated.
JS_ASSERT(dbgs->begin() == begin);
if ((*dbgp)->trackingAllocationSites && (*dbgp)->enabled)
allocationTrackingDbg = *dbgp;
}
if (!allocationTrackingDbg)
return;
allocationSamplingProbability = allocationTrackingDbg->allocationSamplingProbability;
}
SavedStacks::FrameState::FrameState(const FrameIter &iter)
: principals(iter.compartment()->principals),
name(iter.isNonEvalFunctionFrame() ? iter.functionDisplayAtom() : nullptr),
@ -736,8 +764,43 @@ SavedStacks::FrameState::trace(JSTracer *trc) {
bool
SavedStacksMetadataCallback(JSContext *cx, JSObject **pmetadata)
{
SavedStacks &stacks = cx->compartment()->savedStacks();
if (stacks.allocationSkipCount > 0) {
stacks.allocationSkipCount--;
return true;
}
stacks.chooseSamplingProbability(cx);
if (stacks.allocationSamplingProbability == 0.0)
return true;
// If the sampling probability is set to 1.0, we are always taking a sample
// and can therefore leave allocationSkipCount at 0.
if (stacks.allocationSamplingProbability != 1.0) {
// Rather than generating a random number on every allocation to decide
// if we want to sample that particular allocation (which would be
// expensive), we calculate the number of allocations to skip before
// taking the next sample.
//
// P = the probability we sample any given event.
//
// ~P = 1-P, the probability we don't sample a given event.
//
// (~P)^n = the probability that we skip at least the next n events.
//
// let X = random between 0 and 1.
//
// floor(log base ~P of X) = n, aka the number of events we should skip
// until we take the next sample. Any value for X less than (~P)^n
// yields a skip count greater than n, so the likelihood of a skip count
// greater than n is (~P)^n, as required.
double notSamplingProb = 1.0 - stacks.allocationSamplingProbability;
stacks.allocationSkipCount = std::floor(std::log(random_nextDouble(&stacks.rngState)) /
std::log(notSamplingProb));
}
RootedSavedFrame frame(cx);
if (!cx->compartment()->savedStacks().saveCurrentStack(cx, &frame))
if (!stacks.saveCurrentStack(cx, &frame))
return false;
*pmetadata = frame;

View File

@ -8,6 +8,7 @@
#define vm_SavedStacks_h
#include "jscntxt.h"
#include "jsmath.h"
#include "js/HashTable.h"
#include "vm/Stack.h"
@ -100,8 +101,20 @@ struct SavedFrame::HashPolicy
};
class SavedStacks {
friend bool SavedStacksMetadataCallback(JSContext *cx, JSObject **pmetadata);
public:
SavedStacks() : frames(), savedFrameProto(nullptr) { }
SavedStacks()
: frames(),
savedFrameProto(nullptr),
allocationSamplingProbability(1.0),
allocationSkipCount(0),
// XXX: Initialize the RNG state to 0 so that random_initSeed is lazily
// called for us on the first call to random_next (via
// random_nextDouble). We need to do this here because /dev/urandom
// doesn't exist on Android, resulting in assertion failures.
rngState(0)
{ }
bool init();
bool initialized() const { return frames.initialized(); }
@ -110,12 +123,16 @@ class SavedStacks {
void trace(JSTracer *trc);
uint32_t count();
void clear();
void setRNGState(uint64_t state) { rngState = state; }
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
private:
SavedFrame::Set frames;
SavedFrame::Set frames;
ReadBarrieredObject savedFrameProto;
double allocationSamplingProbability;
uint32_t allocationSkipCount;
uint64_t rngState;
bool insertFrames(JSContext *cx, FrameIter &iter, MutableHandleSavedFrame frame,
unsigned maxFrameCount = 0);
@ -124,6 +141,7 @@ class SavedStacks {
// be accessed through this method.
JSObject *getOrCreateSavedFramePrototype(JSContext *cx);
SavedFrame *createFrameFromLookup(JSContext *cx, SavedFrame::HandleLookup lookup);
void chooseSamplingProbability(JSContext* cx);
// Cache for memoizing PCToLineNumber lookups.

Some files were not shown because too many files have changed in this diff Show More