mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central
This commit is contained in:
commit
518d96c53f
@ -12,7 +12,7 @@
|
||||
#include "States.h"
|
||||
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
@ -127,7 +127,7 @@ AccShowEvent::
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccTextSelChangeEvent::AccTextSelChangeEvent(HyperTextAccessible* aTarget,
|
||||
Selection* aSelection,
|
||||
dom::Selection* aSelection,
|
||||
int32_t aReason) :
|
||||
AccEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED, aTarget,
|
||||
eAutoDetect, eCoalesceTextSelChange),
|
||||
|
@ -12,7 +12,9 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class Selection;
|
||||
}
|
||||
|
||||
namespace a11y {
|
||||
|
||||
@ -367,7 +369,8 @@ private:
|
||||
class AccTextSelChangeEvent : public AccEvent
|
||||
{
|
||||
public:
|
||||
AccTextSelChangeEvent(HyperTextAccessible* aTarget, Selection* aSelection,
|
||||
AccTextSelChangeEvent(HyperTextAccessible* aTarget,
|
||||
dom::Selection* aSelection,
|
||||
int32_t aReason);
|
||||
virtual ~AccTextSelChangeEvent();
|
||||
|
||||
@ -386,7 +389,7 @@ public:
|
||||
bool IsCaretMoveOnly() const;
|
||||
|
||||
private:
|
||||
nsRefPtr<Selection> mSel;
|
||||
nsRefPtr<dom::Selection> mSel;
|
||||
int32_t mReason;
|
||||
|
||||
friend class EventQueue;
|
||||
|
@ -14,11 +14,12 @@
|
||||
#include "nsIAccessibleTypes.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
using mozilla::dom::Selection;
|
||||
|
||||
struct mozilla::a11y::SelData MOZ_FINAL
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ HyperTextAccessible::IsValidRange(int32_t aStartOffset, int32_t aEndOffset)
|
||||
inline bool
|
||||
HyperTextAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
|
||||
{
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
return domSel &&
|
||||
SetSelectionBoundsAt(domSel->GetRangeCount(), aStartOffset, aEndOffset);
|
||||
}
|
||||
@ -149,7 +149,7 @@ HyperTextAccessible::FrameSelection() const
|
||||
return frame ? frame->GetFrameSelection() : nullptr;
|
||||
}
|
||||
|
||||
inline Selection*
|
||||
inline dom::Selection*
|
||||
HyperTextAccessible::DOMSelection() const
|
||||
{
|
||||
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "nsTextFragment.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "gfxSkipChars.h"
|
||||
#include <algorithm>
|
||||
@ -1117,7 +1117,7 @@ HyperTextAccessible::SetSelectionRange(int32_t aStartPos, int32_t aEndPos)
|
||||
if (isFocusable)
|
||||
TakeFocus();
|
||||
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
NS_ENSURE_STATE(domSel);
|
||||
|
||||
// Set up the selection.
|
||||
@ -1164,7 +1164,7 @@ HyperTextAccessible::CaretOffset() const
|
||||
|
||||
// Turn the focus node and offset of the selection into caret hypretext
|
||||
// offset.
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
NS_ENSURE_TRUE(domSel, -1);
|
||||
|
||||
nsINode* focusNode = domSel->GetFocusNode();
|
||||
@ -1194,7 +1194,7 @@ HyperTextAccessible::CaretLineNumber()
|
||||
if (!frameSelection)
|
||||
return -1;
|
||||
|
||||
Selection* domSel =
|
||||
dom::Selection* domSel =
|
||||
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
if (!domSel)
|
||||
return - 1;
|
||||
@ -1310,7 +1310,7 @@ HyperTextAccessible::GetSelectionDOMRanges(int16_t aType,
|
||||
frameSelection->GetDisplaySelection() <= nsISelectionController::SELECTION_HIDDEN)
|
||||
return;
|
||||
|
||||
Selection* domSel = frameSelection->GetSelection(aType);
|
||||
dom::Selection* domSel = frameSelection->GetSelection(aType);
|
||||
if (!domSel)
|
||||
return;
|
||||
|
||||
@ -1397,7 +1397,7 @@ HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
|
||||
int32_t startOffset = ConvertMagicOffset(aStartOffset);
|
||||
int32_t endOffset = ConvertMagicOffset(aEndOffset);
|
||||
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
if (!domSel)
|
||||
return false;
|
||||
|
||||
@ -1426,7 +1426,7 @@ HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
|
||||
bool
|
||||
HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum)
|
||||
{
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
if (!domSel)
|
||||
return false;
|
||||
|
||||
@ -1521,7 +1521,7 @@ HyperTextAccessible::SelectionRanges(nsTArray<a11y::TextRange>* aRanges) const
|
||||
{
|
||||
NS_ASSERTION(aRanges->Length() != 0, "TextRange array supposed to be empty");
|
||||
|
||||
Selection* sel = DOMSelection();
|
||||
dom::Selection* sel = DOMSelection();
|
||||
if (!sel)
|
||||
return;
|
||||
|
||||
@ -1848,7 +1848,7 @@ HyperTextAccessible::GetSpellTextAttribute(nsINode* aNode,
|
||||
if (!fs)
|
||||
return NS_OK;
|
||||
|
||||
Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
|
||||
dom::Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
|
||||
if (!domSel)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -489,7 +489,7 @@ protected:
|
||||
* Return frame/DOM selection object for the accessible.
|
||||
*/
|
||||
already_AddRefed<nsFrameSelection> FrameSelection() const;
|
||||
Selection* DOMSelection() const;
|
||||
dom::Selection* DOMSelection() const;
|
||||
|
||||
/**
|
||||
* Return selection ranges within the accessible subtree.
|
||||
|
@ -139,7 +139,6 @@
|
||||
@BINPATH@/components/composer.xpt
|
||||
@BINPATH@/components/content_base.xpt
|
||||
@BINPATH@/components/content_events.xpt
|
||||
@BINPATH@/components/content_canvas.xpt
|
||||
@BINPATH@/components/content_htmldoc.xpt
|
||||
@BINPATH@/components/content_html.xpt
|
||||
@BINPATH@/components/content_xslt.xpt
|
||||
|
@ -286,6 +286,10 @@ let SessionHistoryListener = {
|
||||
return true;
|
||||
},
|
||||
|
||||
OnHistoryReplaceEntry: function (index) {
|
||||
this.collect();
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference
|
||||
|
@ -369,6 +369,7 @@ HistoryListener.prototype = {
|
||||
OnHistoryGoForward: function(forwardURI) { return true; },
|
||||
OnHistoryGotoIndex: function(index, gotoURI) { return true; },
|
||||
OnHistoryPurge: function(numEntries) { return true; },
|
||||
OnHistoryReplaceEntry: function(index) {},
|
||||
|
||||
OnHistoryReload: function(reloadURI, reloadFlags) {
|
||||
this.callback();
|
||||
|
@ -2581,6 +2581,12 @@ let SessionStoreInternal = {
|
||||
// Save the index in case we updated it above.
|
||||
tabData.index = activeIndex + 1;
|
||||
|
||||
// In electrolysis, we may need to change the browser's remote
|
||||
// attribute so that it runs in a content process.
|
||||
let activePageData = tabData.entries[activeIndex] || null;
|
||||
let uri = activePageData ? activePageData.url || null : null;
|
||||
tabbrowser.updateBrowserRemoteness(browser, uri);
|
||||
|
||||
// Start a new epoch and include the epoch in the restoreHistory
|
||||
// message. If a message is received that relates to a previous epoch, we
|
||||
// discard it.
|
||||
@ -2604,12 +2610,6 @@ let SessionStoreInternal = {
|
||||
pageStyle: tabData.pageStyle || null
|
||||
});
|
||||
|
||||
// In electrolysis, we may need to change the browser's remote
|
||||
// attribute so that it runs in a content process.
|
||||
let activePageData = tabData.entries[activeIndex] || null;
|
||||
let uri = activePageData ? activePageData.url || null : null;
|
||||
tabbrowser.updateBrowserRemoteness(browser, uri);
|
||||
|
||||
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory",
|
||||
{tabData: tabData, epoch: epoch});
|
||||
|
||||
|
@ -220,15 +220,15 @@ add_task(function test_pushstate_replacestate() {
|
||||
is(entries[1].url, "http://example.com/test-entry/", "url is correct");
|
||||
|
||||
// Disabled until replaceState invalidation is supported. See Bug 967028.
|
||||
// browser.messageManager.
|
||||
// sendAsyncMessage("ss-test:historyReplaceState", {url: 'test-entry2/'});
|
||||
// yield promiseContentMessage(browser, "ss-test:historyReplaceState");
|
||||
browser.messageManager.
|
||||
sendAsyncMessage("ss-test:historyReplaceState", {url: 'test-entry2/'});
|
||||
yield promiseContentMessage(browser, "ss-test:historyReplaceState");
|
||||
|
||||
// // Check that we have modified the history entry.
|
||||
// SyncHandlers.get(browser).flush();
|
||||
// let {entries} = JSON.parse(ss.getTabState(tab));
|
||||
// is(entries.length, 2, "there is still two shistory entries");
|
||||
// is(entries[1].url, "http://example.com/test-entry/test-entry2/", "url is correct");
|
||||
// Check that we have modified the history entry.
|
||||
SyncHandlers.get(browser).flush();
|
||||
let {entries} = JSON.parse(ss.getTabState(tab));
|
||||
is(entries.length, 2, "there is still two shistory entries");
|
||||
is(entries[1].url, "http://example.com/test-entry/test-entry2/", "url is correct");
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
|
@ -170,7 +170,6 @@
|
||||
@BINPATH@/components/composer.xpt
|
||||
@BINPATH@/components/content_base.xpt
|
||||
@BINPATH@/components/content_events.xpt
|
||||
@BINPATH@/components/content_canvas.xpt
|
||||
@BINPATH@/components/content_htmldoc.xpt
|
||||
@BINPATH@/components/content_html.xpt
|
||||
#ifdef MOZ_WEBRTC
|
||||
|
@ -109,12 +109,12 @@ template<class T> class nsReadingIterator;
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
class EventListenerManager;
|
||||
class Selection;
|
||||
|
||||
namespace dom {
|
||||
class DocumentFragment;
|
||||
class Element;
|
||||
class EventTarget;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
|
||||
namespace layers {
|
||||
@ -2086,7 +2086,7 @@ public:
|
||||
* @param aOutStartOffset Output start offset
|
||||
* @param aOutEndOffset Output end offset
|
||||
*/
|
||||
static void GetSelectionInTextControl(mozilla::Selection* aSelection,
|
||||
static void GetSelectionInTextControl(mozilla::dom::Selection* aSelection,
|
||||
Element* aRoot,
|
||||
int32_t& aOutStartOffset,
|
||||
int32_t& aOutEndOffset);
|
||||
|
@ -331,7 +331,7 @@ interface nsIXMLHttpRequest : nsISupports
|
||||
readonly attribute boolean mozSystem;
|
||||
};
|
||||
|
||||
[scriptable, uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
|
||||
[uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
|
||||
interface nsIXHRSendable : nsISupports {
|
||||
void getSendInfo(out nsIInputStream body,
|
||||
out uint64_t contentLength,
|
||||
|
@ -50,7 +50,7 @@
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsAttrName.h"
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsITransferable.h" // for kUnicodeMime
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -4,12 +4,6 @@
|
||||
# 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/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsICanvasGLPrivate.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'content_canvas'
|
||||
|
||||
EXPORTS += [
|
||||
'nsICanvasRenderingContextInternal.h',
|
||||
]
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/* These are private interface that's used to identify
|
||||
* specific concrete classes so we know what we can cast.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(eba2aa03-ae19-46e2-bad7-6b966037e22c)]
|
||||
interface nsICanvasGLBuffer : nsISupports
|
||||
{
|
||||
};
|
||||
|
||||
[scriptable, uuid(27310aab-1988-43e8-882e-6293c8c9df60)]
|
||||
interface nsICanvasGLTexture : nsISupports
|
||||
{
|
||||
};
|
@ -12,8 +12,7 @@
|
||||
* which implements the phonetic interface.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(BC6EA726-AB56-46b6-A21A-AA7B76D6818F)]
|
||||
|
||||
[uuid(BC6EA726-AB56-46b6-A21A-AA7B76D6818F)]
|
||||
interface nsIPhonetic : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsTextEditRules.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -234,7 +234,7 @@ public:
|
||||
{
|
||||
// Deprecated
|
||||
}
|
||||
mozilla::Selection* GetSelection(mozilla::ErrorResult& aRv);
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aRv);
|
||||
// The XPCOM CaptureEvents works fine for us.
|
||||
// The XPCOM ReleaseEvents works fine for us.
|
||||
// We're picking up GetLocation from Document
|
||||
|
@ -10871,8 +10871,9 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
||||
|
||||
// Step 5: If aReplace is false, indicating that we're doing a pushState
|
||||
// rather than a replaceState, notify bfcache that we've added a page to
|
||||
// the history so it can evict content viewers if appropriate.
|
||||
if (!aReplace) {
|
||||
// the history so it can evict content viewers if appropriate. Otherwise
|
||||
// call ReplaceEntry so that we notify nsIHistoryListeners that an entry
|
||||
// was replaced.
|
||||
nsCOMPtr<nsISHistory> rootSH;
|
||||
GetRootSessionHistory(getter_AddRefs(rootSH));
|
||||
NS_ENSURE_TRUE(rootSH, NS_ERROR_UNEXPECTED);
|
||||
@ -10881,11 +10882,20 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
||||
do_QueryInterface(rootSH);
|
||||
NS_ENSURE_TRUE(internalSH, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (!aReplace) {
|
||||
int32_t curIndex = -1;
|
||||
rv = rootSH->GetIndex(&curIndex);
|
||||
if (NS_SUCCEEDED(rv) && curIndex > -1) {
|
||||
internalSH->EvictOutOfRangeContentViewers(curIndex);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsISHEntry> rootSHEntry = GetRootSHEntry(newSHEntry);
|
||||
|
||||
int32_t index = -1;
|
||||
rv = rootSH->GetIndexOfEntry(rootSHEntry, &index);
|
||||
if (NS_SUCCEEDED(rv) && index > -1) {
|
||||
internalSH->ReplaceEntry(index, rootSHEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: If the document's URI changed, update document's URI and update
|
||||
|
@ -22,12 +22,12 @@ interface nsISimpleEnumerator;
|
||||
|
||||
%{C++
|
||||
#define NS_SHISTORY_CID \
|
||||
{0x7294fe9c, 0x14d8, 0x11d5, {0x98, 0x82, 0x00, 0xC0, 0x4f, 0xa0, 0x2f, 0x40}}
|
||||
{0x7b807041, 0xe60a, 0x4384, {0x93, 0x5f, 0xaf, 0x30, 0x61, 0xd8, 0xb8, 0x15}}
|
||||
|
||||
#define NS_SHISTORY_CONTRACTID "@mozilla.org/browser/shistory;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(b4440e2e-0fc2-11e3-971f-59e799890b3c)]
|
||||
[scriptable, uuid(7b807041-e60a-4384-935f-af3061d8b815)]
|
||||
interface nsISHistory: nsISupports
|
||||
{
|
||||
/**
|
||||
@ -147,4 +147,16 @@ interface nsISHistory: nsISupports
|
||||
readonly attribute nsISimpleEnumerator SHistoryEnumerator;
|
||||
|
||||
void reloadCurrentEntry();
|
||||
|
||||
/**
|
||||
* Called to obtain the index to a given history entry.
|
||||
*
|
||||
* @param aEntry The entry to obtain the index of.
|
||||
*
|
||||
* @return <code>NS_OK</code> index for the history entry
|
||||
* is obtained successfully.
|
||||
* <code>NS_ERROR_FAILURE</code> Error in obtaining
|
||||
* index for the given history entry.
|
||||
*/
|
||||
long getIndexOfEntry(in nsISHEntry aEntry);
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ interface nsIURI;
|
||||
* A session history listener can be registered on a particular nsISHistory
|
||||
* instance via the nsISHistory::addSHistoryListener() method.
|
||||
*/
|
||||
[scriptable, uuid(3b07f591-e8e1-11d4-9882-00c04fa02f40)]
|
||||
[scriptable, uuid(125c0833-746a-400e-9b89-d2d18545c08a)]
|
||||
interface nsISHistoryListener : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -87,4 +87,14 @@ interface nsISHistoryListener : nsISupports
|
||||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean OnHistoryPurge(in long aNumEntries);
|
||||
|
||||
/**
|
||||
* Called when an entry is replaced in the session history. Entries are
|
||||
* replaced when navigating away from non-persistent history entries (such as
|
||||
* about pages) and when history.replaceState is called.
|
||||
*
|
||||
* @param aIndex The index in session history of the entry being
|
||||
* replaced
|
||||
*/
|
||||
void OnHistoryReplaceEntry(in long aIndex);
|
||||
};
|
||||
|
@ -415,8 +415,11 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist)
|
||||
if(currentTxn)
|
||||
currentTxn->GetPersist(¤tPersist);
|
||||
|
||||
int32_t currentIndex = mIndex;
|
||||
|
||||
if(!currentPersist)
|
||||
{
|
||||
NOTIFY_LISTENERS(OnHistoryReplaceEntry, (currentIndex));
|
||||
NS_ENSURE_SUCCESS(currentTxn->SetSHEntry(aSHEntry),NS_ERROR_FAILURE);
|
||||
currentTxn->SetPersist(aPersist);
|
||||
return NS_OK;
|
||||
@ -426,7 +429,6 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist)
|
||||
NS_ENSURE_TRUE(txn, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
int32_t currentIndex = mIndex;
|
||||
aSHEntry->GetURI(getter_AddRefs(uri));
|
||||
NOTIFY_LISTENERS(OnHistoryNewEntry, (uri));
|
||||
|
||||
@ -555,6 +557,50 @@ nsSHistory::GetTransactionAtIndex(int32_t aIndex, nsISHTransaction ** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Get the index of a given entry */
|
||||
NS_IMETHODIMP
|
||||
nsSHistory::GetIndexOfEntry(nsISHEntry* aSHEntry, int32_t* aResult) {
|
||||
NS_ENSURE_ARG(aSHEntry);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = -1;
|
||||
|
||||
if (mLength <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISHTransaction> currentTxn;
|
||||
int32_t cnt = 0;
|
||||
|
||||
nsresult rv = GetRootTransaction(getter_AddRefs(currentTxn));
|
||||
if (NS_FAILED(rv) || !currentTxn) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
nsCOMPtr<nsISHEntry> entry;
|
||||
rv = currentTxn->GetSHEntry(getter_AddRefs(entry));
|
||||
if (NS_FAILED(rv) || !entry) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aSHEntry == entry) {
|
||||
*aResult = cnt;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = currentTxn->GetNext(getter_AddRefs(currentTxn));
|
||||
if (NS_FAILED(rv) || !currentTxn) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
nsresult
|
||||
nsSHistory::PrintHistory()
|
||||
@ -734,6 +780,8 @@ nsSHistory::ReplaceEntry(int32_t aIndex, nsISHEntry * aReplaceEntry)
|
||||
|
||||
if(currentTxn)
|
||||
{
|
||||
NOTIFY_LISTENERS(OnHistoryReplaceEntry, (aIndex));
|
||||
|
||||
// Set the replacement entry in the transaction
|
||||
rv = currentTxn->SetSHEntry(aReplaceEntry);
|
||||
rv = currentTxn->SetPersist(true);
|
||||
|
@ -39,6 +39,8 @@ SHistoryListener.prototype = {
|
||||
return this.retval;
|
||||
},
|
||||
|
||||
OnHistoryReplaceEntry: function (aIndex) {},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ function test() {
|
||||
OnHistoryGoForward: function () true,
|
||||
OnHistoryGotoIndex: function () true,
|
||||
OnHistoryPurge: function () true,
|
||||
OnHistoryReplaceEntry: function () true,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(194b55d9-39c0-45c6-b8ef-b8049f978ea5)]
|
||||
[uuid(194b55d9-39c0-45c6-b8ef-b8049f978ea5)]
|
||||
interface nsIAudioChannelAgentCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -40,7 +40,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
||||
* 1. Changes to the playable status of this channel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(2b0222a5-8f7b-49d2-9ab8-cd01b744b23e)]
|
||||
[uuid(2b0222a5-8f7b-49d2-9ab8-cd01b744b23e)]
|
||||
interface nsIAudioChannelAgent : nsISupports
|
||||
{
|
||||
const long AUDIO_AGENT_CHANNEL_NORMAL = 0;
|
||||
|
@ -75,7 +75,6 @@
|
||||
// DOM core includes
|
||||
#include "nsError.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsIDOMXPathNamespace.h"
|
||||
#include "nsIDOMXULButtonElement.h"
|
||||
#include "nsIDOMXULCheckboxElement.h"
|
||||
#include "nsIDOMXULPopupElement.h"
|
||||
@ -223,7 +222,6 @@ DOMCI_DATA_NO_CLASS(DOMPrototype)
|
||||
DOMCI_DATA_NO_CLASS(DOMConstructor)
|
||||
|
||||
DOMCI_DATA_NO_CLASS(UserDataHandler)
|
||||
DOMCI_DATA_NO_CLASS(XPathNamespace)
|
||||
DOMCI_DATA_NO_CLASS(XULControlElement)
|
||||
DOMCI_DATA_NO_CLASS(XULLabeledControlElement)
|
||||
DOMCI_DATA_NO_CLASS(XULButtonElement)
|
||||
@ -448,8 +446,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(UserDataHandler, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(XPathNamespace, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULLabeledControlElement, nsDOMGenericSH,
|
||||
@ -1121,10 +1117,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMUserDataHandler)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XPathNamespace, nsIDOMXPathNamespace)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNamespace)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControlElement, nsIDOMXULControlElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULControlElement)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
@ -3166,7 +3158,6 @@ const InterfaceShimEntry kInterfaceShimMap[] =
|
||||
{ "nsIDOMRange", "Range" },
|
||||
{ "nsIDOMSVGLength", "SVGLength" },
|
||||
{ "nsIDOMNodeFilter", "NodeFilter" },
|
||||
{ "nsIDOMXPathNamespace", "XPathNamespace" },
|
||||
{ "nsIDOMXPathResult", "XPathResult" } };
|
||||
|
||||
static nsresult
|
||||
|
@ -93,7 +93,6 @@ DOMCI_CLASS(CSSPageRule)
|
||||
DOMCI_CLASS(CSSFontFeatureValuesRule)
|
||||
|
||||
DOMCI_CLASS(UserDataHandler)
|
||||
DOMCI_CLASS(XPathNamespace)
|
||||
DOMCI_CLASS(XULControlElement)
|
||||
DOMCI_CLASS(XULLabeledControlElement)
|
||||
DOMCI_CLASS(XULButtonElement)
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
@ -172,7 +172,7 @@
|
||||
|
||||
#include "nsIDragService.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
@ -1607,6 +1607,8 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
mAudioContexts.Clear();
|
||||
|
||||
#ifdef MOZ_GAMEPAD
|
||||
DisableGamepadUpdates();
|
||||
mHasGamepad = false;
|
||||
mGamepads.Clear();
|
||||
#endif
|
||||
}
|
||||
|
@ -104,7 +104,6 @@ class nsWindowSizes;
|
||||
|
||||
namespace mozilla {
|
||||
class DOMEventTargetHelper;
|
||||
class Selection;
|
||||
namespace dom {
|
||||
class BarProp;
|
||||
class Console;
|
||||
@ -114,6 +113,7 @@ class Gamepad;
|
||||
class MediaQueryList;
|
||||
class Navigator;
|
||||
class OwningExternalOrWindowProxy;
|
||||
class Selection;
|
||||
class SpeechSynthesis;
|
||||
class WakeLock;
|
||||
namespace indexedDB {
|
||||
@ -882,7 +882,7 @@ public:
|
||||
mozilla::ErrorResult& aError);
|
||||
nsIDOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||
nsIDOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsICSSDeclaration>
|
||||
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
|
||||
|
@ -974,7 +974,6 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'Selection': {
|
||||
'nativeType': 'mozilla::Selection',
|
||||
'resultNotAddRefed': [ 'anchorNode', 'focusNode', 'getRangeAt' ],
|
||||
},
|
||||
|
||||
|
@ -276,28 +276,6 @@ KeyboardEvent::InitKeyEvent(const nsAString& aType,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
KeyboardEvent::InitKeyboardEvent(const nsAString& aType,
|
||||
bool aCanBubble,
|
||||
bool aCancelable,
|
||||
nsIDOMWindow* aView,
|
||||
uint32_t aDetail,
|
||||
const nsAString& aKey,
|
||||
uint32_t aLocation,
|
||||
const nsAString& aModifiersList,
|
||||
bool aRepeat,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
|
||||
|
||||
WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
|
||||
keyEvent->modifiers = UIEvent::ComputeModifierState(aModifiersList);
|
||||
keyEvent->location = aLocation;
|
||||
keyEvent->mIsRepeat = aRepeat;
|
||||
keyEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
|
||||
keyEvent->mKeyValue = aKey;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -69,13 +69,6 @@ public:
|
||||
aKeyCode, aCharCode);
|
||||
}
|
||||
|
||||
void InitKeyboardEvent(const nsAString& aType,
|
||||
bool aCanBubble, bool aCancelable,
|
||||
nsIDOMWindow* aView, uint32_t aDetail,
|
||||
const nsAString& aKey, uint32_t aLocation,
|
||||
const nsAString& aModifiersList, bool aRepeat,
|
||||
ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
// True, if the instance is created with Constructor().
|
||||
bool mInitializedByCtor;
|
||||
|
@ -20,126 +20,55 @@ SimpleTest.waitForFocus(runTests, window);
|
||||
function testInitializingUntrustedEvent()
|
||||
{
|
||||
const kTests = [
|
||||
// initKeyEvent
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyboardEvent",
|
||||
type: "keydown", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 0
|
||||
keyCode: 0x00, charCode: 0x00 },
|
||||
|
||||
{ createEventArg: "keyboardevent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyboardevent",
|
||||
type: "keyup", bubbles: false, cancelable: true, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x10, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 1
|
||||
keyCode: 0x10, charCode: 0x00 },
|
||||
|
||||
{ createEventArg: "Keyboardevent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "Keyboardevent",
|
||||
type: "keypess", bubbles: true, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x11, charCode: 0x30,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 2
|
||||
keyCode: 0x11, charCode: 0x30 },
|
||||
|
||||
{ createEventArg: "keyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyboardEvent",
|
||||
type: "boo", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
|
||||
keyCode: 0x30, charCode: 0x40,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 3
|
||||
keyCode: 0x30, charCode: 0x40 },
|
||||
|
||||
{ createEventArg: "KeyEvents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyEvents",
|
||||
type: "foo", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
|
||||
keyCode: 0x00, charCode: 0x50,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 4
|
||||
keyCode: 0x00, charCode: 0x50 },
|
||||
|
||||
{ createEventArg: "keyevents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyevents",
|
||||
type: "bar", bubbles: false, cancelable: true, view: window,
|
||||
ctrlKey: true, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x60,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 5
|
||||
keyCode: 0x00, charCode: 0x60 },
|
||||
|
||||
{ createEventArg: "Keyevents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "Keyevents",
|
||||
type: "keydown", bubbles: true, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: true,
|
||||
keyCode: 0x30, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 6
|
||||
keyCode: 0x30, charCode: 0x00 },
|
||||
|
||||
{ createEventArg: "keyEvents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyEvents",
|
||||
type: "keyup", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: true, metaKey: false,
|
||||
keyCode: 0x10, charCode: 0x80,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 7
|
||||
keyCode: 0x10, charCode: 0x80 },
|
||||
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyboardEvent",
|
||||
type: "keypress", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: true, metaKey: true,
|
||||
keyCode: 0x10, charCode: 0x80,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 8
|
||||
keyCode: 0x10, charCode: 0x80 },
|
||||
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyboardEvent",
|
||||
type: "foo", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
|
||||
keyCode: 0x10, charCode: 0x80,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 9
|
||||
|
||||
// initKeyboardEvent
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: true,
|
||||
type: "keydown", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 10
|
||||
|
||||
{ createEventArg: "keyboardevent", useInitKeyboardEvent: true,
|
||||
type: "keyup", bubbles: false, cancelable: true, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 2, key: "Unidentified", location: 1, modifiersList: "Control", repeat: false,
|
||||
}, // 11
|
||||
|
||||
{ createEventArg: "Keyboardevent", useInitKeyboardEvent: true,
|
||||
type: "keypess", bubbles: true, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "FooBar", location: 2, modifiersList: "Alt", repeat: true,
|
||||
}, // 12
|
||||
|
||||
{ createEventArg: "keyboardevent", useInitKeyboardEvent: true,
|
||||
type: "foo", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "a", location: 0, modifiersList: "Meta", repeat: false,
|
||||
}, // 13
|
||||
|
||||
{ createEventArg: "Keyevents", useInitKeyboardEvent: true,
|
||||
type: "", bubbles: false, cancelable: false, view: null,
|
||||
ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "3", location: 0, modifiersList: "Control Alt Meta Shift", repeat: true,
|
||||
}, // 14
|
||||
|
||||
{ createEventArg: "keyevents", useInitKeyboardEvent: true,
|
||||
type: "", bubbles: false, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "3", location: 6, modifiersList: "Shift", repeat: true,
|
||||
}, // 15
|
||||
|
||||
{ createEventArg: "keyevents", useInitKeyboardEvent: true,
|
||||
type: "", bubbles: false, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "", location: 4, modifiersList: "Shift, Alt", repeat: false,
|
||||
}, // 16
|
||||
keyCode: 0x10, charCode: 0x80 },
|
||||
];
|
||||
|
||||
const kOtherModifierName = [
|
||||
@ -156,23 +85,17 @@ function testInitializingUntrustedEvent()
|
||||
var description = "testInitializingUntrustedEvent, Index: " + i + ", ";
|
||||
const kTest = kTests[i];
|
||||
var e = document.createEvent(kTest.createEventArg);
|
||||
if (kTest.useInitKeyboardEvent) {
|
||||
// IE has extra argument for |.locale|. Calling with it shouldn't cause error for compatibility with IE.
|
||||
e.initKeyboardEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view, kTest.detail,
|
||||
kTest.key, kTest.location, kTest.modifiersList, kTest.repeat, "locale");
|
||||
} else {
|
||||
e.initKeyEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
|
||||
kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
|
||||
kTest.keyCode, kTest.charCode);
|
||||
}
|
||||
is(e.toString(), "[object KeyboardEvent]",
|
||||
description + 'class string should be "KeyboardEvent"');
|
||||
|
||||
for (var attr in kTest) {
|
||||
if (attr == "createEventArg" || attr == "useInitKeyboardEvent" || attr == "modifiersList") {
|
||||
if (attr == "createEventArg") {
|
||||
continue;
|
||||
}
|
||||
if (!kTest.useInitKeyboardEvent && attr == "keyCode") {
|
||||
if (attr == "keyCode") {
|
||||
// If this is keydown, keyup of keypress event, keycod must be correct.
|
||||
if (kTest.type == "keydown" || kTest.type == "keyup" || kTest.type == "keypress") {
|
||||
is(e[attr], kTest[attr], description + attr + " returns wrong value");
|
||||
@ -180,7 +103,7 @@ function testInitializingUntrustedEvent()
|
||||
} else {
|
||||
is(e[attr], 0, description + attr + " returns non-zero for invalid event");
|
||||
}
|
||||
} else if (!kTest.useInitKeyboardEvent && attr == "charCode") {
|
||||
} else if (attr == "charCode") {
|
||||
// If this is keydown or keyup event, charCode always 0.
|
||||
if (kTest.type == "keydown" || kTest.type == "keyup") {
|
||||
is(e[attr], 0, description + attr + " returns non-zero for keydown or keyup event");
|
||||
@ -199,6 +122,9 @@ function testInitializingUntrustedEvent()
|
||||
}
|
||||
is(e.isTrusted, false, description + "isTrusted returns wrong value");
|
||||
|
||||
// Currently, there is no way to initialize char and key attribute values.
|
||||
ok(e.key === "", description + "key must return empty string - got " + e.key);
|
||||
|
||||
// getModifierState() tests
|
||||
is(e.getModifierState("Shift"), kTest.shiftKey,
|
||||
description + "getModifierState(\"Shift\") returns wrong value");
|
||||
|
@ -37,8 +37,8 @@
|
||||
[ "Callback message", msg, "Error: hello" ],
|
||||
[ "Event error-object", errorEvent.error, thrown],
|
||||
[ "Callback error-object", error, thrown ],
|
||||
[ "Event column", errorEvent.colno, 0 ], // Sadly not correct right now
|
||||
[ "Callback column", column, 0 ]
|
||||
[ "Event column", errorEvent.colno, 6 ], // Sadly not correct right now
|
||||
[ "Callback column", column, 6 ]
|
||||
]);
|
||||
</script>
|
||||
<script>
|
||||
|
@ -10,7 +10,7 @@
|
||||
* collection of DOM window objects.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(a6cf906f-15b3-11d2-932e-00805f8add32)]
|
||||
[uuid(a6cf906f-15b3-11d2-932e-00805f8add32)]
|
||||
interface nsIDOMWindowCollection : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -8,7 +8,6 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMNSXPathExpression.idl',
|
||||
'nsIDOMXPathEvaluator.idl',
|
||||
'nsIDOMXPathExpression.idl',
|
||||
'nsIDOMXPathNamespace.idl',
|
||||
'nsIDOMXPathNSResolver.idl',
|
||||
'nsIDOMXPathResult.idl',
|
||||
]
|
||||
|
@ -1,19 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
|
||||
*/
|
||||
|
||||
#include "nsIDOMNode.idl"
|
||||
|
||||
[scriptable, uuid(558c2ab9-513e-43c2-afea-4930024b15b3)]
|
||||
interface nsIDOMXPathNamespace : nsIDOMNode
|
||||
{
|
||||
// XPathNodeType
|
||||
const unsigned short XPATH_NAMESPACE_NODE = 13;
|
||||
|
||||
readonly attribute nsIDOMElement ownerElement;
|
||||
};
|
@ -747,6 +747,7 @@ TabChild::Observe(nsISupports *aSubject,
|
||||
|
||||
if (SameCOMIdentity(subject, doc)) {
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
|
||||
utils->SetIsFirstPaint(true);
|
||||
|
||||
mContentDocumentIsDisplayed = true;
|
||||
|
||||
@ -810,9 +811,6 @@ TabChild::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(do_GetInterface(window));
|
||||
utils->SetIsFirstPaint(true);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> progressDoc;
|
||||
window->GetDocument(getter_AddRefs(progressDoc));
|
||||
if (!progressDoc) {
|
||||
|
@ -584,7 +584,6 @@ exports.browser = {
|
||||
XPathEvaluator : false,
|
||||
XPathException : false,
|
||||
XPathExpression : false,
|
||||
XPathNamespace : false,
|
||||
XPathNSResolver : false,
|
||||
XPathResult : false
|
||||
};
|
||||
|
@ -1189,8 +1189,6 @@ var interfaceNamesInGlobalScope =
|
||||
"XPathEvaluator",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XPathExpression",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XPathNamespace",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"XPathNSResolver",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -31,17 +31,6 @@ interface KeyboardEvent : UIEvent
|
||||
readonly attribute boolean isComposing;
|
||||
|
||||
readonly attribute DOMString key;
|
||||
|
||||
[Throws]
|
||||
void initKeyboardEvent(DOMString typeArg,
|
||||
boolean bubblesArg,
|
||||
boolean cancelableArg,
|
||||
WindowProxy? viewArg,
|
||||
long detailArg,
|
||||
DOMString keyArg,
|
||||
unsigned long locationArg,
|
||||
DOMString modifiersListArg,
|
||||
boolean repeatArg);
|
||||
};
|
||||
|
||||
dictionary KeyboardEventInit : UIEventInit
|
||||
|
@ -66,7 +66,12 @@ nsXBLPrototypeResources::FlushSkinSheets()
|
||||
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
mLoader->mBinding->XBLDocumentInfo()->GetDocument();
|
||||
mozilla::css::Loader* cssLoader = doc->CSSLoader();
|
||||
|
||||
// If doc is null, we're in the process of tearing things down, so just
|
||||
// return without rebuilding anything.
|
||||
if (!doc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We have scoped stylesheets. Reload any chrome stylesheets we
|
||||
// encounter. (If they aren't skin sheets, it doesn't matter, since
|
||||
@ -76,6 +81,8 @@ nsXBLPrototypeResources::FlushSkinSheets()
|
||||
sheet_array_type oldSheets(mStyleSheetList);
|
||||
mStyleSheetList.Clear();
|
||||
|
||||
mozilla::css::Loader* cssLoader = doc->CSSLoader();
|
||||
|
||||
for (sheet_array_type::size_type i = 0, count = oldSheets.Length();
|
||||
i < count; ++i) {
|
||||
nsCSSStyleSheet* oldSheet = oldSheets[i];
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "nsIDOMCharacterData.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMXPathNamespace.h"
|
||||
#include "nsXPathResult.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
@ -94,8 +93,7 @@ nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
|
||||
nodeType != nsIDOMNode::ELEMENT_NODE &&
|
||||
nodeType != nsIDOMNode::ATTRIBUTE_NODE &&
|
||||
nodeType != nsIDOMNode::COMMENT_NODE &&
|
||||
nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE &&
|
||||
nodeType != nsIDOMXPathNamespace::XPATH_NAMESPACE_NODE) {
|
||||
nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "DeleteRangeTxn.h"
|
||||
#include "DeleteTextTxn.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
@ -22,6 +22,7 @@
|
||||
class nsIDOMRange;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// note that aEditor is not refcounted
|
||||
DeleteRangeTxn::DeleteRangeTxn()
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "DeleteTextTxn.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsEditor.h"
|
||||
@ -17,6 +17,7 @@
|
||||
#include "nsAString.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
DeleteTextTxn::DeleteTextTxn() :
|
||||
EditTxn(),
|
||||
|
@ -7,9 +7,10 @@
|
||||
#include "nsEditor.h"
|
||||
#include "IMETextTxn.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
PlaceholderTxn::PlaceholderTxn() : EditAggregateTxn(),
|
||||
mAbsorb(true),
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
nsIEditor::EDirection aDirection) = 0;
|
||||
NS_IMETHOD AfterEdit(EditAction action,
|
||||
nsIEditor::EDirection aDirection) = 0;
|
||||
NS_IMETHOD WillDoAction(mozilla::Selection* aSelection, nsRulesInfo* aInfo,
|
||||
NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo,
|
||||
bool* aCancel, bool* aHandled) = 0;
|
||||
NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
|
||||
NS_IMETHOD DocumentIsEmpty(bool *aDocumentIsEmpty)=0;
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "mozInlineSpellChecker.h" // for mozInlineSpellChecker
|
||||
#include "mozilla/IMEStateManager.h" // for IMEStateManager
|
||||
#include "mozilla/Preferences.h" // for Preferences
|
||||
#include "mozilla/Selection.h" // for Selection, etc
|
||||
#include "mozilla/dom/Selection.h" // for Selection, etc
|
||||
#include "mozilla/Services.h" // for GetObserverService
|
||||
#include "mozilla/TextComposition.h" // for TextComposition
|
||||
#include "mozilla/TextEvents.h"
|
||||
|
@ -67,13 +67,13 @@ class nsString;
|
||||
class nsTransactionManager;
|
||||
|
||||
namespace mozilla {
|
||||
class Selection;
|
||||
class TextComposition;
|
||||
|
||||
namespace dom {
|
||||
class DataTransfer;
|
||||
class Element;
|
||||
class EventTarget;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@ -435,7 +435,7 @@ public:
|
||||
/** routines for managing the preservation of selection across
|
||||
* various editor actions */
|
||||
bool ArePreservingSelection();
|
||||
void PreserveSelectionAcrossActions(mozilla::Selection* aSel);
|
||||
void PreserveSelectionAcrossActions(mozilla::dom::Selection* aSel);
|
||||
nsresult RestorePreservedSelection(nsISelection *aSel);
|
||||
void StopPreservingSelection();
|
||||
|
||||
@ -623,17 +623,17 @@ public:
|
||||
static nsCOMPtr<nsIDOMNode> GetNodeAtRangeOffsetPoint(nsIDOMNode* aParentOrNode, int32_t aOffset);
|
||||
|
||||
static nsresult GetStartNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outStartNode, int32_t *outStartOffset);
|
||||
static nsresult GetStartNodeAndOffset(mozilla::Selection* aSelection,
|
||||
static nsresult GetStartNodeAndOffset(mozilla::dom::Selection* aSelection,
|
||||
nsINode** aStartNode,
|
||||
int32_t* aStartOffset);
|
||||
static nsresult GetEndNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outEndNode, int32_t *outEndOffset);
|
||||
static nsresult GetEndNodeAndOffset(mozilla::Selection* aSelection,
|
||||
static nsresult GetEndNodeAndOffset(mozilla::dom::Selection* aSelection,
|
||||
nsINode** aEndNode,
|
||||
int32_t* aEndOffset);
|
||||
#if DEBUG_JOE
|
||||
static void DumpNode(nsIDOMNode *aNode, int32_t indent=0);
|
||||
#endif
|
||||
mozilla::Selection* GetSelection();
|
||||
mozilla::dom::Selection* GetSelection();
|
||||
|
||||
// Helpers to add a node to the selection.
|
||||
// Used by table cell selection methods
|
||||
|
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsEditorUtils.h"
|
||||
@ -24,6 +24,7 @@ class nsIDOMRange;
|
||||
class nsISupports;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
/******************************************************************************
|
||||
* nsAutoSelectionReset
|
||||
|
@ -56,12 +56,12 @@ class MOZ_STACK_CLASS nsAutoSelectionReset
|
||||
{
|
||||
private:
|
||||
/** ref-counted reference to the selection that we are supposed to restore */
|
||||
nsRefPtr<mozilla::Selection> mSel;
|
||||
nsRefPtr<mozilla::dom::Selection> mSel;
|
||||
nsEditor *mEd; // non-owning ref to nsEditor
|
||||
|
||||
public:
|
||||
/** constructor responsible for remembering all state needed to restore aSel */
|
||||
nsAutoSelectionReset(mozilla::Selection* aSel, nsEditor* aEd);
|
||||
nsAutoSelectionReset(mozilla::dom::Selection* aSel, nsEditor* aEd);
|
||||
|
||||
/** destructor restores mSel to its former state */
|
||||
~nsAutoSelectionReset();
|
||||
|
@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/Selection.h" // for Selection
|
||||
#include "mozilla/dom/Selection.h" // for Selection
|
||||
#include "nsAString.h" // for nsAString_internal::Length
|
||||
#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
@ -21,6 +21,7 @@
|
||||
#include "nsSelectionState.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
/***************************************************************************
|
||||
* class for recording selection info. stores selection as collection of
|
||||
|
@ -18,8 +18,10 @@ class nsIDOMRange;
|
||||
class nsISelection;
|
||||
class nsRange;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Selection;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* class for recording selection info. stores selection as collection of
|
||||
@ -59,7 +61,7 @@ class nsSelectionState
|
||||
void DoTraverse(nsCycleCollectionTraversalCallback &cb);
|
||||
void DoUnlink() { MakeEmpty(); }
|
||||
|
||||
void SaveSelection(mozilla::Selection *aSel);
|
||||
void SaveSelection(mozilla::dom::Selection *aSel);
|
||||
nsresult RestoreSelection(nsISelection *aSel);
|
||||
bool IsCollapsed();
|
||||
bool IsEqual(nsSelectionState *aSelState);
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "nsAString.h"
|
||||
@ -52,6 +52,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#define BLACK_BG_RGB_TRIGGER 0xd0
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "nsAString.h"
|
||||
@ -61,6 +61,7 @@ class nsISupports;
|
||||
class nsRulesInfo;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
//const static char* kMOZEditorBogusNodeAttr="MOZ_EDITOR_BOGUS_NODE";
|
||||
//const static char* kMOZEditorBogusNodeValue="TRUE";
|
||||
|
@ -33,9 +33,9 @@ class nsPlaintextEditor;
|
||||
class nsRange;
|
||||
class nsRulesInfo;
|
||||
namespace mozilla {
|
||||
class Selection;
|
||||
namespace dom {
|
||||
class Element;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
struct DOMPoint;
|
||||
@ -79,7 +79,7 @@ public:
|
||||
nsIEditor::EDirection aDirection);
|
||||
NS_IMETHOD AfterEdit(EditAction action,
|
||||
nsIEditor::EDirection aDirection);
|
||||
NS_IMETHOD WillDoAction(mozilla::Selection* aSelection, nsRulesInfo* aInfo,
|
||||
NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo,
|
||||
bool* aCancel, bool* aHandled);
|
||||
NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
NS_IMETHOD DocumentModified();
|
||||
@ -127,19 +127,19 @@ protected:
|
||||
// nsHTMLEditRules implementation methods
|
||||
nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
|
||||
nsresult WillInsertText( EditAction aAction,
|
||||
mozilla::Selection* aSelection,
|
||||
mozilla::dom::Selection* aSelection,
|
||||
bool *aCancel,
|
||||
bool *aHandled,
|
||||
const nsAString *inString,
|
||||
nsAString *outString,
|
||||
int32_t aMaxLength);
|
||||
nsresult WillLoadHTML(nsISelection *aSelection, bool *aCancel);
|
||||
nsresult WillInsertBreak(mozilla::Selection* aSelection,
|
||||
nsresult WillInsertBreak(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult StandardBreakImpl(nsIDOMNode *aNode, int32_t aOffset, nsISelection *aSelection);
|
||||
nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
|
||||
nsresult SplitMailCites(nsISelection *aSelection, bool aPlaintext, bool *aHandled);
|
||||
nsresult WillDeleteSelection(mozilla::Selection* aSelection,
|
||||
nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
|
||||
nsIEditor::EDirection aAction,
|
||||
nsIEditor::EStripWrappers aStripWrappers,
|
||||
bool* aCancel, bool* aHandled);
|
||||
@ -154,36 +154,36 @@ protected:
|
||||
nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset);
|
||||
nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset);
|
||||
nsresult DeleteNonTableElements(nsINode* aNode);
|
||||
nsresult WillMakeList(mozilla::Selection* aSelection,
|
||||
nsresult WillMakeList(mozilla::dom::Selection* aSelection,
|
||||
const nsAString* aListType,
|
||||
bool aEntireList,
|
||||
const nsAString* aBulletType,
|
||||
bool* aCancel, bool* aHandled,
|
||||
const nsAString* aItemType = nullptr);
|
||||
nsresult WillRemoveList(mozilla::Selection* aSelection,
|
||||
nsresult WillRemoveList(mozilla::dom::Selection* aSelection,
|
||||
bool aOrdered, bool* aCancel, bool* aHandled);
|
||||
nsresult WillIndent(mozilla::Selection* aSelection,
|
||||
nsresult WillIndent(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillCSSIndent(mozilla::Selection* aSelection,
|
||||
nsresult WillCSSIndent(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillHTMLIndent(mozilla::Selection* aSelection,
|
||||
nsresult WillHTMLIndent(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillOutdent(mozilla::Selection* aSelection,
|
||||
nsresult WillOutdent(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillAlign(mozilla::Selection* aSelection,
|
||||
nsresult WillAlign(mozilla::dom::Selection* aSelection,
|
||||
const nsAString* alignType,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillAbsolutePosition(mozilla::Selection* aSelection,
|
||||
nsresult WillAbsolutePosition(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillRemoveAbsolutePosition(mozilla::Selection* aSelection,
|
||||
nsresult WillRemoveAbsolutePosition(mozilla::dom::Selection* aSelection,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillRelativeChangeZIndex(mozilla::Selection* aSelection,
|
||||
nsresult WillRelativeChangeZIndex(mozilla::dom::Selection* aSelection,
|
||||
int32_t aChange,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillMakeDefListItem(mozilla::Selection* aSelection,
|
||||
nsresult WillMakeDefListItem(mozilla::dom::Selection* aSelection,
|
||||
const nsAString* aBlockType, bool aEntireList,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult WillMakeBasicBlock(mozilla::Selection* aSelection,
|
||||
nsresult WillMakeBasicBlock(mozilla::dom::Selection* aSelection,
|
||||
const nsAString* aBlockType,
|
||||
bool* aCancel, bool* aHandled);
|
||||
nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
|
@ -69,13 +69,14 @@
|
||||
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
#include "nsTextFragment.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
// Some utilities to handle annoying overloading of "A" tag for link and named anchor
|
||||
|
@ -4,7 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "TypeInState.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "nsAString.h"
|
||||
@ -52,6 +52,7 @@
|
||||
class nsISupports;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
static bool
|
||||
IsEmptyTextNode(nsHTMLEditor* aThis, nsINode* aNode)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsAlgorithm.h"
|
||||
@ -42,6 +42,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
/***************************************************************************
|
||||
* stack based helper class for restoring selection after table edit
|
||||
|
@ -336,7 +336,7 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
int32_t aOffset,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aPriorNode);
|
||||
nsresult GetPreviousWSNode(DOMPoint aPoint,
|
||||
nsresult GetPreviousWSNode(::DOMPoint aPoint,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aPriorNode);
|
||||
nsresult GetNextWSNode(nsIDOMNode *aStartNode,
|
||||
@ -346,7 +346,7 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
int32_t aOffset,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aNextNode);
|
||||
nsresult GetNextWSNode(DOMPoint aPoint,
|
||||
nsresult GetNextWSNode(::DOMPoint aPoint,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aNextNode);
|
||||
nsresult PrepareToDeleteRangePriv(nsWSRunObject* aEndObject);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
@ -64,6 +64,7 @@ class nsISupports;
|
||||
class nsISupportsArray;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsPlaintextEditor::nsPlaintextEditor()
|
||||
: nsEditor()
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsAString.h"
|
||||
@ -43,6 +43,7 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
|
||||
if (IsReadonly() || IsDisabled()) \
|
||||
|
@ -21,7 +21,9 @@ class nsIDOMElement;
|
||||
class nsIDOMNode;
|
||||
class nsISelection;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
/** Object that encapsulates HTML text-specific editing rules.
|
||||
@ -53,8 +55,8 @@ public:
|
||||
nsIEditor::EDirection aDirection);
|
||||
NS_IMETHOD AfterEdit(EditAction action,
|
||||
nsIEditor::EDirection aDirection);
|
||||
NS_IMETHOD WillDoAction(mozilla::Selection* aSelection, nsRulesInfo* aInfo,
|
||||
bool* aCancel, bool* aHandled);
|
||||
NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection,
|
||||
nsRulesInfo* aInfo, bool* aCancel, bool* aHandled);
|
||||
NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||
NS_IMETHOD DocumentIsEmpty(bool *aDocumentIsEmpty);
|
||||
NS_IMETHOD DocumentModified();
|
||||
@ -102,7 +104,7 @@ protected:
|
||||
|
||||
// nsTextEditRules implementation methods
|
||||
nsresult WillInsertText( EditAction aAction,
|
||||
mozilla::Selection* aSelection,
|
||||
mozilla::dom::Selection* aSelection,
|
||||
bool *aCancel,
|
||||
bool *aHandled,
|
||||
const nsAString *inString,
|
||||
@ -111,14 +113,14 @@ protected:
|
||||
nsresult DidInsertText(nsISelection *aSelection, nsresult aResult);
|
||||
nsresult GetTopEnclosingPre(nsIDOMNode *aNode, nsIDOMNode** aOutPreNode);
|
||||
|
||||
nsresult WillInsertBreak(mozilla::Selection* aSelection, bool* aCancel,
|
||||
nsresult WillInsertBreak(mozilla::dom::Selection* aSelection, bool* aCancel,
|
||||
bool *aHandled, int32_t aMaxLength);
|
||||
nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
|
||||
nsresult DidInsert(nsISelection *aSelection, nsresult aResult);
|
||||
|
||||
nsresult WillDeleteSelection(mozilla::Selection* aSelection,
|
||||
nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
|
||||
nsIEditor::EDirection aCollapsedAction,
|
||||
bool *aCancel,
|
||||
bool *aHandled);
|
||||
@ -167,7 +169,7 @@ protected:
|
||||
|
||||
/** returns a truncated insertion string if insertion would place us
|
||||
over aMaxLength */
|
||||
nsresult TruncateInsertionIfNeeded(mozilla::Selection* aSelection,
|
||||
nsresult TruncateInsertionIfNeeded(mozilla::dom::Selection* aSelection,
|
||||
const nsAString *aInString,
|
||||
nsAString *aOutString,
|
||||
int32_t aMaxLength,
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsPlaintextEditor.h"
|
||||
@ -21,6 +21,7 @@
|
||||
#include "nscore.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// Test for distance between caret and text that will be deleted
|
||||
nsresult
|
||||
|
@ -366,6 +366,12 @@ WebBrowserChrome::OnHistoryPurge(int32_t aNumEntries, bool *aContinue)
|
||||
return SendHistoryStatusMessage(nullptr, "purge", aNumEntries);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryReplaceEntry(int32_t aIndex)
|
||||
{
|
||||
return SendHistoryStatusMessage(nullptr, "replace", aIndex);
|
||||
}
|
||||
|
||||
static void
|
||||
AppendIntToCString(int32_t info1, nsCString& aResult)
|
||||
{
|
||||
@ -438,6 +444,11 @@ WebBrowserChrome::SendHistoryStatusMessage(nsIURI * aURI, char * operation, int3
|
||||
AppendIntToCString(info1, status);
|
||||
status.Append(" purged from Session History");
|
||||
}
|
||||
else if (!(strcmp(operation, "replace")))
|
||||
{
|
||||
status.Assign("Replacing HistoryIndex: ");
|
||||
AppentIntToCString(info1, status);
|
||||
}
|
||||
|
||||
nsString wstatus;
|
||||
NS_CStringToUTF16(status, NS_CSTRING_ENCODING_UTF8, wstatus);
|
||||
|
@ -41,7 +41,9 @@ ActiveElementManager::SetTargetElement(nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
if (mTarget) {
|
||||
// Multiple fingers on screen (since HandleTouchEnd clears mTarget).
|
||||
CancelTask();
|
||||
ResetActive();
|
||||
mTarget = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
|
||||
#include "mozilla/dom/TabChild.h" // for TabChild
|
||||
#include "mozilla/hal_sandbox/PHal.h" // for ScreenConfiguration
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableChild, etc
|
||||
#include "mozilla/layers/ContentClient.h" // for ContentClientRemote
|
||||
#include "mozilla/layers/CompositableClient.h"
|
||||
#include "mozilla/layers/ContentClient.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/layers/LayersMessages.h" // for EditReply, etc
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||
@ -379,10 +379,10 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
|
||||
const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(obs.compositableChild());
|
||||
CompositableClient* compositable =
|
||||
CompositableClient::FromIPDLActor(obs.compositableChild());
|
||||
ContentClientRemote* contentClient =
|
||||
static_cast<ContentClientRemote*>(compositableChild->GetCompositableClient());
|
||||
static_cast<ContentClientRemote*>(compositable);
|
||||
MOZ_ASSERT(contentClient);
|
||||
|
||||
contentClient->SwapBuffers(obs.frontUpdatedRegion());
|
||||
@ -394,12 +394,10 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
|
||||
const OpTextureSwap& ots = reply.get_OpTextureSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(ots.compositableChild());
|
||||
MOZ_ASSERT(compositableChild);
|
||||
|
||||
compositableChild->GetCompositableClient()
|
||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
CompositableClient* compositable =
|
||||
CompositableClient::FromIPDLActor(ots.compositableChild());
|
||||
MOZ_ASSERT(compositable);
|
||||
compositable->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
break;
|
||||
}
|
||||
case EditReply::TReturnReleaseFence: {
|
||||
|
@ -21,6 +21,67 @@ using namespace mozilla::gfx;
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* IPDL actor used by CompositableClient to match with its corresponding
|
||||
* CompositableHost on the compositor side.
|
||||
*
|
||||
* CompositableChild is owned by a CompositableClient.
|
||||
*/
|
||||
class CompositableChild : public PCompositableChild
|
||||
{
|
||||
public:
|
||||
CompositableChild()
|
||||
: mCompositableClient(nullptr), mAsyncID(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CompositableChild);
|
||||
}
|
||||
|
||||
~CompositableChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CompositableChild);
|
||||
}
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason) MOZ_OVERRIDE {
|
||||
if (mCompositableClient) {
|
||||
mCompositableClient->mCompositableChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CompositableClient* mCompositableClient;
|
||||
|
||||
uint64_t mAsyncID;
|
||||
};
|
||||
|
||||
PCompositableChild*
|
||||
CompositableClient::CreateIPDLActor()
|
||||
{
|
||||
return new CompositableChild();
|
||||
}
|
||||
|
||||
bool
|
||||
CompositableClient::DestroyIPDLActor(PCompositableChild* actor)
|
||||
{
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CompositableClient::InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
CompositableChild* child = static_cast<CompositableChild*>(aActor);
|
||||
mCompositableChild = child;
|
||||
child->mCompositableClient = this;
|
||||
child->mAsyncID = aAsyncID;
|
||||
}
|
||||
|
||||
CompositableClient*
|
||||
CompositableClient::FromIPDLActor(PCompositableChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
return static_cast<CompositableChild*>(aActor)->mCompositableClient;
|
||||
}
|
||||
|
||||
CompositableClient::CompositableClient(CompositableForwarder* aForwarder,
|
||||
TextureFlags aTextureFlags)
|
||||
: mCompositableChild(nullptr)
|
||||
@ -48,7 +109,7 @@ CompositableClient::SetIPDLActor(CompositableChild* aChild)
|
||||
mCompositableChild = aChild;
|
||||
}
|
||||
|
||||
CompositableChild*
|
||||
PCompositableChild*
|
||||
CompositableClient::GetIPDLActor() const
|
||||
{
|
||||
return mCompositableChild;
|
||||
@ -70,8 +131,8 @@ CompositableClient::Destroy()
|
||||
if (!mCompositableChild) {
|
||||
return;
|
||||
}
|
||||
mCompositableChild->SetClient(nullptr);
|
||||
mCompositableChild->Destroy();
|
||||
mCompositableChild->mCompositableClient = nullptr;
|
||||
PCompositableChild::Send__delete__(mCompositableChild);
|
||||
mCompositableChild = nullptr;
|
||||
}
|
||||
|
||||
@ -79,18 +140,11 @@ uint64_t
|
||||
CompositableClient::GetAsyncID() const
|
||||
{
|
||||
if (mCompositableChild) {
|
||||
return mCompositableChild->GetAsyncID();
|
||||
return mCompositableChild->mAsyncID;
|
||||
}
|
||||
return 0; // zero is always an invalid async ID
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CompositableChild::Destroy()
|
||||
{
|
||||
Send__delete__(this);
|
||||
}
|
||||
|
||||
TemporaryRef<BufferTextureClient>
|
||||
CompositableClient::CreateBufferTextureClient(SurfaceFormat aFormat,
|
||||
TextureFlags aTextureFlags,
|
||||
|
@ -105,7 +105,7 @@ public:
|
||||
|
||||
void Destroy();
|
||||
|
||||
CompositableChild* GetIPDLActor() const;
|
||||
PCompositableChild* GetIPDLActor() const;
|
||||
|
||||
// should only be called by a CompositableForwarder
|
||||
virtual void SetIPDLActor(CompositableChild* aChild);
|
||||
@ -146,6 +146,22 @@ public:
|
||||
*/
|
||||
virtual void ClearCachedResources() {}
|
||||
|
||||
static CompositableClient* FromIPDLActor(PCompositableChild* aActor);
|
||||
|
||||
/**
|
||||
* Allocate and deallocate a CompositableChild actor.
|
||||
*
|
||||
* CompositableChild is an implementation detail of CompositableClient that is not
|
||||
* exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
|
||||
* are for use with the managing IPDL protocols only (so that they can
|
||||
* implement AllocCompositableChild and DeallocPCompositableChild).
|
||||
*/
|
||||
static PCompositableChild* CreateIPDLActor();
|
||||
|
||||
static bool DestroyIPDLActor(PCompositableChild* actor);
|
||||
|
||||
void InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID = 0);
|
||||
|
||||
protected:
|
||||
CompositableChild* mCompositableChild;
|
||||
CompositableForwarder* mForwarder;
|
||||
@ -156,53 +172,6 @@ protected:
|
||||
friend class CompositableChild;
|
||||
};
|
||||
|
||||
/**
|
||||
* IPDL actor used by CompositableClient to match with its corresponding
|
||||
* CompositableHost on the compositor side.
|
||||
*
|
||||
* CompositableChild is owned by a CompositableClient.
|
||||
*/
|
||||
class CompositableChild : public PCompositableChild
|
||||
{
|
||||
public:
|
||||
CompositableChild()
|
||||
: mCompositableClient(nullptr), mID(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CompositableChild);
|
||||
}
|
||||
~CompositableChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CompositableChild);
|
||||
}
|
||||
|
||||
void Destroy();
|
||||
|
||||
void SetClient(CompositableClient* aClient)
|
||||
{
|
||||
mCompositableClient = aClient;
|
||||
}
|
||||
|
||||
CompositableClient* GetCompositableClient() const
|
||||
{
|
||||
return mCompositableClient;
|
||||
}
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason) MOZ_OVERRIDE {
|
||||
if (mCompositableClient) {
|
||||
mCompositableClient->mCompositableChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SetAsyncID(uint64_t aID) { mID = aID; }
|
||||
uint64_t GetAsyncID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
private:
|
||||
CompositableClient* mCompositableClient;
|
||||
uint64_t mID;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
|
@ -236,9 +236,9 @@ public:
|
||||
/**
|
||||
* Allocate and deallocate a TextureChild actor.
|
||||
*
|
||||
* TextureChild is an implementation detail of TextureHost that is not
|
||||
* TextureChild is an implementation detail of TextureClient that is not
|
||||
* exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
|
||||
* are for use with the maging IPDL protocols only (so that they can
|
||||
* are for use with the managing IPDL protocols only (so that they can
|
||||
* implement AllocPextureChild and DeallocPTextureChild).
|
||||
*/
|
||||
static PTextureChild* CreateIPDLActor();
|
||||
|
@ -264,26 +264,22 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable)
|
||||
{
|
||||
MOZ_ASSERT(aCompositable);
|
||||
uint64_t id = 0;
|
||||
CompositableChild* child = static_cast<CompositableChild*>(
|
||||
SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id));
|
||||
PCompositableChild* child =
|
||||
SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id);
|
||||
MOZ_ASSERT(child);
|
||||
child->SetAsyncID(id);
|
||||
aCompositable->SetIPDLActor(child);
|
||||
MOZ_ASSERT(child->GetAsyncID() == id);
|
||||
child->SetClient(aCompositable);
|
||||
aCompositable->InitIPDLActor(child, id);
|
||||
}
|
||||
|
||||
PCompositableChild*
|
||||
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID)
|
||||
{
|
||||
return new CompositableChild();
|
||||
return CompositableClient::CreateIPDLActor();
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeChild::DeallocPCompositableChild(PCompositableChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
return CompositableClient::DestroyIPDLActor(aActor);
|
||||
}
|
||||
|
||||
|
||||
@ -491,13 +487,12 @@ ImageBridgeChild::EndTransaction()
|
||||
case EditReply::TOpTextureSwap: {
|
||||
const OpTextureSwap& ots = reply.get_OpTextureSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(ots.compositableChild());
|
||||
CompositableClient* compositable =
|
||||
CompositableClient::FromIPDLActor(ots.compositableChild());
|
||||
|
||||
MOZ_ASSERT(compositableChild);
|
||||
MOZ_ASSERT(compositable);
|
||||
|
||||
compositableChild->GetCompositableClient()
|
||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
compositable->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
break;
|
||||
}
|
||||
case EditReply::TReturnReleaseFence: {
|
||||
|
@ -73,14 +73,13 @@ LayerTransactionChild::DeallocPLayerChild(PLayerChild* actor)
|
||||
PCompositableChild*
|
||||
LayerTransactionChild::AllocPCompositableChild(const TextureInfo& aInfo)
|
||||
{
|
||||
return new CompositableChild();
|
||||
return CompositableClient::CreateIPDLActor();
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionChild::DeallocPCompositableChild(PCompositableChild* actor)
|
||||
{
|
||||
delete actor;
|
||||
return true;
|
||||
return CompositableClient::DestroyIPDLActor(actor);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -648,11 +648,10 @@ ShadowLayerForwarder::Connect(CompositableClient* aCompositable)
|
||||
if (!mShadowManager->IPCOpen()) {
|
||||
return;
|
||||
}
|
||||
CompositableChild* child = static_cast<CompositableChild*>(
|
||||
mShadowManager->SendPCompositableConstructor(aCompositable->GetTextureInfo()));
|
||||
MOZ_ASSERT(child);
|
||||
aCompositable->SetIPDLActor(child);
|
||||
child->SetClient(aCompositable);
|
||||
PCompositableChild* actor =
|
||||
mShadowManager->SendPCompositableConstructor(aCompositable->GetTextureInfo());
|
||||
MOZ_ASSERT(actor);
|
||||
aCompositable->InitIPDLActor(actor);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3436,6 +3436,8 @@ EmitVariables(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmit
|
||||
|
||||
ParseNode *next;
|
||||
for (ParseNode *pn2 = pn->pn_head; ; pn2 = next) {
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn2->pn_pos.begin))
|
||||
return false;
|
||||
next = pn2->pn_next;
|
||||
|
||||
ParseNode *pn3;
|
||||
@ -5904,6 +5906,9 @@ EmitObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
for (ParseNode *pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn2->pn_pos.begin))
|
||||
return false;
|
||||
|
||||
/* Emit an index for t[2] for later consumption by JSOP_INITELEM. */
|
||||
ParseNode *pn3 = pn2->pn_left;
|
||||
bool isIndex = false;
|
||||
@ -6065,6 +6070,8 @@ EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t co
|
||||
if (nspread && !EmitNumberOp(cx, 0, bce))
|
||||
return false;
|
||||
for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn2->pn_pos.begin))
|
||||
return false;
|
||||
if (pn2->isKind(PNK_ELISION)) {
|
||||
if (Emit1(cx, bce, JSOP_HOLE) < 0)
|
||||
return false;
|
||||
@ -6372,6 +6379,8 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
case PNK_COMMA:
|
||||
{
|
||||
for (ParseNode *pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn2->pn_pos.begin))
|
||||
return false;
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return false;
|
||||
if (!pn2->pn_next)
|
||||
|
@ -1,38 +1,93 @@
|
||||
load(libdir + "asm.js");
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var callFFI1 = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function asmfun1() { return ffi(1)|0 } return asmfun1");
|
||||
var callFFI2 = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function asmfun2() { return ffi(2)|0 } return asmfun2");
|
||||
function matchStack(stackString, stackArray)
|
||||
{
|
||||
var match = 0;
|
||||
for (name of stackArray) {
|
||||
match = stackString.indexOf(name, match);
|
||||
if (match === -1)
|
||||
throw name + " not found in the stack " + stack;
|
||||
}
|
||||
}
|
||||
|
||||
var stack;
|
||||
function dumpStack(i) { stack = new Error().stack; return i+11 }
|
||||
function dumpStack()
|
||||
{
|
||||
stack = new Error().stack
|
||||
}
|
||||
|
||||
var asmfun1 = asmLink(callFFI1, null, {ffi:dumpStack});
|
||||
assertEq(asmfun1(), 12);
|
||||
assertEq(stack.indexOf("asmfun1") === -1, false);
|
||||
var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f");
|
||||
|
||||
var asmfun2 = asmLink(callFFI2, null, {ffi:function ffi(i){return asmfun1()+20}});
|
||||
assertEq(asmfun2(), 32);
|
||||
assertEq(stack.indexOf("asmfun1") == -1, false);
|
||||
assertEq(stack.indexOf("asmfun2") == -1, false);
|
||||
assertEq(stack.indexOf("asmfun2") > stack.indexOf("asmfun1"), true);
|
||||
var f = asmLink(callFFI, null, {ffi:dumpStack});
|
||||
for (var i = 0; i < 5000; i++) {
|
||||
stack = null;
|
||||
f();
|
||||
matchStack(stack, ['dumpStack', 'f']);
|
||||
}
|
||||
|
||||
if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
|
||||
var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f");
|
||||
assertEq(isAsmJSModuleLoadedFromCache(callFFI), true);
|
||||
stack = null;
|
||||
f();
|
||||
matchStack(stack, ['dumpStack', 'f']);
|
||||
}
|
||||
|
||||
var f1 = asmLink(callFFI, null, {ffi:dumpStack});
|
||||
var f2 = asmLink(callFFI, null, {ffi:function middle() { f1() }});
|
||||
stack = null;
|
||||
(function outer() { f2() })();
|
||||
matchStack(stack, ["dumpStack", "f", "middle", "f"]);
|
||||
|
||||
function returnStackDumper() { return { valueOf:function() { stack = new Error().stack } } }
|
||||
var f = asmLink(callFFI, null, {ffi:returnStackDumper});
|
||||
for (var i = 0; i < 5000; i++) {
|
||||
stack = null;
|
||||
f();
|
||||
matchStack(stack, ['valueOf', 'f']);
|
||||
}
|
||||
|
||||
var caught = false;
|
||||
try {
|
||||
stack = null;
|
||||
asmLink(asmCompile(USE_ASM + "function asmRec() { asmRec() } return asmRec"))();
|
||||
} catch (e) {
|
||||
caught = true;
|
||||
matchStack(e.stack, ['asmRec', 'asmRec', 'asmRec', 'asmRec']);
|
||||
}
|
||||
assertEq(caught, true);
|
||||
|
||||
var caught = false;
|
||||
try {
|
||||
callFFI1(null, {ffi:Object.preventExtensions})();
|
||||
callFFI(null, {ffi:Object.preventExtensions})();
|
||||
} catch (e) {
|
||||
caught = true;
|
||||
}
|
||||
assertEq(caught, true);
|
||||
|
||||
assertEq(asmLink(callFFI1, null, {ffi:eval})(), 1);
|
||||
assertEq(asmLink(callFFI1, null, {ffi:Function})(), 0);
|
||||
assertEq(asmLink(callFFI1, null, {ffi:Error})(), 0);
|
||||
asmLink(callFFI, null, {ffi:eval})();
|
||||
asmLink(callFFI, null, {ffi:Function})();
|
||||
asmLink(callFFI, null, {ffi:Error})();
|
||||
|
||||
var manyCalls = asmCompile('global', 'ffis',
|
||||
USE_ASM +
|
||||
"var ffi=ffis.ffi;\
|
||||
function f1(a,b,c,d,e,f,g,h,i,j,k) { \
|
||||
a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0; \
|
||||
ffi(); \
|
||||
return (a+b+c+d+e+f+g+h+i+j+k)|0; \
|
||||
} \
|
||||
function f2() { \
|
||||
return f1(1,2,3,4,5,6,7,8,f1(1,2,3,4,5,6,7,8,9,10,11)|0,10,11)|0; \
|
||||
} \
|
||||
function f3() { return 13 } \
|
||||
function f4(i) { \
|
||||
i=i|0; \
|
||||
return TBL[i&3]()|0; \
|
||||
} \
|
||||
var TBL=[f3, f3, f2, f3]; \
|
||||
return f4;");
|
||||
stack = null;
|
||||
assertEq(asmLink(manyCalls, null, {ffi:dumpStack})(2), 123);
|
||||
matchStack(stack, ['dumpStack', 'f1', 'f2', 'f4']);
|
||||
|
@ -8,11 +8,7 @@ dbg.onDebuggerStatement = function (frame) {
|
||||
assertEq(exc.message, "diaf");
|
||||
assertEq(exc.fileName, "fail");
|
||||
assertEq(exc.lineNumber, 4);
|
||||
|
||||
// Arrant nonsense? Sure -- but different from lineNumber is all this
|
||||
// test exists to verify. If you're the person to make column numbers
|
||||
// actually work, change this accordingly.
|
||||
assertEq(exc.columnNumber, 0);
|
||||
assertEq(exc.columnNumber, 20);
|
||||
return;
|
||||
}
|
||||
throw new Error("deleteProperty should throw");
|
||||
|
@ -16,4 +16,4 @@ Debugger(global).onDebuggerStatement = function (frame) {
|
||||
global.log = '';
|
||||
global.eval("function f(n) { for (var i = 0; i < n; ++i) log += '. '; log += '! '; } debugger;");
|
||||
global.f(3);
|
||||
assertEq(global.log, "21 32 44 . 39 32 44 . 39 32 44 . 39 32 57 ! 69 ");
|
||||
assertEq(global.log, "25 32 44 . 39 32 44 . 39 32 44 . 39 32 57 ! 69 ");
|
||||
|
21
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-02.js
Normal file
21
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-02.js
Normal file
@ -0,0 +1,21 @@
|
||||
// getColumnOffsets correctly places multiple variable declarations.
|
||||
|
||||
var global = newGlobal();
|
||||
Debugger(global).onDebuggerStatement = function (frame) {
|
||||
var script = frame.eval("f").return.script;
|
||||
script.getAllColumnOffsets().forEach(function (offset) {
|
||||
script.setBreakpoint(offset.offset, {
|
||||
hit: function (frame) {
|
||||
assertEq(offset.lineNumber, 1);
|
||||
global.log += offset.columnNumber + " ";
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
global.log = '';
|
||||
global.eval("function f(n){var w0,x1=3,y2=4,z3=9} debugger;");
|
||||
global.f(3);
|
||||
|
||||
// Should have hit each variable declared.
|
||||
assertEq(global.log, "18 21 26 31 33 ");
|
20
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-03.js
Normal file
20
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-03.js
Normal file
@ -0,0 +1,20 @@
|
||||
// getColumnOffsets correctly places comma separated expressions.
|
||||
|
||||
var global = newGlobal();
|
||||
Debugger(global).onDebuggerStatement = function (frame) {
|
||||
var script = frame.eval("f").return.script;
|
||||
script.getAllColumnOffsets().forEach(function (offset) {
|
||||
script.setBreakpoint(offset.offset, {
|
||||
hit: function (frame) {
|
||||
assertEq(offset.lineNumber, 1);
|
||||
global.log += offset.columnNumber + " ";
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
global.log = '';
|
||||
global.eval("function f(n){print(n),print(n),print(n)} debugger;");
|
||||
global.f(3);
|
||||
// Should hit each call that was separated by commas.
|
||||
assertEq(global.log, "14 23 32 40 ");
|
20
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-04.js
Normal file
20
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-04.js
Normal file
@ -0,0 +1,20 @@
|
||||
// getColumnOffsets correctly places object properties.
|
||||
|
||||
var global = newGlobal();
|
||||
Debugger(global).onDebuggerStatement = function (frame) {
|
||||
var script = frame.eval("f").return.script;
|
||||
script.getAllColumnOffsets().forEach(function (offset) {
|
||||
script.setBreakpoint(offset.offset, {
|
||||
hit: function (frame) {
|
||||
assertEq(offset.lineNumber, 1);
|
||||
global.log += offset.columnNumber + " ";
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
global.log = '';
|
||||
global.eval("function f(n){var o={a:1,b:2,c:3}} debugger;");
|
||||
global.f(3);
|
||||
// Should hit each property in the object.
|
||||
assertEq(global.log, "18 21 25 29 19 ");
|
20
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-05.js
Normal file
20
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-05.js
Normal file
@ -0,0 +1,20 @@
|
||||
// getColumnOffsets correctly places array properties.
|
||||
|
||||
var global = newGlobal();
|
||||
Debugger(global).onDebuggerStatement = function (frame) {
|
||||
var script = frame.eval("f").return.script;
|
||||
script.getAllColumnOffsets().forEach(function (offset) {
|
||||
script.setBreakpoint(offset.offset, {
|
||||
hit: function (frame) {
|
||||
assertEq(offset.lineNumber, 1);
|
||||
global.log += offset.columnNumber + " ";
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
global.log = '';
|
||||
global.eval("function f(n){var a=[1,2,3]} debugger;");
|
||||
global.f(3);
|
||||
// Should hit each item in the array.
|
||||
assertEq(global.log, "18 21 23 25 19 ");
|
@ -1036,7 +1036,6 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
FuncPtrTableVector funcPtrTables_;
|
||||
ExitMap exits_;
|
||||
MathNameMap standardLibraryMathNames_;
|
||||
GlobalAccessVector globalAccesses_;
|
||||
Label stackOverflowLabel_;
|
||||
Label interruptLabel_;
|
||||
|
||||
@ -1077,7 +1076,6 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
funcPtrTables_(cx),
|
||||
exits_(cx),
|
||||
standardLibraryMathNames_(cx),
|
||||
globalAccesses_(cx),
|
||||
errorString_(nullptr),
|
||||
errorOffset_(UINT32_MAX),
|
||||
errorOverRecursed_(false),
|
||||
@ -1091,7 +1089,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
~ModuleCompiler() {
|
||||
if (errorString_) {
|
||||
JS_ASSERT(errorOffset_ != UINT32_MAX);
|
||||
parser_.tokenStream.reportAsmJSError(errorOffset_,
|
||||
tokenStream().reportAsmJSError(errorOffset_,
|
||||
JSMSG_USE_ASM_TYPE_FAIL,
|
||||
errorString_);
|
||||
js_free(errorString_);
|
||||
@ -1142,7 +1140,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
}
|
||||
|
||||
uint32_t funcStart = parser_.pc->maybeFunction->pn_body->pn_pos.begin;
|
||||
uint32_t offsetToEndOfUseAsm = parser_.tokenStream.currentToken().pos.end;
|
||||
uint32_t offsetToEndOfUseAsm = tokenStream().currentToken().pos.end;
|
||||
|
||||
// "use strict" should be added to the source if we are in an implicit
|
||||
// strict context, see also comment above addUseStrict in
|
||||
@ -1174,14 +1172,14 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
// Since pn is typically only null under OOM, this suppression simply forces any GC to be
|
||||
// delayed until the compilation is off the stack and more memory can be freed.
|
||||
gc::AutoSuppressGC nogc(cx_);
|
||||
return failOffset(parser_.tokenStream.peekTokenPos().begin, str);
|
||||
return failOffset(tokenStream().peekTokenPos().begin, str);
|
||||
}
|
||||
|
||||
bool failfVA(ParseNode *pn, const char *fmt, va_list ap) {
|
||||
JS_ASSERT(!errorString_);
|
||||
JS_ASSERT(errorOffset_ == UINT32_MAX);
|
||||
JS_ASSERT(fmt);
|
||||
errorOffset_ = pn ? pn->pn_pos.begin : parser_.tokenStream.currentToken().pos.end;
|
||||
errorOffset_ = pn ? pn->pn_pos.begin : tokenStream().currentToken().pos.end;
|
||||
errorString_ = JS_vsmprintf(fmt, ap);
|
||||
return false;
|
||||
}
|
||||
@ -1216,7 +1214,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
SlowFunction sf;
|
||||
sf.name = func.name();
|
||||
sf.ms = func.compileTime();
|
||||
parser_.tokenStream.srcCoords.lineNumAndColumnIndex(func.srcOffset(), &sf.line, &sf.column);
|
||||
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcOffset(), &sf.line, &sf.column);
|
||||
return slowFunctions_.append(sf);
|
||||
}
|
||||
|
||||
@ -1224,6 +1222,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
|
||||
ExclusiveContext *cx() const { return cx_; }
|
||||
AsmJSParser &parser() const { return parser_; }
|
||||
TokenStream &tokenStream() const { return parser_.tokenStream; }
|
||||
MacroAssembler &masm() { return masm_; }
|
||||
Label &stackOverflowLabel() { return stackOverflowLabel_; }
|
||||
Label &interruptLabel() { return interruptLabel_; }
|
||||
@ -1397,11 +1396,8 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
for (unsigned i = 0; i < args.length(); i++)
|
||||
argCoercions[i] = args[i].toCoercion();
|
||||
AsmJSModule::ReturnType retType = func->sig().retType().toModuleReturnType();
|
||||
uint32_t line, column;
|
||||
parser_.tokenStream.srcCoords.lineNumAndColumnIndex(func->srcOffset(), &line, &column);
|
||||
return module_->addExportedFunction(func->name(), line, column,
|
||||
func->srcOffset(), func->endOffset(), maybeFieldName,
|
||||
Move(argCoercions), retType);
|
||||
return module_->addExportedFunction(func->name(), func->srcOffset(), func->endOffset(),
|
||||
maybeFieldName, Move(argCoercions), retType);
|
||||
}
|
||||
bool addExit(unsigned ffiIndex, PropertyName *name, Signature &&sig, unsigned *exitIndex) {
|
||||
ExitDescriptor exitDescriptor(name, Move(sig));
|
||||
@ -1414,8 +1410,8 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
return false;
|
||||
return exits_.add(p, Move(exitDescriptor), *exitIndex);
|
||||
}
|
||||
bool addGlobalAccess(AsmJSGlobalAccess access) {
|
||||
return globalAccesses_.append(access);
|
||||
bool addFunctionName(PropertyName *name, uint32_t *index) {
|
||||
return module_->addFunctionName(name, index);
|
||||
}
|
||||
|
||||
// Note a constraint on the minimum size of the heap. The heap size is
|
||||
@ -1430,18 +1426,10 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
return moduleLifo_;
|
||||
}
|
||||
|
||||
bool collectAccesses(MIRGenerator &gen) {
|
||||
if (!module_->addHeapAccesses(gen.heapAccesses()))
|
||||
return false;
|
||||
if (!globalAccesses_.appendAll(gen.globalAccesses()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
bool trackProfiledFunction(const Func &func, unsigned endCodeOffset) {
|
||||
unsigned lineno = 0U, columnIndex = 0U;
|
||||
parser().tokenStream.srcCoords.lineNumAndColumnIndex(func.srcOffset(), &lineno, &columnIndex);
|
||||
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcOffset(), &lineno, &columnIndex);
|
||||
unsigned startCodeOffset = func.code()->offset();
|
||||
return module_->trackProfiledFunction(func.name(), startCodeOffset, endCodeOffset,
|
||||
lineno, columnIndex);
|
||||
@ -1458,10 +1446,6 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
}
|
||||
#endif
|
||||
|
||||
bool addFunctionCounts(IonScriptCounts *counts) {
|
||||
return module_->addFunctionCounts(counts);
|
||||
}
|
||||
|
||||
void finishFunctionBodies() {
|
||||
JS_ASSERT(!finishedFunctionBodies_);
|
||||
masm_.align(AsmJSPageSize);
|
||||
@ -1518,12 +1502,15 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
|
||||
bool finish(ScopedJSDeletePtr<AsmJSModule> *module)
|
||||
{
|
||||
module_->initFuncEnd(parser_.tokenStream.currentToken().pos.end,
|
||||
parser_.tokenStream.peekTokenPos().end);
|
||||
module_->initFuncEnd(tokenStream().currentToken().pos.end,
|
||||
tokenStream().peekTokenPos().end);
|
||||
masm_.finish();
|
||||
if (masm_.oom())
|
||||
return false;
|
||||
|
||||
module_->assignCallSites(masm_.extractCallSites());
|
||||
module_->assignHeapAccesses(masm_.extractAsmJSHeapAccesses());
|
||||
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
// Now that compilation has finished, we need to update offsets to
|
||||
// reflect actual offsets (an ARM distinction).
|
||||
@ -1531,6 +1518,10 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
AsmJSHeapAccess &a = module_->heapAccess(i);
|
||||
a.setOffset(masm_.actualOffset(a.offset()));
|
||||
}
|
||||
for (unsigned i = 0; i < module_->numCallSites(); i++) {
|
||||
CallSite &c = module_->callSite(i);
|
||||
c.setReturnAddressOffset(masm_.actualOffset(c.returnAddressOffset()));
|
||||
}
|
||||
#endif
|
||||
|
||||
// The returned memory is owned by module_.
|
||||
@ -1605,8 +1596,8 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
// Global data accesses in x86 need to be patched with the absolute
|
||||
// address of the global. Globals are allocated sequentially after the
|
||||
// code section so we can just use an RelativeLink.
|
||||
for (unsigned i = 0; i < globalAccesses_.length(); i++) {
|
||||
AsmJSGlobalAccess a = globalAccesses_[i];
|
||||
for (unsigned i = 0; i < masm_.numAsmJSGlobalAccesses(); i++) {
|
||||
AsmJSGlobalAccess a = masm_.asmJSGlobalAccess(i);
|
||||
AsmJSModule::RelativeLink link;
|
||||
link.patchAtOffset = masm_.labelOffsetToPatchOffset(a.patchAt.offset());
|
||||
link.targetOffset = module_->offsetOfGlobalData() + a.globalDataOffset;
|
||||
@ -1619,8 +1610,8 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
// Global data accesses on x64 use rip-relative addressing and thus do
|
||||
// not need patching after deserialization.
|
||||
uint8_t *code = module_->codeBase();
|
||||
for (unsigned i = 0; i < globalAccesses_.length(); i++) {
|
||||
AsmJSGlobalAccess a = globalAccesses_[i];
|
||||
for (unsigned i = 0; i < masm_.numAsmJSGlobalAccesses(); i++) {
|
||||
AsmJSGlobalAccess a = masm_.asmJSGlobalAccess(i);
|
||||
masm_.patchAsmJSGlobalAccess(a.patchAt, code, module_->globalData(), a.globalDataOffset);
|
||||
}
|
||||
#endif
|
||||
@ -1902,6 +1893,7 @@ class FunctionCompiler
|
||||
ModuleCompiler & m_;
|
||||
LifoAlloc & lifo_;
|
||||
ParseNode * fn_;
|
||||
uint32_t functionNameIndex_;
|
||||
|
||||
LocalMap locals_;
|
||||
VarInitializerVector varInitializers_;
|
||||
@ -1922,11 +1914,15 @@ class FunctionCompiler
|
||||
LabeledBlockMap labeledBreaks_;
|
||||
LabeledBlockMap labeledContinues_;
|
||||
|
||||
static const uint32_t NO_FUNCTION_NAME_INDEX = UINT32_MAX;
|
||||
JS_STATIC_ASSERT(NO_FUNCTION_NAME_INDEX > CallSiteDesc::FUNCTION_NAME_INDEX_MAX);
|
||||
|
||||
public:
|
||||
FunctionCompiler(ModuleCompiler &m, ParseNode *fn, LifoAlloc &lifo)
|
||||
: m_(m),
|
||||
lifo_(lifo),
|
||||
fn_(fn),
|
||||
functionNameIndex_(NO_FUNCTION_NAME_INDEX),
|
||||
locals_(m.cx()),
|
||||
varInitializers_(m.cx()),
|
||||
alloc_(nullptr),
|
||||
@ -2029,8 +2025,6 @@ class FunctionCompiler
|
||||
if (!newBlock(/* pred = */ nullptr, &curBlock_, fn_))
|
||||
return false;
|
||||
|
||||
curBlock_->add(MAsmJSCheckOverRecursed::New(alloc(), &m_.stackOverflowLabel()));
|
||||
|
||||
for (ABIArgTypeIter i = argTypes; !i.done(); i++) {
|
||||
MAsmJSParameter *ins = MAsmJSParameter::New(alloc(), *i, i.mirType());
|
||||
curBlock_->add(ins);
|
||||
@ -2278,6 +2272,7 @@ class FunctionCompiler
|
||||
|
||||
class Call
|
||||
{
|
||||
ParseNode *node_;
|
||||
ABIArgGenerator abi_;
|
||||
uint32_t prevMaxStackBytes_;
|
||||
uint32_t maxChildStackBytes_;
|
||||
@ -2290,8 +2285,9 @@ class FunctionCompiler
|
||||
friend class FunctionCompiler;
|
||||
|
||||
public:
|
||||
Call(FunctionCompiler &f, RetType retType)
|
||||
: prevMaxStackBytes_(0),
|
||||
Call(FunctionCompiler &f, ParseNode *callNode, RetType retType)
|
||||
: node_(callNode),
|
||||
prevMaxStackBytes_(0),
|
||||
maxChildStackBytes_(0),
|
||||
spIncrement_(0),
|
||||
sig_(f.m().lifo(), retType),
|
||||
@ -2364,10 +2360,21 @@ class FunctionCompiler
|
||||
*def = nullptr;
|
||||
return true;
|
||||
}
|
||||
MAsmJSCall *ins = MAsmJSCall::New(alloc(), callee, call.regArgs_, returnType,
|
||||
|
||||
uint32_t line, column;
|
||||
m_.tokenStream().srcCoords.lineNumAndColumnIndex(call.node_->pn_pos.begin, &line, &column);
|
||||
|
||||
if (functionNameIndex_ == NO_FUNCTION_NAME_INDEX) {
|
||||
if (!m_.addFunctionName(FunctionName(fn_), &functionNameIndex_))
|
||||
return false;
|
||||
}
|
||||
|
||||
CallSiteDesc desc(line, column, functionNameIndex_);
|
||||
MAsmJSCall *ins = MAsmJSCall::New(alloc(), desc, callee, call.regArgs_, returnType,
|
||||
call.spIncrement_);
|
||||
if (!ins)
|
||||
return false;
|
||||
|
||||
curBlock_->add(ins);
|
||||
*def = ins;
|
||||
return true;
|
||||
@ -2768,7 +2775,7 @@ class FunctionCompiler
|
||||
#if defined(JS_ION_PERF)
|
||||
if (pn) {
|
||||
unsigned line = 0U, column = 0U;
|
||||
m().parser().tokenStream.srcCoords.lineNumAndColumnIndex(pn->pn_pos.begin, &line, &column);
|
||||
m().tokenStream().srcCoords.lineNumAndColumnIndex(pn->pn_pos.begin, &line, &column);
|
||||
blk->setLineno(line);
|
||||
blk->setColumnIndex(column);
|
||||
}
|
||||
@ -3883,7 +3890,7 @@ static bool
|
||||
CheckInternalCall(FunctionCompiler &f, ParseNode *callNode, PropertyName *calleeName,
|
||||
RetType retType, MDefinition **def, Type *type)
|
||||
{
|
||||
FunctionCompiler::Call call(f, retType);
|
||||
FunctionCompiler::Call call(f, callNode, retType);
|
||||
|
||||
if (!CheckCallArgs(f, callNode, CheckIsVarType, &call))
|
||||
return false;
|
||||
@ -3959,7 +3966,7 @@ CheckFuncPtrCall(FunctionCompiler &f, ParseNode *callNode, RetType retType, MDef
|
||||
if (!indexType.isIntish())
|
||||
return f.failf(indexNode, "%s is not a subtype of intish", indexType.toChars());
|
||||
|
||||
FunctionCompiler::Call call(f, retType);
|
||||
FunctionCompiler::Call call(f, callNode, retType);
|
||||
|
||||
if (!CheckCallArgs(f, callNode, CheckIsVarType, &call))
|
||||
return false;
|
||||
@ -3992,7 +3999,7 @@ CheckFFICall(FunctionCompiler &f, ParseNode *callNode, unsigned ffiIndex, RetTyp
|
||||
if (retType == RetType::Float)
|
||||
return f.fail(callNode, "FFI calls can't return float");
|
||||
|
||||
FunctionCompiler::Call call(f, retType);
|
||||
FunctionCompiler::Call call(f, callNode, retType);
|
||||
if (!CheckCallArgs(f, callNode, CheckIsExternType, &call))
|
||||
return false;
|
||||
|
||||
@ -4117,7 +4124,7 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltinF
|
||||
if (retType != RetType::Double && retType != RetType::Float)
|
||||
return f.failf(callNode, "return type of math function is double or float, used as %s", retType.toType().toChars());
|
||||
|
||||
FunctionCompiler::Call call(f, retType);
|
||||
FunctionCompiler::Call call(f, callNode, retType);
|
||||
if (retType == RetType::Float && !CheckCallArgs(f, callNode, CheckIsMaybeFloat, &call))
|
||||
return false;
|
||||
if (retType == RetType::Double && !CheckCallArgs(f, callNode, CheckIsMaybeDouble, &call))
|
||||
@ -5319,7 +5326,7 @@ CheckStatement(FunctionCompiler &f, ParseNode *stmt, LabelVector *maybeLabels)
|
||||
static bool
|
||||
ParseFunction(ModuleCompiler &m, ParseNode **fnOut)
|
||||
{
|
||||
TokenStream &tokenStream = m.parser().tokenStream;
|
||||
TokenStream &tokenStream = m.tokenStream();
|
||||
|
||||
DebugOnly<TokenKind> tk = tokenStream.getToken();
|
||||
JS_ASSERT(tk == TOK_FUNCTION);
|
||||
@ -5359,7 +5366,7 @@ ParseFunction(ModuleCompiler &m, ParseNode **fnOut)
|
||||
AsmJSParseContext funpc(&m.parser(), outerpc, fn, funbox, &newDirectives,
|
||||
outerpc->staticLevel + 1, outerpc->blockidGen,
|
||||
/* blockScopeDepth = */ 0);
|
||||
if (!funpc.init(m.parser().tokenStream))
|
||||
if (!funpc.init(tokenStream))
|
||||
return false;
|
||||
|
||||
if (!m.parser().functionArgsAndBodyGeneric(fn, fun, Normal, Statement, &newDirectives))
|
||||
@ -5470,19 +5477,10 @@ GenerateCode(ModuleCompiler &m, ModuleCompiler::Func &func, MIRGenerator &mir, L
|
||||
|
||||
m.masm().bind(func.code());
|
||||
|
||||
ScopedJSDeletePtr<CodeGenerator> codegen(jit::GenerateCode(&mir, &lir, &m.masm()));
|
||||
if (!codegen)
|
||||
ScopedJSDeletePtr<CodeGenerator> codegen(js_new<CodeGenerator>(&mir, &lir, &m.masm()));
|
||||
if (!codegen || !codegen->generateAsmJS(&m.stackOverflowLabel()))
|
||||
return m.fail(nullptr, "internal codegen failure (probably out of memory)");
|
||||
|
||||
if (!m.collectAccesses(mir))
|
||||
return false;
|
||||
|
||||
jit::IonScriptCounts *counts = codegen->extractUnassociatedScriptCounts();
|
||||
if (counts && !m.addFunctionCounts(counts)) {
|
||||
js_delete(counts);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
// Profiling might not be active now, but it may be activated later (perhaps
|
||||
// after the module has been cached and reloaded from the cache). Function
|
||||
@ -6048,6 +6046,16 @@ StackDecrementForCall(MacroAssembler &masm, const VectorT &argTypes, unsigned ex
|
||||
static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * sizeof(intptr_t) +
|
||||
NonVolatileRegs.fpus().size() * sizeof(double);
|
||||
|
||||
// On arm, we need to include an extra word of space at the top of the stack so
|
||||
// we can explicitly store the return address before making the call to C++ or
|
||||
// Ion. On x86/x64, this isn't necessary since the call instruction pushes the
|
||||
// return address.
|
||||
#ifdef JS_CODEGEN_ARM
|
||||
static const unsigned MaybeRetAddr = sizeof(void*);
|
||||
#else
|
||||
static const unsigned MaybeRetAddr = 0;
|
||||
#endif
|
||||
|
||||
static bool
|
||||
GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFunc)
|
||||
{
|
||||
@ -6127,7 +6135,7 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
|
||||
|
||||
// Call into the real function.
|
||||
AssertStackAlignment(masm);
|
||||
masm.call(func.code());
|
||||
masm.call(CallSiteDesc::Entry(), func.code());
|
||||
|
||||
// Pop the stack and recover the original 'argv' argument passed to the
|
||||
// trampoline (which was pushed on the stack).
|
||||
@ -6321,15 +6329,15 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
MIRTypeVector invokeArgTypes(m.cx());
|
||||
invokeArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
|
||||
|
||||
// Reserve space for a call to InvokeFromAsmJS_* and an array of values
|
||||
// passed to this FFI call.
|
||||
// The stack layout looks like:
|
||||
// | return address | stack arguments | array of values |
|
||||
unsigned arraySize = Max<size_t>(1, exit.sig().args().length()) * sizeof(Value);
|
||||
unsigned stackDec = StackDecrementForCall(masm, invokeArgTypes, arraySize);
|
||||
unsigned stackDec = StackDecrementForCall(masm, invokeArgTypes, arraySize + MaybeRetAddr);
|
||||
masm.reserveStack(stackDec);
|
||||
|
||||
// Fill the argument array.
|
||||
unsigned offsetToCallerStackArgs = AlignmentAtPrologue + masm.framePushed();
|
||||
unsigned offsetToArgv = StackArgBytes(invokeArgTypes);
|
||||
unsigned offsetToArgv = StackArgBytes(invokeArgTypes) + MaybeRetAddr;
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
FillArgumentArray(m, exit.sig().args(), offsetToArgv, offsetToCallerStackArgs, scratch);
|
||||
|
||||
@ -6338,6 +6346,9 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
Register activation = ABIArgGenerator::NonArgReturnVolatileReg1;
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
|
||||
// Record sp in the AsmJSActivation for stack-walking.
|
||||
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitSP()));
|
||||
|
||||
// argument 0: cx
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
LoadJSContextFromActivation(masm, activation, i->gpr());
|
||||
@ -6377,16 +6388,16 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
AssertStackAlignment(masm);
|
||||
switch (exit.sig().retType().which()) {
|
||||
case RetType::Void:
|
||||
masm.call(AsmJSImm_InvokeFromAsmJS_Ignore);
|
||||
masm.callExit(AsmJSImm_InvokeFromAsmJS_Ignore, i.stackBytesConsumedSoFar());
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
break;
|
||||
case RetType::Signed:
|
||||
masm.call(AsmJSImm_InvokeFromAsmJS_ToInt32);
|
||||
masm.callExit(AsmJSImm_InvokeFromAsmJS_ToInt32, i.stackBytesConsumedSoFar());
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.unboxInt32(argv, ReturnReg);
|
||||
break;
|
||||
case RetType::Double:
|
||||
masm.call(AsmJSImm_InvokeFromAsmJS_ToNumber);
|
||||
masm.callExit(AsmJSImm_InvokeFromAsmJS_ToNumber, i.stackBytesConsumedSoFar());
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.loadDouble(argv, ReturnFloatReg);
|
||||
break;
|
||||
@ -6415,16 +6426,20 @@ GenerateOOLConvert(ModuleCompiler &m, RetType retType, Label *throwLabel)
|
||||
// the stack usage here needs to kept in sync with GenerateFFIIonExit.
|
||||
|
||||
// Store value
|
||||
unsigned offsetToArgv = StackArgBytes(callArgTypes);
|
||||
unsigned offsetToArgv = StackArgBytes(callArgTypes) + MaybeRetAddr;
|
||||
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToArgv));
|
||||
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
Register activation = ABIArgGenerator::NonArgReturnVolatileReg1;
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
|
||||
// Record sp in the AsmJSActivation for stack-walking.
|
||||
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitSP()));
|
||||
|
||||
// Store real arguments
|
||||
ABIArgMIRTypeIter i(callArgTypes);
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
|
||||
// argument 0: cx
|
||||
Register activation = ABIArgGenerator::NonArgReturnVolatileReg1;
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
LoadJSContextFromActivation(masm, activation, i->gpr());
|
||||
} else {
|
||||
@ -6448,12 +6463,12 @@ GenerateOOLConvert(ModuleCompiler &m, RetType retType, Label *throwLabel)
|
||||
AssertStackAlignment(masm);
|
||||
switch (retType.which()) {
|
||||
case RetType::Signed:
|
||||
masm.call(AsmJSImm_CoerceInPlace_ToInt32);
|
||||
masm.callExit(AsmJSImm_CoerceInPlace_ToInt32, i.stackBytesConsumedSoFar());
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
|
||||
break;
|
||||
case RetType::Double:
|
||||
masm.call(AsmJSImm_CoerceInPlace_ToNumber);
|
||||
masm.callExit(AsmJSImm_CoerceInPlace_ToNumber, i.stackBytesConsumedSoFar());
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnFloatReg);
|
||||
break;
|
||||
@ -6488,19 +6503,9 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
// conversion of the result. A frame large enough for both is allocated.
|
||||
//
|
||||
// Arguments to the Ion function are in the following order on the stack:
|
||||
// descriptor | callee | argc | this | arg1 | arg2 | ...
|
||||
// | return address | descriptor | callee | argc | this | arg1 | arg2 | ...
|
||||
unsigned argBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
|
||||
|
||||
// On ARM, we call with ma_callIonNoPush which, following the Ion calling convention,
|
||||
// stores the return address into *sp. This means we need to include an extra word of
|
||||
// space before the arguments in the stack allocation. (On x86/x64, the call
|
||||
// instruction does the push itself and the ABI just requires us to be aligned before
|
||||
// the call instruction.)
|
||||
unsigned offsetToArgs = 0;
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
offsetToArgs += sizeof(size_t);
|
||||
#endif
|
||||
|
||||
unsigned offsetToArgs = MaybeRetAddr;
|
||||
unsigned stackDecForIonCall = StackDecrementForCall(masm, argBytes + offsetToArgs);
|
||||
|
||||
// Reserve space for a call to AsmJSImm_CoerceInPlace_* and an array of values used by
|
||||
@ -6509,7 +6514,8 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
MIRType typeArray[] = { MIRType_Pointer, MIRType_Pointer }; // cx, argv
|
||||
MIRTypeVector callArgTypes(m.cx());
|
||||
callArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
|
||||
unsigned stackDecForOOLCall = StackDecrementForCall(masm, callArgTypes, sizeof(Value));
|
||||
unsigned oolExtraBytes = sizeof(Value) + MaybeRetAddr;
|
||||
unsigned stackDecForOOLCall = StackDecrementForCall(masm, callArgTypes, oolExtraBytes);
|
||||
|
||||
// Allocate a frame large enough for both of the above calls.
|
||||
unsigned stackDec = Max(stackDecForIonCall, stackDecForOOLCall);
|
||||
@ -6531,10 +6537,10 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
unsigned globalDataOffset = m.module().exitIndexToGlobalDataOffset(exitIndex);
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
CodeOffsetLabel label2 = masm.leaRipRelative(callee);
|
||||
m.addGlobalAccess(AsmJSGlobalAccess(label2.offset(), globalDataOffset));
|
||||
m.masm().append(AsmJSGlobalAccess(label2.offset(), globalDataOffset));
|
||||
#elif defined(JS_CODEGEN_X86)
|
||||
CodeOffsetLabel label2 = masm.movlWithPatch(Imm32(0), callee);
|
||||
m.addGlobalAccess(AsmJSGlobalAccess(label2.offset(), globalDataOffset));
|
||||
m.masm().append(AsmJSGlobalAccess(label2.offset(), globalDataOffset));
|
||||
#else
|
||||
masm.lea(Operand(GlobalReg, globalDataOffset), callee);
|
||||
#endif
|
||||
@ -6592,6 +6598,9 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
|
||||
LoadAsmJSActivationIntoRegister(masm, reg0);
|
||||
|
||||
// Record sp in the AsmJSActivation for stack-walking.
|
||||
masm.storePtr(StackPointer, Address(reg0, AsmJSActivation::offsetOfExitSP()));
|
||||
|
||||
// The following is inlined:
|
||||
// JSContext *cx = activation->cx();
|
||||
// Activation *act = cx->mainThread().activation();
|
||||
@ -6618,14 +6627,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
|
||||
// 2. Call
|
||||
AssertStackAlignment(masm);
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
masm.ma_callIonNoPush(callee);
|
||||
// The return address has been popped from the stack, so adjust the stack
|
||||
// without changing the frame-pushed counter to keep the stack aligned.
|
||||
masm.subPtr(Imm32(4), sp);
|
||||
#else
|
||||
masm.callIon(callee);
|
||||
#endif
|
||||
masm.callIonFromAsmJS(callee);
|
||||
AssertStackAlignment(masm);
|
||||
|
||||
{
|
||||
@ -6739,30 +6741,40 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.align(CodeAlignment);
|
||||
masm.bind(&m.stackOverflowLabel());
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
// Ensure that at least one slot is pushed for passing 'cx' below.
|
||||
masm.push(Imm32(0));
|
||||
#endif
|
||||
// The overflow check always occurs before the initial function-specific
|
||||
// stack-size adjustment. See CodeGenerator::generateAsmJSPrologue.
|
||||
masm.setFramePushed(AlignmentMidPrologue - AlignmentAtPrologue);
|
||||
|
||||
// We know that StackPointer is word-aligned, but nothing past that. Thus,
|
||||
// we must align StackPointer dynamically. Don't worry about restoring
|
||||
// StackPointer since throwLabel will clobber StackPointer immediately.
|
||||
masm.andPtr(Imm32(~(StackAlignment - 1)), StackPointer);
|
||||
if (ShadowStackSpace)
|
||||
masm.subPtr(Imm32(ShadowStackSpace), StackPointer);
|
||||
MIRTypeVector argTypes(m.cx());
|
||||
argTypes.infallibleAppend(MIRType_Pointer); // cx
|
||||
|
||||
// Prepare the arguments for the call to js_ReportOverRecursed.
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
LoadAsmJSActivationIntoRegister(masm, eax);
|
||||
LoadJSContextFromActivation(masm, eax, eax);
|
||||
masm.storePtr(eax, Address(StackPointer, 0));
|
||||
#else
|
||||
LoadAsmJSActivationIntoRegister(masm, IntArgReg0);
|
||||
LoadJSContextFromActivation(masm, IntArgReg0, IntArgReg0);
|
||||
#endif
|
||||
masm.call(AsmJSImm_ReportOverRecursed);
|
||||
unsigned stackDec = StackDecrementForCall(masm, argTypes, MaybeRetAddr);
|
||||
masm.reserveStack(stackDec);
|
||||
|
||||
Register activation = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
|
||||
// Record sp in the AsmJSActivation for stack-walking.
|
||||
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitSP()));
|
||||
|
||||
ABIArgMIRTypeIter i(argTypes);
|
||||
|
||||
// argument 0: cx
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
LoadJSContextFromActivation(masm, activation, i->gpr());
|
||||
} else {
|
||||
LoadJSContextFromActivation(masm, activation, activation);
|
||||
masm.storePtr(activation, Address(StackPointer, i->offsetFromArgBase()));
|
||||
}
|
||||
i++;
|
||||
|
||||
JS_ASSERT(i.done());
|
||||
|
||||
AssertStackAlignment(masm);
|
||||
masm.callExit(AsmJSImm_ReportOverRecursed, i.stackBytesConsumedSoFar());
|
||||
|
||||
// Don't worry about restoring the stack; throwLabel will pop everything.
|
||||
masm.jump(throwLabel);
|
||||
|
||||
return !masm.oom();
|
||||
}
|
||||
|
||||
@ -6914,6 +6926,8 @@ GenerateStubs(ModuleCompiler &m)
|
||||
m.setEntryOffset(i);
|
||||
if (!GenerateEntry(m, m.module().exportedFunction(i)))
|
||||
return false;
|
||||
if (m.masm().oom())
|
||||
return false;
|
||||
}
|
||||
|
||||
Label throwLabel;
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#include "jit/AsmJSLink.h"
|
||||
|
||||
#include "mozilla/BinarySearch.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#ifdef MOZ_VTUNE
|
||||
# include "vtune/VTuneWrapper.h"
|
||||
#endif
|
||||
@ -29,7 +32,102 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::BinarySearch;
|
||||
using mozilla::IsNaN;
|
||||
using mozilla::PodZero;
|
||||
|
||||
AsmJSFrameIterator::AsmJSFrameIterator(const AsmJSActivation *activation)
|
||||
{
|
||||
if (!activation || activation->isInterruptedSP()) {
|
||||
PodZero(this);
|
||||
JS_ASSERT(done());
|
||||
return;
|
||||
}
|
||||
|
||||
module_ = &activation->module();
|
||||
sp_ = activation->exitSP();
|
||||
|
||||
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
|
||||
// For calls to Ion/C++ on x86/x64, the exitSP is the SP right before the call
|
||||
// to C++. Since the call instruction pushes the return address, we know
|
||||
// that the return address is 1 word below exitSP.
|
||||
returnAddress_ = *(uint8_t**)(sp_ - sizeof(void*));
|
||||
#else
|
||||
// For calls to Ion/C++ on ARM, the *caller* pushes the return address on
|
||||
// the stack. For Ion, this is just part of the ABI. For C++, the return
|
||||
// address is explicitly pushed before the call since we cannot expect the
|
||||
// callee to immediately push lr. This means that exitSP points to the
|
||||
// return address.
|
||||
returnAddress_ = *(uint8_t**)sp_;
|
||||
#endif
|
||||
|
||||
settle();
|
||||
}
|
||||
|
||||
struct GetCallSite
|
||||
{
|
||||
const AsmJSModule &module;
|
||||
GetCallSite(const AsmJSModule &module) : module(module) {}
|
||||
uint32_t operator[](size_t index) const {
|
||||
return module.callSite(index).returnAddressOffset();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
AsmJSFrameIterator::popFrame()
|
||||
{
|
||||
// After adding stackDepth, sp points to the word before the return address,
|
||||
// on both ARM and x86/x64.
|
||||
sp_ += callsite_->stackDepth();
|
||||
returnAddress_ = *(uint8_t**)(sp_ - sizeof(void*));
|
||||
}
|
||||
|
||||
void
|
||||
AsmJSFrameIterator::settle()
|
||||
{
|
||||
while (true) {
|
||||
uint32_t target = returnAddress_ - module_->codeBase();
|
||||
size_t lowerBound = 0;
|
||||
size_t upperBound = module_->numCallSites();
|
||||
|
||||
size_t match;
|
||||
if (!BinarySearch(GetCallSite(*module_), lowerBound, upperBound, target, &match)) {
|
||||
callsite_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
callsite_ = &module_->callSite(match);
|
||||
|
||||
if (callsite_->isExit()) {
|
||||
popFrame();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (callsite_->isEntry()) {
|
||||
callsite_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
JS_ASSERT(callsite_->isNormal());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
AsmJSFrameIterator::functionDisplayAtom() const
|
||||
{
|
||||
JS_ASSERT(!done());
|
||||
return module_->functionName(callsite_->functionNameIndex());
|
||||
}
|
||||
|
||||
unsigned
|
||||
AsmJSFrameIterator::computeLine(uint32_t *column) const
|
||||
{
|
||||
JS_ASSERT(!done());
|
||||
if (column)
|
||||
*column = callsite_->column();
|
||||
return callsite_->line();
|
||||
}
|
||||
|
||||
static bool
|
||||
CloneModule(JSContext *cx, MutableHandle<AsmJSModuleObject*> moduleObj)
|
||||
@ -408,8 +506,7 @@ CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
|
||||
// that the optimized asm.js-to-Ion FFI call path (which we want to be
|
||||
// very fast) can avoid doing so. The JitActivation is marked as
|
||||
// inactive so stack iteration will skip over it.
|
||||
unsigned exportIndex = FunctionToExportedFunctionIndex(callee);
|
||||
AsmJSActivation activation(cx, module, exportIndex);
|
||||
AsmJSActivation activation(cx, module);
|
||||
JitActivation jitActivation(cx, /* firstFrameIsConstructing = */ false, /* active */ false);
|
||||
|
||||
// Call the per-exported-function trampoline created by GenerateEntry.
|
||||
|
@ -9,8 +9,33 @@
|
||||
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
class JSAtom;
|
||||
|
||||
namespace js {
|
||||
|
||||
class AsmJSActivation;
|
||||
class AsmJSModule;
|
||||
namespace jit { class CallSite; }
|
||||
|
||||
// Iterates over the frames of a single AsmJSActivation.
|
||||
class AsmJSFrameIterator
|
||||
{
|
||||
const AsmJSModule *module_;
|
||||
const jit::CallSite *callsite_;
|
||||
uint8_t *sp_;
|
||||
uint8_t *returnAddress_;
|
||||
|
||||
void popFrame();
|
||||
void settle();
|
||||
|
||||
public:
|
||||
AsmJSFrameIterator(const AsmJSActivation *activation);
|
||||
void operator++() { popFrame(); settle(); }
|
||||
bool done() const { return !callsite_; }
|
||||
JSAtom *functionDisplayAtom() const;
|
||||
unsigned computeLine(uint32_t *column) const;
|
||||
};
|
||||
|
||||
#ifdef JS_ION
|
||||
|
||||
// Create a new JSFunction to replace originalFun as the representation of the
|
||||
|
@ -371,9 +371,6 @@ AsmJSModule::~AsmJSModule()
|
||||
|
||||
DeallocateExecutableMemory(code_, pod.totalBytes_);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < numFunctionCounts(); i++)
|
||||
js_delete(functionCounts(i));
|
||||
}
|
||||
|
||||
void
|
||||
@ -385,6 +382,8 @@ AsmJSModule::addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModu
|
||||
globals_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
exits_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
exports_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
callSites_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
functionNames_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
heapAccesses_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
profiledFunctions_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
@ -392,7 +391,6 @@ AsmJSModule::addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModu
|
||||
#if defined(JS_ION_PERF)
|
||||
perfProfiledBlocksFunctions_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
#endif
|
||||
functionCounts_.sizeOfExcludingThis(mallocSizeOf) +
|
||||
staticLinkData_.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
@ -481,6 +479,12 @@ SerializedNameSize(PropertyName *name)
|
||||
(name ? name->length() * sizeof(jschar) : 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
AsmJSModule::Name::serializedSize() const
|
||||
{
|
||||
return SerializedNameSize(name_);
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
SerializeName(uint8_t *cursor, PropertyName *name)
|
||||
{
|
||||
@ -494,6 +498,12 @@ SerializeName(uint8_t *cursor, PropertyName *name)
|
||||
return cursor;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
AsmJSModule::Name::serialize(uint8_t *cursor) const
|
||||
{
|
||||
return SerializeName(cursor, name_);
|
||||
}
|
||||
|
||||
static const uint8_t *
|
||||
DeserializeName(ExclusiveContext *cx, const uint8_t *cursor, PropertyName **name)
|
||||
{
|
||||
@ -525,6 +535,19 @@ DeserializeName(ExclusiveContext *cx, const uint8_t *cursor, PropertyName **name
|
||||
return cursor + length * sizeof(jschar);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
AsmJSModule::Name::deserialize(ExclusiveContext *cx, const uint8_t *cursor)
|
||||
{
|
||||
return DeserializeName(cx, cursor, &name_);
|
||||
}
|
||||
|
||||
bool
|
||||
AsmJSModule::Name::clone(ExclusiveContext *cx, Name *out) const
|
||||
{
|
||||
out->name_ = name_;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
size_t
|
||||
SerializedVectorSize(const js::Vector<T, 0, SystemAllocPolicy> &vec)
|
||||
@ -792,6 +815,8 @@ AsmJSModule::serializedSize() const
|
||||
SerializedVectorSize(globals_) +
|
||||
SerializedVectorSize(exits_) +
|
||||
SerializedVectorSize(exports_) +
|
||||
SerializedPodVectorSize(callSites_) +
|
||||
SerializedVectorSize(functionNames_) +
|
||||
SerializedPodVectorSize(heapAccesses_) +
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
SerializedVectorSize(profiledFunctions_) +
|
||||
@ -810,6 +835,8 @@ AsmJSModule::serialize(uint8_t *cursor) const
|
||||
cursor = SerializeVector(cursor, globals_);
|
||||
cursor = SerializeVector(cursor, exits_);
|
||||
cursor = SerializeVector(cursor, exports_);
|
||||
cursor = SerializePodVector(cursor, callSites_);
|
||||
cursor = SerializeVector(cursor, functionNames_);
|
||||
cursor = SerializePodVector(cursor, heapAccesses_);
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
cursor = SerializeVector(cursor, profiledFunctions_);
|
||||
@ -834,6 +861,8 @@ AsmJSModule::deserialize(ExclusiveContext *cx, const uint8_t *cursor)
|
||||
(cursor = DeserializeVector(cx, cursor, &globals_)) &&
|
||||
(cursor = DeserializeVector(cx, cursor, &exits_)) &&
|
||||
(cursor = DeserializeVector(cx, cursor, &exports_)) &&
|
||||
(cursor = DeserializePodVector(cx, cursor, &callSites_)) &&
|
||||
(cursor = DeserializeVector(cx, cursor, &functionNames_)) &&
|
||||
(cursor = DeserializePodVector(cx, cursor, &heapAccesses_)) &&
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
(cursor = DeserializeVector(cx, cursor, &profiledFunctions_)) &&
|
||||
@ -901,6 +930,8 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
|
||||
if (!CloneVector(cx, globals_, &out.globals_) ||
|
||||
!CloneVector(cx, exits_, &out.exits_) ||
|
||||
!CloneVector(cx, exports_, &out.exports_) ||
|
||||
!ClonePodVector(cx, callSites_, &out.callSites_) ||
|
||||
!CloneVector(cx, functionNames_, &out.functionNames_) ||
|
||||
!ClonePodVector(cx, heapAccesses_, &out.heapAccesses_) ||
|
||||
!staticLinkData_.clone(cx, &out.staticLinkData_))
|
||||
{
|
||||
|
@ -221,8 +221,6 @@ class AsmJSModule
|
||||
struct Pod {
|
||||
ReturnType returnType_;
|
||||
uint32_t codeOffset_;
|
||||
uint32_t line_;
|
||||
uint32_t column_;
|
||||
// These two fields are offsets to the beginning of the ScriptSource
|
||||
// of the module, and thus invariant under serialization (unlike
|
||||
// absolute offsets into ScriptSource).
|
||||
@ -233,7 +231,6 @@ class AsmJSModule
|
||||
friend class AsmJSModule;
|
||||
|
||||
ExportedFunction(PropertyName *name,
|
||||
uint32_t line, uint32_t column,
|
||||
uint32_t startOffsetInModule, uint32_t endOffsetInModule,
|
||||
PropertyName *maybeFieldName,
|
||||
ArgCoercionVector &&argCoercions,
|
||||
@ -244,8 +241,6 @@ class AsmJSModule
|
||||
argCoercions_ = mozilla::Move(argCoercions);
|
||||
pod.returnType_ = returnType;
|
||||
pod.codeOffset_ = UINT32_MAX;
|
||||
pod.line_ = line;
|
||||
pod.column_ = column;
|
||||
pod.startOffsetInModule_ = startOffsetInModule;
|
||||
pod.endOffsetInModule_ = endOffsetInModule;
|
||||
JS_ASSERT_IF(maybeFieldName_, name_->isTenured());
|
||||
@ -274,12 +269,6 @@ class AsmJSModule
|
||||
PropertyName *name() const {
|
||||
return name_;
|
||||
}
|
||||
uint32_t line() const {
|
||||
return pod.line_;
|
||||
}
|
||||
uint32_t column() const {
|
||||
return pod.column_;
|
||||
}
|
||||
uint32_t startOffsetInModule() const {
|
||||
return pod.startOffsetInModule_;
|
||||
}
|
||||
@ -305,6 +294,20 @@ class AsmJSModule
|
||||
bool clone(ExclusiveContext *cx, ExportedFunction *out) const;
|
||||
};
|
||||
|
||||
class Name
|
||||
{
|
||||
PropertyName *name_;
|
||||
public:
|
||||
Name() : name_(nullptr) {}
|
||||
Name(PropertyName *name) : name_(name) {}
|
||||
PropertyName *name() const { return name_; }
|
||||
PropertyName *&name() { return name_; }
|
||||
size_t serializedSize() const;
|
||||
uint8_t *serialize(uint8_t *cursor) const;
|
||||
const uint8_t *deserialize(ExclusiveContext *cx, const uint8_t *cursor);
|
||||
bool clone(ExclusiveContext *cx, Name *out) const;
|
||||
};
|
||||
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
// Function information to add to the VTune JIT profiler following linking.
|
||||
struct ProfiledFunction
|
||||
@ -400,9 +403,11 @@ class AsmJSModule
|
||||
};
|
||||
|
||||
private:
|
||||
typedef Vector<ExportedFunction, 0, SystemAllocPolicy> ExportedFunctionVector;
|
||||
typedef Vector<Global, 0, SystemAllocPolicy> GlobalVector;
|
||||
typedef Vector<Exit, 0, SystemAllocPolicy> ExitVector;
|
||||
typedef Vector<ExportedFunction, 0, SystemAllocPolicy> ExportedFunctionVector;
|
||||
typedef Vector<jit::CallSite, 0, SystemAllocPolicy> CallSiteVector;
|
||||
typedef Vector<Name, 0, SystemAllocPolicy> FunctionNameVector;
|
||||
typedef Vector<jit::AsmJSHeapAccess, 0, SystemAllocPolicy> HeapAccessVector;
|
||||
typedef Vector<jit::IonScriptCounts *, 0, SystemAllocPolicy> FunctionCountsVector;
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
@ -420,6 +425,8 @@ class AsmJSModule
|
||||
GlobalVector globals_;
|
||||
ExitVector exits_;
|
||||
ExportedFunctionVector exports_;
|
||||
CallSiteVector callSites_;
|
||||
FunctionNameVector functionNames_;
|
||||
HeapAccessVector heapAccesses_;
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
ProfiledFunctionVector profiledFunctions_;
|
||||
@ -458,8 +465,6 @@ class AsmJSModule
|
||||
|
||||
ScriptSource * scriptSource_;
|
||||
|
||||
FunctionCountsVector functionCounts_;
|
||||
|
||||
// This field is accessed concurrently when requesting an interrupt.
|
||||
// Access must be synchronized via the runtime's interrupt lock.
|
||||
mutable bool codeIsProtected_;
|
||||
@ -478,6 +483,8 @@ class AsmJSModule
|
||||
if (exitIndexToGlobalDatum(i).fun)
|
||||
MarkObject(trc, &exitIndexToGlobalDatum(i).fun, "asm.js imported function");
|
||||
}
|
||||
for (unsigned i = 0; i < functionNames_.length(); i++)
|
||||
MarkStringUnbarriered(trc, &functionNames_[i].name(), "asm.js module function name");
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
for (unsigned i = 0; i < profiledFunctions_.length(); i++)
|
||||
profiledFunctions_[i].trace(trc);
|
||||
@ -596,17 +603,13 @@ class AsmJSModule
|
||||
*exitIndex = unsigned(exits_.length());
|
||||
return exits_.append(Exit(ffiIndex, globalDataOffset));
|
||||
}
|
||||
bool addFunctionCounts(jit::IonScriptCounts *counts) {
|
||||
return functionCounts_.append(counts);
|
||||
}
|
||||
|
||||
bool addExportedFunction(PropertyName *name, uint32_t line, uint32_t column,
|
||||
uint32_t srcStart, uint32_t srcEnd,
|
||||
bool addExportedFunction(PropertyName *name, uint32_t srcStart, uint32_t srcEnd,
|
||||
PropertyName *maybeFieldName,
|
||||
ArgCoercionVector &&argCoercions,
|
||||
ReturnType returnType)
|
||||
{
|
||||
ExportedFunction func(name, line, column, srcStart, srcEnd, maybeFieldName,
|
||||
ExportedFunction func(name, srcStart, srcEnd, maybeFieldName,
|
||||
mozilla::Move(argCoercions), returnType);
|
||||
if (exports_.length() >= UINT32_MAX)
|
||||
return false;
|
||||
@ -626,6 +629,17 @@ class AsmJSModule
|
||||
return JS_DATA_TO_FUNC_PTR(CodePtr, code_ + func.pod.codeOffset_);
|
||||
}
|
||||
|
||||
bool addFunctionName(PropertyName *name, uint32_t *nameIndex) {
|
||||
JS_ASSERT(name->isTenured());
|
||||
if (functionNames_.length() > jit::CallSiteDesc::FUNCTION_NAME_INDEX_MAX)
|
||||
return false;
|
||||
*nameIndex = functionNames_.length();
|
||||
return functionNames_.append(name);
|
||||
}
|
||||
PropertyName *functionName(uint32_t i) const {
|
||||
return functionNames_[i].name();
|
||||
}
|
||||
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
bool trackProfiledFunction(PropertyName *name, unsigned startCodeOffset, unsigned endCodeOffset,
|
||||
unsigned line, unsigned column)
|
||||
@ -687,12 +701,6 @@ class AsmJSModule
|
||||
JS_ASSERT(exit.ionCodeOffset_);
|
||||
return code_ + exit.ionCodeOffset_;
|
||||
}
|
||||
unsigned numFunctionCounts() const {
|
||||
return functionCounts_.length();
|
||||
}
|
||||
jit::IonScriptCounts *functionCounts(unsigned i) {
|
||||
return functionCounts_[i];
|
||||
}
|
||||
|
||||
// An Exit holds bookkeeping information about an exit; the ExitDatum
|
||||
// struct overlays the actual runtime data stored in the global data
|
||||
@ -764,18 +772,32 @@ class AsmJSModule
|
||||
return pc >= code_ && pc < (code_ + functionBytes());
|
||||
}
|
||||
|
||||
bool addHeapAccesses(const jit::AsmJSHeapAccessVector &accesses) {
|
||||
return heapAccesses_.appendAll(accesses);
|
||||
void assignHeapAccesses(jit::AsmJSHeapAccessVector &&accesses) {
|
||||
heapAccesses_ = Move(accesses);
|
||||
}
|
||||
unsigned numHeapAccesses() const {
|
||||
return heapAccesses_.length();
|
||||
}
|
||||
jit::AsmJSHeapAccess &heapAccess(unsigned i) {
|
||||
return heapAccesses_[i];
|
||||
}
|
||||
const jit::AsmJSHeapAccess &heapAccess(unsigned i) const {
|
||||
return heapAccesses_[i];
|
||||
}
|
||||
jit::AsmJSHeapAccess &heapAccess(unsigned i) {
|
||||
return heapAccesses_[i];
|
||||
}
|
||||
|
||||
void assignCallSites(jit::CallSiteVector &&callsites) {
|
||||
callSites_ = Move(callsites);
|
||||
}
|
||||
unsigned numCallSites() const {
|
||||
return callSites_.length();
|
||||
}
|
||||
const jit::CallSite &callSite(unsigned i) const {
|
||||
return callSites_[i];
|
||||
}
|
||||
jit::CallSite &callSite(unsigned i) {
|
||||
return callSites_[i];
|
||||
}
|
||||
|
||||
void initHeap(Handle<ArrayBufferObject*> heap, JSContext *cx);
|
||||
|
||||
void requireHeapLengthToBeAtLeast(uint32_t len) {
|
||||
|
@ -342,7 +342,7 @@ HandleSimulatorInterrupt(JSRuntime *rt, AsmJSActivation *activation, void *fault
|
||||
if (module.containsPC((void *)rt->mainThread.simulator()->get_pc()) &&
|
||||
module.containsPC(faultingAddress))
|
||||
{
|
||||
activation->setResumePC(nullptr);
|
||||
activation->setInterrupted(nullptr);
|
||||
int32_t nextpc = int32_t(module.interruptExit());
|
||||
rt->mainThread.simulator()->set_resume_pc(nextpc);
|
||||
return true;
|
||||
@ -452,7 +452,7 @@ HandleException(PEXCEPTION_POINTERS exception)
|
||||
// The trampoline will jump to activation->resumePC if execution isn't
|
||||
// interrupted.
|
||||
if (module.containsPC(faultingAddress)) {
|
||||
activation->setResumePC(pc);
|
||||
activation->setInterrupted(pc);
|
||||
*ppc = module.interruptExit();
|
||||
|
||||
JSRuntime::AutoLockForInterrupt lock(rt);
|
||||
@ -655,7 +655,7 @@ HandleMachException(JSRuntime *rt, const ExceptionRequest &request)
|
||||
// The trampoline will jump to activation->resumePC if execution isn't
|
||||
// interrupted.
|
||||
if (module.containsPC(faultingAddress)) {
|
||||
activation->setResumePC(pc);
|
||||
activation->setInterrupted(pc);
|
||||
*ppc = module.interruptExit();
|
||||
|
||||
JSRuntime::AutoLockForInterrupt lock(rt);
|
||||
@ -905,7 +905,7 @@ HandleSignal(int signum, siginfo_t *info, void *ctx)
|
||||
// The trampoline will jump to activation->resumePC if execution isn't
|
||||
// interrupted.
|
||||
if (module.containsPC(faultingAddress)) {
|
||||
activation->setResumePC(pc);
|
||||
activation->setInterrupted(pc);
|
||||
*ppc = module.interruptExit();
|
||||
|
||||
JSRuntime::AutoLockForInterrupt lock(rt);
|
||||
|
@ -77,7 +77,7 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
|
||||
cx->mainThread().ionTop = nullptr;
|
||||
JitActivationIterator jitActivations(cx->runtime());
|
||||
IonBailoutIterator iter(jitActivations, sp);
|
||||
JitActivation *activation = jitActivations.activation()->asJit();
|
||||
JitActivation *activation = jitActivations->asJit();
|
||||
|
||||
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLogTimestamp(logger, TraceLogger::Bailout);
|
||||
@ -111,7 +111,7 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
|
||||
cx->mainThread().ionTop = nullptr;
|
||||
JitActivationIterator jitActivations(cx->runtime());
|
||||
IonBailoutIterator iter(jitActivations, sp);
|
||||
JitActivation *activation = jitActivations.activation()->asJit();
|
||||
JitActivation *activation = jitActivations->asJit();
|
||||
|
||||
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLogTimestamp(logger, TraceLogger::Invalidation);
|
||||
@ -179,7 +179,7 @@ jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
|
||||
cx->mainThread().ionTop = nullptr;
|
||||
JitActivationIterator jitActivations(cx->runtime());
|
||||
IonBailoutIterator iter(jitActivations, frame.frame());
|
||||
JitActivation *activation = jitActivations.activation()->asJit();
|
||||
JitActivation *activation = jitActivations->asJit();
|
||||
|
||||
BaselineBailoutInfo *bailoutInfo = nullptr;
|
||||
uint32_t retval = BailoutIonToBaseline(cx, activation, iter, true, &bailoutInfo, &excInfo);
|
||||
|
@ -958,7 +958,7 @@ jit::MarkActiveBaselineScripts(Zone *zone)
|
||||
{
|
||||
JSRuntime *rt = zone->runtimeFromMainThread();
|
||||
for (JitActivationIterator iter(rt); !iter.done(); ++iter) {
|
||||
if (iter.activation()->compartment()->zone() == zone)
|
||||
if (iter->compartment()->zone() == zone)
|
||||
MarkActiveBaselineScripts(rt, iter);
|
||||
}
|
||||
}
|
||||
|
@ -150,14 +150,12 @@ MNewStringObject::templateObj() const {
|
||||
CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm)
|
||||
: CodeGeneratorSpecific(gen, graph, masm)
|
||||
, ionScriptLabels_(gen->alloc())
|
||||
, unassociatedScriptCounts_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CodeGenerator::~CodeGenerator()
|
||||
{
|
||||
JS_ASSERT_IF(!gen->compilingAsmJS(), masm.numAsmJSAbsoluteLinks() == 0);
|
||||
js_delete(unassociatedScriptCounts_);
|
||||
}
|
||||
|
||||
typedef bool (*StringToNumberFn)(ThreadSafeContext *, JSString *, double *);
|
||||
@ -2748,17 +2746,6 @@ class CheckOverRecursedFailure : public OutOfLineCodeBase<CodeGenerator>
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
CodeGenerator::omitOverRecursedCheck() const
|
||||
{
|
||||
// If the current function makes no calls (which means it isn't recursive)
|
||||
// and it uses only a small amount of stack space, it doesn't need a
|
||||
// stack overflow check. Note that the actual number here is somewhat
|
||||
// arbitrary, and codegen actually uses small bounded amounts of
|
||||
// additional stack space in some cases too.
|
||||
return frameSize() < 64 && !gen->performsCall();
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitCheckOverRecursed(LCheckOverRecursed *lir)
|
||||
{
|
||||
@ -2987,15 +2974,15 @@ CodeGenerator::maybeCreateScriptCounts()
|
||||
if (!cx || !cx->runtime()->profilingScripts)
|
||||
return nullptr;
|
||||
|
||||
IonScriptCounts *counts = nullptr;
|
||||
|
||||
CompileInfo *outerInfo = &gen->info();
|
||||
JSScript *script = outerInfo->script();
|
||||
|
||||
if (script && !script->hasScriptCounts() && !script->initScriptCounts(cx))
|
||||
if (!script)
|
||||
return nullptr;
|
||||
|
||||
counts = js_new<IonScriptCounts>();
|
||||
if (!script->hasScriptCounts() && !script->initScriptCounts(cx))
|
||||
return nullptr;
|
||||
|
||||
IonScriptCounts *counts = js_new<IonScriptCounts>();
|
||||
if (!counts || !counts->init(graph.numBlocks())) {
|
||||
js_delete(counts);
|
||||
return nullptr;
|
||||
@ -3004,33 +2991,24 @@ CodeGenerator::maybeCreateScriptCounts()
|
||||
for (size_t i = 0; i < graph.numBlocks(); i++) {
|
||||
MBasicBlock *block = graph.getBlock(i)->mir();
|
||||
|
||||
uint32_t offset = 0;
|
||||
if (script) {
|
||||
// Find a PC offset in the outermost script to use. If this block
|
||||
// is from an inlined script, find a location in the outer script
|
||||
// to associate information about the inlining with.
|
||||
MResumePoint *resume = block->entryResumePoint();
|
||||
while (resume->caller())
|
||||
resume = resume->caller();
|
||||
offset = script->pcToOffset(resume->pc());
|
||||
}
|
||||
|
||||
uint32_t offset = script->pcToOffset(resume->pc());
|
||||
if (!counts->block(i).init(block->id(), offset, block->numSuccessors())) {
|
||||
js_delete(counts);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < block->numSuccessors(); j++)
|
||||
counts->block(i).setSuccessor(j, block->getSuccessor(j)->id());
|
||||
}
|
||||
|
||||
if (script) {
|
||||
script->addIonCounts(counts);
|
||||
} else {
|
||||
// Compiling code for Asm.js. Leave the counts on the CodeGenerator to
|
||||
// be picked up by the AsmJSModule after generation finishes.
|
||||
unassociatedScriptCounts_ = counts;
|
||||
}
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
@ -6202,7 +6180,7 @@ CodeGenerator::visitRestPar(LRestPar *lir)
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::generateAsmJS()
|
||||
CodeGenerator::generateAsmJS(Label *stackOverflowLabel)
|
||||
{
|
||||
IonSpew(IonSpew_Codegen, "# Emitting asm.js code");
|
||||
|
||||
@ -6215,7 +6193,7 @@ CodeGenerator::generateAsmJS()
|
||||
// parameters have been useFixed()ed to these ABI-specified positions.
|
||||
// Thus, there is nothing special to do in the prologue except (possibly)
|
||||
// bump the stack.
|
||||
if (!generatePrologue())
|
||||
if (!generateAsmJSPrologue(stackOverflowLabel))
|
||||
return false;
|
||||
if (!generateBody())
|
||||
return false;
|
||||
@ -8240,6 +8218,7 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mir->spIncrement())
|
||||
masm.freeStack(mir->spIncrement());
|
||||
|
||||
@ -8256,13 +8235,13 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
|
||||
MAsmJSCall::Callee callee = mir->callee();
|
||||
switch (callee.which()) {
|
||||
case MAsmJSCall::Callee::Internal:
|
||||
masm.call(callee.internal());
|
||||
masm.call(mir->desc(), callee.internal());
|
||||
break;
|
||||
case MAsmJSCall::Callee::Dynamic:
|
||||
masm.call(ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex())));
|
||||
masm.call(mir->desc(), ToRegister(ins->getOperand(mir->dynamicCalleeOperandIndex())));
|
||||
break;
|
||||
case MAsmJSCall::Callee::Builtin:
|
||||
masm.call(callee.builtin());
|
||||
masm.call(mir->desc(), callee.builtin());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -8297,20 +8276,6 @@ CodeGenerator::visitAsmJSVoidReturn(LAsmJSVoidReturn *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitAsmJSCheckOverRecursed(LAsmJSCheckOverRecursed *lir)
|
||||
{
|
||||
// If we don't push anything on the stack, skip the check.
|
||||
if (omitOverRecursedCheck())
|
||||
return true;
|
||||
|
||||
masm.branchPtr(Assembler::AboveOrEqual,
|
||||
AsmJSAbsoluteAddress(AsmJSImm_StackLimit),
|
||||
StackPointer,
|
||||
lir->mir()->onError());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::emitAssertRangeI(const Range *r, Register input)
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
|
||||
public:
|
||||
bool generate();
|
||||
bool generateAsmJS();
|
||||
bool generateAsmJS(Label *stackOverflowLabel);
|
||||
bool link(JSContext *cx, types::CompilerConstraintList *constraints);
|
||||
|
||||
bool visitLabel(LLabel *lir);
|
||||
@ -294,7 +294,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
|
||||
bool visitCheckOverRecursed(LCheckOverRecursed *lir);
|
||||
bool visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool);
|
||||
bool visitAsmJSCheckOverRecursed(LAsmJSCheckOverRecursed *lir);
|
||||
|
||||
bool visitCheckOverRecursedPar(LCheckOverRecursedPar *lir);
|
||||
bool visitCheckOverRecursedFailurePar(CheckOverRecursedFailurePar *ool);
|
||||
@ -350,12 +349,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
|
||||
bool visitRecompileCheck(LRecompileCheck *ins);
|
||||
|
||||
IonScriptCounts *extractUnassociatedScriptCounts() {
|
||||
IonScriptCounts *counts = unassociatedScriptCounts_;
|
||||
unassociatedScriptCounts_ = nullptr; // prevent delete in dtor
|
||||
return counts;
|
||||
}
|
||||
|
||||
private:
|
||||
bool addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
@ -447,8 +440,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool emitAssertRangeI(const Range *r, Register input);
|
||||
bool emitAssertRangeD(const Range *r, FloatRegister input, FloatRegister temp);
|
||||
|
||||
bool omitOverRecursedCheck() const;
|
||||
|
||||
Vector<CodeOffsetLabel, 0, IonAllocPolicy> ionScriptLabels_;
|
||||
#ifdef DEBUG
|
||||
bool branchIfInvalidated(Register temp, Label *invalidated);
|
||||
@ -458,9 +449,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool emitValueResultChecks(LInstruction *lir, MDefinition *mir);
|
||||
#endif
|
||||
|
||||
// Script counts created when compiling code with no associated JSScript.
|
||||
IonScriptCounts *unassociatedScriptCounts_;
|
||||
|
||||
#if defined(JS_ION_PERF)
|
||||
PerfSpewer perfSpewer_;
|
||||
#endif
|
||||
|
@ -1628,29 +1628,22 @@ GenerateLIR(MIRGenerator *mir)
|
||||
}
|
||||
|
||||
CodeGenerator *
|
||||
GenerateCode(MIRGenerator *mir, LIRGraph *lir, MacroAssembler *maybeMasm)
|
||||
GenerateCode(MIRGenerator *mir, LIRGraph *lir)
|
||||
{
|
||||
CodeGenerator *codegen = js_new<CodeGenerator>(mir, lir, maybeMasm);
|
||||
CodeGenerator *codegen = js_new<CodeGenerator>(mir, lir);
|
||||
if (!codegen)
|
||||
return nullptr;
|
||||
|
||||
if (mir->compilingAsmJS()) {
|
||||
if (!codegen->generateAsmJS()) {
|
||||
js_delete(codegen);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (!codegen->generate()) {
|
||||
js_delete(codegen);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return codegen;
|
||||
}
|
||||
|
||||
CodeGenerator *
|
||||
CompileBackEnd(MIRGenerator *mir, MacroAssembler *maybeMasm)
|
||||
CompileBackEnd(MIRGenerator *mir)
|
||||
{
|
||||
if (!OptimizeMIR(mir))
|
||||
return nullptr;
|
||||
@ -1659,7 +1652,7 @@ CompileBackEnd(MIRGenerator *mir, MacroAssembler *maybeMasm)
|
||||
if (!lir)
|
||||
return nullptr;
|
||||
|
||||
return GenerateCode(mir, lir, maybeMasm);
|
||||
return GenerateCode(mir, lir);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2660,7 +2653,7 @@ jit::InvalidateAll(FreeOp *fop, Zone *zone)
|
||||
StopAllOffThreadCompilations(comp);
|
||||
|
||||
for (JitActivationIterator iter(fop->runtime()); !iter.done(); ++iter) {
|
||||
if (iter.activation()->compartment()->zone() == zone) {
|
||||
if (iter->compartment()->zone() == zone) {
|
||||
IonContext ictx(CompileRuntime::get(fop->runtime()));
|
||||
AutoFlushCache afc("InvalidateAll", fop->runtime()->jitRuntime());
|
||||
IonSpew(IonSpew_Invalidate, "Invalidating all frames for GC");
|
||||
@ -3081,7 +3074,7 @@ AutoDebugModeInvalidation::~AutoDebugModeInvalidation()
|
||||
jit::MarkActiveBaselineScripts(zone);
|
||||
|
||||
for (JitActivationIterator iter(rt); !iter.done(); ++iter) {
|
||||
JSCompartment *comp = iter.activation()->compartment();
|
||||
JSCompartment *comp = iter->compartment();
|
||||
if (comp_ == comp || zone_ == comp->zone()) {
|
||||
IonContext ictx(CompileRuntime::get(rt));
|
||||
AutoFlushCache afc("AutoDebugModeInvalidation", rt->jitRuntime());
|
||||
|
@ -149,8 +149,8 @@ class CodeGenerator;
|
||||
|
||||
bool OptimizeMIR(MIRGenerator *mir);
|
||||
LIRGraph *GenerateLIR(MIRGenerator *mir);
|
||||
CodeGenerator *GenerateCode(MIRGenerator *mir, LIRGraph *lir, MacroAssembler *maybeMasm = nullptr);
|
||||
CodeGenerator *CompileBackEnd(MIRGenerator *mir, MacroAssembler *maybeMasm = nullptr);
|
||||
CodeGenerator *GenerateCode(MIRGenerator *mir, LIRGraph *lir);
|
||||
CodeGenerator *CompileBackEnd(MIRGenerator *mir);
|
||||
|
||||
void AttachFinishedCompilations(JSContext *cx);
|
||||
void FinishOffThreadBuilder(IonBuilder *builder);
|
||||
|
@ -92,7 +92,7 @@ JitFrameIterator::JitFrameIterator(const ActivationIterator &activations)
|
||||
returnAddressToFp_(nullptr),
|
||||
frameSize_(0),
|
||||
cachedSafepointIndex_(nullptr),
|
||||
activation_(activations.activation()->asJit()),
|
||||
activation_(activations->asJit()),
|
||||
mode_(SequentialExecution)
|
||||
{
|
||||
}
|
||||
@ -1174,7 +1174,7 @@ MarkRectifierFrame(JSTracer *trc, const JitFrameIterator &frame)
|
||||
static void
|
||||
MarkJitActivation(JSTracer *trc, const JitActivationIterator &activations)
|
||||
{
|
||||
JitActivation *activation = activations.activation()->asJit();
|
||||
JitActivation *activation = activations->asJit();
|
||||
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
if (js_JitOptions.checkOsiPointRegisters) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user