mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team a=merge
This commit is contained in:
commit
25d3579892
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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',
|
||||
|
59
accessible/xpcom/xpcAccessibleApplication.cpp
Normal file
59
accessible/xpcom/xpcAccessibleApplication.cpp
Normal 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;
|
||||
}
|
36
accessible/xpcom/xpcAccessibleApplication.h
Normal file
36
accessible/xpcom/xpcAccessibleApplication.h
Normal 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
|
135
accessible/xpcom/xpcAccessibleDocument.cpp
Normal file
135
accessible/xpcom/xpcAccessibleDocument.cpp
Normal 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;
|
||||
}
|
42
accessible/xpcom/xpcAccessibleDocument.h
Normal file
42
accessible/xpcom/xpcAccessibleDocument.h
Normal 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
|
44
accessible/xpcom/xpcAccessibleImage.cpp
Normal file
44
accessible/xpcom/xpcAccessibleImage.cpp
Normal 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;
|
||||
}
|
34
accessible/xpcom/xpcAccessibleImage.h
Normal file
34
accessible/xpcom/xpcAccessibleImage.h
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "6890cdf5807b0c9a4341b97ee39fd692dc95fd0c",
|
||||
"revision": "aa27f131a40f855892c6ed638e05b6d0ef92aece",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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'
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
||||
|
1
config/external/nss/nss.def
vendored
1
config/external/nss/nss.def
vendored
@ -670,3 +670,4 @@ VFY_End
|
||||
VFY_Update
|
||||
VFY_VerifyDataDirect
|
||||
VFY_VerifyDataWithAlgorithmID
|
||||
_SGN_VerifyPKCS1DigestInfo
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
},
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -4622,6 +4622,7 @@ CanvasPath::AddPath(CanvasPath& aCanvasPath, const Optional<NonNull<SVGMatrix>>&
|
||||
}
|
||||
}
|
||||
|
||||
EnsurePathBuilder(); // in case a path is added to itself
|
||||
tempPath->StreamToSink(mPathBuilder);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
},
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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;
|
@ -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);
|
@ -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));
|
||||
|
@ -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_;
|
||||
|
@ -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)
|
||||
|
@ -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_;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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 *
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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'
|
||||
|
@ -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;
|
||||
|
@ -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).
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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)) {
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user