mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
commit
11c73f1659
@ -11,6 +11,7 @@
|
||||
#include "nsBindingManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccIterator
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
virtual Accessible* Next() = 0;
|
||||
|
||||
private:
|
||||
friend class Relation;
|
||||
friend class mozilla::a11y::Relation;
|
||||
nsAutoPtr<AccIterable> mNextIter;
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,9 @@
|
||||
|
||||
#include "AccIterator.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* This class is used to return Relation objects from functions. A copy
|
||||
* constructor doesn't work here because we need to mutate the old relation to
|
||||
@ -117,5 +120,8 @@ private:
|
||||
AccIterable* mLastIter;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -3,12 +3,15 @@
|
||||
* 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 TextUpdater_h_
|
||||
#define TextUpdater_h_
|
||||
#ifndef mozilla_a11y_TextUpdater_h__
|
||||
#define mozilla_a11y_TextUpdater_h__
|
||||
|
||||
#include "AccEvent.h"
|
||||
#include "HyperTextAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* Used to find a difference between old and new text and fire text change
|
||||
* events.
|
||||
@ -19,13 +22,11 @@ public:
|
||||
/**
|
||||
* Start text of the text leaf update.
|
||||
*/
|
||||
static void Run(DocAccessible* aDocument,
|
||||
mozilla::a11y::TextLeafAccessible* aTextLeaf,
|
||||
static void Run(DocAccessible* aDocument, TextLeafAccessible* aTextLeaf,
|
||||
const nsAString& aNewText);
|
||||
|
||||
private:
|
||||
TextUpdater(DocAccessible* aDocument,
|
||||
mozilla::a11y::TextLeafAccessible* aTextLeaf) :
|
||||
TextUpdater(DocAccessible* aDocument, TextLeafAccessible* aTextLeaf) :
|
||||
mDocument(aDocument), mTextLeaf(aTextLeaf), mHyperText(nsnull),
|
||||
mTextOffset(-1) { }
|
||||
|
||||
@ -84,9 +85,12 @@ private:
|
||||
|
||||
private:
|
||||
DocAccessible* mDocument;
|
||||
mozilla::a11y::TextLeafAccessible* mTextLeaf;
|
||||
TextLeafAccessible* mTextLeaf;
|
||||
HyperTextAccessible* mHyperText;
|
||||
PRInt32 mTextOffset;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -508,50 +508,34 @@ ARIAGridAccessible::GetSelectedRowIndices(PRUint32* aRowCount,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ARIAGridAccessible::SelectRow(PRInt32 aRow)
|
||||
void
|
||||
ARIAGridAccessible::SelectRow(PRUint32 aRowIdx)
|
||||
{
|
||||
NS_ENSURE_ARG(IsValidRow(aRow));
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
Accessible* row = nsnull;
|
||||
for (PRInt32 rowIdx = 0; (row = rowIter.Next()); rowIdx++) {
|
||||
nsresult rv = SetARIASelected(row, rowIdx == aRow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = SetARIASelected(row, rowIdx == aRowIdx);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetARIASelected() Shouldn't fail!");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ARIAGridAccessible::SelectColumn(PRInt32 aColumn)
|
||||
void
|
||||
ARIAGridAccessible::SelectCol(PRUint32 aColIdx)
|
||||
{
|
||||
NS_ENSURE_ARG(IsValidColumn(aColumn));
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
Accessible* row = nsnull;
|
||||
while ((row = rowIter.Next())) {
|
||||
// Unselect all cells in the row.
|
||||
nsresult rv = SetARIASelected(row, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetARIASelected() Shouldn't fail!");
|
||||
|
||||
// Select cell at the column index.
|
||||
Accessible* cell = GetCellInRowAt(row, aColumn);
|
||||
if (cell) {
|
||||
rv = SetARIASelected(cell, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
Accessible* cell = GetCellInRowAt(row, aColIdx);
|
||||
if (cell)
|
||||
SetARIASelected(cell, true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -42,6 +42,8 @@ public:
|
||||
virtual PRUint32 ColCount();
|
||||
virtual PRUint32 RowCount();
|
||||
virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
|
||||
virtual void SelectCol(PRUint32 aColIdx);
|
||||
virtual void SelectRow(PRUint32 aRowIdx);
|
||||
virtual void UnselectCol(PRUint32 aColIdx);
|
||||
virtual void UnselectRow(PRUint32 aRowIdx);
|
||||
|
||||
|
@ -28,7 +28,6 @@ class KeyBinding;
|
||||
class Accessible;
|
||||
class HyperTextAccessible;
|
||||
struct nsRoleMapEntry;
|
||||
class Relation;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@ -36,6 +35,7 @@ namespace a11y {
|
||||
class HTMLImageMapAccessible;
|
||||
class HTMLLIAccessible;
|
||||
class ImageAccessible;
|
||||
class Relation;
|
||||
class TableAccessible;
|
||||
class TextLeafAccessible;
|
||||
class XULTreeAccessible;
|
||||
@ -306,7 +306,7 @@ public:
|
||||
/**
|
||||
* Get the relation of the given type.
|
||||
*/
|
||||
virtual Relation RelationByType(PRUint32 aType);
|
||||
virtual mozilla::a11y::Relation RelationByType(PRUint32 aType);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Initializing methods
|
||||
|
@ -1224,6 +1224,9 @@ HyperTextAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
|
||||
else if (mContent->Tag() == nsGkAtoms::aside)
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
|
||||
NS_LITERAL_STRING("complementary"));
|
||||
else if (mContent->Tag() == nsGkAtoms::article)
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
|
||||
NS_LITERAL_STRING("article"));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
class Relation;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
|
@ -1068,36 +1068,28 @@ HTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLTableAccessible::SelectRow(PRInt32 aRow)
|
||||
void
|
||||
HTMLTableAccessible::SelectRow(PRUint32 aRowIdx)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = RemoveRowsOrColumnsFromSelection(aRowIdx,
|
||||
nsISelectionPrivate::TABLESELECTION_ROW,
|
||||
true);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
|
||||
|
||||
nsresult rv =
|
||||
RemoveRowsOrColumnsFromSelection(aRow,
|
||||
nsISelectionPrivate::TABLESELECTION_ROW,
|
||||
true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AddRowOrColumnToSelection(aRow,
|
||||
nsISelectionPrivate::TABLESELECTION_ROW);
|
||||
AddRowOrColumnToSelection(aRowIdx, nsISelectionPrivate::TABLESELECTION_ROW);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLTableAccessible::SelectColumn(PRInt32 aColumn)
|
||||
void
|
||||
HTMLTableAccessible::SelectCol(PRUint32 aColIdx)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = RemoveRowsOrColumnsFromSelection(aColIdx,
|
||||
nsISelectionPrivate::TABLESELECTION_COLUMN,
|
||||
true);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
|
||||
|
||||
nsresult rv =
|
||||
RemoveRowsOrColumnsFromSelection(aColumn,
|
||||
nsISelectionPrivate::TABLESELECTION_COLUMN,
|
||||
true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AddRowOrColumnToSelection(aColumn,
|
||||
nsISelectionPrivate::TABLESELECTION_COLUMN);
|
||||
AddRowOrColumnToSelection(aColIdx, nsISelectionPrivate::TABLESELECTION_COLUMN);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -106,6 +106,8 @@ public:
|
||||
virtual PRInt32 CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx);
|
||||
virtual PRUint32 ColExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
|
||||
virtual PRUint32 RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
|
||||
virtual void SelectCol(PRUint32 aColIdx);
|
||||
virtual void SelectRow(PRUint32 aRowIdx);
|
||||
virtual void UnselectCol(PRUint32 aColIdx);
|
||||
virtual void UnselectRow(PRUint32 aRowIdx);
|
||||
virtual bool IsProbablyLayoutTable();
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "AccessibleRelation_i.c"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
ia2AccessibleRelation::ia2AccessibleRelation(PRUint32 aType, Relation* aRel) :
|
||||
mType(aType), mReferences(0)
|
||||
{
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
#include "AccessibleRelation.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class ia2AccessibleRelation : public IAccessibleRelation
|
||||
{
|
||||
public:
|
||||
@ -57,5 +60,8 @@ private:
|
||||
ULONG mReferences;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
nsAccessibleRelation::nsAccessibleRelation(PRUint32 aType,
|
||||
Relation* aRel) :
|
||||
mType(aType)
|
||||
|
@ -11,6 +11,9 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class Relation;
|
||||
|
||||
/**
|
||||
@ -33,4 +36,7 @@ private:
|
||||
nsCOMPtr<nsIMutableArray> mTargets;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -144,6 +144,32 @@ xpcAccessibleTable::IsProbablyForLayout(bool* aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xpcAccessibleTable::SelectColumn(PRInt32 aColIdx)
|
||||
{
|
||||
if (!mTable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
mTable->SelectCol(aColIdx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xpcAccessibleTable::SelectRow(PRInt32 aRowIdx)
|
||||
{
|
||||
if (!mTable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->RowCount())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
mTable->SelectRow(aRowIdx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xpcAccessibleTable::UnselectColumn(PRInt32 aColIdx)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
PRInt32* aColumnExtent);
|
||||
nsresult GetRowExtentAt(PRInt32 row, PRInt32 column,
|
||||
PRInt32* aRowExtent);
|
||||
nsresult SelectColumn(PRInt32 aColIdx);
|
||||
nsresult SelectRow(PRInt32 aRowIdx);
|
||||
nsresult UnselectColumn(PRInt32 aColIdx);
|
||||
nsresult UnselectRow(PRInt32 aRowIdx);
|
||||
nsresult IsProbablyForLayout(bool* aIsForLayout);
|
||||
@ -74,8 +76,10 @@ protected:
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellIndices(PRUint32 *cellsArraySize NS_OUTPARAM, PRInt32 **cellsArray NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectRow(PRInt32 rowIndex); \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectColumn(PRInt32 columnIndex); \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectRow(PRInt32 aRowIdx) \
|
||||
{ return xpcAccessibleTable::SelectRow(aRowIdx); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectColumn(PRInt32 aColIdx) \
|
||||
{ return xpcAccessibleTable::SelectColumn(aColIdx); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD UnselectColumn(PRInt32 aColIdx) \
|
||||
{ return xpcAccessibleTable::UnselectColumn(aColIdx); } \
|
||||
NS_IMETHOD UnselectRow(PRInt32 aRowIdx) \
|
||||
|
@ -668,29 +668,17 @@ XULListboxAccessible::GetSelectedRowIndices(PRUint32* aNumRows,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULListboxAccessible::SelectRow(PRInt32 aRow)
|
||||
void
|
||||
XULListboxAccessible::SelectRow(PRUint32 aRowIdx)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
|
||||
do_QueryInterface(mContent);
|
||||
NS_ASSERTION(control,
|
||||
"Doesn't implement nsIDOMXULMultiSelectControlElement.");
|
||||
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
|
||||
control->GetItemAtIndex(aRow, getter_AddRefs(item));
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
|
||||
|
||||
return control->SelectItem(item);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULListboxAccessible::SelectColumn(PRInt32 aColumn)
|
||||
{
|
||||
// xul:listbox and xul:richlistbox support row selection only.
|
||||
return NS_OK;
|
||||
control->GetItemAtIndex(aRowIdx, getter_AddRefs(item));
|
||||
control->SelectItem(item);
|
||||
}
|
||||
|
||||
void
|
||||
@ -701,11 +689,9 @@ XULListboxAccessible::UnselectRow(PRUint32 aRowIdx)
|
||||
NS_ASSERTION(control,
|
||||
"Doesn't implement nsIDOMXULMultiSelectControlElement.");
|
||||
|
||||
if (control) {
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
|
||||
control->GetItemAtIndex(aRowIdx, getter_AddRefs(item));
|
||||
control->RemoveItemFromSelection(item);
|
||||
}
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
|
||||
control->GetItemAtIndex(aRowIdx, getter_AddRefs(item));
|
||||
control->RemoveItemFromSelection(item);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -76,6 +76,7 @@ public:
|
||||
virtual PRUint32 ColCount();
|
||||
virtual PRUint32 RowCount();
|
||||
virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
|
||||
virtual void SelectRow(PRUint32 aRowIdx);
|
||||
virtual void UnselectRow(PRUint32 aRowIdx);
|
||||
|
||||
// nsAccessNode
|
||||
|
@ -4,12 +4,15 @@
|
||||
* 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 _XULSelectControlAccessible_H_
|
||||
#define _XULSelectControlAccessible_H_
|
||||
#ifndef mozilla_a11y_XULSelectControlAccessible_h__
|
||||
#define mozilla_a11y_XULSelectControlAccessible_h__
|
||||
|
||||
#include "AccessibleWrap.h"
|
||||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* The basic implementation of accessible selection for XUL select controls.
|
||||
*/
|
||||
@ -43,5 +46,8 @@ protected:
|
||||
nsCOMPtr<nsIDOMXULSelectControlElement> mSelectControl;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -447,23 +447,17 @@ XULTreeGridAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
|
||||
return IsRowSelected(aRowIndex, aIsSelected);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULTreeGridAccessible::SelectRow(PRInt32 aRowIndex)
|
||||
void
|
||||
XULTreeGridAccessible::SelectRow(PRUint32 aRowIdx)
|
||||
{
|
||||
if (!mTreeView)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsITreeSelection> selection;
|
||||
mTreeView->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_STATE(selection);
|
||||
NS_ASSERTION(selection, "GetSelection() Shouldn't fail!");
|
||||
|
||||
return selection->Select(aRowIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULTreeGridAccessible::SelectColumn(PRInt32 aColumnIndex)
|
||||
{
|
||||
return NS_OK;
|
||||
selection->Select(aRowIdx);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
virtual PRUint32 ColCount();
|
||||
virtual PRUint32 RowCount();
|
||||
virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
|
||||
virtual void SelectRow(PRUint32 aRowIdx);
|
||||
virtual void UnselectRow(PRUint32 aRowIdx);
|
||||
|
||||
// nsAccessNode
|
||||
|
@ -26,6 +26,7 @@
|
||||
testAttrs("section", {"xml-roles" : "region"}, true);
|
||||
testAttrs("main", {"xml-roles" : "main"}, true); // // ARIA override
|
||||
testAttrs("form", {"xml-roles" : "form"}, true);
|
||||
testAttrs("article", {"xml-roles" : "article"}, true);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
@ -61,6 +62,11 @@
|
||||
title="Map ARIA role FORM">
|
||||
Bug 734982
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=761891"
|
||||
title="HTML5 article element should expose xml-roles:article object attribute">
|
||||
Bug 761891
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -72,6 +78,7 @@
|
||||
<section id="section">a section</section>
|
||||
<article id="main" role="main">a main area</article>
|
||||
<article id="form" role="form">a form area</article>
|
||||
<article id="article">article</article>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
1
aclocal.m4
vendored
1
aclocal.m4
vendored
@ -18,6 +18,7 @@ builtin(include, build/autoconf/frameptr.m4)dnl
|
||||
builtin(include, build/autoconf/compiler-opts.m4)dnl
|
||||
builtin(include, build/autoconf/expandlibs.m4)dnl
|
||||
builtin(include, build/autoconf/arch.m4)dnl
|
||||
builtin(include, build/autoconf/android.m4)dnl
|
||||
|
||||
MOZ_PROG_CHECKMSYS()
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifdef ANDROID
|
||||
sizemode="fullscreen"
|
||||
#endif
|
||||
style="background: black; overflow: hidden; width:480px; height:800px"
|
||||
style="background: black; overflow: hidden; width:320px; height:480px"
|
||||
onload="shell.start();"
|
||||
onunload="shell.stop();">
|
||||
|
||||
|
@ -214,5 +214,7 @@
|
||||
</dict>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>GeckoNSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -11,8 +11,6 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = src
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -18,9 +18,7 @@ EXTRA_PP_JS_MODULES = \
|
||||
PageThumbs.jsm \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -9,9 +9,7 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -10,9 +10,7 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -469,6 +469,8 @@
|
||||
#ifdef MOZ_SAFE_BROWSING
|
||||
@BINPATH@/components/nsSafebrowsingApplication.manifest
|
||||
@BINPATH@/components/nsSafebrowsingApplication.js
|
||||
#endif
|
||||
#ifdef MOZ_URL_CLASSIFIER
|
||||
@BINPATH@/components/nsURLClassifier.manifest
|
||||
@BINPATH@/components/nsUrlClassifierHashCompleter.js
|
||||
@BINPATH@/components/nsUrlClassifierListManager.js
|
||||
|
241
build/autoconf/android.m4
Normal file
241
build/autoconf/android.m4
Normal file
@ -0,0 +1,241 @@
|
||||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
AC_DEFUN([MOZ_ANDROID_NDK],
|
||||
[
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-ndk,
|
||||
[ --with-android-ndk=DIR
|
||||
location where the Android NDK can be found],
|
||||
android_ndk=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-toolchain,
|
||||
[ --with-android-toolchain=DIR
|
||||
location of the android toolchain],
|
||||
android_toolchain=$withval)
|
||||
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-version,
|
||||
[ --with-android-version=VER
|
||||
android platform version, default 5],
|
||||
android_version=$withval,
|
||||
android_version=5)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-platform,
|
||||
[ --with-android-platform=DIR
|
||||
location of platform dir],
|
||||
android_platform=$withval)
|
||||
|
||||
case "$target" in
|
||||
arm-linux*-android*|*-linuxandroid*)
|
||||
android_tool_prefix="arm-linux-androideabi"
|
||||
;;
|
||||
i?86-*android*)
|
||||
android_tool_prefix="i686-android-linux"
|
||||
;;
|
||||
mipsel-*android*)
|
||||
android_tool_prefix="mipsel-linux-android"
|
||||
;;
|
||||
*)
|
||||
android_tool_prefix="$target_os"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$android_ndk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
|
||||
fi
|
||||
|
||||
if test -z "$android_toolchain" ; then
|
||||
AC_MSG_CHECKING([for android toolchain directory])
|
||||
|
||||
kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm-linux-androideabi-4.4.3
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86-4.4.3
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mipsel-linux-android-4.4.3
|
||||
;;
|
||||
esac
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
|
||||
if test -d "$android_toolchain" ; then
|
||||
AC_MSG_RESULT([$android_toolchain])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$android_platform" ; then
|
||||
AC_MSG_CHECKING([for android platform directory])
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mips
|
||||
;;
|
||||
esac
|
||||
|
||||
android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
|
||||
|
||||
if test -d "$android_platform" ; then
|
||||
AC_MSG_RESULT([$android_platform])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl set up compilers
|
||||
AS="$android_toolchain"/bin/"$android_tool_prefix"-as
|
||||
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
|
||||
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
|
||||
CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
|
||||
LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
|
||||
AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
|
||||
RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
|
||||
STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
|
||||
OBJCOPY="$android_toolchain"/bin/"$android_tool_prefix"-objcopy
|
||||
|
||||
CPPFLAGS="-isystem $android_platform/usr/include $CPPFLAGS"
|
||||
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
|
||||
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS"
|
||||
ASFLAGS="-isystem $android_platform/usr/include -DANDROID $ASFLAGS"
|
||||
|
||||
dnl Add -llog by default, since we use it all over the place.
|
||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||
dnl undefined symbol (present on the hardware, just not in the
|
||||
dnl NDK.)
|
||||
LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS"
|
||||
dnl prevent cross compile section from using these flags as host flags
|
||||
if test -z "$HOST_CPPFLAGS" ; then
|
||||
HOST_CPPFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CFLAGS" ; then
|
||||
HOST_CFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CXXFLAGS" ; then
|
||||
HOST_CXXFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_LDFLAGS" ; then
|
||||
HOST_LDFLAGS=" "
|
||||
fi
|
||||
|
||||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version)
|
||||
AC_SUBST(ANDROID_VERSION)
|
||||
CROSS_COMPILE=1
|
||||
AC_SUBST(ANDROID_NDK)
|
||||
AC_SUBST(ANDROID_TOOLCHAIN)
|
||||
AC_SUBST(ANDROID_PLATFORM)
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([MOZ_ANDROID_STLPORT],
|
||||
[
|
||||
|
||||
if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
|
||||
case "${CPU_ARCH}-${MOZ_ARCH}" in
|
||||
arm-armv7*)
|
||||
ANDROID_CPU_ARCH=armeabi-v7a
|
||||
;;
|
||||
arm-*)
|
||||
ANDROID_CPU_ARCH=armeabi
|
||||
;;
|
||||
x86-*)
|
||||
ANDROID_CPU_ARCH=x86
|
||||
;;
|
||||
mips-*) # When target_cpu is mipsel, CPU_ARCH is mips
|
||||
ANDROID_CPU_ARCH=mips
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$STLPORT_CPPFLAGS$STLPORT_LDFLAGS$STLPORT_LIBS"; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
|
||||
STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
elif test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
|
||||
STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
else
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
STLPORT_SOURCES="$android_ndk/sources/cxx-stl/stlport"
|
||||
STLPORT_CPPFLAGS="-I$_objdir/build/stlport -I$android_ndk/sources/cxx-stl/stlport/stlport"
|
||||
STLPORT_LIBS="-lstlport_static"
|
||||
elif test "$target" != "arm-android-eabi"; then
|
||||
dnl fail if we're not building with NDKr4
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
fi
|
||||
CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
|
||||
LIBS="$LIBS $STLPORT_LIBS"
|
||||
fi
|
||||
AC_SUBST([STLPORT_SOURCES])
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([MOZ_ANDROID_SDK],
|
||||
[
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-sdk,
|
||||
[ --with-android-sdk=DIR
|
||||
location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
|
||||
android_sdk=$withval)
|
||||
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$android_sdk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
|
||||
else
|
||||
if ! test -e "$android_sdk"/source.properties ; then
|
||||
AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
|
||||
fi
|
||||
|
||||
# Get the api level from "$android_sdk"/source.properties.
|
||||
android_api_level=`$AWK -F = changequote(<<, >>)'<<$>>1 == "AndroidVersion.ApiLevel" {print <<$>>2}'changequote([, ]) "$android_sdk"/source.properties`
|
||||
|
||||
if test -z "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: no AndroidVersion.ApiLevel field has been found in source.properties.])
|
||||
fi
|
||||
|
||||
if ! test "$android_api_level" -eq "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
|
||||
fi
|
||||
|
||||
if test $android_api_level -lt $1 ; then
|
||||
AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($1 or higher required).])
|
||||
fi
|
||||
fi
|
||||
|
||||
android_platform_tools="$android_sdk"/../../platform-tools
|
||||
if test ! -d "$android_platform_tools" ; then
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
fi
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
AC_SUBST(ANDROID_SDK)
|
||||
AC_SUBST(ANDROID_PLATFORM_TOOLS)
|
||||
;;
|
||||
esac
|
||||
|
||||
])
|
@ -25,7 +25,7 @@ setuptools_packages := \
|
||||
|
||||
|
||||
define install_setuptools_package
|
||||
cd $(topsrcdir)/$(1)/; $(PYTHON) setup.py develop
|
||||
cd $(topsrcdir)/$(1)/; CFLAGS="$(HOST_CFLAGS)" LDFLAGS="$(HOST_LDFLAGS)" CXXFLAGS="$(HOST_CXXFLAGS)" $(PYTHON) setup.py develop
|
||||
|
||||
endef
|
||||
|
||||
|
@ -611,13 +611,13 @@ NS_IMPL_QUERY_INTERFACE2_CI(nsPrincipal,
|
||||
NS_IMPL_CI_INTERFACE_GETTER2(nsPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
NS_IMPL_ADDREF_INHERITED(nsPrincipal, nsBasePrincipal);
|
||||
NS_IMPL_RELEASE_INHERITED(nsPrincipal, nsBasePrincipal);
|
||||
NS_IMPL_ADDREF_INHERITED(nsPrincipal, nsBasePrincipal)
|
||||
NS_IMPL_RELEASE_INHERITED(nsPrincipal, nsBasePrincipal)
|
||||
|
||||
nsPrincipal::nsPrincipal()
|
||||
: mInitialized(false),
|
||||
mCodebaseImmutable(false),
|
||||
mDomainImmutable(false)
|
||||
: mCodebaseImmutable(false)
|
||||
, mDomainImmutable(false)
|
||||
, mInitialized(false)
|
||||
{ }
|
||||
|
||||
nsPrincipal::~nsPrincipal()
|
||||
@ -1216,8 +1216,8 @@ NS_IMPL_QUERY_INTERFACE2_CI(nsExpandedPrincipal,
|
||||
NS_IMPL_CI_INTERFACE_GETTER2(nsExpandedPrincipal,
|
||||
nsIPrincipal,
|
||||
nsIExpandedPrincipal)
|
||||
NS_IMPL_ADDREF_INHERITED(nsExpandedPrincipal, nsBasePrincipal);
|
||||
NS_IMPL_RELEASE_INHERITED(nsExpandedPrincipal, nsBasePrincipal);
|
||||
NS_IMPL_ADDREF_INHERITED(nsExpandedPrincipal, nsBasePrincipal)
|
||||
NS_IMPL_RELEASE_INHERITED(nsExpandedPrincipal, nsBasePrincipal)
|
||||
|
||||
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr <nsIPrincipal> > &aWhiteList)
|
||||
{
|
||||
|
264
configure.in
264
configure.in
@ -154,53 +154,6 @@ if test -z "$PERL" -o "$PERL" = ":"; then
|
||||
AC_MSG_ERROR([perl not found in \$PATH])
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Android uses a very custom (hacky) toolchain; we need to do this
|
||||
dnl = here, so that the compiler checks can succeed
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-ndk,
|
||||
[ --with-android-ndk=DIR
|
||||
location where the Android NDK can be found],
|
||||
android_ndk=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-toolchain,
|
||||
[ --with-android-toolchain=DIR
|
||||
location of the android toolchain],
|
||||
android_toolchain=$withval)
|
||||
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-version,
|
||||
[ --with-android-version=VER
|
||||
android platform version, default 5],
|
||||
android_version=$withval,
|
||||
android_version=5)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-sdk,
|
||||
[ --with-android-sdk=DIR
|
||||
location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
|
||||
android_sdk=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-platform,
|
||||
[ --with-android-platform=DIR
|
||||
location of platform dir],
|
||||
android_platform=$withval)
|
||||
|
||||
case "$target" in
|
||||
arm-linux*-android*|*-linuxandroid*)
|
||||
android_tool_prefix="arm-linux-androideabi"
|
||||
;;
|
||||
i?86-*android*)
|
||||
android_tool_prefix="i686-android-linux"
|
||||
;;
|
||||
mipsel-*android*)
|
||||
android_tool_prefix="mipsel-linux-android"
|
||||
;;
|
||||
*)
|
||||
android_tool_prefix="$target_os"
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_WITH_STRING(gonk,
|
||||
[ --with-gonk=DIR
|
||||
location of gonk dir],
|
||||
@ -269,158 +222,23 @@ if test -n "$gonkdir" ; then
|
||||
ZLIB_DIR=yes
|
||||
direct_nspr_config=1
|
||||
else
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$android_ndk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
|
||||
fi
|
||||
MOZ_ANDROID_NDK
|
||||
|
||||
if test -z "$android_sdk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
|
||||
else
|
||||
if ! test -e "$android_sdk"/source.properties ; then
|
||||
AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$ANDROID_PACKAGE_NAME" ; then
|
||||
ANDROID_PACKAGE_NAME='org.mozilla.$(MOZ_APP_NAME)'
|
||||
fi
|
||||
|
||||
# Minimum Android SDK API Level we require.
|
||||
android_min_api_level=13
|
||||
|
||||
# Get the api level from "$android_sdk"/source.properties.
|
||||
android_api_level=`$AWK -F = '$1 == "AndroidVersion.ApiLevel" {print $2}' "$android_sdk"/source.properties`
|
||||
|
||||
if test -z "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: no AndroidVersion.ApiLevel field has been found in source.properties.])
|
||||
fi
|
||||
|
||||
if ! test "$android_api_level" -eq "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
|
||||
fi
|
||||
|
||||
if test $android_api_level -lt $android_min_api_level ; then
|
||||
AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($android_min_api_level or higher required).])
|
||||
fi
|
||||
fi
|
||||
|
||||
android_platform_tools="$android_sdk"/../../platform-tools
|
||||
if test ! -d "$android_platform_tools" ; then
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
fi
|
||||
|
||||
if test -z "$android_toolchain" ; then
|
||||
AC_MSG_CHECKING([for android toolchain directory])
|
||||
|
||||
kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm-linux-androideabi-4.4.3
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86-4.4.3
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mipsel-linux-android-4.4.3
|
||||
;;
|
||||
esac
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
|
||||
if test -d "$android_toolchain" ; then
|
||||
AC_MSG_RESULT([$android_toolchain])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$android_platform" ; then
|
||||
AC_MSG_CHECKING([for android platform directory])
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mips
|
||||
;;
|
||||
esac
|
||||
|
||||
android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
|
||||
|
||||
if test -d "$android_platform" ; then
|
||||
AC_MSG_RESULT([$android_platform])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl set up compilers
|
||||
AS="$android_toolchain"/bin/"$android_tool_prefix"-as
|
||||
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
|
||||
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
|
||||
CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
|
||||
LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
|
||||
AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
|
||||
RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
|
||||
STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
|
||||
OBJCOPY="$android_toolchain"/bin/"$android_tool_prefix"-objcopy
|
||||
|
||||
CPPFLAGS="-isystem $android_platform/usr/include $CPPFLAGS"
|
||||
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
|
||||
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS"
|
||||
ASFLAGS="-isystem $android_platform/usr/include -DANDROID $ASFLAGS"
|
||||
|
||||
dnl Add -llog by default, since we use it all over the place.
|
||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||
dnl undefined symbol (present on the hardware, just not in the
|
||||
dnl NDK.)
|
||||
LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS"
|
||||
|
||||
dnl prevent cross compile section from using these flags as host flags
|
||||
if test -z "$HOST_CPPFLAGS" ; then
|
||||
HOST_CPPFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CFLAGS" ; then
|
||||
HOST_CFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CXXFLAGS" ; then
|
||||
HOST_CXXFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_LDFLAGS" ; then
|
||||
HOST_LDFLAGS=" "
|
||||
fi
|
||||
|
||||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
if test -z "$ANDROID_PACKAGE_NAME" ; then
|
||||
ANDROID_PACKAGE_NAME='org.mozilla.$(MOZ_APP_NAME)'
|
||||
fi
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version)
|
||||
AC_SUBST(ANDROID_VERSION)
|
||||
CROSS_COMPILE=1
|
||||
MOZ_CHROME_FILE_FORMAT=omni
|
||||
ZLIB_DIR=yes
|
||||
;;
|
||||
*-linux*)
|
||||
AC_PATH_PROG(OBJCOPY,objcopy)
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_CHROME_FILE_FORMAT=omni
|
||||
ZLIB_DIR=yes
|
||||
;;
|
||||
*-linux*)
|
||||
AC_PATH_PROG(OBJCOPY,objcopy)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_SUBST(ANDROID_NDK)
|
||||
AC_SUBST(ANDROID_TOOLCHAIN)
|
||||
AC_SUBST(ANDROID_SOURCE)
|
||||
AC_SUBST(ANDROID_PLATFORM)
|
||||
AC_SUBST(ANDROID_SDK)
|
||||
AC_SUBST(ANDROID_PLATFORM_TOOLS)
|
||||
AC_SUBST(ANDROID_PACKAGE_NAME)
|
||||
AC_SUBST(OBJCOPY)
|
||||
|
||||
@ -1591,45 +1409,7 @@ dnl Android libstdc++, placed here so it can use MOZ_ARCH
|
||||
dnl computed above.
|
||||
dnl ========================================================
|
||||
|
||||
if test "$OS_TARGET" = "Android"; then
|
||||
case "${CPU_ARCH}-${MOZ_ARCH}" in
|
||||
arm-armv7*)
|
||||
ANDROID_CPU_ARCH=armeabi-v7a
|
||||
;;
|
||||
arm-*)
|
||||
ANDROID_CPU_ARCH=armeabi
|
||||
;;
|
||||
x86-*)
|
||||
ANDROID_CPU_ARCH=x86
|
||||
;;
|
||||
mips-*) # When target_cpu is mipsel, CPU_ARCH is mips
|
||||
ANDROID_CPU_ARCH=mips
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
|
||||
STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
elif test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
|
||||
STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
else
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
STLPORT_SOURCES="$android_ndk/sources/cxx-stl/stlport"
|
||||
STLPORT_CPPFLAGS="-I$_objdir/build/stlport -I$android_ndk/sources/cxx-stl/stlport/stlport"
|
||||
STLPORT_LIBS="-lstlport_static"
|
||||
elif test "$target" != "arm-android-eabi"; then
|
||||
dnl fail if we're not building with NDKr4
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
|
||||
LIBS="$LIBS $STLPORT_LIBS"
|
||||
fi
|
||||
|
||||
AC_SUBST([STLPORT_SOURCES])
|
||||
MOZ_ANDROID_STLPORT
|
||||
|
||||
dnl ========================================================
|
||||
dnl Suppress Clang Argument Warnings
|
||||
@ -4699,6 +4479,24 @@ AC_SUBST(MOZ_XULRUNNER)
|
||||
|
||||
AC_DEFINE_UNQUOTED(MOZ_BUILD_APP,$MOZ_BUILD_APP)
|
||||
|
||||
dnl ========================================================
|
||||
dnl Check android sdk version depending on mobile target
|
||||
dnl ========================================================
|
||||
|
||||
if test -z "$gonkdir" ; then
|
||||
# Minimum Android SDK API Level we require.
|
||||
case "$MOZ_BUILD_APP" in
|
||||
mobile/xul)
|
||||
android_min_api_level=13
|
||||
;;
|
||||
mobile/android)
|
||||
android_min_api_level=14
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ANDROID_SDK($android_min_api_level)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl =
|
||||
dnl = Toolkit Options
|
||||
|
@ -259,8 +259,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
inline mozilla::dom::Element* nsINode::AsElement() {
|
||||
NS_ASSERTION(IsElement(), "Not an element?");
|
||||
inline mozilla::dom::Element* nsINode::AsElement()
|
||||
{
|
||||
MOZ_ASSERT(IsElement());
|
||||
return static_cast<mozilla::dom::Element*>(this);
|
||||
}
|
||||
|
||||
|
@ -923,4 +923,10 @@ public:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContent, NS_ICONTENT_IID)
|
||||
|
||||
inline nsIContent* nsINode::AsContent()
|
||||
{
|
||||
MOZ_ASSERT(IsContent());
|
||||
return static_cast<nsIContent*>(this);
|
||||
}
|
||||
|
||||
#endif /* nsIContent_h___ */
|
||||
|
@ -374,6 +374,19 @@ public:
|
||||
*/
|
||||
mozilla::dom::Element* AsElement();
|
||||
|
||||
/**
|
||||
* Return whether the node is a content node
|
||||
*/
|
||||
bool IsContent() const {
|
||||
return IsNodeOfType(eCONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this node as nsIContent. Should only be used for nodes for which
|
||||
* IsContent() is true. This is defined inline in nsIContent.h.
|
||||
*/
|
||||
nsIContent* AsContent();
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() = 0;
|
||||
|
||||
/**
|
||||
|
@ -9600,7 +9600,8 @@ nsIDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
|
||||
|
||||
if (mPresShell) {
|
||||
mPresShell->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf,
|
||||
&aWindowSizes->mLayoutArenas,
|
||||
&aWindowSizes->mArenaStats,
|
||||
&aWindowSizes->mLayoutPresShell,
|
||||
&aWindowSizes->mLayoutStyleSets,
|
||||
&aWindowSizes->mLayoutTextRuns,
|
||||
&aWindowSizes->mLayoutPresContext);
|
||||
|
@ -3212,6 +3212,29 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class RemoveFromBindingManagerRunnable : public nsRunnable {
|
||||
public:
|
||||
RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
|
||||
Element* aElement,
|
||||
nsIDocument* aDoc,
|
||||
nsIContent* aBindingParent):
|
||||
mManager(aManager), mElement(aElement), mDoc(aDoc),
|
||||
mBindingParent(aBindingParent)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mManager->RemovedFromDocumentInternal(mElement, mDoc, mBindingParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsBindingManager> mManager;
|
||||
nsRefPtr<Element> mElement;
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
nsCOMPtr<nsIContent> mBindingParent;
|
||||
};
|
||||
|
||||
void
|
||||
nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
@ -3254,7 +3277,11 @@ nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
if (document) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
document->BindingManager()->RemovedFromDocument(this, document);
|
||||
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
|
||||
document, GetBindingParent()));
|
||||
}
|
||||
|
||||
document->ClearBoxObjectFor(this);
|
||||
}
|
||||
@ -4183,19 +4210,11 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
|
||||
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
nsIContent* newContent = static_cast<nsIContent*>(aNewChild);
|
||||
PRInt32 insPos;
|
||||
|
||||
mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
|
||||
|
||||
// Figure out which index to insert at
|
||||
if (aRefChild) {
|
||||
insPos = IndexOf(aRefChild);
|
||||
if (insPos < 0) {
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
insPos = GetChildCount();
|
||||
if (newContent->IsRootOfAnonymousSubtree()) {
|
||||
// This is anonymous content. Don't allow its insertion
|
||||
// anywhere, since it might have UnbindFromTree calls coming
|
||||
// its way.
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
// Make sure that the inserted node is allowed as a child of its new parent.
|
||||
@ -4203,18 +4222,17 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
nsAutoMutationBatch mb;
|
||||
// If we're replacing
|
||||
// Record the node to insert before, if any
|
||||
nsINode* nodeToInsertBefore;
|
||||
if (aReplace) {
|
||||
mb.Init(this, true, true);
|
||||
RemoveChildAt(insPos, true);
|
||||
nodeToInsertBefore = aRefChild->GetNextSibling();
|
||||
} else {
|
||||
nodeToInsertBefore = aRefChild;
|
||||
}
|
||||
|
||||
if (newContent->IsRootOfAnonymousSubtree()) {
|
||||
// This is anonymous content. Don't allow its insertion
|
||||
// anywhere, since it might have UnbindFromTree calls coming
|
||||
// its way.
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
if (nodeToInsertBefore == aNewChild) {
|
||||
// We're going to remove aNewChild from its parent, so use its next sibling
|
||||
// as the node to insert before.
|
||||
nodeToInsertBefore = nodeToInsertBefore->GetNextSibling();
|
||||
}
|
||||
|
||||
// Remove the new child from the old parent if one exists
|
||||
@ -4227,21 +4245,97 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
nsAutoMutationBatch mb(oldParent, true, true);
|
||||
oldParent->RemoveChildAt(removeIndex, true);
|
||||
if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
|
||||
mb.RemovalDone();
|
||||
mb.SetPrevSibling(oldParent->GetChildAt(removeIndex - 1));
|
||||
mb.SetNextSibling(oldParent->GetChildAt(removeIndex));
|
||||
// Hold a strong ref to nodeToInsertBefore across the removal of newContent
|
||||
nsCOMPtr<nsINode> kungFuDeathGrip = nodeToInsertBefore;
|
||||
|
||||
// Removing a child can run script, via XBL destructors.
|
||||
nsMutationGuard guard;
|
||||
|
||||
// Scope for the mutation batch and scriptblocker, so they go away
|
||||
// while kungFuDeathGrip is still alive.
|
||||
{
|
||||
mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
|
||||
nsAutoMutationBatch mb(oldParent, true, true);
|
||||
oldParent->RemoveChildAt(removeIndex, true);
|
||||
if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
|
||||
mb.RemovalDone();
|
||||
mb.SetPrevSibling(oldParent->GetChildAt(removeIndex - 1));
|
||||
mb.SetNextSibling(oldParent->GetChildAt(removeIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust insert index if the node we ripped out was a sibling
|
||||
// of the node we're inserting before
|
||||
if (oldParent == this && removeIndex < insPos) {
|
||||
--insPos;
|
||||
// We expect one mutation (the removal) to have happened.
|
||||
if (guard.Mutated(1)) {
|
||||
// XBL destructors, yuck.
|
||||
|
||||
// Verify that nodeToInsertBefore, if non-null, is still our child. If
|
||||
// it's not, there's no way we can do this insert sanely; just bail out.
|
||||
if (nodeToInsertBefore && nodeToInsertBefore->GetParent() != this) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
// Verify that newContent has no parent.
|
||||
if (newContent->GetParent()) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
// And verify that newContent is still allowed as our child.
|
||||
if (aNewChild == aRefChild) {
|
||||
// We've already removed aRefChild. So even if we were doing a replace,
|
||||
// now we're doing a simple insert before nodeToInsertBefore.
|
||||
if (!IsAllowedAsChild(newContent, this, false, nodeToInsertBefore)) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
} else {
|
||||
if ((aRefChild && aRefChild->GetParent() != this) ||
|
||||
!IsAllowedAsChild(newContent, this, aReplace, aRefChild)) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
// And recompute nodeToInsertBefore, just in case.
|
||||
if (aReplace) {
|
||||
nodeToInsertBefore = aRefChild->GetNextSibling();
|
||||
} else {
|
||||
nodeToInsertBefore = aRefChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
|
||||
nsAutoMutationBatch mb;
|
||||
|
||||
// Figure out which index we want to insert at. Note that we use
|
||||
// nodeToInsertBefore to determine this, because it's possible that
|
||||
// aRefChild == aNewChild, in which case we just removed it from the
|
||||
// parent list.
|
||||
PRInt32 insPos;
|
||||
if (nodeToInsertBefore) {
|
||||
insPos = IndexOf(nodeToInsertBefore);
|
||||
if (insPos < 0) {
|
||||
// XXXbz How the heck would _that_ happen, exactly?
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
insPos = GetChildCount();
|
||||
}
|
||||
|
||||
// If we're replacing and we haven't removed aRefChild yet, do so now
|
||||
if (aReplace && aRefChild != aNewChild) {
|
||||
mb.Init(this, true, true);
|
||||
|
||||
// Since aRefChild is never null in the aReplace case, we know that at
|
||||
// this point nodeToInsertBefore is the next sibling of aRefChild.
|
||||
NS_ASSERTION(aRefChild->GetNextSibling() == nodeToInsertBefore,
|
||||
"Unexpected nodeToInsertBefore");
|
||||
|
||||
// An since nodeToInsertBefore is at index insPos, we want to remove
|
||||
// at the previous index.
|
||||
NS_ASSERTION(insPos >= 1, "insPos too small");
|
||||
RemoveChildAt(insPos-1, true);
|
||||
--insPos;
|
||||
}
|
||||
|
||||
nsresult res = NS_OK;
|
||||
// Move new child over to our document if needed. Do this after removing
|
||||
// it from its parent so that AdoptNode doesn't fire DOMNodeRemoved
|
||||
|
@ -505,8 +505,8 @@ nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMETy
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRUint32 permission;
|
||||
rv = permissionManager->TestPermission(topUri,
|
||||
"plugins",
|
||||
rv = permissionManager->TestPermission(topUri,
|
||||
"plugins",
|
||||
&permission);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (permission == nsIPermissionManager::ALLOW_ACTION) {
|
||||
|
@ -227,7 +227,9 @@ WebGLContext::DestroyResourcesAndContext()
|
||||
// We just got rid of everything, so the context had better
|
||||
// have been going away.
|
||||
#ifdef DEBUG
|
||||
printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
|
||||
if (gl->DebugMode()) {
|
||||
printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
gl = nsnull;
|
||||
@ -519,7 +521,9 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf_stderr ("--- WebGL context created: %p\n", gl.get());
|
||||
if (gl->DebugMode()) {
|
||||
printf_stderr("--- WebGL context created: %p\n", gl.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
mWidth = width;
|
||||
|
@ -87,9 +87,7 @@ ifdef MOZ_MEDIA_PLUGINS
|
||||
PARALLEL_DIRS += plugins
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
PARALLEL_DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
|
@ -615,7 +615,8 @@ nsBindingManager::SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aWra
|
||||
|
||||
void
|
||||
nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
|
||||
nsIDocument* aOldDocument)
|
||||
nsIDocument* aOldDocument,
|
||||
nsIContent* aContentBindingParent)
|
||||
{
|
||||
NS_PRECONDITION(aOldDocument != nsnull, "no old document");
|
||||
|
||||
@ -626,7 +627,7 @@ nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
|
||||
// table.
|
||||
nsRefPtr<nsXBLBinding> binding = GetBinding(aContent);
|
||||
if (aContent->HasFlag(NODE_IS_INSERTION_PARENT)) {
|
||||
nsRefPtr<nsXBLBinding> parentBinding = GetBinding(aContent->GetBindingParent());
|
||||
nsRefPtr<nsXBLBinding> parentBinding = GetBinding(aContentBindingParent);
|
||||
if (parentBinding) {
|
||||
parentBinding->RemoveInsertionParent(aContent);
|
||||
// Clear insertion parent only if we don't have a binding which
|
||||
|
@ -61,11 +61,13 @@ public:
|
||||
void RemovedFromDocument(nsIContent* aContent, nsIDocument* aOldDocument)
|
||||
{
|
||||
if (aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
|
||||
RemovedFromDocumentInternal(aContent, aOldDocument);
|
||||
RemovedFromDocumentInternal(aContent, aOldDocument,
|
||||
aContent->GetBindingParent());
|
||||
}
|
||||
}
|
||||
void RemovedFromDocumentInternal(nsIContent* aContent,
|
||||
nsIDocument* aOldDocument);
|
||||
nsIDocument* aOldDocument,
|
||||
nsIContent* aContentBindingParent);
|
||||
|
||||
nsIAtom* ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID);
|
||||
|
||||
|
@ -13,9 +13,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
MODULE = xul
|
||||
PARALLEL_DIRS = public src
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
PARALLEL_DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -131,6 +131,7 @@ static nsITimer *sGCTimer;
|
||||
static nsITimer *sShrinkGCBuffersTimer;
|
||||
static nsITimer *sCCTimer;
|
||||
static nsITimer *sFullGCTimer;
|
||||
static nsITimer *sInterSliceGCTimer;
|
||||
|
||||
static PRTime sLastCCEndTime;
|
||||
|
||||
@ -3096,11 +3097,15 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
|
||||
void
|
||||
GCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
NS_RELEASE(sGCTimer);
|
||||
if (aTimer == sGCTimer) {
|
||||
NS_RELEASE(sGCTimer);
|
||||
} else {
|
||||
NS_RELEASE(sInterSliceGCTimer);
|
||||
}
|
||||
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||
nsGCNormal, false);
|
||||
nsGCIncremental, false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3318,6 +3323,15 @@ nsJSContext::KillFullGCTimer()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::KillInterSliceGCTimer()
|
||||
{
|
||||
if (sInterSliceGCTimer) {
|
||||
sInterSliceGCTimer->Cancel();
|
||||
NS_RELEASE(sInterSliceGCTimer);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillShrinkGCBuffersTimer()
|
||||
@ -3417,13 +3431,18 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
|
||||
|
||||
// The GC has more work to do, so schedule another GC slice.
|
||||
if (aProgress == js::GC_SLICE_END) {
|
||||
nsJSContext::KillGCTimer();
|
||||
nsJSContext::PokeGC(js::gcreason::INTER_SLICE_GC, NS_INTERSLICE_GC_DELAY);
|
||||
nsJSContext::KillInterSliceGCTimer();
|
||||
CallCreateInstance("@mozilla.org/timer;1", &sInterSliceGCTimer);
|
||||
js::gcreason::Reason reason = js::gcreason::INTER_SLICE_GC;
|
||||
sInterSliceGCTimer->InitWithFuncCallback(GCTimerFired,
|
||||
reinterpret_cast<void *>(reason),
|
||||
NS_INTERSLICE_GC_DELAY,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
if (aProgress == js::GC_CYCLE_END) {
|
||||
// May need to kill the inter-slice GC timer
|
||||
nsJSContext::KillGCTimer();
|
||||
nsJSContext::KillInterSliceGCTimer();
|
||||
|
||||
sCCollectedWaitingForGC = 0;
|
||||
sCleanupsSinceLastGC = 0;
|
||||
@ -3844,6 +3863,7 @@ nsJSRuntime::Shutdown()
|
||||
nsJSContext::KillShrinkGCBuffersTimer();
|
||||
nsJSContext::KillCCTimer();
|
||||
nsJSContext::KillFullGCTimer();
|
||||
nsJSContext::KillInterSliceGCTimer();
|
||||
|
||||
NS_IF_RELEASE(gNameSpaceManager);
|
||||
|
||||
|
@ -163,6 +163,7 @@ public:
|
||||
static void MaybePokeCC();
|
||||
static void KillCCTimer();
|
||||
static void KillFullGCTimer();
|
||||
static void KillInterSliceGCTimer();
|
||||
|
||||
virtual void GC(js::gcreason::Reason aReason);
|
||||
|
||||
|
@ -181,10 +181,26 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
||||
"Memory used by style sheets within a window.");
|
||||
aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
|
||||
|
||||
REPORT("/layout/arenas", windowSizes.mLayoutArenas,
|
||||
"Memory used by layout PresShell, PresContext, and other related "
|
||||
"areas within a window.");
|
||||
aWindowTotalSizes->mLayoutArenas += windowSizes.mLayoutArenas;
|
||||
REPORT("/layout/pres-shell", windowSizes.mLayoutPresShell,
|
||||
"Memory used by layout's PresShell, along with any structures "
|
||||
"allocated in its arena and not measured elsewhere, "
|
||||
"within a window.");
|
||||
aWindowTotalSizes->mLayoutPresShell += windowSizes.mLayoutPresShell;
|
||||
|
||||
REPORT("/layout/line-boxes", windowSizes.mArenaStats.mLineBoxes,
|
||||
"Memory used by line boxes within a window.");
|
||||
aWindowTotalSizes->mArenaStats.mLineBoxes
|
||||
+= windowSizes.mArenaStats.mLineBoxes;
|
||||
|
||||
REPORT("/layout/rule-nodes", windowSizes.mArenaStats.mRuleNodes,
|
||||
"Memory used by CSS rule nodes within a window.");
|
||||
aWindowTotalSizes->mArenaStats.mRuleNodes
|
||||
+= windowSizes.mArenaStats.mRuleNodes;
|
||||
|
||||
REPORT("/layout/style-contexts", windowSizes.mArenaStats.mStyleContexts,
|
||||
"Memory used by style contexts within a window.");
|
||||
aWindowTotalSizes->mArenaStats.mStyleContexts
|
||||
+= windowSizes.mArenaStats.mStyleContexts;
|
||||
|
||||
REPORT("/layout/style-sets", windowSizes.mLayoutStyleSets,
|
||||
"Memory used by style sets within a window.");
|
||||
@ -200,6 +216,34 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
||||
"within a window.");
|
||||
aWindowTotalSizes->mLayoutPresContext += windowSizes.mLayoutPresContext;
|
||||
|
||||
// There are many different kinds of frames, but it is very likely
|
||||
// that only a few matter. Implement a cutoff so we don't bloat
|
||||
// about:memory with many uninteresting entries.
|
||||
static const size_t FRAME_SUNDRIES_THRESHOLD = 8192;
|
||||
size_t frameSundriesSize = 0;
|
||||
#define FRAME_ID(classname) \
|
||||
{ \
|
||||
size_t frameSize \
|
||||
= windowSizes.mArenaStats.FRAME_ID_STAT_FIELD(classname); \
|
||||
if (frameSize < FRAME_SUNDRIES_THRESHOLD) { \
|
||||
frameSundriesSize += frameSize; \
|
||||
} else { \
|
||||
REPORT("/layout/frames/" # classname, frameSize, \
|
||||
"Memory used by frames of " \
|
||||
"type " #classname " within a window."); \
|
||||
aWindowTotalSizes->mArenaStats.FRAME_ID_STAT_FIELD(classname) \
|
||||
+= frameSize; \
|
||||
} \
|
||||
}
|
||||
#include "nsFrameIdList.h"
|
||||
#undef FRAME_ID
|
||||
|
||||
if (frameSundriesSize > 0) {
|
||||
REPORT("/layout/frames/sundries", frameSundriesSize,
|
||||
"The sum of all memory used by frames which were too small "
|
||||
"to be shown individually.");
|
||||
}
|
||||
|
||||
#undef REPORT
|
||||
|
||||
return NS_OK;
|
||||
@ -288,11 +332,26 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
"Memory used for style sheets within windows. "
|
||||
"This is the sum of all windows' 'style-sheets' numbers.");
|
||||
|
||||
REPORT("window-objects-layout-arenas", windowTotalSizes.mLayoutArenas,
|
||||
REPORT("window-objects-layout-pres-shell", windowTotalSizes.mLayoutPresShell,
|
||||
"Memory used by layout PresShell and other related "
|
||||
"areas within windows. This is the sum of all windows' "
|
||||
"'layout/arenas' numbers.");
|
||||
|
||||
REPORT("window-objects-layout-line-boxes",
|
||||
windowTotalSizes.mArenaStats.mLineBoxes,
|
||||
"Memory used for line-boxes within windows. "
|
||||
"This is the sum of all windows' 'layout/line-boxes' numbers.");
|
||||
|
||||
REPORT("window-objects-layout-rule-nodes",
|
||||
windowTotalSizes.mArenaStats.mRuleNodes,
|
||||
"Memory used for CSS rule nodes within windows. "
|
||||
"This is the sum of all windows' 'layout/rule-nodes' numbers.");
|
||||
|
||||
REPORT("window-objects-layout-style-contexts",
|
||||
windowTotalSizes.mArenaStats.mStyleContexts,
|
||||
"Memory used for style contexts within windows. "
|
||||
"This is the sum of all windows' 'layout/style-contexts' numbers.");
|
||||
|
||||
REPORT("window-objects-layout-style-sets", windowTotalSizes.mLayoutStyleSets,
|
||||
"Memory used for style sets within windows. "
|
||||
"This is the sum of all windows' 'layout/style-sets' numbers.");
|
||||
@ -305,6 +364,16 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
"Memory used for layout PresContexts within windows. "
|
||||
"This is the sum of all windows' 'layout/pres-contexts' numbers.");
|
||||
|
||||
size_t frameTotal = 0;
|
||||
#define FRAME_ID(classname) \
|
||||
frameTotal += windowTotalSizes.mArenaStats.FRAME_ID_STAT_FIELD(classname);
|
||||
#include "nsFrameIdList.h"
|
||||
#undef FRAME_ID
|
||||
|
||||
REPORT("window-objects-layout-frames", frameTotal,
|
||||
"Memory used for layout frames within windows. "
|
||||
"This is the sum of all windows' 'layout/frames/' numbers.");
|
||||
|
||||
#undef REPORT
|
||||
|
||||
return NS_OK;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsArenaMemoryStats.h"
|
||||
|
||||
// This should be used for any nsINode sub-class that has fields of its own
|
||||
// that it needs to measure; any sub-class that doesn't use it will inherit
|
||||
@ -27,13 +28,14 @@ public:
|
||||
mMallocSizeOf = aMallocSizeOf;
|
||||
}
|
||||
nsMallocSizeOfFun mMallocSizeOf;
|
||||
nsArenaMemoryStats mArenaStats;
|
||||
size_t mDOMElementNodes;
|
||||
size_t mDOMTextNodes;
|
||||
size_t mDOMCDATANodes;
|
||||
size_t mDOMCommentNodes;
|
||||
size_t mDOMOther;
|
||||
size_t mStyleSheets;
|
||||
size_t mLayoutArenas;
|
||||
size_t mLayoutPresShell;
|
||||
size_t mLayoutStyleSets;
|
||||
size_t mLayoutTextRuns;
|
||||
size_t mLayoutPresContext;
|
||||
|
@ -82,6 +82,7 @@ bindinggen_dependencies := \
|
||||
Bindings.conf \
|
||||
Configuration.py \
|
||||
Codegen.py \
|
||||
parser/WebIDL.py \
|
||||
ParserResults.pkl \
|
||||
$(GLOBAL_DEPS) \
|
||||
$(NULL)
|
||||
@ -119,6 +120,7 @@ globalgen_dependencies := \
|
||||
Bindings.conf \
|
||||
Configuration.py \
|
||||
Codegen.py \
|
||||
parser/WebIDL.py \
|
||||
$(CACHE_DIR)/.done \
|
||||
$(GLOBAL_DEPS) \
|
||||
$(NULL)
|
||||
|
@ -51,15 +51,19 @@ def enum(*names):
|
||||
return Foo()
|
||||
|
||||
class WebIDLError(Exception):
|
||||
def __init__(self, message, location, warning=False):
|
||||
def __init__(self, message, location, warning=False, extraLocation=""):
|
||||
self.message = message
|
||||
self.location = location
|
||||
self.warning = warning
|
||||
self.extraLocation = extraLocation
|
||||
|
||||
def __str__(self):
|
||||
return "%s: %s%s%s" % (self.warning and 'warning' or 'error',
|
||||
self.message, ", " if self.location else "",
|
||||
self.location)
|
||||
return "%s: %s%s%s%s%s" % (self.warning and 'warning' or 'error',
|
||||
self.message,
|
||||
", " if self.location else "",
|
||||
self.location,
|
||||
"\n" if self.extraLocation else "",
|
||||
self.extraLocation)
|
||||
|
||||
class Location(object):
|
||||
def __init__(self, lexer, lineno, lexpos, filename):
|
||||
@ -313,7 +317,7 @@ class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
|
||||
IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
|
||||
IDLScope.__init__(self, location, parentScope, self.identifier)
|
||||
|
||||
class IDLParentPlaceholder(IDLObjectWithIdentifier):
|
||||
class IDLInterfacePlaceholder(IDLObjectWithIdentifier):
|
||||
def __init__(self, location, identifier):
|
||||
assert isinstance(identifier, IDLUnresolvedIdentifier)
|
||||
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
|
||||
@ -354,12 +358,13 @@ class IDLInterface(IDLObjectWithScope):
|
||||
def __init__(self, location, parentScope, name, parent, members):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
assert isinstance(name, IDLUnresolvedIdentifier)
|
||||
assert not parent or isinstance(parent, IDLParentPlaceholder)
|
||||
assert not parent or isinstance(parent, IDLInterfacePlaceholder)
|
||||
|
||||
self.parent = parent
|
||||
self._callback = False
|
||||
self._finished = False
|
||||
self.members = list(members) # clone the list
|
||||
self.implementedInterfaces = set()
|
||||
|
||||
IDLObjectWithScope.__init__(self, location, parentScope, name)
|
||||
|
||||
@ -398,7 +403,7 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
self._finished = True
|
||||
|
||||
assert not self.parent or isinstance(self.parent, IDLParentPlaceholder)
|
||||
assert not self.parent or isinstance(self.parent, IDLInterfacePlaceholder)
|
||||
parent = self.parent.finish(scope) if self.parent else None
|
||||
assert not parent or isinstance(parent, IDLInterface)
|
||||
|
||||
@ -408,31 +413,57 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
if self.parent:
|
||||
self.parent.finish(scope)
|
||||
assert iter(self.parent.members)
|
||||
|
||||
members = list(self.parent.members)
|
||||
members.extend(self.members)
|
||||
else:
|
||||
members = list(self.members)
|
||||
# Callbacks must not inherit from non-callbacks or inherit from
|
||||
# anything that has consequential interfaces.
|
||||
if self.isCallback():
|
||||
assert(self.parent.isCallback())
|
||||
assert(len(self.parent.getConsequentialInterfaces()) == 0)
|
||||
|
||||
def memberNotOnParentChain(member, iface):
|
||||
assert iface
|
||||
for iface in self.implementedInterfaces:
|
||||
iface.finish(scope)
|
||||
|
||||
if not iface.parent:
|
||||
return True
|
||||
# Now resolve() and finish() our members before importing the
|
||||
# ones from our implemented interfaces.
|
||||
|
||||
assert isinstance(iface.parent, IDLInterface)
|
||||
if member in iface.parent.members:
|
||||
return False
|
||||
return memberNotOnParentChain(member, iface.parent)
|
||||
# resolve() will modify self.members, so we need to iterate
|
||||
# over a copy of the member list here.
|
||||
for member in list(self.members):
|
||||
member.resolve(self)
|
||||
|
||||
for member in self.members:
|
||||
member.finish(scope)
|
||||
|
||||
ctor = self.ctor()
|
||||
if ctor is not None:
|
||||
ctor.finish(scope)
|
||||
|
||||
# Make a copy of our member list, so things tht implement us
|
||||
# can get those without all the stuff we implement ourselves
|
||||
# admixed.
|
||||
self.originalMembers = list(self.members)
|
||||
|
||||
# Import everything from our consequential interfaces into
|
||||
# self.members. Sort our consequential interfaces by name
|
||||
# just so we have a consistent order.
|
||||
for iface in sorted(self.getConsequentialInterfaces(),
|
||||
cmp=cmp,
|
||||
key=lambda x: x.identifier.name):
|
||||
additionalMembers = iface.originalMembers;
|
||||
for additionalMember in additionalMembers:
|
||||
for member in self.members:
|
||||
if additionalMember.identifier.name == member.identifier.name:
|
||||
raise WebIDLError(
|
||||
"Multiple definitions of %s on %s coming from 'implements' statements" %
|
||||
(member.identifier.name, self),
|
||||
additionalMember.location,
|
||||
extraLocation=member.location)
|
||||
self.members.extend(additionalMembers)
|
||||
|
||||
# Ensure that there's at most one of each {named,indexed}
|
||||
# {getter,setter,creator,deleter}.
|
||||
specialMembersSeen = set()
|
||||
for member in members:
|
||||
if memberNotOnParentChain(member, self):
|
||||
member.resolve(self)
|
||||
|
||||
for member in self.members:
|
||||
if member.tag != IDLInterfaceMember.Tags.Method:
|
||||
continue
|
||||
|
||||
@ -460,13 +491,6 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
specialMembersSeen.add(memberType)
|
||||
|
||||
for member in self.members:
|
||||
member.finish(scope)
|
||||
|
||||
ctor = self.ctor()
|
||||
if ctor is not None:
|
||||
ctor.finish(scope)
|
||||
|
||||
def isInterface(self):
|
||||
return True
|
||||
|
||||
@ -531,6 +555,39 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True
|
||||
|
||||
def addImplementedInterface(self, implementedInterface):
|
||||
assert(isinstance(implementedInterface, IDLInterface))
|
||||
self.implementedInterfaces.add(implementedInterface)
|
||||
|
||||
def getInheritedInterfaces(self):
|
||||
"""
|
||||
Returns a list of the interfaces this interface inherits from
|
||||
(not including this interface itself). The list is in order
|
||||
from most derived to least derived.
|
||||
"""
|
||||
assert(self._finished)
|
||||
if not self.parent:
|
||||
return []
|
||||
parentInterfaces = self.parent.getInheritedInterfaces()
|
||||
parentInterfaces.insert(0, self.parent)
|
||||
return parentInterfaces
|
||||
|
||||
def getConsequentialInterfaces(self):
|
||||
assert(self._finished)
|
||||
# The interfaces we implement directly
|
||||
consequentialInterfaces = set(self.implementedInterfaces)
|
||||
|
||||
# And their inherited interfaces
|
||||
for iface in self.implementedInterfaces:
|
||||
consequentialInterfaces |= set(iface.getInheritedInterfaces())
|
||||
|
||||
# And now collect up the consequential interfaces of all of those
|
||||
temp = set()
|
||||
for iface in consequentialInterfaces:
|
||||
temp |= iface.getConsequentialInterfaces()
|
||||
|
||||
return consequentialInterfaces | temp
|
||||
|
||||
class IDLEnum(IDLObjectWithIdentifier):
|
||||
def __init__(self, location, parentScope, name, values):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
@ -1740,6 +1797,22 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
assert not isinstance(type.name, IDLUnresolvedIdentifier)
|
||||
argument.type = type
|
||||
|
||||
class IDLImplementsStatement(IDLObject):
|
||||
def __init__(self, location, implementor, implementee):
|
||||
IDLObject.__init__(self, location)
|
||||
self.implementor = implementor;
|
||||
self.implementee = implementee
|
||||
|
||||
def finish(self, scope):
|
||||
assert(isinstance(self.implementor, IDLInterfacePlaceholder))
|
||||
assert(isinstance(self.implementee, IDLInterfacePlaceholder))
|
||||
implementor = self.implementor.finish(scope)
|
||||
implementee = self.implementee.finish(scope)
|
||||
implementor.addImplementedInterface(implementee)
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
|
||||
# Parser
|
||||
|
||||
class Tokenizer(object):
|
||||
@ -1968,7 +2041,7 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
Inheritance : COLON ScopedName
|
||||
"""
|
||||
p[0] = IDLParentPlaceholder(self.getLocation(p, 2), p[2])
|
||||
p[0] = IDLInterfacePlaceholder(self.getLocation(p, 2), p[2])
|
||||
|
||||
def p_InheritanceEmpty(self, p):
|
||||
"""
|
||||
@ -2093,7 +2166,11 @@ class Parser(Tokenizer):
|
||||
"""
|
||||
ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
|
||||
"""
|
||||
pass
|
||||
assert(p[2] == "implements")
|
||||
implementor = IDLInterfacePlaceholder(self.getLocation(p, 1), p[1])
|
||||
implementee = IDLInterfacePlaceholder(self.getLocation(p, 3), p[3])
|
||||
p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor,
|
||||
implementee)
|
||||
|
||||
def p_Const(self, p):
|
||||
"""
|
||||
@ -2950,7 +3027,16 @@ class Parser(Tokenizer):
|
||||
self._filename = None
|
||||
|
||||
def finish(self):
|
||||
for production in self._productions:
|
||||
# First, finish all the IDLImplementsStatements. In particular, we
|
||||
# have to make sure we do those before we do the IDLInterfaces.
|
||||
# XXX khuey hates this bit and wants to nuke it from orbit.
|
||||
implementsStatements = [ p for p in self._productions if
|
||||
isinstance(p, IDLImplementsStatement)]
|
||||
otherStatements = [ p for p in self._productions if
|
||||
not isinstance(p, IDLImplementsStatement)]
|
||||
for production in implementsStatements:
|
||||
production.finish(self.globalScope())
|
||||
for production in otherStatements:
|
||||
production.finish(self.globalScope())
|
||||
|
||||
# De-duplicate self._productions, without modifying its order.
|
||||
|
143
dom/bindings/parser/tests/test_implements.py
Normal file
143
dom/bindings/parser/tests/test_implements.py
Normal file
@ -0,0 +1,143 @@
|
||||
# Import the WebIDL module, so we can do isinstance checks and whatnot
|
||||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
# Basic functionality
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
A implements B;
|
||||
interface B {
|
||||
attribute long x;
|
||||
};
|
||||
interface A {
|
||||
attribute long y;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(not threw, "Should not have thrown on implements statement "
|
||||
"before interfaces")
|
||||
harness.check(len(results), 3, "We have three statements")
|
||||
harness.ok(isinstance(results[1], WebIDL.IDLInterface), "B is an interface")
|
||||
harness.check(len(results[1].members), 1, "B has one member")
|
||||
A = results[2]
|
||||
harness.ok(isinstance(A, WebIDL.IDLInterface), "A is an interface")
|
||||
harness.check(len(A.members), 2, "A has two members")
|
||||
harness.check(A.members[0].identifier.name, "y", "First member is 'y'")
|
||||
harness.check(A.members[1].identifier.name, "x", "Second member is 'x'")
|
||||
|
||||
# Duplicated member names not allowed
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
C implements D;
|
||||
interface D {
|
||||
attribute long x;
|
||||
};
|
||||
interface C {
|
||||
attribute long x;
|
||||
};
|
||||
""")
|
||||
parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown on implemented interface duplicating "
|
||||
"a name on base interface")
|
||||
|
||||
# Same, but duplicated across implemented interfaces
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
E implements F;
|
||||
E implements G;
|
||||
interface F {
|
||||
attribute long x;
|
||||
};
|
||||
interface G {
|
||||
attribute long x;
|
||||
};
|
||||
interface E {};
|
||||
""")
|
||||
parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown on implemented interfaces "
|
||||
"duplicating each other's member names")
|
||||
|
||||
# Same, but duplicated across indirectly implemented interfaces
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
H implements I;
|
||||
H implements J;
|
||||
I implements K;
|
||||
interface K {
|
||||
attribute long x;
|
||||
};
|
||||
interface L {
|
||||
attribute long x;
|
||||
};
|
||||
interface I {};
|
||||
interface J : L {};
|
||||
interface H {};
|
||||
""")
|
||||
parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown on indirectly implemented interfaces "
|
||||
"duplicating each other's member names")
|
||||
|
||||
# Same, but duplicated across an implemented interface and its parent
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
M implements N;
|
||||
interface O {
|
||||
attribute long x;
|
||||
};
|
||||
interface N : O {
|
||||
attribute long x;
|
||||
};
|
||||
interface M {};
|
||||
""")
|
||||
parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown on implemented interface and its "
|
||||
"ancestor duplicating member names")
|
||||
|
||||
# Reset the parser so we can actually find things where we expect
|
||||
# them in the list
|
||||
parser = WebIDL.Parser()
|
||||
|
||||
# Diamonds should be allowed
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
P implements Q;
|
||||
P implements R;
|
||||
Q implements S;
|
||||
R implements S;
|
||||
interface Q {};
|
||||
interface R {};
|
||||
interface S {
|
||||
attribute long x;
|
||||
};
|
||||
interface P {};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(not threw, "Diamond inheritance is fine")
|
||||
harness.check(results[6].identifier.name, "S", "We should be looking at 'S'")
|
||||
harness.check(len(results[6].members), 1, "S should have one member")
|
||||
harness.check(results[6].members[0].identifier.name, "x",
|
||||
"S's member should be 'x'")
|
@ -44,6 +44,7 @@ bindinggen_dependencies := \
|
||||
../Bindings.conf \
|
||||
../Configuration.py \
|
||||
../Codegen.py \
|
||||
../parser/WebIDL.py \
|
||||
../ParserResults.pkl \
|
||||
../Makefile \
|
||||
$(GLOBAL_DEPS) \
|
||||
|
@ -294,6 +294,18 @@ public:
|
||||
int8_t GetAttributeRenamedTo(ErrorResult&);
|
||||
void SetAttributeRenamedTo(int8_t, ErrorResult&);
|
||||
|
||||
// Methods and properties imported via "implements"
|
||||
bool GetImplementedProperty(ErrorResult&);
|
||||
void SetImplementedProperty(bool, ErrorResult&);
|
||||
void ImplementedMethod(ErrorResult&);
|
||||
bool GetImplementedParentProperty(ErrorResult&);
|
||||
void SetImplementedParentProperty(bool, ErrorResult&);
|
||||
void ImplementedParentMethod(ErrorResult&);
|
||||
bool GetIndirectlyImplementedProperty(ErrorResult&);
|
||||
void SetIndirectlyImplementedProperty(bool, ErrorResult&);
|
||||
void IndirectlyImplementedMethod(ErrorResult&);
|
||||
uint32_t GetDiamondImplementedProperty(ErrorResult&);
|
||||
|
||||
private:
|
||||
// We add signatures here that _could_ start matching if the codegen
|
||||
// got data types wrong. That way if it ever does we'll have a call
|
||||
|
@ -16,6 +16,8 @@ enum TestEnum {
|
||||
|
||||
callback TestCallback = void();
|
||||
|
||||
TestInterface implements ImplementedInterface;
|
||||
|
||||
[Constructor,
|
||||
Constructor(DOMString str),
|
||||
Constructor(unsigned long num, boolean? bool),
|
||||
@ -223,3 +225,44 @@ interface TestInterface {
|
||||
readonly attribute byte attributeGetterRenamedFrom;
|
||||
attribute byte attributeRenamedFrom;
|
||||
};
|
||||
|
||||
interface ImplementedInterfaceParent {
|
||||
void implementedParentMethod();
|
||||
attribute boolean implementedParentProperty;
|
||||
|
||||
const long implementedParentConstant = 8;
|
||||
};
|
||||
|
||||
ImplementedInterfaceParent implements IndirectlyImplementedInterface;
|
||||
|
||||
interface IndirectlyImplementedInterface {
|
||||
void indirectlyImplementedMethod();
|
||||
attribute boolean indirectlyImplementedProperty;
|
||||
|
||||
const long indirectlyImplementedConstant = 9;
|
||||
};
|
||||
|
||||
interface ImplementedInterface : ImplementedInterfaceParent {
|
||||
void implementedMethod();
|
||||
attribute boolean implementedProperty;
|
||||
|
||||
const long implementedConstant = 5;
|
||||
};
|
||||
|
||||
interface DiamondImplements {
|
||||
readonly attribute long diamondImplementedProperty;
|
||||
};
|
||||
interface DiamondBranch1A {
|
||||
};
|
||||
interface DiamondBranch1B {
|
||||
};
|
||||
interface DiamondBranch2A : DiamondImplements {
|
||||
};
|
||||
interface DiamondBranch2B : DiamondImplements {
|
||||
};
|
||||
TestInterface implements DiamondBranch1A;
|
||||
TestInterface implements DiamondBranch1B;
|
||||
TestInterface implements DiamondBranch2A;
|
||||
TestInterface implements DiamondBranch2B;
|
||||
DiamondBranch1A implements DiamondImplements;
|
||||
DiamondBranch1B implements DiamondImplements;
|
||||
|
@ -16,6 +16,7 @@ Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
|
||||
// Event whitelisted for bubbling.
|
||||
let whitelistedEvents = [
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE, // Back button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_SLEEP, // Power button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_F5, // Search button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP, // Volume up.
|
||||
|
@ -9,6 +9,7 @@ let Ci = Components.interfaces;
|
||||
|
||||
let whitelistedEvents = [
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE, // Back button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_SLEEP, // Power button
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_F5, // Search button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP, // Volume up.
|
||||
@ -27,7 +28,7 @@ iframe.src = browserElementTestHelpers.focusPage;
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// Number of expected events at which point we will consider the test as done.
|
||||
var nbEvents = 15;
|
||||
var nbEvents = whitelistedEvents.length * 3;
|
||||
|
||||
function eventHandler(e) {
|
||||
ok(((e.type == 'keydown' || e.type == 'keypress' || e.type == 'keyup') &&
|
||||
@ -70,6 +71,7 @@ function runTest() {
|
||||
synthesizeKey("VK_PAGE_UP", {}); // keypress is ignored because .preventDefault() will be called.
|
||||
synthesizeKey("VK_PAGE_DOWN", {}); // keypress is ignored because .preventDefault() will be called.
|
||||
synthesizeKey("VK_CONTEXT_MENU", {});
|
||||
synthesizeKey("VK_SLEEP", {});
|
||||
}
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
|
@ -31,9 +31,7 @@ EXTRA_JS_MODULES = \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += tests
|
||||
endif
|
||||
TEST_DIRS += tests
|
||||
|
||||
# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
|
||||
# subdirectory (and the ipc one).
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsIPrincipal.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -307,7 +308,8 @@ public:
|
||||
nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
|
||||
nsIURI* aURI,
|
||||
DeviceStorageFile* aFile,
|
||||
bool aEditable);
|
||||
bool aEditable,
|
||||
PRUint64 aSince);
|
||||
|
||||
private:
|
||||
~nsDOMDeviceStorageCursor();
|
||||
@ -319,6 +321,7 @@ protected:
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
bool mEditable;
|
||||
PRUint64 mSince;
|
||||
|
||||
// to access mFiles
|
||||
friend class InitCursorEvent;
|
||||
@ -498,16 +501,30 @@ public:
|
||||
void collectFiles(DeviceStorageFile* aFile)
|
||||
{
|
||||
// TODO - we may want to do this incrementally.
|
||||
if (!aFile)
|
||||
if (!aFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
aFile->mFile->GetDirectoryEntries(getter_AddRefs(e));
|
||||
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDirectoryEnumerator> files = do_QueryInterface(e);
|
||||
nsCOMPtr<nsIFile> f;
|
||||
|
||||
while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(f))) && f) {
|
||||
nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
|
||||
|
||||
PRInt64 msecs;
|
||||
f->GetLastModifiedTime(&msecs);
|
||||
|
||||
if (msecs < (PRInt64) cursor->mSince) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isDir;
|
||||
f->IsDirectory(&isDir);
|
||||
|
||||
@ -534,7 +551,6 @@ public:
|
||||
collectFiles(dsf);
|
||||
}
|
||||
else if (isFile) {
|
||||
nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
|
||||
cursor->mFiles.AppendElement(dsf);
|
||||
}
|
||||
}
|
||||
@ -561,12 +577,14 @@ NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
|
||||
nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
|
||||
nsIURI* aURI,
|
||||
DeviceStorageFile* aFile,
|
||||
bool aEditable)
|
||||
bool aEditable,
|
||||
PRUint64 aSince)
|
||||
: DOMRequest(aWindow)
|
||||
, mOkToCallContinue(false)
|
||||
, mFile(aFile)
|
||||
, mURI(aURI)
|
||||
, mEditable(aEditable)
|
||||
, mSince(aSince)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1243,35 +1261,85 @@ nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMReq
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDeviceStorage::Enumerate(const nsAString & aPath,
|
||||
nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM)
|
||||
nsDOMDeviceStorage::Enumerate(const JS::Value & aName,
|
||||
const JS::Value & aOptions,
|
||||
JSContext* aCx,
|
||||
PRUint8 aArgc,
|
||||
nsIDOMDeviceStorageCursor** aRetval)
|
||||
{
|
||||
return EnumerateInternal(aPath, _retval, false);
|
||||
return EnumerateInternal(aName, aOptions, aCx, aArgc, false, aRetval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDeviceStorage::EnumerateEditable(const nsAString & aPath,
|
||||
nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM)
|
||||
nsDOMDeviceStorage::EnumerateEditable(const JS::Value & aName,
|
||||
const JS::Value & aOptions,
|
||||
JSContext* aCx,
|
||||
PRUint8 aArgc,
|
||||
nsIDOMDeviceStorageCursor** aRetval)
|
||||
{
|
||||
return EnumerateInternal(aPath, _retval, true);
|
||||
return EnumerateInternal(aName, aOptions, aCx, aArgc, true, aRetval);
|
||||
}
|
||||
|
||||
|
||||
static PRTime
|
||||
ExtractDateFromOptions(JSContext* aCx, const JS::Value& aOptions)
|
||||
{
|
||||
PRTime result = 0;
|
||||
DeviceStorageEnumerationParameters params;
|
||||
if (!JSVAL_IS_VOID(aOptions) && !aOptions.isNull()) {
|
||||
nsresult rv = params.Init(aCx, &aOptions);
|
||||
if (NS_SUCCEEDED(rv) && !JSVAL_IS_VOID(params.since) && !params.since.isNull() && params.since.isObject()) {
|
||||
JSObject* obj = JSVAL_TO_OBJECT(params.since);
|
||||
if (JS_ObjectIsDate(aCx, obj) && js_DateIsValid(aCx, obj)) {
|
||||
result = js_DateGetMsecSinceEpoch(aCx, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDeviceStorage::EnumerateInternal(const nsAString & aPath,
|
||||
nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM,
|
||||
bool aEditable)
|
||||
nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName,
|
||||
const JS::Value & aOptions,
|
||||
JSContext* aCx,
|
||||
PRUint8 aArgc,
|
||||
bool aEditable,
|
||||
nsIDOMDeviceStorageCursor** aRetval)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mOwner);
|
||||
if (!win)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, aPath);
|
||||
|
||||
nsRefPtr<nsDOMDeviceStorageCursor> cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, aEditable);
|
||||
NS_ADDREF(*_retval = cursor);
|
||||
PRTime since = 0;
|
||||
nsString path;
|
||||
path.SetIsVoid(true);
|
||||
|
||||
if (aArgc > 0) {
|
||||
// inspect the first value to see if it is a string
|
||||
if (JSVAL_IS_STRING(aName)) {
|
||||
JSString* jsstr = JS_ValueToString(aCx, aName);
|
||||
nsDependentJSString jspath;
|
||||
jspath.init(aCx, jsstr);
|
||||
path.Assign(jspath);
|
||||
} else if (!JSVAL_IS_PRIMITIVE(aName)) {
|
||||
// it also might be an options object
|
||||
since = ExtractDateFromOptions(aCx, aName);
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aArgc == 2 && (JSVAL_IS_VOID(aOptions) || aOptions.isNull() || !aOptions.isObject())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
since = ExtractDateFromOptions(aCx, aOptions);
|
||||
}
|
||||
|
||||
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
|
||||
nsRefPtr<nsDOMDeviceStorageCursor> cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, aEditable, since);
|
||||
nsRefPtr<DeviceStorageCursorRequest> r = new DeviceStorageCursorRequest(cursor);
|
||||
|
||||
NS_ADDREF(*aRetval = cursor);
|
||||
|
||||
if (mozilla::Preferences::GetBool("device.storage.prompt.testing", false)) {
|
||||
r->Allow();
|
||||
return NS_OK;
|
||||
|
@ -39,7 +39,8 @@ private:
|
||||
|
||||
|
||||
nsresult GetInternal(const JS::Value & aName, JSContext* aCx, nsIDOMDOMRequest * *_retval NS_OUTPARAM, bool aEditable);
|
||||
nsresult EnumerateInternal(const nsAString & aName, nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM, bool aEditable);
|
||||
|
||||
nsresult EnumerateInternal(const JS::Value & aName, const JS::Value & aOptions, JSContext* aCx, PRUint8 aArgc, bool aEditable, nsIDOMDeviceStorageCursor** aRetval);
|
||||
|
||||
PRInt32 mStorageType;
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
|
@ -1755,5 +1755,24 @@ IndexedDatabaseManager::AsyncDeleteFileRunnable::Run()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// sqlite3_quota_remove won't actually remove anything if we're not tracking
|
||||
// the quota here. Manually remove the file if it exists.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> file =
|
||||
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = file->InitWithPath(mFilePath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool exists;
|
||||
rv = file->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (exists) {
|
||||
rv = file->Remove(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2373,6 +2373,16 @@ DeleteDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
NS_WARNING("Failed to delete db file!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
// sqlite3_quota_remove won't actually remove anything if we're not tracking
|
||||
// the quota here. Manually remove the file if it exists.
|
||||
rv = dbFile->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (exists) {
|
||||
rv = dbFile->Remove(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> fileManagerDirectory;
|
||||
|
@ -7,6 +7,11 @@ interface nsIDOMBlob;
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIDOMDeviceStorageCursor;
|
||||
|
||||
dictionary DeviceStorageEnumerationParameters
|
||||
{
|
||||
jsval since;
|
||||
};
|
||||
|
||||
[scriptable, uuid(05C0D0C8-D698-4CCD-899C-7198A33BD7EC)]
|
||||
interface nsIDOMDeviceStorage : nsISupports
|
||||
{
|
||||
@ -28,7 +33,9 @@ interface nsIDOMDeviceStorage : nsISupports
|
||||
[implicit_jscontext]
|
||||
nsIDOMDOMRequest delete(in jsval aName);
|
||||
|
||||
nsIDOMDeviceStorageCursor enumerate([optional] in DOMString directory);
|
||||
[optional_argc, implicit_jscontext]
|
||||
nsIDOMDeviceStorageCursor enumerate([optional] in jsval aName, /* DeviceStorageEnumerationParameters */ [optional] in jsval options);
|
||||
|
||||
nsIDOMDeviceStorageCursor enumerateEditable([optional] in DOMString directory);
|
||||
[optional_argc, implicit_jscontext]
|
||||
nsIDOMDeviceStorageCursor enumerateEditable([optional] in jsval aName, /* DeviceStorageEnumerationParameters */ [optional] in jsval options);
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
p.setSitesWithDataCapabilities(true);
|
||||
|
||||
ok(PluginUtils.withTestPlugin(runTest), "Test plugin found");
|
||||
SimpleTest.finish();
|
||||
|
||||
function stored(needles) {
|
||||
var something = pluginHost.siteHasData(this.pluginTag, null);
|
||||
@ -191,8 +192,6 @@
|
||||
ok(!stored(["b\u00FCcher.nz"]), "Data cleared for UTF-8 representation");
|
||||
ok(!stored(["xn--bcher-kva.nz"]), "Data cleared for ACE representation");
|
||||
ok(!stored(null), "All data cleared");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
@ -36,9 +36,7 @@ XPIDLSRCS = \
|
||||
nsIPowerManagerService.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
@ -28,9 +28,7 @@ EXTRA_JS_MODULES = \
|
||||
SettingsChangeNotifier.jsm \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += tests
|
||||
endif
|
||||
TEST_DIRS += tests
|
||||
|
||||
# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
|
||||
# subdirectory (and the ipc one).
|
||||
|
@ -19,6 +19,8 @@ _TEST_FILES = \
|
||||
test_enumerateMultipleContinue.html \
|
||||
test_overwrite.html \
|
||||
test_dotdot.html \
|
||||
test_enumerateOptions.html \
|
||||
test_lastModificationFilter.html \
|
||||
devicestorage_common.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -5,6 +5,13 @@
|
||||
|
||||
var oldVal = false;
|
||||
|
||||
// Array Remove - By John Resig (MIT Licensed)
|
||||
Array.prototype.remove = function(from, to) {
|
||||
var rest = this.slice((to || from) + 1 || this.length);
|
||||
this.length = from < 0 ? this.length + from : from;
|
||||
return this.push.apply(this, rest);
|
||||
};
|
||||
|
||||
function devicestorage_setup() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
try {
|
||||
@ -46,3 +53,7 @@ function randomFilename(l) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function reportErrorAndQuit(e) {
|
||||
ok(false, "handleError was called : " + e.target.error.name);
|
||||
devicestorage_cleanup();
|
||||
}
|
||||
|
@ -22,13 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=717103
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
// Array Remove - By John Resig (MIT Licensed)
|
||||
Array.prototype.remove = function(from, to) {
|
||||
var rest = this.slice((to || from) + 1 || this.length);
|
||||
this.length = from < 0 ? this.length + from : from;
|
||||
return this.push.apply(this, rest);
|
||||
};
|
||||
|
||||
devicestorage_setup();
|
||||
|
||||
function enumerateSuccess(e) {
|
||||
@ -40,9 +33,6 @@ function enumerateSuccess(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
dump("asdfasdf"+ e.target.result + "\n");
|
||||
dump("asdfasdf"+ e.target.result.name + "\n");
|
||||
|
||||
var filename = e.target.result.name;
|
||||
|
||||
var index = files.indexOf(filename);
|
||||
|
81
dom/tests/mochitest/devicestorage/test_enumerateOptions.html
Normal file
81
dom/tests/mochitest/devicestorage/test_enumerateOptions.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=717103
|
||||
-->
|
||||
<head>
|
||||
<title>Test for basic sanity of the device storage API </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="devicestorage_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
devicestorage_setup()
|
||||
|
||||
storage = navigator.getDeviceStorage("profile");
|
||||
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate();
|
||||
} catch(e) {throws = true}
|
||||
ok(!throws, "enumerate no parameter");
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate("string");
|
||||
} catch(e) {throws = true}
|
||||
ok(!throws, "enumerate one string parameter");
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate("string", "string2");
|
||||
} catch(e) {throws = true}
|
||||
ok(throws, "enumerate two string parameter");
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate("string", {"since": 1});
|
||||
} catch(e) {throws = true}
|
||||
ok(!throws, "enumerate a string and object parameter");
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate({"path": "a"});
|
||||
} catch(e) {throws = true}
|
||||
ok(!throws, "enumerate object parameter with path");
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate({}, "string");
|
||||
} catch(e) {throws = true}
|
||||
ok(throws, "enumerate object then a string");
|
||||
|
||||
throws = false;
|
||||
try {
|
||||
var cursor = storage[0].enumerate({"path": "a", "since": 0});
|
||||
} catch(e) {throws = true}
|
||||
ok(!throws, "enumerate object parameter with path");
|
||||
|
||||
|
||||
|
||||
|
||||
devicestorage_cleanup()
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,111 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html> <!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=717103
|
||||
-->
|
||||
<head>
|
||||
<title>Test for the device storage API </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="devicestorage_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
|
||||
|
||||
function verifyAndDelete(prefix, files, e) {
|
||||
|
||||
if (e.target.result == null) {
|
||||
ok(files.length == 0, "when the enumeration is done, we shouldn't have any files in this array")
|
||||
dump("We still have length = " + files.length + "\n");
|
||||
dump(files + "\n");
|
||||
devicestorage_cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
var filename = e.target.result.name;
|
||||
|
||||
var index = files.indexOf(filename);
|
||||
ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
files.remove(index);
|
||||
|
||||
// clean up
|
||||
var storage = navigator.getDeviceStorage("profile");
|
||||
var cleanup = storage[0].delete(prefix + "/" + filename);
|
||||
cleanup.onsuccess = function(e) {}
|
||||
}
|
||||
|
||||
function addFiles(prefix, files, date, callback) {
|
||||
|
||||
const Cc = SpecialPowers.wrap(Components).classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
|
||||
for (var i=0; i<files.length; i++) {
|
||||
var f = directoryService.get("ProfD", Components.interfaces.nsIFile);
|
||||
var path = prefix + '/' + files[i];
|
||||
path.split("/").forEach(function(p) {
|
||||
f.appendRelativePath(p);
|
||||
});
|
||||
f.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
|
||||
f.lastModifiedTime = date;
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
|
||||
devicestorage_setup();
|
||||
|
||||
var prefix = "devicestorage/" + randomFilename(12)
|
||||
|
||||
var oldFiles = ["a", "b", "c"];
|
||||
var newFiles = ["d", "e", "f"];
|
||||
|
||||
// 157795200 is a long long time ago.
|
||||
addFiles(prefix, oldFiles, 157795200, addNewFiles);
|
||||
|
||||
function enumerateNew() {
|
||||
|
||||
var storage = navigator.getDeviceStorage("profile");
|
||||
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
|
||||
|
||||
// 836031600 is a long time ago
|
||||
var cursor = storage[0].enumerate(prefix, {"since": new Date(836031600)});
|
||||
cursor.onsuccess = function(e) {
|
||||
verifyAndDelete(prefix, newFiles, e);
|
||||
if (e.target.result) {
|
||||
e.target.continue();
|
||||
}
|
||||
}
|
||||
|
||||
cursor.onerror = function (e) {
|
||||
ok(false, "handleError was called : " + e.target.error.name);
|
||||
devicestorage_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
function addNewFiles() {
|
||||
addFiles(prefix, newFiles, Date.now(), enumerateNew);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -327,7 +327,7 @@ nsEditor::InstallEventListeners()
|
||||
NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Initialize the event target.
|
||||
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(GetRoot());
|
||||
nsCOMPtr<nsIContent> rootContent = GetRoot();
|
||||
NS_ENSURE_TRUE(rootContent, NS_ERROR_NOT_AVAILABLE);
|
||||
mEventTarget = do_QueryInterface(rootContent->GetParent());
|
||||
NS_ENSURE_TRUE(mEventTarget, NS_ERROR_NOT_AVAILABLE);
|
||||
@ -1938,8 +1938,9 @@ NS_IMETHODIMP
|
||||
nsEditor::DumpContentTree()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIContent> root = do_QueryInterface(mRootElement);
|
||||
if (root) root->List(stdout);
|
||||
if (mRootElement) {
|
||||
mRootElement->List(stdout);
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2139,7 +2140,7 @@ nsEditor::GetPreferredIMEState(IMEState *aState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(GetRoot());
|
||||
nsCOMPtr<nsIContent> content = GetRoot();
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
|
@ -2382,10 +2382,12 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection,
|
||||
// If something visible is deleted, no need to join.
|
||||
// Visible means all nodes except non-visible textnodes and breaks.
|
||||
if (join && origCollapsed) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(somenode);
|
||||
if (!content) {
|
||||
if (!somenode->IsContent()) {
|
||||
join = false;
|
||||
} else if (content->NodeType() == nsIDOMNode::TEXT_NODE) {
|
||||
continue;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = somenode->AsContent();
|
||||
if (content->NodeType() == nsIDOMNode::TEXT_NODE) {
|
||||
mHTMLEditor->IsVisTextNode(content, &join, true);
|
||||
} else {
|
||||
join = content->IsHTML(nsGkAtoms::br) &&
|
||||
|
@ -361,16 +361,17 @@ nsHTMLEditor::FindSelectionRoot(nsINode *aNode)
|
||||
aNode->IsNodeOfType(nsINode::eCONTENT),
|
||||
"aNode must be content or document node");
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIDocument> doc = aNode->GetCurrentDoc();
|
||||
if (!doc) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (doc->HasFlag(NODE_IS_EDITABLE) || !content) {
|
||||
nsCOMPtr<nsIContent> content;
|
||||
if (doc->HasFlag(NODE_IS_EDITABLE) || !aNode->IsContent()) {
|
||||
content = doc->GetRootElement();
|
||||
return content.forget();
|
||||
}
|
||||
content = aNode->AsContent();
|
||||
|
||||
// XXX If we have readonly flag, shouldn't return the element which has
|
||||
// contenteditable="true"? However, such case isn't there without chrome
|
||||
@ -3396,8 +3397,8 @@ nsHTMLEditor::DeleteSelectionImpl(EDirection aAction,
|
||||
NS_ENSURE_STATE(selection->GetAnchorFocusRange());
|
||||
NS_ENSURE_STATE(selection->GetAnchorFocusRange()->Collapsed());
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(selection->GetAnchorNode());
|
||||
NS_ENSURE_STATE(content);
|
||||
NS_ENSURE_STATE(selection->GetAnchorNode()->IsContent());
|
||||
nsCOMPtr<nsIContent> content = selection->GetAnchorNode()->AsContent();
|
||||
|
||||
// Don't strip wrappers if this is the only wrapper in the block. Then we'll
|
||||
// add a <br> later, so it won't be an empty wrapper in the end.
|
||||
|
@ -1177,10 +1177,13 @@ nsHTMLEditor::GetInlinePropertyBase(nsIAtom *aProperty,
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
for (iter->Init(range); !iter->IsDone(); iter->Next()) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(iter->GetCurrentNode());
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(content);
|
||||
if (!iter->GetCurrentNode()->IsContent()) {
|
||||
continue;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = iter->GetCurrentNode()->AsContent();
|
||||
nsCOMPtr<nsIDOMNode> node = content->AsDOMNode();
|
||||
|
||||
if (node && nsTextEditUtils::IsBody(node)) {
|
||||
if (nsTextEditUtils::IsBody(node)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1208,61 +1211,60 @@ nsHTMLEditor::GetInlinePropertyBase(nsIAtom *aProperty,
|
||||
// handle non-text leaf nodes here
|
||||
continue;
|
||||
}
|
||||
if (node) {
|
||||
bool isSet = false;
|
||||
if (first) {
|
||||
if (mHTMLCSSUtils->IsCSSEditableProperty(node, aProperty,
|
||||
aAttribute) &&
|
||||
// Bug 747889: we don't support CSS for fontSize values
|
||||
(aProperty != nsEditProperty::font ||
|
||||
!aAttribute->EqualsLiteral("size"))) {
|
||||
// the HTML styles defined by aProperty/aAttribute has a CSS
|
||||
// equivalence in this implementation for node; let's check if it
|
||||
// carries those css styles
|
||||
if (aValue) {
|
||||
firstValue.Assign(*aValue);
|
||||
}
|
||||
mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
|
||||
isSet, firstValue,
|
||||
COMPUTED_STYLE_TYPE);
|
||||
} else {
|
||||
IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, isSet,
|
||||
&firstValue);
|
||||
}
|
||||
*aFirst = isSet;
|
||||
first = false;
|
||||
if (outValue) {
|
||||
*outValue = firstValue;
|
||||
|
||||
bool isSet = false;
|
||||
if (first) {
|
||||
if (mHTMLCSSUtils->IsCSSEditableProperty(node, aProperty,
|
||||
aAttribute) &&
|
||||
// Bug 747889: we don't support CSS for fontSize values
|
||||
(aProperty != nsEditProperty::font ||
|
||||
!aAttribute->EqualsLiteral("size"))) {
|
||||
// the HTML styles defined by aProperty/aAttribute has a CSS
|
||||
// equivalence in this implementation for node; let's check if it
|
||||
// carries those css styles
|
||||
if (aValue) {
|
||||
firstValue.Assign(*aValue);
|
||||
}
|
||||
mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
|
||||
isSet, firstValue,
|
||||
COMPUTED_STYLE_TYPE);
|
||||
} else {
|
||||
if (mHTMLCSSUtils->IsCSSEditableProperty(node, aProperty,
|
||||
aAttribute) &&
|
||||
// Bug 747889: we don't support CSS for fontSize values
|
||||
(aProperty != nsEditProperty::font ||
|
||||
!aAttribute->EqualsLiteral("size"))) {
|
||||
// the HTML styles defined by aProperty/aAttribute has a CSS equivalence
|
||||
// in this implementation for node; let's check if it carries those css styles
|
||||
if (aValue) {
|
||||
theValue.Assign(*aValue);
|
||||
}
|
||||
mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
|
||||
isSet, theValue,
|
||||
COMPUTED_STYLE_TYPE);
|
||||
} else {
|
||||
IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, isSet,
|
||||
&theValue);
|
||||
}
|
||||
if (firstValue != theValue) {
|
||||
*aAll = false;
|
||||
}
|
||||
IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, isSet,
|
||||
&firstValue);
|
||||
}
|
||||
|
||||
if (isSet) {
|
||||
*aAny = true;
|
||||
*aFirst = isSet;
|
||||
first = false;
|
||||
if (outValue) {
|
||||
*outValue = firstValue;
|
||||
}
|
||||
} else {
|
||||
if (mHTMLCSSUtils->IsCSSEditableProperty(node, aProperty,
|
||||
aAttribute) &&
|
||||
// Bug 747889: we don't support CSS for fontSize values
|
||||
(aProperty != nsEditProperty::font ||
|
||||
!aAttribute->EqualsLiteral("size"))) {
|
||||
// the HTML styles defined by aProperty/aAttribute has a CSS equivalence
|
||||
// in this implementation for node; let's check if it carries those css styles
|
||||
if (aValue) {
|
||||
theValue.Assign(*aValue);
|
||||
}
|
||||
mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, aAttribute,
|
||||
isSet, theValue,
|
||||
COMPUTED_STYLE_TYPE);
|
||||
} else {
|
||||
IsTextPropertySetByContent(node, aProperty, aAttribute, aValue, isSet,
|
||||
&theValue);
|
||||
}
|
||||
if (firstValue != theValue) {
|
||||
*aAll = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSet) {
|
||||
*aAny = true;
|
||||
} else {
|
||||
*aAll = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!*aAny) {
|
||||
@ -1621,8 +1623,8 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsCOMArray<nsIContent> arrayOfNodes;
|
||||
while (!iter->IsDone()) {
|
||||
nsCOMPtr<nsIContent> node = do_QueryInterface(iter->GetCurrentNode());
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(iter->GetCurrentNode()->IsContent(), NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIContent> node = iter->GetCurrentNode()->AsContent();
|
||||
|
||||
if (IsEditable(node)) {
|
||||
arrayOfNodes.AppendObject(node);
|
||||
|
@ -1,19 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<textarea id="testBox" readonly></textarea>
|
||||
<script type="text/javascript">
|
||||
//Adding focus to the textbox should trigger a spellcheck
|
||||
var textbox = document.getElementById("testBox");
|
||||
addEventListener("load", function() {
|
||||
textbox.readOnly = false;
|
||||
textbox.focus();
|
||||
textbox.value = "blahblahblah";
|
||||
textbox.selectionStart = textbox.selectionEnd = 0;
|
||||
textbox.blur();
|
||||
}, false);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<textarea id="testBox" readonly></textarea>
|
||||
<script type="text/javascript">
|
||||
//Adding focus to the textbox should trigger a spellcheck
|
||||
var textbox = document.getElementById("testBox");
|
||||
addEventListener("load", function() {
|
||||
textbox.readOnly = false;
|
||||
textbox.focus();
|
||||
textbox.value = "blahblahblah";
|
||||
textbox.selectionStart = textbox.selectionEnd = 0;
|
||||
textbox.blur();
|
||||
}, false);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -785,13 +785,11 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
|
||||
|
||||
while (!iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(iter->GetCurrentNode());
|
||||
|
||||
if (IsTextNode(content))
|
||||
{
|
||||
if (iter->GetCurrentNode()->NodeType() == nsIDOMNode::TEXT_NODE) {
|
||||
// We found a text node, so position the document's
|
||||
// iterator at the beginning of the block, then get
|
||||
// the selection in terms of the string offset.
|
||||
nsCOMPtr<nsIContent> content = iter->GetCurrentNode()->AsContent();
|
||||
|
||||
result = mIterator->PositionAt(content);
|
||||
|
||||
@ -910,12 +908,10 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
|
||||
|
||||
while (!iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(iter->GetCurrentNode());
|
||||
|
||||
if (IsTextNode(content))
|
||||
{
|
||||
if (iter->GetCurrentNode()->NodeType() == nsIDOMNode::TEXT_NODE) {
|
||||
// We found a text node! Adjust the document's iterator to point
|
||||
// to the beginning of its text block, then get the current selection.
|
||||
nsCOMPtr<nsIContent> content = iter->GetCurrentNode()->AsContent();
|
||||
|
||||
result = mIterator->PositionAt(content);
|
||||
|
||||
@ -1377,13 +1373,13 @@ nsTextServicesDocument::DeleteSelection()
|
||||
|
||||
nsCOMPtr<nsIContent> curContent;
|
||||
|
||||
if (mIteratorStatus != nsTextServicesDocument::eIsDone)
|
||||
{
|
||||
if (mIteratorStatus != nsTextServicesDocument::eIsDone &&
|
||||
mIterator->GetCurrentNode()->IsContent()) {
|
||||
// The old iterator is still pointing to something valid,
|
||||
// so get its current node so we can restore it after we
|
||||
// create the new iterator!
|
||||
|
||||
curContent = do_QueryInterface(mIterator->GetCurrentNode());
|
||||
curContent = mIterator->GetCurrentNode()->AsContent();
|
||||
}
|
||||
|
||||
// Create the new iterator.
|
||||
@ -2674,8 +2670,8 @@ nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockS
|
||||
} else {
|
||||
// The parent has no children, so position the iterator
|
||||
// on the parent.
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(parent);
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(parent->IsContent(), NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIContent> content = parent->AsContent();
|
||||
|
||||
result = iter->PositionAt(content);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
@ -3160,7 +3156,9 @@ nsTextServicesDocument::FirstTextNodeInCurrentBlock(nsIContentIterator *iter)
|
||||
|
||||
while (!iter->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(iter->GetCurrentNode());
|
||||
nsCOMPtr<nsIContent> content = iter->GetCurrentNode()->IsContent()
|
||||
? iter->GetCurrentNode()->AsContent()
|
||||
: nsnull;
|
||||
|
||||
if (IsTextNode(content))
|
||||
{
|
||||
@ -3231,7 +3229,9 @@ nsTextServicesDocument::FirstTextNodeInNextBlock(nsIContentIterator *aIterator)
|
||||
|
||||
while (!aIterator->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aIterator->GetCurrentNode());
|
||||
nsCOMPtr<nsIContent> content = aIterator->GetCurrentNode()->IsContent()
|
||||
? aIterator->GetCurrentNode()->AsContent()
|
||||
: nsnull;
|
||||
|
||||
if (IsTextNode(content))
|
||||
{
|
||||
@ -3277,7 +3277,9 @@ nsTextServicesDocument::GetFirstTextNodeInPrevBlock(nsIContent **aContent)
|
||||
|
||||
if (!mIterator->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> current = do_QueryInterface(mIterator->GetCurrentNode());
|
||||
nsCOMPtr<nsIContent> current = mIterator->GetCurrentNode()->IsContent()
|
||||
? mIterator->GetCurrentNode()->AsContent()
|
||||
: nsnull;
|
||||
current.forget(aContent);
|
||||
}
|
||||
|
||||
@ -3311,7 +3313,9 @@ nsTextServicesDocument::GetFirstTextNodeInNextBlock(nsIContent **aContent)
|
||||
|
||||
if (!mIterator->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> current = do_QueryInterface(mIterator->GetCurrentNode());
|
||||
nsCOMPtr<nsIContent> current = mIterator->GetCurrentNode()->IsContent()
|
||||
? mIterator->GetCurrentNode()->AsContent()
|
||||
: nsnull;
|
||||
current.forget(aContent);
|
||||
}
|
||||
|
||||
@ -3371,7 +3375,9 @@ nsTextServicesDocument::CreateOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable,
|
||||
|
||||
while (!aIterator->IsDone())
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aIterator->GetCurrentNode());
|
||||
nsCOMPtr<nsIContent> content = aIterator->GetCurrentNode()->IsContent()
|
||||
? aIterator->GetCurrentNode()->AsContent()
|
||||
: nsnull;
|
||||
|
||||
if (IsTextNode(content))
|
||||
{
|
||||
|
@ -311,10 +311,24 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (PR_GetEnv("MOZ_GL_DEBUG"))
|
||||
sDebugMode |= DebugEnabled;
|
||||
|
||||
// enables extra verbose output, informing of the start and finish of every GL call.
|
||||
// useful e.g. to record information to investigate graphics system crashes/lockups
|
||||
if (PR_GetEnv("MOZ_GL_DEBUG_VERBOSE"))
|
||||
sDebugMode |= DebugTrace;
|
||||
|
||||
// aborts on GL error. Can be useful to debug quicker code that is known not to generate any GL error in principle.
|
||||
if (PR_GetEnv("MOZ_GL_DEBUG_ABORT_ON_ERROR"))
|
||||
sDebugMode |= DebugAbortOnError;
|
||||
#endif
|
||||
|
||||
if (mInitialized) {
|
||||
#ifdef DEBUG
|
||||
static bool once = false;
|
||||
if (!once) {
|
||||
if (DebugMode() && !once) {
|
||||
const char *vendors[VendorOther] = {
|
||||
"Intel",
|
||||
"NVIDIA",
|
||||
@ -486,20 +500,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
UpdateActualFormat();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (PR_GetEnv("MOZ_GL_DEBUG"))
|
||||
sDebugMode |= DebugEnabled;
|
||||
|
||||
// enables extra verbose output, informing of the start and finish of every GL call.
|
||||
// useful e.g. to record information to investigate graphics system crashes/lockups
|
||||
if (PR_GetEnv("MOZ_GL_DEBUG_VERBOSE"))
|
||||
sDebugMode |= DebugTrace;
|
||||
|
||||
// aborts on GL error. Can be useful to debug quicker code that is known not to generate any GL error in principle.
|
||||
if (PR_GetEnv("MOZ_GL_DEBUG_ABORT_ON_ERROR"))
|
||||
sDebugMode |= DebugAbortOnError;
|
||||
#endif
|
||||
|
||||
if (mInitialized)
|
||||
reporter.SetSuccessful();
|
||||
else {
|
||||
@ -527,7 +527,7 @@ GLContext::InitExtensions()
|
||||
const bool once = true;
|
||||
#endif
|
||||
|
||||
if (!once) {
|
||||
if (DebugMode() && !once) {
|
||||
printf_stderr("GL extensions: %s\n", exts);
|
||||
}
|
||||
|
||||
@ -543,7 +543,7 @@ GLContext::InitExtensions()
|
||||
|
||||
for (int i = 0; sExtensionNames[i]; ++i) {
|
||||
if (strcmp(s, sExtensionNames[i]) == 0) {
|
||||
if (!once) {
|
||||
if (DebugMode() && !once) {
|
||||
printf_stderr("Found extension %s\n", s);
|
||||
}
|
||||
mAvailableExtensions[i] = 1;
|
||||
@ -1505,7 +1505,9 @@ GLContext::AssembleOffscreenFBOs(const GLuint colorMSRB,
|
||||
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
||||
NS_WARNING("DrawFBO: Incomplete");
|
||||
#ifdef DEBUG
|
||||
printf_stderr("Framebuffer status: %X\n", status);
|
||||
if (DebugMode()) {
|
||||
printf_stderr("Framebuffer status: %X\n", status);
|
||||
}
|
||||
#endif
|
||||
isComplete = false;
|
||||
}
|
||||
@ -1515,7 +1517,9 @@ GLContext::AssembleOffscreenFBOs(const GLuint colorMSRB,
|
||||
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
||||
NS_WARNING("ReadFBO: Incomplete");
|
||||
#ifdef DEBUG
|
||||
printf_stderr("Framebuffer status: %X\n", status);
|
||||
if (DebugMode()) {
|
||||
printf_stderr("Framebuffer status: %X\n", status);
|
||||
}
|
||||
#endif
|
||||
isComplete = false;
|
||||
}
|
||||
@ -3038,19 +3042,21 @@ ReportArrayContents(const nsTArray<GLContext::NamedResource>& aArray)
|
||||
void
|
||||
GLContext::ReportOutstandingNames()
|
||||
{
|
||||
printf_stderr("== GLContext %p ==\n", this);
|
||||
printf_stderr("Outstanding Textures:\n");
|
||||
ReportArrayContents(mTrackedTextures);
|
||||
printf_stderr("Outstanding Buffers:\n");
|
||||
ReportArrayContents(mTrackedBuffers);
|
||||
printf_stderr("Outstanding Programs:\n");
|
||||
ReportArrayContents(mTrackedPrograms);
|
||||
printf_stderr("Outstanding Shaders:\n");
|
||||
ReportArrayContents(mTrackedShaders);
|
||||
printf_stderr("Outstanding Framebuffers:\n");
|
||||
ReportArrayContents(mTrackedFramebuffers);
|
||||
printf_stderr("Outstanding Renderbuffers:\n");
|
||||
ReportArrayContents(mTrackedRenderbuffers);
|
||||
if (DebugMode()) {
|
||||
printf_stderr("== GLContext %p ==\n", this);
|
||||
printf_stderr("Outstanding Textures:\n");
|
||||
ReportArrayContents(mTrackedTextures);
|
||||
printf_stderr("Outstanding Buffers:\n");
|
||||
ReportArrayContents(mTrackedBuffers);
|
||||
printf_stderr("Outstanding Programs:\n");
|
||||
ReportArrayContents(mTrackedPrograms);
|
||||
printf_stderr("Outstanding Shaders:\n");
|
||||
ReportArrayContents(mTrackedShaders);
|
||||
printf_stderr("Outstanding Framebuffers:\n");
|
||||
ReportArrayContents(mTrackedFramebuffers);
|
||||
printf_stderr("Outstanding Renderbuffers:\n");
|
||||
ReportArrayContents(mTrackedRenderbuffers);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
@ -658,7 +658,9 @@ public:
|
||||
GLX_DOUBLEBUFFER, &db);
|
||||
if (GLX_BAD_ATTRIBUTE != err) {
|
||||
#ifdef DEBUG
|
||||
printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
|
||||
if (DebugMode()) {
|
||||
printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
* effective visible region (snapped or unsnapped, it doesn't matter).
|
||||
*/
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMasklayer,
|
||||
Layer* aMasklayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback) {}
|
||||
@ -98,14 +98,14 @@ public:
|
||||
mOperator = aOperator;
|
||||
}
|
||||
gfxContext::GraphicsOperator GetOperator() const { return mOperator; }
|
||||
|
||||
/**
|
||||
* Return a surface for this layer. Will use an existing surface, if
|
||||
* possible, or may create a temporary surface.
|
||||
* Implement this method for any layers that might be used as a mask.
|
||||
* Should only return null if a surface cannor be created.
|
||||
*/
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Return a surface for this layer. Will use an existing surface, if
|
||||
* possible, or may create a temporary surface.
|
||||
* Implement this method for any layers that might be used as a mask.
|
||||
* Should only return null if a surface cannor be created.
|
||||
*/
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() { return nsnull; }
|
||||
|
||||
bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
@ -184,7 +184,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
|
@ -872,7 +872,7 @@ LayerD3D10::LoadMaskTexture()
|
||||
|
||||
gfxMatrix maskTransform;
|
||||
bool maskIs2D = maskLayer->GetEffectiveTransform().CanDraw2D(&maskTransform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
gfxRect bounds = gfxRect(gfxPoint(), size);
|
||||
bounds = maskTransform.TransformBounds(bounds);
|
||||
|
||||
|
@ -35,7 +35,7 @@ gfxAndroidPlatform::gfxAndroidPlatform()
|
||||
|
||||
mOffscreenFormat = mScreenDepth == 16
|
||||
? gfxASurface::ImageFormatRGB16_565
|
||||
: gfxASurface::ImageFormatARGB32;
|
||||
: gfxASurface::ImageFormatRGB24;
|
||||
}
|
||||
|
||||
gfxAndroidPlatform::~gfxAndroidPlatform()
|
||||
|
@ -447,37 +447,44 @@ class _DestroyReason:
|
||||
## Intermediate representation (IR) nodes used during lowering
|
||||
|
||||
class _ConvertToCxxType(TypeVisitor):
|
||||
def __init__(self, side): self.side = side
|
||||
def __init__(self, side, fq):
|
||||
self.side = side
|
||||
self.fq = fq
|
||||
|
||||
def typename(self, thing):
|
||||
if self.fq:
|
||||
return thing.fullname()
|
||||
return thing.name()
|
||||
|
||||
def visitBuiltinCxxType(self, t):
|
||||
return Type(t.name())
|
||||
return Type(self.typename(t))
|
||||
|
||||
def visitImportedCxxType(self, t):
|
||||
return Type(t.name())
|
||||
return Type(self.typename(t))
|
||||
|
||||
def visitActorType(self, a):
|
||||
return Type(_actorName(a.protocol.name(), self.side), ptr=1)
|
||||
return Type(_actorName(self.typename(a.protocol), self.side), ptr=1)
|
||||
|
||||
def visitStructType(self, s):
|
||||
return Type(s.name())
|
||||
return Type(self.typename(s))
|
||||
|
||||
def visitUnionType(self, u):
|
||||
return Type(u.name())
|
||||
return Type(self.typename(u))
|
||||
|
||||
def visitArrayType(self, a):
|
||||
basecxxtype = a.basetype.accept(self)
|
||||
return _cxxArrayType(basecxxtype)
|
||||
|
||||
def visitShmemType(self, s):
|
||||
return Type(s.name())
|
||||
return Type(self.typename(s))
|
||||
|
||||
def visitProtocolType(self, p): assert 0
|
||||
def visitMessageType(self, m): assert 0
|
||||
def visitVoidType(self, v): assert 0
|
||||
def visitStateType(self, st): assert 0
|
||||
|
||||
def _cxxBareType(ipdltype, side):
|
||||
return ipdltype.accept(_ConvertToCxxType(side))
|
||||
def _cxxBareType(ipdltype, side, fq=0):
|
||||
return ipdltype.accept(_ConvertToCxxType(side, fq))
|
||||
|
||||
def _cxxRefType(ipdltype, side):
|
||||
t = _cxxBareType(ipdltype, side)
|
||||
@ -1531,11 +1538,13 @@ class _GenerateProtocolCode(ipdl.ast.Visitor):
|
||||
def genBridgeFunc(self, bridge):
|
||||
p = self.protocol
|
||||
parentHandleType = _cxxBareType(ActorType(bridge.parent.ptype),
|
||||
_otherSide(bridge.parent.side))
|
||||
_otherSide(bridge.parent.side),
|
||||
fq=1)
|
||||
parentvar = ExprVar('parentHandle')
|
||||
|
||||
childHandleType = _cxxBareType(ActorType(bridge.child.ptype),
|
||||
_otherSide(bridge.child.side))
|
||||
_otherSide(bridge.child.side),
|
||||
fq=1)
|
||||
childvar = ExprVar('childHandle')
|
||||
|
||||
bridgefunc = MethodDefn(MethodDecl(
|
||||
@ -1556,7 +1565,8 @@ class _GenerateProtocolCode(ipdl.ast.Visitor):
|
||||
def genOpenFunc(self, o):
|
||||
p = self.protocol
|
||||
localside = o.opener.side
|
||||
openertype = _cxxBareType(ActorType(o.opener.ptype), o.opener.side)
|
||||
openertype = _cxxBareType(ActorType(o.opener.ptype), o.opener.side,
|
||||
fq=1)
|
||||
openervar = ExprVar('opener')
|
||||
openfunc = MethodDefn(MethodDecl(
|
||||
'Open',
|
||||
|
@ -1,5 +1,5 @@
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
namespace _ipdltest2 {
|
||||
|
||||
// (Opens protocols can have different semantics than the endpoints
|
||||
// that opened them)
|
||||
@ -25,4 +25,4 @@ state DEAD:
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
||||
} // namespace _ipdltest2
|
||||
|
@ -12,17 +12,19 @@ struct RunnableMethodTraits<mozilla::_ipdltest::TestOpensChild>
|
||||
};
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::_ipdltest::TestOpensOpenedChild>
|
||||
struct RunnableMethodTraits<mozilla::_ipdltest2::TestOpensOpenedChild>
|
||||
{
|
||||
static void RetainCallee(mozilla::_ipdltest::TestOpensOpenedChild* obj) { }
|
||||
static void ReleaseCallee(mozilla::_ipdltest::TestOpensOpenedChild* obj) { }
|
||||
static void RetainCallee(mozilla::_ipdltest2::TestOpensOpenedChild* obj) { }
|
||||
static void ReleaseCallee(mozilla::_ipdltest2::TestOpensOpenedChild* obj) { }
|
||||
};
|
||||
|
||||
using namespace base;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
// NB: this is generally bad style, but I am lazy.
|
||||
using namespace _ipdltest;
|
||||
using namespace _ipdltest2;
|
||||
|
||||
static MessageLoop* gMainThread;
|
||||
|
||||
@ -274,5 +276,4 @@ TestOpensOpenedChild::ActorDestroy(ActorDestroyReason why)
|
||||
this, mTransport));
|
||||
}
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
@ -6,14 +6,15 @@
|
||||
#include "mozilla/_ipdltest/PTestOpensParent.h"
|
||||
#include "mozilla/_ipdltest/PTestOpensChild.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestOpensOpenedParent.h"
|
||||
#include "mozilla/_ipdltest/PTestOpensOpenedChild.h"
|
||||
#include "mozilla/_ipdltest2/PTestOpensOpenedParent.h"
|
||||
#include "mozilla/_ipdltest2/PTestOpensOpenedChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
// parent process
|
||||
|
||||
namespace _ipdltest {
|
||||
|
||||
class TestOpensParent : public PTestOpensParent
|
||||
{
|
||||
public:
|
||||
@ -34,6 +35,10 @@ protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
|
||||
namespace _ipdltest2 {
|
||||
|
||||
class TestOpensOpenedParent : public PTestOpensOpenedParent
|
||||
{
|
||||
public:
|
||||
@ -56,9 +61,12 @@ protected:
|
||||
Transport* mTransport;
|
||||
};
|
||||
|
||||
} // namespace _ipdltest2
|
||||
|
||||
// child process
|
||||
|
||||
namespace _ipdltest {
|
||||
|
||||
class TestOpensChild : public PTestOpensChild
|
||||
{
|
||||
public:
|
||||
@ -77,6 +85,10 @@ protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
|
||||
namespace _ipdltest2 {
|
||||
|
||||
class TestOpensOpenedChild : public PTestOpensOpenedChild
|
||||
{
|
||||
public:
|
||||
@ -99,8 +111,8 @@ protected:
|
||||
Transport* mTransport;
|
||||
};
|
||||
|
||||
} // namespace _ipdltest2
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
|
@ -220,10 +220,10 @@ class HashTable : private AllocPolicy
|
||||
JS_ASSERT(&k != &HashPolicy::getKey(this->cur->t));
|
||||
if (match(*this->cur, l))
|
||||
return;
|
||||
Entry e = *this->cur;
|
||||
HashPolicy::setKey(e.t, const_cast<Key &>(k));
|
||||
typename HashTableEntry<T>::NonConstT t = this->cur->t;
|
||||
HashPolicy::setKey(t, const_cast<Key &>(k));
|
||||
table.remove(*this->cur);
|
||||
table.add(l, e);
|
||||
table.putNewInfallible(l, t);
|
||||
added = true;
|
||||
this->validEntry = false;
|
||||
}
|
||||
@ -234,22 +234,27 @@ class HashTable : private AllocPolicy
|
||||
|
||||
/* Potentially rehashes the table. */
|
||||
~Enum() {
|
||||
if (added)
|
||||
table.checkOverloaded();
|
||||
JS_ASSERT(!added);
|
||||
if (removed)
|
||||
table.checkUnderloaded();
|
||||
}
|
||||
|
||||
/* Can be used to end the enumeration before the destructor. */
|
||||
void endEnumeration() {
|
||||
/*
|
||||
* Can be used to end the enumeration before the destructor. Unlike
|
||||
* |~Enum()|, this can report OOM on resize, so must be called if
|
||||
* |rekeyFront()| is used during enumeration.
|
||||
*/
|
||||
bool endEnumeration() {
|
||||
if (added) {
|
||||
table.checkOverloaded();
|
||||
added = false;
|
||||
if (table.checkOverloaded() == RehashFailed)
|
||||
return false;
|
||||
}
|
||||
if (removed) {
|
||||
table.checkUnderloaded();
|
||||
removed = false;
|
||||
table.checkUnderloaded();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -519,7 +524,7 @@ class HashTable : private AllocPolicy
|
||||
Entry *entry = &table[h1];
|
||||
|
||||
/* Miss: return space for a new entry. */
|
||||
if (entry->isFree()) {
|
||||
if (!entry->isLive()) {
|
||||
METER(stats.misses++);
|
||||
return *entry;
|
||||
}
|
||||
@ -535,14 +540,16 @@ class HashTable : private AllocPolicy
|
||||
h1 = applyDoubleHash(h1, dh);
|
||||
|
||||
entry = &table[h1];
|
||||
if (entry->isFree()) {
|
||||
if (!entry->isLive()) {
|
||||
METER(stats.misses++);
|
||||
return *entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool changeTableSize(int deltaLog2)
|
||||
enum RebuildStatus { NotOverloaded, Rehashed, RehashFailed };
|
||||
|
||||
RebuildStatus changeTableSize(int deltaLog2)
|
||||
{
|
||||
/* Look, but don't touch, until we succeed in getting new entry store. */
|
||||
Entry *oldTable = table;
|
||||
@ -551,12 +558,12 @@ class HashTable : private AllocPolicy
|
||||
uint32_t newCapacity = JS_BIT(newLog2);
|
||||
if (newCapacity > sMaxCapacity) {
|
||||
this->reportAllocOverflow();
|
||||
return false;
|
||||
return RehashFailed;
|
||||
}
|
||||
|
||||
Entry *newTable = createTable(*this, newCapacity);
|
||||
if (!newTable)
|
||||
return false;
|
||||
return RehashFailed;
|
||||
|
||||
/* We can't fail from here on, so update table parameters. */
|
||||
setTableSizeLog2(newLog2);
|
||||
@ -573,32 +580,13 @@ class HashTable : private AllocPolicy
|
||||
}
|
||||
|
||||
destroyTable(*this, oldTable, oldCap);
|
||||
return true;
|
||||
return Rehashed;
|
||||
}
|
||||
|
||||
void add(const Lookup &l, const Entry &e)
|
||||
{
|
||||
JS_ASSERT(table);
|
||||
|
||||
HashNumber keyHash = prepareHash(l);
|
||||
Entry &entry = lookup(l, keyHash, sCollisionBit);
|
||||
|
||||
if (entry.isRemoved()) {
|
||||
METER(stats.addOverRemoved++);
|
||||
removedCount--;
|
||||
keyHash |= sCollisionBit;
|
||||
}
|
||||
|
||||
entry.t = e.t;
|
||||
entry.setLive(keyHash);
|
||||
entryCount++;
|
||||
mutationCount++;
|
||||
}
|
||||
|
||||
bool checkOverloaded()
|
||||
RebuildStatus checkOverloaded()
|
||||
{
|
||||
if (!overloaded())
|
||||
return false;
|
||||
return NotOverloaded;
|
||||
|
||||
/* Compress if a quarter or more of all entries are removed. */
|
||||
int deltaLog2;
|
||||
@ -732,8 +720,11 @@ class HashTable : private AllocPolicy
|
||||
removedCount--;
|
||||
p.keyHash |= sCollisionBit;
|
||||
} else {
|
||||
if (checkOverloaded())
|
||||
/* Preserve the validity of |p.entry|. */
|
||||
/* Preserve the validity of |p.entry|. */
|
||||
RebuildStatus status = checkOverloaded();
|
||||
if (status == RehashFailed)
|
||||
return false;
|
||||
if (status == Rehashed)
|
||||
p.entry = &findFreeEntry(p.keyHash);
|
||||
}
|
||||
|
||||
@ -764,6 +755,34 @@ class HashTable : private AllocPolicy
|
||||
return true;
|
||||
}
|
||||
|
||||
void putNewInfallible(const Lookup &l, const T &t)
|
||||
{
|
||||
JS_ASSERT(table);
|
||||
|
||||
HashNumber keyHash = prepareHash(l);
|
||||
Entry *entry = &findFreeEntry(keyHash);
|
||||
|
||||
if (entry->isRemoved()) {
|
||||
METER(stats.addOverRemoved++);
|
||||
removedCount--;
|
||||
keyHash |= sCollisionBit;
|
||||
}
|
||||
|
||||
entry->t = t;
|
||||
entry->setLive(keyHash);
|
||||
entryCount++;
|
||||
mutationCount++;
|
||||
}
|
||||
|
||||
bool putNew(const Lookup &l, const T &t)
|
||||
{
|
||||
if (checkOverloaded() == RehashFailed)
|
||||
return false;
|
||||
|
||||
putNewInfallible(l, t);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool relookupOrAdd(AddPtr& p, const Lookup &l, const T& t)
|
||||
{
|
||||
p.mutationCount = mutationCount;
|
||||
@ -1149,9 +1168,7 @@ class HashMap
|
||||
|
||||
/* Like put, but assert that the given key is not already present. */
|
||||
bool putNew(const Key &k, const Value &v) {
|
||||
AddPtr p = lookupForAdd(k);
|
||||
JS_ASSERT(!p);
|
||||
return add(p, k, v);
|
||||
return impl.putNew(k, Entry(k, v));
|
||||
}
|
||||
|
||||
/* Add (k,defaultValue) if k no found. Return false-y Ptr on oom. */
|
||||
@ -1357,15 +1374,11 @@ class HashSet
|
||||
|
||||
/* Like put, but assert that the given key is not already present. */
|
||||
bool putNew(const T &t) {
|
||||
AddPtr p = lookupForAdd(t);
|
||||
JS_ASSERT(!p);
|
||||
return add(p, t);
|
||||
return impl.putNew(t, t);
|
||||
}
|
||||
|
||||
bool putNew(const Lookup &l, const T &t) {
|
||||
AddPtr p = lookupForAdd(l);
|
||||
JS_ASSERT(!p);
|
||||
return add(p, t);
|
||||
return impl.putNew(l, t);
|
||||
}
|
||||
|
||||
void remove(const Lookup &l) {
|
||||
|
1
js/src/aclocal.m4
vendored
1
js/src/aclocal.m4
vendored
@ -17,5 +17,6 @@ builtin(include, build/autoconf/frameptr.m4)dnl
|
||||
builtin(include, build/autoconf/compiler-opts.m4)dnl
|
||||
builtin(include, build/autoconf/expandlibs.m4)dnl
|
||||
builtin(include, build/autoconf/arch.m4)dnl
|
||||
builtin(include, build/autoconf/android.m4)dn
|
||||
|
||||
MOZ_PROG_CHECKMSYS()
|
||||
|
241
js/src/build/autoconf/android.m4
Normal file
241
js/src/build/autoconf/android.m4
Normal file
@ -0,0 +1,241 @@
|
||||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
AC_DEFUN([MOZ_ANDROID_NDK],
|
||||
[
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-ndk,
|
||||
[ --with-android-ndk=DIR
|
||||
location where the Android NDK can be found],
|
||||
android_ndk=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-toolchain,
|
||||
[ --with-android-toolchain=DIR
|
||||
location of the android toolchain],
|
||||
android_toolchain=$withval)
|
||||
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-version,
|
||||
[ --with-android-version=VER
|
||||
android platform version, default 5],
|
||||
android_version=$withval,
|
||||
android_version=5)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-platform,
|
||||
[ --with-android-platform=DIR
|
||||
location of platform dir],
|
||||
android_platform=$withval)
|
||||
|
||||
case "$target" in
|
||||
arm-linux*-android*|*-linuxandroid*)
|
||||
android_tool_prefix="arm-linux-androideabi"
|
||||
;;
|
||||
i?86-*android*)
|
||||
android_tool_prefix="i686-android-linux"
|
||||
;;
|
||||
mipsel-*android*)
|
||||
android_tool_prefix="mipsel-linux-android"
|
||||
;;
|
||||
*)
|
||||
android_tool_prefix="$target_os"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$android_ndk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
|
||||
fi
|
||||
|
||||
if test -z "$android_toolchain" ; then
|
||||
AC_MSG_CHECKING([for android toolchain directory])
|
||||
|
||||
kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm-linux-androideabi-4.4.3
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86-4.4.3
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mipsel-linux-android-4.4.3
|
||||
;;
|
||||
esac
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
|
||||
if test -d "$android_toolchain" ; then
|
||||
AC_MSG_RESULT([$android_toolchain])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$android_platform" ; then
|
||||
AC_MSG_CHECKING([for android platform directory])
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mips
|
||||
;;
|
||||
esac
|
||||
|
||||
android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
|
||||
|
||||
if test -d "$android_platform" ; then
|
||||
AC_MSG_RESULT([$android_platform])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl set up compilers
|
||||
AS="$android_toolchain"/bin/"$android_tool_prefix"-as
|
||||
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
|
||||
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
|
||||
CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
|
||||
LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
|
||||
AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
|
||||
RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
|
||||
STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
|
||||
OBJCOPY="$android_toolchain"/bin/"$android_tool_prefix"-objcopy
|
||||
|
||||
CPPFLAGS="-isystem $android_platform/usr/include $CPPFLAGS"
|
||||
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
|
||||
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS"
|
||||
ASFLAGS="-isystem $android_platform/usr/include -DANDROID $ASFLAGS"
|
||||
|
||||
dnl Add -llog by default, since we use it all over the place.
|
||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||
dnl undefined symbol (present on the hardware, just not in the
|
||||
dnl NDK.)
|
||||
LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS"
|
||||
dnl prevent cross compile section from using these flags as host flags
|
||||
if test -z "$HOST_CPPFLAGS" ; then
|
||||
HOST_CPPFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CFLAGS" ; then
|
||||
HOST_CFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CXXFLAGS" ; then
|
||||
HOST_CXXFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_LDFLAGS" ; then
|
||||
HOST_LDFLAGS=" "
|
||||
fi
|
||||
|
||||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version)
|
||||
AC_SUBST(ANDROID_VERSION)
|
||||
CROSS_COMPILE=1
|
||||
AC_SUBST(ANDROID_NDK)
|
||||
AC_SUBST(ANDROID_TOOLCHAIN)
|
||||
AC_SUBST(ANDROID_PLATFORM)
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([MOZ_ANDROID_STLPORT],
|
||||
[
|
||||
|
||||
if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
|
||||
case "${CPU_ARCH}-${MOZ_ARCH}" in
|
||||
arm-armv7*)
|
||||
ANDROID_CPU_ARCH=armeabi-v7a
|
||||
;;
|
||||
arm-*)
|
||||
ANDROID_CPU_ARCH=armeabi
|
||||
;;
|
||||
x86-*)
|
||||
ANDROID_CPU_ARCH=x86
|
||||
;;
|
||||
mips-*) # When target_cpu is mipsel, CPU_ARCH is mips
|
||||
ANDROID_CPU_ARCH=mips
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$STLPORT_CPPFLAGS$STLPORT_LDFLAGS$STLPORT_LIBS"; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
|
||||
STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
elif test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
|
||||
STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
else
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
STLPORT_SOURCES="$android_ndk/sources/cxx-stl/stlport"
|
||||
STLPORT_CPPFLAGS="-I$_objdir/build/stlport -I$android_ndk/sources/cxx-stl/stlport/stlport"
|
||||
STLPORT_LIBS="-lstlport_static"
|
||||
elif test "$target" != "arm-android-eabi"; then
|
||||
dnl fail if we're not building with NDKr4
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
fi
|
||||
CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
|
||||
LIBS="$LIBS $STLPORT_LIBS"
|
||||
fi
|
||||
AC_SUBST([STLPORT_SOURCES])
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([MOZ_ANDROID_SDK],
|
||||
[
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-sdk,
|
||||
[ --with-android-sdk=DIR
|
||||
location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
|
||||
android_sdk=$withval)
|
||||
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$android_sdk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
|
||||
else
|
||||
if ! test -e "$android_sdk"/source.properties ; then
|
||||
AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
|
||||
fi
|
||||
|
||||
# Get the api level from "$android_sdk"/source.properties.
|
||||
android_api_level=`$AWK -F = changequote(<<, >>)'<<$>>1 == "AndroidVersion.ApiLevel" {print <<$>>2}'changequote([, ]) "$android_sdk"/source.properties`
|
||||
|
||||
if test -z "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: no AndroidVersion.ApiLevel field has been found in source.properties.])
|
||||
fi
|
||||
|
||||
if ! test "$android_api_level" -eq "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
|
||||
fi
|
||||
|
||||
if test $android_api_level -lt $1 ; then
|
||||
AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($1 or higher required).])
|
||||
fi
|
||||
fi
|
||||
|
||||
android_platform_tools="$android_sdk"/../../platform-tools
|
||||
if test ! -d "$android_platform_tools" ; then
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
fi
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
AC_SUBST(ANDROID_SDK)
|
||||
AC_SUBST(ANDROID_PLATFORM_TOOLS)
|
||||
;;
|
||||
esac
|
||||
|
||||
])
|
@ -179,39 +179,6 @@ MapObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
fop->delete_(map);
|
||||
}
|
||||
|
||||
class AddToMap {
|
||||
private:
|
||||
ValueMap *map;
|
||||
|
||||
public:
|
||||
AddToMap(ValueMap *map) : map(map) {}
|
||||
|
||||
bool operator()(JSContext *cx, const Value &v) {
|
||||
JSObject *pairobj = js_ValueToNonNullObject(cx, v);
|
||||
if (!pairobj)
|
||||
return false;
|
||||
|
||||
Value key;
|
||||
if (!pairobj->getElement(cx, 0, &key))
|
||||
return false;
|
||||
HashableValue hkey;
|
||||
if (!hkey.setValue(cx, key))
|
||||
return false;
|
||||
|
||||
HashableValue::AutoRooter hkeyRoot(cx, &hkey);
|
||||
|
||||
Value val;
|
||||
if (!pairobj->getElement(cx, 1, &val))
|
||||
return false;
|
||||
|
||||
if (!map->put(hkey, val)) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
JSBool
|
||||
MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -230,7 +197,31 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.hasDefined(0)) {
|
||||
if (!ForOf(cx, args[0], AddToMap(map)))
|
||||
ForOfIterator iter(cx, args[0]);
|
||||
while (iter.next()) {
|
||||
JSObject *pairobj = js_ValueToNonNullObject(cx, iter.value());
|
||||
if (!pairobj)
|
||||
return false;
|
||||
|
||||
Value key;
|
||||
if (!pairobj->getElement(cx, 0, &key))
|
||||
return false;
|
||||
HashableValue hkey;
|
||||
if (!hkey.setValue(cx, key))
|
||||
return false;
|
||||
|
||||
HashableValue::AutoRooter hkeyRoot(cx, &hkey);
|
||||
|
||||
Value val;
|
||||
if (!pairobj->getElement(cx, 1, &val))
|
||||
return false;
|
||||
|
||||
if (!map->put(hkey, val)) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!iter.close())
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -379,25 +370,6 @@ SetObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
fop->delete_(set);
|
||||
}
|
||||
|
||||
class AddToSet {
|
||||
private:
|
||||
ValueSet *set;
|
||||
|
||||
public:
|
||||
AddToSet(ValueSet *set) : set(set) {}
|
||||
|
||||
bool operator()(JSContext *cx, const Value &v) {
|
||||
HashableValue key;
|
||||
if (!key.setValue(cx, v))
|
||||
return false;
|
||||
if (!set->put(key)) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
JSBool
|
||||
SetObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -416,7 +388,17 @@ SetObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.hasDefined(0)) {
|
||||
if (!ForOf(cx, args[0], AddToSet(set)))
|
||||
ForOfIterator iter(cx, args[0]);
|
||||
while (iter.next()) {
|
||||
HashableValue key;
|
||||
if (!key.setValue(cx, iter.value()))
|
||||
return false;
|
||||
if (!set->put(key)) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!iter.close())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -146,53 +146,6 @@ else
|
||||
fi
|
||||
AC_SUBST(JS_SHARED_LIBRARY)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Android uses a very custom (hacky) toolchain; we need to do this
|
||||
dnl = here, so that the compiler checks can succeed
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-ndk,
|
||||
[ --with-android-ndk=DIR
|
||||
location where the Android NDK can be found],
|
||||
android_ndk=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-toolchain,
|
||||
[ --with-android-toolchain=DIR
|
||||
location of the android toolchain],
|
||||
android_toolchain=$withval)
|
||||
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-version,
|
||||
[ --with-android-version=VER
|
||||
android platform version, default 5],
|
||||
android_version=$withval,
|
||||
android_version=5)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-sdk,
|
||||
[ --with-android-sdk=DIR
|
||||
location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
|
||||
android_sdk=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-platform,
|
||||
[ --with-android-platform=DIR
|
||||
location of platform dir],
|
||||
android_platform=$withval)
|
||||
|
||||
case "$target" in
|
||||
arm-linux*-android*|*-linuxandroid*)
|
||||
android_tool_prefix="arm-linux-androideabi"
|
||||
;;
|
||||
i?86-*android*)
|
||||
android_tool_prefix="i686-android-linux"
|
||||
;;
|
||||
mipsel-*android*)
|
||||
android_tool_prefix="mipsel-linux-android"
|
||||
;;
|
||||
*)
|
||||
android_tool_prefix="$target_os"
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_WITH_STRING(gonk,
|
||||
[ --with-gonk=DIR
|
||||
location of gonk dir],
|
||||
@ -250,160 +203,13 @@ if test -n "$gonkdir" ; then
|
||||
HOST_LDFLAGS=" "
|
||||
fi
|
||||
|
||||
# save these for libffi's subconfigure,
|
||||
# which doesn't know how to figure this stuff out on its own
|
||||
ANDROID_CFLAGS="$CFLAGS"
|
||||
ANDROID_CPPFLAGS="$CPPFLAGS"
|
||||
ANDROID_LDFLAGS="$LDFLAGS"
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE(GONK)
|
||||
CROSS_COMPILE=1
|
||||
else
|
||||
case "$target" in
|
||||
*-android*|*-linuxandroid*)
|
||||
if test -z "$android_ndk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
|
||||
fi
|
||||
|
||||
if test -z "$android_sdk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
|
||||
fi
|
||||
|
||||
android_platform_tools="$android_sdk"/../../platform-tools
|
||||
if test ! -d "$android_platform_tools" ; then
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
else
|
||||
if ! test -e "$android_sdk"/source.properties ; then
|
||||
AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
|
||||
fi
|
||||
|
||||
# Minimum Android SDK API Level we require.
|
||||
android_min_api_level=13
|
||||
|
||||
# Get the api level from "$android_sdk"/source.properties.
|
||||
android_api_level=`$AWK -F = '$1 == "AndroidVersion.ApiLevel" {print $2}' "$android_sdk"/source.properties`
|
||||
|
||||
if test -z "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: no AndroidVersion.ApiLevel field has been found in source.properties.])
|
||||
fi
|
||||
|
||||
if ! test "$android_api_level" -eq "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
|
||||
fi
|
||||
|
||||
if test $android_api_level -lt $android_min_api_level ; then
|
||||
AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($android_min_api_level or higher required).])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$android_toolchain" ; then
|
||||
AC_MSG_CHECKING([for android toolchain directory])
|
||||
|
||||
kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm-linux-androideabi-4.4.3
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86-4.4.3
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mipsel-linux-android-4.4.3
|
||||
;;
|
||||
esac
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
|
||||
if test -d "$android_toolchain" ; then
|
||||
AC_MSG_RESULT([$android_toolchain])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$android_platform" ; then
|
||||
AC_MSG_CHECKING([for android platform directory])
|
||||
|
||||
case "$target_cpu" in
|
||||
arm)
|
||||
target_name=arm
|
||||
;;
|
||||
i?86)
|
||||
target_name=x86
|
||||
;;
|
||||
mipsel)
|
||||
target_name=mips
|
||||
;;
|
||||
esac
|
||||
|
||||
android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
|
||||
|
||||
if test -d "$android_platform" ; then
|
||||
AC_MSG_RESULT([$android_platform])
|
||||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl set up compilers
|
||||
AS="$android_toolchain"/bin/"$android_tool_prefix"-as
|
||||
CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
|
||||
CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
|
||||
CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
|
||||
LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
|
||||
AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
|
||||
RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
|
||||
STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
|
||||
|
||||
CPPFLAGS="-isystem $android_platform/usr/include $CPPFLAGS"
|
||||
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
|
||||
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions -Wno-psabi $CXXFLAGS"
|
||||
ASFLAGS="-isystem $android_platform/usr/include -DANDROID $ASFLAGS"
|
||||
|
||||
dnl Add -llog by default, since we use it all over the place.
|
||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||
dnl undefined symbol (present on the hardware, just not in the
|
||||
dnl NDK.)
|
||||
LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS"
|
||||
|
||||
dnl prevent cross compile section from using these flags as host flags
|
||||
if test -z "$HOST_CPPFLAGS" ; then
|
||||
HOST_CPPFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CFLAGS" ; then
|
||||
HOST_CFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_CXXFLAGS" ; then
|
||||
HOST_CXXFLAGS=" "
|
||||
fi
|
||||
if test -z "$HOST_LDFLAGS" ; then
|
||||
HOST_LDFLAGS=" "
|
||||
fi
|
||||
|
||||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version)
|
||||
AC_SUBST(ANDROID_VERSION)
|
||||
CROSS_COMPILE=1
|
||||
MOZ_CHROME_FILE_FORMAT=omni
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ANDROID_NDK
|
||||
fi
|
||||
|
||||
AC_SUBST(ANDROID_NDK)
|
||||
AC_SUBST(ANDROID_TOOLCHAIN)
|
||||
AC_SUBST(ANDROID_PLATFORM)
|
||||
AC_SUBST(ANDROID_SDK)
|
||||
AC_SUBST(ANDROID_PLATFORM_TOOLS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl Checks for compilers.
|
||||
dnl ========================================================
|
||||
@ -1469,48 +1275,7 @@ dnl Android libstdc++, placed here so it can use MOZ_ARCH
|
||||
dnl computed above.
|
||||
dnl ========================================================
|
||||
|
||||
if test "$OS_TARGET" = "Android"; then
|
||||
case "${CPU_ARCH}-${MOZ_ARCH}" in
|
||||
arm-armv7*)
|
||||
ANDROID_CPU_ARCH=armeabi-v7a
|
||||
;;
|
||||
arm-*)
|
||||
ANDROID_CPU_ARCH=armeabi
|
||||
;;
|
||||
x86-*)
|
||||
ANDROID_CPU_ARCH=x86
|
||||
;;
|
||||
mips-*) # When target_cpu is mipsel, CPU_ARCH is mips
|
||||
ANDROID_CPU_ARCH=mips
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
|
||||
if test -z "$STLPORT_CPPFLAGS$STLPORT_LDFLAGS$STLPORT_LIBS"; then
|
||||
if test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a" ; then
|
||||
STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/stlport/stlport"
|
||||
STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
|
||||
STLPORT_LIBS="-lstlport_static"
|
||||
elif test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a" ; then
|
||||
STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/stlport/stlport"
|
||||
STLPORT_LDFLAGS="-L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH"
|
||||
STLPORT_LIBS="-lstlport_static"
|
||||
elif test "$target" != "arm-android-eabi"; then
|
||||
dnl fail if we're not building with NDKr4
|
||||
AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
|
||||
fi
|
||||
fi
|
||||
CXXFLAGS="$CXXFLAGS $STLPORT_CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $STLPORT_LDFLAGS"
|
||||
LIBS="$LIBS $STLPORT_LIBS"
|
||||
|
||||
# save these for libffi's subconfigure,
|
||||
# which doesn't know how to figure this stuff out on its own
|
||||
ANDROID_CFLAGS="$CFLAGS"
|
||||
ANDROID_CPPFLAGS="$CPPFLAGS"
|
||||
ANDROID_LDFLAGS="$LDFLAGS"
|
||||
fi
|
||||
MOZ_ANDROID_STLPORT
|
||||
|
||||
dnl ========================================================
|
||||
dnl Suppress Clang Argument Warnings
|
||||
|
@ -700,8 +700,7 @@ struct ChunkBitmap
|
||||
PodArrayZero(bitmap);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool noBitsSet(ArenaHeader *aheader) {
|
||||
uintptr_t *arenaBits(ArenaHeader *aheader) {
|
||||
/*
|
||||
* We assume that the part of the bitmap corresponding to the arena
|
||||
* has the exact number of words so we do not need to deal with a word
|
||||
@ -711,13 +710,8 @@ struct ChunkBitmap
|
||||
|
||||
uintptr_t *word, unused;
|
||||
getMarkWordAndMask(reinterpret_cast<Cell *>(aheader->address()), BLACK, &word, &unused);
|
||||
for (size_t i = 0; i != ArenaBitmapWords; i++) {
|
||||
if (word[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return word;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(ArenaBitmapBytes * ArenasPerChunk == sizeof(ChunkBitmap));
|
||||
|
@ -193,11 +193,13 @@ BEGIN_TEST(testHashRekeyManual)
|
||||
CHECK(AddLowKeys(&am, &bm, i));
|
||||
CHECK(MapsAreEqual(am, bm));
|
||||
|
||||
for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
|
||||
IntMap::Enum e(am);
|
||||
for (; !e.empty(); e.popFront()) {
|
||||
uint32_t tmp = LowToHigh::rekey(e.front().key);
|
||||
if (tmp != e.front().key)
|
||||
e.rekeyFront(tmp);
|
||||
}
|
||||
CHECK(e.endEnumeration());
|
||||
CHECK(SlowRekey<LowToHigh>(&bm));
|
||||
|
||||
CHECK(MapsAreEqual(am, bm));
|
||||
@ -215,11 +217,13 @@ BEGIN_TEST(testHashRekeyManual)
|
||||
CHECK(AddLowKeys(&as, &bs, i));
|
||||
CHECK(SetsAreEqual(as, bs));
|
||||
|
||||
for (IntSet::Enum e(as); !e.empty(); e.popFront()) {
|
||||
IntSet::Enum e(as);
|
||||
for (; !e.empty(); e.popFront()) {
|
||||
uint32_t tmp = LowToHigh::rekey(e.front());
|
||||
if (tmp != e.front())
|
||||
e.rekeyFront(tmp);
|
||||
}
|
||||
CHECK(e.endEnumeration());
|
||||
CHECK(SlowRekey<LowToHigh>(&bs));
|
||||
|
||||
CHECK(SetsAreEqual(as, bs));
|
||||
@ -243,7 +247,8 @@ BEGIN_TEST(testHashRekeyManualRemoval)
|
||||
CHECK(AddLowKeys(&am, &bm, i));
|
||||
CHECK(MapsAreEqual(am, bm));
|
||||
|
||||
for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
|
||||
IntMap::Enum e(am);
|
||||
for (; !e.empty(); e.popFront()) {
|
||||
if (LowToHighWithRemoval::shouldBeRemoved(e.front().key)) {
|
||||
e.removeFront();
|
||||
} else {
|
||||
@ -252,6 +257,7 @@ BEGIN_TEST(testHashRekeyManualRemoval)
|
||||
e.rekeyFront(tmp);
|
||||
}
|
||||
}
|
||||
CHECK(e.endEnumeration());
|
||||
CHECK(SlowRekey<LowToHighWithRemoval>(&bm));
|
||||
|
||||
CHECK(MapsAreEqual(am, bm));
|
||||
@ -269,7 +275,8 @@ BEGIN_TEST(testHashRekeyManualRemoval)
|
||||
CHECK(AddLowKeys(&as, &bs, i));
|
||||
CHECK(SetsAreEqual(as, bs));
|
||||
|
||||
for (IntSet::Enum e(as); !e.empty(); e.popFront()) {
|
||||
IntSet::Enum e(as);
|
||||
for (; !e.empty(); e.popFront()) {
|
||||
if (LowToHighWithRemoval::shouldBeRemoved(e.front())) {
|
||||
e.removeFront();
|
||||
} else {
|
||||
@ -278,6 +285,7 @@ BEGIN_TEST(testHashRekeyManualRemoval)
|
||||
e.rekeyFront(tmp);
|
||||
}
|
||||
}
|
||||
CHECK(e.endEnumeration());
|
||||
CHECK(SlowRekey<LowToHighWithRemoval>(&bs));
|
||||
|
||||
CHECK(SetsAreEqual(as, bs));
|
||||
|
@ -356,7 +356,7 @@ JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
|
||||
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Value v = e.front().value;
|
||||
if (v.isObject()) {
|
||||
if (e.front().key.kind == CrossCompartmentKey::ObjectWrapper) {
|
||||
JSObject *wrapper = &v.toObject();
|
||||
|
||||
/*
|
||||
@ -539,13 +539,14 @@ JSCompartment::sweepCrossCompartmentWrappers()
|
||||
{
|
||||
/* Remove dead wrappers from the table. */
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Value key = e.front().key;
|
||||
bool keyMarked = IsValueMarked(&key);
|
||||
CrossCompartmentKey key = e.front().key;
|
||||
bool keyMarked = IsCellMarked(&key.wrapped);
|
||||
bool valMarked = IsValueMarked(e.front().value.unsafeGet());
|
||||
JS_ASSERT_IF(!keyMarked && valMarked, key.isString());
|
||||
if (!keyMarked || !valMarked)
|
||||
bool dbgMarked = !key.debugger || IsObjectMarked(&key.debugger);
|
||||
JS_ASSERT_IF(!keyMarked && valMarked, key.kind == CrossCompartmentKey::StringWrapper);
|
||||
if (!keyMarked || !valMarked || !dbgMarked)
|
||||
e.removeFront();
|
||||
else if (key != e.front().key)
|
||||
else
|
||||
e.rekeyFront(key);
|
||||
}
|
||||
}
|
||||
|
@ -52,20 +52,54 @@ class DtoaCache {
|
||||
/* If HashNumber grows, need to change WrapperHasher. */
|
||||
JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
|
||||
|
||||
struct WrapperHasher
|
||||
struct CrossCompartmentKey
|
||||
{
|
||||
typedef Value Lookup;
|
||||
enum Kind {
|
||||
ObjectWrapper,
|
||||
StringWrapper,
|
||||
DebuggerScript,
|
||||
DebuggerObject,
|
||||
DebuggerEnvironment
|
||||
};
|
||||
|
||||
static HashNumber hash(Value key) {
|
||||
JS_ASSERT(!IsPoisonedValue(key));
|
||||
uint64_t bits = JSVAL_TO_IMPL(key).asBits;
|
||||
return uint32_t(bits) ^ uint32_t(bits >> 32);
|
||||
}
|
||||
Kind kind;
|
||||
JSObject *debugger;
|
||||
js::gc::Cell *wrapped;
|
||||
|
||||
static bool match(const Value &l, const Value &k) { return l == k; }
|
||||
CrossCompartmentKey()
|
||||
: kind(ObjectWrapper), debugger(NULL), wrapped(NULL) {}
|
||||
CrossCompartmentKey(JSObject *wrapped)
|
||||
: kind(ObjectWrapper), debugger(NULL), wrapped(wrapped) {}
|
||||
CrossCompartmentKey(JSString *wrapped)
|
||||
: kind(StringWrapper), debugger(NULL), wrapped(wrapped) {}
|
||||
CrossCompartmentKey(Value wrapped)
|
||||
: kind(wrapped.isString() ? StringWrapper : ObjectWrapper),
|
||||
debugger(NULL),
|
||||
wrapped((js::gc::Cell *)wrapped.toGCThing()) {}
|
||||
CrossCompartmentKey(const RootedValue &wrapped)
|
||||
: kind(wrapped.raw().isString() ? StringWrapper : ObjectWrapper),
|
||||
debugger(NULL),
|
||||
wrapped((js::gc::Cell *)wrapped.raw().toGCThing()) {}
|
||||
CrossCompartmentKey(Kind kind, JSObject *dbg, js::gc::Cell *wrapped)
|
||||
: kind(kind), debugger(dbg), wrapped(wrapped) {}
|
||||
};
|
||||
|
||||
typedef HashMap<Value, ReadBarrieredValue, WrapperHasher, SystemAllocPolicy> WrapperMap;
|
||||
struct WrapperHasher
|
||||
{
|
||||
typedef CrossCompartmentKey Lookup;
|
||||
|
||||
static HashNumber hash(const CrossCompartmentKey &key) {
|
||||
JS_ASSERT(!IsPoisonedPtr(key.wrapped));
|
||||
return uint32_t(uintptr_t(key.wrapped)) | uint32_t(key.kind);
|
||||
}
|
||||
|
||||
static bool match(const CrossCompartmentKey &l, const CrossCompartmentKey &k) {
|
||||
return l.kind == k.kind && l.debugger == k.debugger && l.wrapped == k.wrapped;
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashMap<CrossCompartmentKey, ReadBarrieredValue,
|
||||
WrapperHasher, SystemAllocPolicy> WrapperMap;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
|
@ -3024,8 +3024,9 @@ BeginMarkPhase(JSRuntime *rt)
|
||||
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_MARK);
|
||||
gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_MARK_ROOTS);
|
||||
|
||||
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront())
|
||||
r.front()->bitmap.clear();
|
||||
/* Unmark everything in the compartments being collected. */
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next())
|
||||
c->arenas.unmarkAll();
|
||||
|
||||
MarkRuntime(gcmarker);
|
||||
}
|
||||
@ -3086,13 +3087,38 @@ EndMarkPhase(JSRuntime *rt)
|
||||
ValidateIncrementalMarking(rt);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Make sure that we didn't mark an object in another compartment */
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
JS_ASSERT_IF(!c->isCollecting() && c != rt->atomsCompartment,
|
||||
c->arenas.checkArenaListAllUnmarked());
|
||||
/*
|
||||
* Having black->gray edges violates our promise to the cycle
|
||||
* collector. This can happen if we're collecting a compartment and it has
|
||||
* an edge to an uncollected compartment: it's possible that the source and
|
||||
* destination of the cross-compartment edge should be gray, but the source
|
||||
* was marked black by the conservative scanner.
|
||||
*/
|
||||
bool foundBlackGray = false;
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
for (WrapperMap::Enum e(c->crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Cell *dst = e.front().key.wrapped;
|
||||
Cell *src = ToMarkable(e.front().value);
|
||||
JS_ASSERT(src->compartment() == c.get());
|
||||
if (IsCellMarked(&src) && !src->isMarked(GRAY) && dst->isMarked(GRAY)) {
|
||||
JS_ASSERT(!dst->compartment()->isCollecting());
|
||||
foundBlackGray = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* To avoid the black->gray edge, we completely clear the mark bits of all
|
||||
* uncollected compartments. This is safe, although it may prevent the
|
||||
* cycle collector from collecting some dead objects.
|
||||
*/
|
||||
if (foundBlackGray) {
|
||||
JS_ASSERT(false);
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (!c->isCollecting())
|
||||
c->arenas.unmarkAll();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rt->gcMarker.stop();
|
||||
|
||||
|
@ -236,8 +236,7 @@ struct ArenaLists {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool checkArenaListAllUnmarked() const {
|
||||
void unmarkAll() {
|
||||
for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
|
||||
# ifdef JS_THREADSAFE
|
||||
/* The background finalization must have stopped at this point. */
|
||||
@ -245,13 +244,11 @@ struct ArenaLists {
|
||||
backgroundFinalizeState[i] == BFS_JUST_FINISHED);
|
||||
# endif
|
||||
for (ArenaHeader *aheader = arenaLists[i].head; aheader; aheader = aheader->next) {
|
||||
if (!aheader->chunk()->bitmap.noBitsSet(aheader))
|
||||
return false;
|
||||
uintptr_t *word = aheader->chunk()->bitmap.arenaBits(aheader);
|
||||
memset(word, 0, ArenaBitmapWords * sizeof(uintptr_t));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
bool doneBackgroundFinalize(AllocKind kind) const {
|
||||
|
@ -1019,27 +1019,6 @@ TypeCheckNextBytecode(JSContext *cx, JSScript *script, unsigned n, const FrameRe
|
||||
#endif
|
||||
}
|
||||
|
||||
class SpreadContext {
|
||||
public:
|
||||
JSContext *cx;
|
||||
RootedObject arr;
|
||||
int32_t *count;
|
||||
SpreadContext(JSContext *cx, JSObject *array, int32_t *count)
|
||||
: cx(cx), arr(cx, array), count(count) {
|
||||
JS_ASSERT(array->isArray());
|
||||
}
|
||||
SpreadContext(SpreadContext &scx)
|
||||
: cx(cx), arr(scx.cx, scx.arr), count(scx.count) {}
|
||||
bool operator ()(JSContext *cx, const Value &item) {
|
||||
if (*count == INT32_MAX) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_SPREAD_TOO_LARGE);
|
||||
return false;
|
||||
}
|
||||
return arr->defineElement(cx, (*count)++, item, NULL, NULL, JSPROP_ENUMERATE);
|
||||
}
|
||||
};
|
||||
|
||||
JS_NEVER_INLINE bool
|
||||
js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
||||
{
|
||||
@ -3228,9 +3207,19 @@ END_CASE(JSOP_INITELEM)
|
||||
BEGIN_CASE(JSOP_SPREAD)
|
||||
{
|
||||
int32_t count = regs.sp[-2].toInt32();
|
||||
SpreadContext scx(cx, ®s.sp[-3].toObject(), &count);
|
||||
RootedObject arr(cx, ®s.sp[-3].toObject());
|
||||
const Value iterable = regs.sp[-1];
|
||||
if (!ForOf(cx, iterable, scx))
|
||||
ForOfIterator iter(cx, iterable);
|
||||
while (iter.next()) {
|
||||
if (count == INT32_MAX) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_SPREAD_TOO_LARGE);
|
||||
goto error;
|
||||
}
|
||||
if (!arr->defineElement(cx, count++, iter.value(), NULL, NULL, JSPROP_ENUMERATE))
|
||||
goto error;
|
||||
}
|
||||
if (!iter.close())
|
||||
goto error;
|
||||
regs.sp[-2].setInt32(count);
|
||||
regs.sp--;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user