mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to m-c.
This commit is contained in:
commit
e3b6b30cd3
@ -10,6 +10,7 @@
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsIAccessibleTypes.h"
|
||||
#include "DocAccessible.h"
|
||||
#include "HTMLListAccessible.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
#include "TextAttrs.h"
|
||||
@ -238,7 +239,7 @@ HyperTextAccessible::DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
|
||||
if (!aNode)
|
||||
return 0;
|
||||
|
||||
uint32_t addTextOffset = 0;
|
||||
uint32_t offset = 0;
|
||||
nsINode* findNode = nullptr;
|
||||
|
||||
if (aNodeOffset == -1) {
|
||||
@ -251,7 +252,7 @@ HyperTextAccessible::DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
|
||||
nsIFrame* frame = aNode->AsContent()->GetPrimaryFrame();
|
||||
NS_ENSURE_TRUE(frame, 0);
|
||||
|
||||
nsresult rv = ContentToRenderedOffset(frame, aNodeOffset, &addTextOffset);
|
||||
nsresult rv = ContentToRenderedOffset(frame, aNodeOffset, &offset);
|
||||
NS_ENSURE_SUCCESS(rv, 0);
|
||||
// Get the child node and
|
||||
findNode = aNode;
|
||||
@ -304,14 +305,20 @@ HyperTextAccessible::DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
|
||||
descendant = GetFirstAvailableAccessible(findNode);
|
||||
}
|
||||
|
||||
// From the descendant, go up and get the immediate child of this hypertext
|
||||
Accessible* childAtOffset = nullptr;
|
||||
return TransformOffset(descendant, offset, aIsEndOffset);
|
||||
}
|
||||
|
||||
int32_t
|
||||
HyperTextAccessible::TransformOffset(Accessible* aDescendant,
|
||||
int32_t aOffset, bool aIsEndOffset) const
|
||||
{
|
||||
// From the descendant, go up and get the immediate child of this hypertext.
|
||||
int32_t offset = aOffset;
|
||||
Accessible* descendant = aDescendant;
|
||||
while (descendant) {
|
||||
Accessible* parent = descendant->Parent();
|
||||
if (parent == this) {
|
||||
childAtOffset = descendant;
|
||||
break;
|
||||
}
|
||||
if (parent == this)
|
||||
return GetChildOffset(descendant) + offset;
|
||||
|
||||
// This offset no longer applies because the passed-in text object is not
|
||||
// a child of the hypertext. This happens when there are nested hypertexts,
|
||||
@ -321,17 +328,16 @@ HyperTextAccessible::DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
|
||||
// is not at 0 offset then the returned offset should be after an embedded
|
||||
// character the original point belongs to.
|
||||
if (aIsEndOffset)
|
||||
addTextOffset = (addTextOffset > 0 || descendant->IndexInParent() > 0) ? 1 : 0;
|
||||
offset = (offset > 0 || descendant->IndexInParent() > 0) ? 1 : 0;
|
||||
else
|
||||
addTextOffset = 0;
|
||||
offset = 0;
|
||||
|
||||
descendant = parent;
|
||||
}
|
||||
|
||||
// If the given DOM point cannot be mapped into offset relative this hypertext
|
||||
// If the given a11y point cannot be mapped into offset relative this hypertext
|
||||
// offset then return length as fallback value.
|
||||
return childAtOffset ?
|
||||
GetChildOffset(childAtOffset) + addTextOffset : CharacterCount();
|
||||
return CharacterCount();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -420,6 +426,31 @@ HyperTextAccessible::FindOffset(int32_t aOffset, nsDirection aDirection,
|
||||
return -1;
|
||||
|
||||
child = text->GetChildAt(childIdx);
|
||||
|
||||
// HTML list items may need special processing because PeekOffset doesn't
|
||||
// work with list bullets.
|
||||
if (text->IsHTMLListItem()) {
|
||||
HTMLLIAccessible* li = text->AsHTMLListItem();
|
||||
if (child == li->Bullet()) {
|
||||
// It works only when the bullet is one single char.
|
||||
if (aDirection == eDirPrevious)
|
||||
return text != this ? TransformOffset(text, 0, false) : 0;
|
||||
|
||||
if (aAmount == eSelectEndLine || aAmount == eSelectLine) {
|
||||
if (text != this)
|
||||
return TransformOffset(text, 1, true);
|
||||
|
||||
// Ask a text leaf next (if not empty) to the bullet for an offset
|
||||
// since list item may be multiline.
|
||||
return aOffset + 1 < CharacterCount() ?
|
||||
FindOffset(aOffset + 1, aDirection, aAmount, aWordMovementType) : 1;
|
||||
}
|
||||
|
||||
// Case of word and char boundaries.
|
||||
return text != this ? TransformOffset(text, 1, true) : 1;
|
||||
}
|
||||
}
|
||||
|
||||
innerOffset -= text->GetChildOffset(childIdx);
|
||||
|
||||
text = child->AsHyperText();
|
||||
@ -463,10 +494,16 @@ HyperTextAccessible::FindOffset(int32_t aOffset, nsDirection aDirection,
|
||||
pos.mContentOffset,
|
||||
aDirection == eDirNext);
|
||||
|
||||
// If we reached the end during search, this means we didn't find the DOM point
|
||||
// and we're actually at the start of the paragraph
|
||||
if (hyperTextOffset == CharacterCount() && aDirection == eDirPrevious)
|
||||
return 0;
|
||||
if (aDirection == eDirPrevious) {
|
||||
// If we reached the end during search, this means we didn't find the DOM point
|
||||
// and we're actually at the start of the paragraph
|
||||
if (hyperTextOffset == CharacterCount())
|
||||
return 0;
|
||||
|
||||
// PeekOffset stops right before bullet so return 0 to workaround it.
|
||||
if (IsHTMLListItem() && aAmount == eSelectBeginLine && hyperTextOffset == 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hyperTextOffset;
|
||||
}
|
||||
|
@ -120,6 +120,12 @@ public:
|
||||
int32_t DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
|
||||
bool aIsEndOffset = false) const;
|
||||
|
||||
/**
|
||||
* Transform the given a11y point into the offset relative this hypertext.
|
||||
*/
|
||||
int32_t TransformOffset(Accessible* aDescendant, int32_t aOffset,
|
||||
bool aIsEndOffset) const;
|
||||
|
||||
/**
|
||||
* Convert start and end hypertext offsets into DOM range.
|
||||
*
|
||||
@ -435,9 +441,9 @@ protected:
|
||||
* Return an offset corresponding to the given direction and selection amount
|
||||
* relative the given offset. A helper used to find word or line boundaries.
|
||||
*/
|
||||
virtual int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
|
||||
nsSelectionAmount aAmount,
|
||||
EWordMovementType aWordMovementType = eDefaultBehavior);
|
||||
int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
|
||||
nsSelectionAmount aAmount,
|
||||
EWordMovementType aWordMovementType = eDefaultBehavior);
|
||||
|
||||
/**
|
||||
* Return the boundaries of the substring in case of textual frame or
|
||||
|
@ -98,33 +98,6 @@ HTMLLIAccessible::GetBounds(int32_t* aX, int32_t* aY,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTMLLIAccessible::FindOffset(int32_t aOffset, nsDirection aDirection,
|
||||
nsSelectionAmount aAmount,
|
||||
EWordMovementType aWordMovementType)
|
||||
{
|
||||
Accessible* child = GetChildAtOffset(aOffset);
|
||||
if (!child)
|
||||
return -1;
|
||||
|
||||
if (child != mBullet) {
|
||||
if (aDirection == eDirPrevious &&
|
||||
(aAmount == eSelectBeginLine || aAmount == eSelectLine))
|
||||
return 0;
|
||||
|
||||
return HyperTextAccessible::FindOffset(aOffset, aDirection,
|
||||
aAmount, aWordMovementType);
|
||||
}
|
||||
|
||||
if (aDirection == eDirPrevious)
|
||||
return 0;
|
||||
|
||||
if (aAmount == eSelectEndLine || aAmount == eSelectLine)
|
||||
return CharacterCount();
|
||||
|
||||
return nsAccUtils::TextLength(child);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLLIAccessible: public
|
||||
|
||||
|
@ -55,12 +55,8 @@ public:
|
||||
virtual a11y::role NativeRole();
|
||||
virtual uint64_t NativeState();
|
||||
|
||||
// HyperTextAccessible
|
||||
virtual int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
|
||||
nsSelectionAmount aAmount,
|
||||
EWordMovementType aWordMovementType) MOZ_OVERRIDE;
|
||||
|
||||
// HTMLLIAccessible
|
||||
HTMLListBulletAccessible* Bullet() const { return mBullet; }
|
||||
void UpdateBullet(bool aHasBullet);
|
||||
|
||||
protected:
|
||||
|
@ -119,6 +119,18 @@
|
||||
|
||||
testTextAtOffset([ "li1" ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 5, kDiscBulletChar + "Item", 0, 5 ] ]);
|
||||
testTextAtOffset([ "li2" ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 1, kDiscBulletChar, 0, 1 ] ]);
|
||||
testTextAtOffset([ "li3" ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 7, kDiscBulletChar + "a long ", 0, 8 ],
|
||||
[ 8, 11, "and ", 8, 12 ] ]);
|
||||
testTextAtOffset([ "li4" ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 6, kDiscBulletChar + "a " + kEmbedChar + " c", 0, 6 ] ]);
|
||||
testTextAtOffset([ "ul1" ], BOUNDARY_LINE_START,
|
||||
[ [ 0, 0, kEmbedChar, 0, 1 ],
|
||||
[ 1, 1, kEmbedChar, 1, 2 ],
|
||||
[ 2, 2, kEmbedChar, 2, 3 ],
|
||||
[ 3, 4, kEmbedChar, 3, 4 ] ]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Nested hypertexts
|
||||
@ -193,8 +205,11 @@ two words
|
||||
<p id="ht_4">Hello world
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<ul id="ul1">
|
||||
<li id="li1">Item</li>
|
||||
<li id="li2"></li>
|
||||
<li id="li3" style="width:10ex; font-family:monospace; font-size:10pt;">a long and winding road that lead me to your door</li>
|
||||
<li id="li4">a <a href=''>b</a> c</li>
|
||||
</ul>
|
||||
|
||||
<div id="ht_5">
|
||||
@ -203,5 +218,6 @@ two words
|
||||
<p>seciofarus</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -288,6 +288,7 @@ run-if = crashreporter
|
||||
[browser_popupNotification.js]
|
||||
skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341)
|
||||
[browser_popupUI.js]
|
||||
[browser_printpreview.js]
|
||||
[browser_private_browsing_window.js]
|
||||
[browser_private_no_prompt.js]
|
||||
[browser_relatedTabs.js]
|
||||
|
65
browser/base/content/test/general/browser_printpreview.js
Normal file
65
browser/base/content/test/general/browser_printpreview.js
Normal file
@ -0,0 +1,65 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
ok(!gInPrintPreviewMode,
|
||||
"Should NOT be in print preview mode at starting this tests");
|
||||
// Skip access key test on platforms which don't support access key.
|
||||
if (!/Win|Linux/.test(navigator.platform)) {
|
||||
openPrintPreview(testClosePrintPreviewWithEscKey);
|
||||
} else {
|
||||
openPrintPreview(testClosePrintPreviewWithAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
function testClosePrintPreviewWithAccessKey() {
|
||||
EventUtils.synthesizeKey("c", { altKey: true });
|
||||
checkPrintPreviewClosed(function (aSucceeded) {
|
||||
ok(aSucceeded,
|
||||
"print preview mode should be finished by access key");
|
||||
openPrintPreview(testClosePrintPreviewWithEscKey);
|
||||
});
|
||||
}
|
||||
|
||||
function testClosePrintPreviewWithEscKey() {
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
checkPrintPreviewClosed(function (aSucceeded) {
|
||||
ok(aSucceeded,
|
||||
"print preview mode should be finished by Esc key press");
|
||||
openPrintPreview(testClosePrintPreviewWithClosingWindowShortcutKey);
|
||||
});
|
||||
}
|
||||
|
||||
function testClosePrintPreviewWithClosingWindowShortcutKey() {
|
||||
EventUtils.synthesizeKey("w", { accelKey: true });
|
||||
checkPrintPreviewClosed(function (aSucceeded) {
|
||||
ok(aSucceeded,
|
||||
"print preview mode should be finished by closing window shortcut key");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function openPrintPreview(aCallback) {
|
||||
document.getElementById("cmd_printPreview").doCommand();
|
||||
executeSoon(function () {
|
||||
if (gInPrintPreviewMode) {
|
||||
executeSoon(aCallback);
|
||||
return;
|
||||
}
|
||||
executeSoon(arguments.callee);
|
||||
});
|
||||
}
|
||||
|
||||
function checkPrintPreviewClosed(aCallback) {
|
||||
let count = 0;
|
||||
executeSoon(function () {
|
||||
if (!gInPrintPreviewMode) {
|
||||
executeSoon(function () { aCallback(count < 1000); });
|
||||
return;
|
||||
}
|
||||
if (++count == 1000) {
|
||||
// The test might fail.
|
||||
PrintUtils.exitPrintPreview();
|
||||
}
|
||||
executeSoon(arguments.callee);
|
||||
});
|
||||
}
|
@ -512,11 +512,9 @@ def dumpScreen(utilityPath):
|
||||
|
||||
# Run the capture
|
||||
try:
|
||||
with mozfile.NamedTemporaryFile(suffix='.png',
|
||||
prefix='mozilla-test-fail-screenshot_',
|
||||
dir=parent_dir,
|
||||
delete=False) as f:
|
||||
returncode = subprocess.call(utility + [f.name])
|
||||
tmpfd, imgfilename = tempfile.mkstemp(prefix='mozilla-test-fail-screenshot_', suffix='.png', dir=parent_dir)
|
||||
os.close(tmpfd)
|
||||
returncode = subprocess.call(utility + [imgfilename])
|
||||
except OSError, err:
|
||||
log.info("Failed to start %s for screenshot: %s",
|
||||
utility[0], err.strerror)
|
||||
|
@ -1460,7 +1460,7 @@ ifeq (,$(wildcard $(DIST)/bin/nsinstall$(HOST_BIN_SUFFIX)))
|
||||
nsinstall_is_usable = $(if $(wildcard $(DIST)/bin/nsinstall$(HOST_BIN_SUFFIX)),yes)
|
||||
|
||||
define install_cmd_override
|
||||
$(1): install_cmd = $$(if $$(nsinstall_is_usable),$$(INSTALL),$$(NSINSTALL_PY)) $$(1)
|
||||
$(1): install_cmd = $$(if $$(nsinstall_is_usable),$$(INSTALL),$$(NSINSTALL_PY) -t) $$(1)
|
||||
endef
|
||||
endif
|
||||
endif
|
||||
|
@ -1249,6 +1249,7 @@ GK_ATOM(feConvolveMatrix, "feConvolveMatrix")
|
||||
GK_ATOM(feDiffuseLighting, "feDiffuseLighting")
|
||||
GK_ATOM(feDisplacementMap, "feDisplacementMap")
|
||||
GK_ATOM(feDistantLight,"feDistantLight")
|
||||
GK_ATOM(feDropShadow, "feDropShadow")
|
||||
GK_ATOM(feFlood, "feFlood")
|
||||
GK_ATOM(feFuncA, "feFuncA")
|
||||
GK_ATOM(feFuncB, "feFuncB")
|
||||
|
@ -306,6 +306,7 @@ nsIAtom** const kElementsSVG[] = {
|
||||
&nsGkAtoms::feDiffuseLighting, // feDiffuseLighting
|
||||
&nsGkAtoms::feDisplacementMap, // feDisplacementMap
|
||||
&nsGkAtoms::feDistantLight, // feDistantLight
|
||||
&nsGkAtoms::feDropShadow, // feDropShadow
|
||||
&nsGkAtoms::feFlood, // feFlood
|
||||
&nsGkAtoms::feFuncA, // feFuncA
|
||||
&nsGkAtoms::feFuncB, // feFuncB
|
||||
|
@ -72,6 +72,8 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
|
||||
// on UpdateCurrentTime to notify our listeners once the stream end
|
||||
// has been reached.
|
||||
EnsureNextIteration();
|
||||
|
||||
SetStreamOrderDirty();
|
||||
}
|
||||
|
||||
void
|
||||
@ -80,6 +82,8 @@ MediaStreamGraphImpl::AddStream(MediaStream* aStream)
|
||||
aStream->mBufferStartTime = mCurrentTime;
|
||||
*mStreams.AppendElement() = already_AddRefed<MediaStream>(aStream);
|
||||
STREAM_LOG(PR_LOG_DEBUG, ("Adding media stream %p to the graph", aStream));
|
||||
|
||||
SetStreamOrderDirty();
|
||||
}
|
||||
|
||||
void
|
||||
@ -97,6 +101,8 @@ MediaStreamGraphImpl::RemoveStream(MediaStream* aStream)
|
||||
}
|
||||
}
|
||||
|
||||
SetStreamOrderDirty();
|
||||
|
||||
// This unrefs the stream, probably destroying it
|
||||
mStreams.RemoveElement(aStream);
|
||||
|
||||
@ -430,6 +436,7 @@ MediaStreamGraphImpl::UpdateCurrentTime()
|
||||
stream->StreamTimeToGraphTime(stream->GetStreamBuffer().GetAllTracksEnd())) {
|
||||
stream->mNotifiedFinished = true;
|
||||
stream->mLastPlayedVideoFrame.SetNull();
|
||||
SetStreamOrderDirty();
|
||||
for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = stream->mListeners[j];
|
||||
l->NotifyFinished(this);
|
||||
@ -1168,7 +1175,9 @@ MediaStreamGraphImpl::RunThread()
|
||||
}
|
||||
messageQueue.Clear();
|
||||
|
||||
UpdateStreamOrder();
|
||||
if (mStreamOrderDirty) {
|
||||
UpdateStreamOrder();
|
||||
}
|
||||
|
||||
// Find the sampling rate that we need to use for non-realtime graphs.
|
||||
TrackRate sampleRate = IdealAudioRate();
|
||||
@ -2279,6 +2288,8 @@ MediaInputPort::Disconnect()
|
||||
mSource = nullptr;
|
||||
mDest->RemoveInput(this);
|
||||
mDest = nullptr;
|
||||
|
||||
GraphImpl()->SetStreamOrderDirty();
|
||||
}
|
||||
|
||||
MediaInputPort::InputInterval
|
||||
@ -2357,6 +2368,7 @@ ProcessedMediaStream::AllocateInputPort(MediaStream* aStream, uint32_t aFlags,
|
||||
{
|
||||
mPort->Init();
|
||||
// The graph holds its reference implicitly
|
||||
mPort->GraphImpl()->SetStreamOrderDirty();
|
||||
mPort.forget();
|
||||
}
|
||||
virtual void RunDuringShutdown()
|
||||
@ -2410,6 +2422,7 @@ ProcessedMediaStream::DestroyImpl()
|
||||
mInputs[i]->Disconnect();
|
||||
}
|
||||
MediaStream::DestroyImpl();
|
||||
GraphImpl()->SetStreamOrderDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1886,7 +1886,7 @@ InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj,
|
||||
JS::Rooted<JSObject*> unwrapped(cx, js::CheckedUnwrap(instance, true));
|
||||
if (unwrapped && jsipc::JavaScriptParent::IsCPOW(unwrapped)) {
|
||||
bool boolp = false;
|
||||
if (!jsipc::JavaScriptParent::DOMInstanceOf(unwrapped, clasp->mPrototypeID,
|
||||
if (!jsipc::JavaScriptParent::DOMInstanceOf(cx, unwrapped, clasp->mPrototypeID,
|
||||
clasp->mDepth, &boolp)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -92,6 +92,10 @@
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#include "mozilla/X11Util.h"
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
@ -352,6 +356,13 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
Open(aChannel, aParentHandle, aIOLoop);
|
||||
sSingleton = this;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// Send the parent our X socket to act as a proxy reference for our X
|
||||
// resources.
|
||||
int xSocketFd = ConnectionNumber(DefaultXDisplay());
|
||||
SendBackUpXResources(FileDescriptor(xSocketFd));
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
SendPCrashReporterConstructor(CrashReporter::CurrentThreadId(),
|
||||
XRE_GetProcessType());
|
||||
|
@ -2012,7 +2012,7 @@ ContentParent::AllocPJavaScriptParent()
|
||||
bool
|
||||
ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
|
||||
{
|
||||
static_cast<mozilla::jsipc::JavaScriptParent *>(parent)->destroyFromContent();
|
||||
static_cast<mozilla::jsipc::JavaScriptParent *>(parent)->decref();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3258,6 +3258,22 @@ ContentParent::RecvRemoveIdleObserver(const uint64_t& aObserver, const uint32_t&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
|
||||
{
|
||||
#ifndef MOZ_X11
|
||||
NS_RUNTIMEABORT("This message only makes sense on X11 platforms");
|
||||
#else
|
||||
NS_ABORT_IF_FALSE(0 > mChildXSocketFdDup.get(),
|
||||
"Already backed up X resources??");
|
||||
mChildXSocketFdDup.forget();
|
||||
if (aXSocketFd.IsValid()) {
|
||||
mChildXSocketFdDup.reset(aXSocketFd.PlatformHandle());
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/HalTypes.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
@ -534,6 +535,9 @@ private:
|
||||
virtual bool RecvRemoveIdleObserver(const uint64_t& observerId,
|
||||
const uint32_t& aIdleTimeInS) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvBackUpXResources(const FileDescriptor& aXSocketFd) MOZ_OVERRIDE;
|
||||
|
||||
// If you add strong pointers to cycle collected objects here, be sure to
|
||||
// release these objects in ShutDownProcess. See the comment there for more
|
||||
// details.
|
||||
@ -586,6 +590,12 @@ private:
|
||||
nsConsoleService* GetConsoleService();
|
||||
|
||||
nsDataHashtable<nsUint64HashKey, nsCOMPtr<ParentIdleListener> > mIdleListeners;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// Dup of child's X socket, used to scope its resources to this
|
||||
// object instead of the child process's lifetime.
|
||||
ScopedClose mChildXSocketFdDup;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -519,6 +519,20 @@ parent:
|
||||
|
||||
AddIdleObserver(uint64_t observerId, uint32_t idleTimeInS);
|
||||
RemoveIdleObserver(uint64_t observerId, uint32_t idleTimeInS);
|
||||
|
||||
/**
|
||||
* This message is only used on X11 platforms.
|
||||
*
|
||||
* Send a dup of the plugin process's X socket to the parent
|
||||
* process. In theory, this scheme keeps the plugin's X resources
|
||||
* around until after both the plugin process shuts down *and* the
|
||||
* parent process closes the dup fd. This is used to prevent the
|
||||
* parent process from crashing on X errors if, e.g., the plugin
|
||||
* crashes *just before* a repaint and the parent process tries to
|
||||
* use the newly-invalid surface.
|
||||
*/
|
||||
BackUpXResources(FileDescriptor aXSocketFd);
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal);
|
||||
|
@ -288,6 +288,11 @@ static bool gCrossSlideEnabled = false;
|
||||
*/
|
||||
static bool gUseProgressiveTilePainting = false;
|
||||
|
||||
/**
|
||||
* Pref that allows or disallows checkerboarding
|
||||
*/
|
||||
static bool gAllowCheckerboarding = true;
|
||||
|
||||
/**
|
||||
* Is aAngle within the given threshold of the horizontal axis?
|
||||
* @param aAngle an angle in radians in the range [0, pi]
|
||||
@ -412,6 +417,7 @@ AsyncPanZoomController::InitializeGlobalState()
|
||||
Preferences::AddIntVarCache(&gAsyncScrollTimeout, "apz.asyncscroll.timeout", gAsyncScrollTimeout);
|
||||
Preferences::AddBoolVarCache(&gCrossSlideEnabled, "apz.cross_slide.enabled", gCrossSlideEnabled);
|
||||
Preferences::AddIntVarCache(&gAxisLockMode, "apz.axis_lock_mode", gAxisLockMode);
|
||||
Preferences::AddBoolVarCache(&gAllowCheckerboarding, "apz.allow-checkerboarding", gAllowCheckerboarding);
|
||||
gUseProgressiveTilePainting = gfxPlatform::UseProgressiveTilePainting();
|
||||
|
||||
gComputedTimingFunction = new ComputedTimingFunction();
|
||||
@ -1537,7 +1543,28 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
|
||||
if (mLastContentPaintMetrics.IsScrollable()) {
|
||||
lastPaintScrollOffset = mLastContentPaintMetrics.mScrollOffset;
|
||||
}
|
||||
LayerPoint translation = (mFrameMetrics.mScrollOffset - lastPaintScrollOffset)
|
||||
|
||||
CSSPoint currentScrollOffset = mFrameMetrics.mScrollOffset;
|
||||
|
||||
// If checkerboarding has been disallowed, clamp the scroll position to stay
|
||||
// within rendered content.
|
||||
if (!gAllowCheckerboarding &&
|
||||
!mLastContentPaintMetrics.mDisplayPort.IsEmpty()) {
|
||||
CSSRect compositedRect = mLastContentPaintMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSPoint maxScrollOffset = lastPaintScrollOffset +
|
||||
CSSPoint(mLastContentPaintMetrics.mDisplayPort.XMost() - compositedRect.width,
|
||||
mLastContentPaintMetrics.mDisplayPort.YMost() - compositedRect.height);
|
||||
CSSPoint minScrollOffset = lastPaintScrollOffset + mLastContentPaintMetrics.mDisplayPort.TopLeft();
|
||||
|
||||
if (minScrollOffset.x < maxScrollOffset.x) {
|
||||
currentScrollOffset.x = clamped(currentScrollOffset.x, minScrollOffset.x, maxScrollOffset.x);
|
||||
}
|
||||
if (minScrollOffset.y < maxScrollOffset.y) {
|
||||
currentScrollOffset.y = clamped(currentScrollOffset.y, minScrollOffset.y, maxScrollOffset.y);
|
||||
}
|
||||
}
|
||||
|
||||
LayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
|
||||
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
|
||||
|
||||
return ViewTransform(-translation,
|
||||
|
@ -581,7 +581,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
|
||||
const std::map<uint32_t, OpenTypeTable>::const_iterator it
|
||||
= table_map.find(Tag(table_parsers[i].tag));
|
||||
|
||||
ots::TableAction action = GetTableAction(it->first);
|
||||
ots::TableAction action = GetTableAction(Tag(table_parsers[i].tag));
|
||||
if (it == table_map.end()) {
|
||||
if (table_parsers[i].required && action == ots::TABLE_ACTION_SANITIZE) {
|
||||
return OTS_FAILURE_MSG_TAG("missing required table", table_parsers[i].tag);
|
||||
|
@ -95,10 +95,18 @@ class CPOWProxyHandler : public BaseProxyHandler
|
||||
|
||||
CPOWProxyHandler CPOWProxyHandler::singleton;
|
||||
|
||||
#define FORWARD(call, args) \
|
||||
JavaScriptParent *parent = ParentOf(proxy); \
|
||||
if (!parent->active()) { \
|
||||
JS_ReportError(cx, "cannot use a CPOW whose process is gone"); \
|
||||
return false; \
|
||||
} \
|
||||
return parent->call args;
|
||||
|
||||
bool
|
||||
CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
|
||||
{
|
||||
return ParentOf(proxy)->preventExtensions(cx, proxy);
|
||||
FORWARD(preventExtensions, (cx, proxy));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -117,7 +125,7 @@ bool
|
||||
CPOWProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc, unsigned flags)
|
||||
{
|
||||
return ParentOf(proxy)->getPropertyDescriptor(cx, proxy, id, desc, flags);
|
||||
FORWARD(getPropertyDescriptor, (cx, proxy, id, desc, flags));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -145,7 +153,7 @@ CPOWProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
|
||||
HandleId id, MutableHandle<JSPropertyDescriptor> desc,
|
||||
unsigned flags)
|
||||
{
|
||||
return ParentOf(proxy)->getOwnPropertyDescriptor(cx, proxy, id, desc, flags);
|
||||
FORWARD(getOwnPropertyDescriptor, (cx, proxy, id, desc, flags));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -172,7 +180,7 @@ bool
|
||||
CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
return ParentOf(proxy)->defineProperty(cx, proxy, id, desc);
|
||||
FORWARD(defineProperty, (cx, proxy, id, desc));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -199,7 +207,7 @@ JavaScriptParent::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
bool
|
||||
CPOWProxyHandler::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
return ParentOf(proxy)->getOwnPropertyNames(cx, proxy, props);
|
||||
FORWARD(getOwnPropertyNames, (cx, proxy, props));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -211,7 +219,7 @@ JavaScriptParent::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdV
|
||||
bool
|
||||
CPOWProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
return ParentOf(proxy)->delete_(cx, proxy, id, bp);
|
||||
FORWARD(delete_, (cx, proxy, id, bp));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -233,7 +241,7 @@ JavaScriptParent::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *
|
||||
bool
|
||||
CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
return ParentOf(proxy)->enumerate(cx, proxy, props);
|
||||
FORWARD(enumerate, (cx, proxy, props));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -245,7 +253,7 @@ JavaScriptParent::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &pro
|
||||
bool
|
||||
CPOWProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
return ParentOf(proxy)->has(cx, proxy, id, bp);
|
||||
FORWARD(has, (cx, proxy, id, bp));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -267,7 +275,7 @@ JavaScriptParent::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
bool
|
||||
CPOWProxyHandler::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
|
||||
{
|
||||
return ParentOf(proxy)->hasOwn(cx, proxy, id, bp);
|
||||
FORWARD(hasOwn, (cx, proxy, id, bp));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -290,7 +298,7 @@ bool
|
||||
CPOWProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp)
|
||||
{
|
||||
return ParentOf(proxy)->get(cx, proxy, receiver, id, vp);
|
||||
FORWARD(get, (cx, proxy, receiver, id, vp));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -319,7 +327,7 @@ bool
|
||||
CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp)
|
||||
{
|
||||
return ParentOf(proxy)->set(cx, proxy, receiver, id, strict, vp);
|
||||
FORWARD(set, (cx, proxy, receiver, id, strict, vp));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -351,7 +359,7 @@ JavaScriptParent::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject re
|
||||
bool
|
||||
CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
{
|
||||
return ParentOf(proxy)->keys(cx, proxy, props);
|
||||
FORWARD(keys, (cx, proxy, props));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -363,7 +371,7 @@ JavaScriptParent::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
|
||||
bool
|
||||
CPOWProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
|
||||
{
|
||||
return ParentOf(proxy)->isExtensible(cx, proxy, extensible);
|
||||
FORWARD(isExtensible, (cx, proxy, extensible));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -381,7 +389,7 @@ JavaScriptParent::isExtensible(JSContext *cx, HandleObject proxy, bool *extensib
|
||||
bool
|
||||
CPOWProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
{
|
||||
return ParentOf(proxy)->call(cx, proxy, args);
|
||||
FORWARD(call, (cx, proxy, args));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -456,7 +464,7 @@ JavaScriptParent::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
bool
|
||||
CPOWProxyHandler::objectClassIs(HandleObject proxy, js::ESClassValue classValue, JSContext *cx)
|
||||
{
|
||||
return ParentOf(proxy)->objectClassIs(cx, proxy, classValue);
|
||||
FORWARD(objectClassIs, (cx, proxy, classValue));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -476,7 +484,10 @@ JavaScriptParent::objectClassIs(JSContext *cx, HandleObject proxy, js::ESClassVa
|
||||
const char *
|
||||
CPOWProxyHandler::className(JSContext *cx, HandleObject proxy)
|
||||
{
|
||||
return ParentOf(proxy)->className(cx, proxy);
|
||||
JavaScriptParent *parent = ParentOf(proxy);
|
||||
if (!parent->active())
|
||||
return "<dead CPOW>";
|
||||
return parent->className(cx, proxy);
|
||||
}
|
||||
|
||||
const char *
|
||||
@ -486,7 +497,7 @@ JavaScriptParent::className(JSContext *cx, HandleObject proxy)
|
||||
|
||||
nsString name;
|
||||
if (!CallClassName(objId, &name))
|
||||
return nullptr;
|
||||
return "<error>";
|
||||
|
||||
return ToNewCString(name);
|
||||
}
|
||||
@ -634,10 +645,9 @@ JavaScriptParent::incref()
|
||||
}
|
||||
|
||||
void
|
||||
JavaScriptParent::destroyFromContent()
|
||||
JavaScriptParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
inactive_ = true;
|
||||
decref();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@ -647,9 +657,12 @@ JavaScriptParent::IsCPOW(JSObject *obj)
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
JavaScriptParent::InstanceOf(JSObject *obj, const nsID *id, bool *bp)
|
||||
JavaScriptParent::InstanceOf(JSObject *proxy, const nsID *id, bool *bp)
|
||||
{
|
||||
return ParentOf(obj)->instanceOf(obj, id, bp);
|
||||
JavaScriptParent *parent = ParentOf(proxy);
|
||||
if (!parent->active())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return parent->instanceOf(proxy, id, bp);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -671,24 +684,21 @@ JavaScriptParent::instanceOf(JSObject *obj, const nsID *id, bool *bp)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JavaScriptParent::DOMInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp)
|
||||
JavaScriptParent::DOMInstanceOf(JSContext *cx, JSObject *proxy, int prototypeID, int depth, bool *bp)
|
||||
{
|
||||
return ParentOf(obj)->domInstanceOf(obj, prototypeID, depth, bp);
|
||||
FORWARD(domInstanceOf, (cx, proxy, prototypeID, depth, bp));
|
||||
}
|
||||
|
||||
bool
|
||||
JavaScriptParent::domInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp)
|
||||
JavaScriptParent::domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp)
|
||||
{
|
||||
ObjectId objId = idOf(obj);
|
||||
|
||||
ReturnStatus status;
|
||||
if (!CallDOMInstanceOf(objId, prototypeID, depth, &status, bp))
|
||||
return false;
|
||||
return ipcfail(cx);
|
||||
|
||||
if (status.type() != ReturnStatus::TReturnSuccess)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return ok(cx, status);
|
||||
}
|
||||
|
||||
mozilla::ipc::IProtocol*
|
||||
|
@ -59,9 +59,12 @@ class JavaScriptParent
|
||||
bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
|
||||
const char* className(JSContext *cx, JS::HandleObject proxy);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
void decref();
|
||||
void incref();
|
||||
void destroyFromContent();
|
||||
|
||||
bool active() { return !inactive_; }
|
||||
|
||||
void drop(JSObject *obj);
|
||||
|
||||
@ -74,8 +77,8 @@ class JavaScriptParent
|
||||
* Check that |obj| is a DOM wrapper whose prototype chain contains
|
||||
* |prototypeID| at depth |depth|.
|
||||
*/
|
||||
static bool DOMInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp);
|
||||
bool domInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp);
|
||||
static bool DOMInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp);
|
||||
bool domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp);
|
||||
|
||||
mozilla::ipc::IProtocol*
|
||||
CloneProtocol(Channel* aChannel, ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
|
||||
|
@ -497,7 +497,7 @@ class NonLocalExitScope {
|
||||
StmtInfoBCE *stmt = bce->topStmt;
|
||||
while (1) {
|
||||
JS_ASSERT(stmt);
|
||||
if (stmt->isBlockScope) {
|
||||
if (stmt->isNestedScope) {
|
||||
openScopeIndex = stmt->blockScopeIndex;
|
||||
break;
|
||||
}
|
||||
@ -512,18 +512,12 @@ class NonLocalExitScope {
|
||||
bce->stackDepth = savedDepth;
|
||||
}
|
||||
|
||||
bool popScopeForNonLocalExit(StaticBlockObject &blockObj, uint32_t blockScopeIndex) {
|
||||
bool popScopeForNonLocalExit(uint32_t blockScopeIndex) {
|
||||
uint32_t scopeObjectIndex = bce->blockScopeList.findEnclosingScope(blockScopeIndex);
|
||||
uint32_t parent = openScopeIndex;
|
||||
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
if (!bce->blockScopeList.append(scopeObjectIndex, bce->offset(), parent))
|
||||
return false;
|
||||
if (blockObj.needsClone()) {
|
||||
if (Emit1(cx, bce, JSOP_POPBLOCKSCOPE) < 0)
|
||||
return false;
|
||||
}
|
||||
openScopeIndex = bce->blockScopeList.length() - 1;
|
||||
return true;
|
||||
}
|
||||
@ -550,10 +544,11 @@ NonLocalExitScope::prepareForNonLocalJump(StmtInfoBCE *toStmt)
|
||||
break;
|
||||
|
||||
case STMT_WITH:
|
||||
/* There's a With object on the stack that we need to pop. */
|
||||
FLUSH_POPS();
|
||||
if (Emit1(cx, bce, JSOP_LEAVEWITH) < 0)
|
||||
return false;
|
||||
JS_ASSERT(stmt->isNestedScope);
|
||||
if (!popScopeForNonLocalExit(stmt->blockScopeIndex))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case STMT_FOR_OF_LOOP:
|
||||
@ -578,9 +573,16 @@ NonLocalExitScope::prepareForNonLocalJump(StmtInfoBCE *toStmt)
|
||||
}
|
||||
|
||||
if (stmt->isBlockScope) {
|
||||
JS_ASSERT(stmt->isNestedScope);
|
||||
StaticBlockObject &blockObj = stmt->staticBlock();
|
||||
if (!popScopeForNonLocalExit(blockObj, stmt->blockScopeIndex))
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
return false;
|
||||
if (!popScopeForNonLocalExit(stmt->blockScopeIndex))
|
||||
return false;
|
||||
if (blockObj.needsClone()) {
|
||||
if (Emit1(cx, bce, JSOP_POPBLOCKSCOPE) < 0)
|
||||
return false;
|
||||
}
|
||||
npops += blockObj.slotCount();
|
||||
}
|
||||
}
|
||||
@ -728,6 +730,55 @@ ComputeAliasedSlots(ExclusiveContext *cx, BytecodeEmitter *bce, Handle<StaticBlo
|
||||
static bool
|
||||
EmitInternedObjectOp(ExclusiveContext *cx, uint32_t index, JSOp op, BytecodeEmitter *bce);
|
||||
|
||||
static bool
|
||||
EnterNestedScope(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *stmt, ObjectBox *objbox,
|
||||
StmtType stmtType)
|
||||
{
|
||||
Rooted<NestedScopeObject *> scopeObj(cx, &objbox->object->as<NestedScopeObject>());
|
||||
uint32_t scopeObjectIndex = bce->objectList.add(objbox);
|
||||
|
||||
switch (stmtType) {
|
||||
case STMT_BLOCK: {
|
||||
Rooted<StaticBlockObject *> blockObj(cx, &scopeObj->as<StaticBlockObject>());
|
||||
|
||||
if (!ComputeAliasedSlots(cx, bce, blockObj))
|
||||
return false;
|
||||
|
||||
if (blockObj->needsClone()) {
|
||||
if (!EmitInternedObjectOp(cx, scopeObjectIndex, JSOP_PUSHBLOCKSCOPE, bce))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STMT_WITH:
|
||||
JS_ASSERT(scopeObj->is<StaticWithObject>());
|
||||
if (!EmitInternedObjectOp(cx, scopeObjectIndex, JSOP_ENTERWITH, bce))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE();
|
||||
}
|
||||
|
||||
uint32_t parent = BlockScopeNote::NoBlockScopeIndex;
|
||||
if (bce->staticScope) {
|
||||
StmtInfoBCE *stmt = bce->topScopeStmt;
|
||||
for (; stmt->staticScope != bce->staticScope; stmt = stmt->down) {}
|
||||
parent = stmt->blockScopeIndex;
|
||||
}
|
||||
|
||||
stmt->blockScopeIndex = bce->blockScopeList.length();
|
||||
if (!bce->blockScopeList.append(scopeObjectIndex, bce->offset(), parent))
|
||||
return false;
|
||||
|
||||
PushStatementBCE(bce, stmt, stmtType, bce->offset());
|
||||
scopeObj->initEnclosingNestedScope(EnclosingStaticScope(bce));
|
||||
FinishPushNestedScope(bce, stmt, *scopeObj);
|
||||
JS_ASSERT(stmt->isNestedScope);
|
||||
stmt->isBlockScope = (stmtType == STMT_BLOCK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ~ Block Scopes ~
|
||||
//
|
||||
// A block scope is a region of a script with an additional set of named
|
||||
@ -771,50 +822,26 @@ EmitInternedObjectOp(ExclusiveContext *cx, uint32_t index, JSOp op, BytecodeEmit
|
||||
// for-in loops.
|
||||
//
|
||||
// Summary: Enter block scopes with EnterBlockScope. It will emit
|
||||
// PUSHBLOCKSCOPE if needed. Leave them with LeaveBlockScope, which will emit
|
||||
// PUSHBLOCKSCOPE if needed. Leave them with LeaveNestedScope, which will emit
|
||||
// DEBUGLEAVEBLOCK and may emit POPBLOCKSCOPE. Pass EnterBlockScope a fresh
|
||||
// StmtInfoBCE object, and pass that same object to the corresponding
|
||||
// LeaveBlockScope. Push locals before entering a scope, and pop them
|
||||
// LeaveNestedScope. Push locals before entering a scope, and pop them
|
||||
// afterwards. Brush your teeth, and clean behind your ears!
|
||||
//
|
||||
static bool
|
||||
EnterBlockScope(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *stmt, ObjectBox *objbox,
|
||||
unsigned extraSlots)
|
||||
{
|
||||
uint32_t parent = BlockScopeNote::NoBlockScopeIndex;
|
||||
if (bce->staticScope) {
|
||||
StmtInfoBCE *stmt = bce->topScopeStmt;
|
||||
for (; stmt->staticScope != bce->staticScope; stmt = stmt->down) {}
|
||||
parent = stmt->blockScopeIndex;
|
||||
}
|
||||
|
||||
Rooted<StaticBlockObject *> blockObj(cx, &objbox->object->as<StaticBlockObject>());
|
||||
|
||||
uint32_t scopeObjectIndex = bce->objectList.add(objbox);
|
||||
|
||||
// FIXME: Once bug 962599 lands, we won't care about the stack depth, so we
|
||||
// won't have extraSlots and thus invocations of EnterBlockScope can become
|
||||
// invocations of EnterNestedScope.
|
||||
int depth = bce->stackDepth - (blockObj->slotCount() + extraSlots);
|
||||
JS_ASSERT(depth >= 0);
|
||||
blockObj->setStackDepth(depth);
|
||||
|
||||
if (!ComputeAliasedSlots(cx, bce, blockObj))
|
||||
return false;
|
||||
|
||||
if (blockObj->needsClone()) {
|
||||
if (!EmitInternedObjectOp(cx, scopeObjectIndex, JSOP_PUSHBLOCKSCOPE, bce))
|
||||
return false;
|
||||
}
|
||||
|
||||
stmt->blockScopeIndex = bce->blockScopeList.length();
|
||||
if (!bce->blockScopeList.append(scopeObjectIndex, bce->offset(), parent))
|
||||
return false;
|
||||
|
||||
PushStatementBCE(bce, stmt, STMT_BLOCK, bce->offset());
|
||||
blockObj->initEnclosingNestedScope(EnclosingStaticScope(bce));
|
||||
FinishPushBlockScope(bce, stmt, *blockObj);
|
||||
|
||||
JS_ASSERT(stmt->isBlockScope);
|
||||
|
||||
return true;
|
||||
return EnterNestedScope(cx, bce, stmt, objbox, STMT_BLOCK);
|
||||
}
|
||||
|
||||
// Patches |breaks| and |continues| unless the top statement info record
|
||||
@ -835,10 +862,11 @@ PopStatementBCE(ExclusiveContext *cx, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
LeaveBlockScope(ExclusiveContext *cx, BytecodeEmitter *bce)
|
||||
LeaveNestedScope(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *stmt)
|
||||
{
|
||||
StmtInfoBCE *stmt = bce->topStmt;
|
||||
JS_ASSERT(stmt->isBlockScope);
|
||||
JS_ASSERT(stmt == bce->topStmt);
|
||||
JS_ASSERT(stmt->isNestedScope);
|
||||
JS_ASSERT(stmt->isBlockScope == !(stmt->type == STMT_WITH));
|
||||
uint32_t blockScopeIndex = stmt->blockScopeIndex;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -848,20 +876,18 @@ LeaveBlockScope(ExclusiveContext *cx, BytecodeEmitter *bce)
|
||||
NestedScopeObject *staticScope = &blockObjBox->object->as<NestedScopeObject>();
|
||||
JS_ASSERT(stmt->staticScope == staticScope);
|
||||
JS_ASSERT(staticScope == bce->staticScope);
|
||||
JS_ASSERT_IF(!stmt->isBlockScope, staticScope->is<StaticWithObject>());
|
||||
#endif
|
||||
|
||||
JS_ASSERT(bce->staticScope->is<StaticBlockObject>());
|
||||
bool blockOnChain = bce->staticScope->as<StaticBlockObject>().needsClone();
|
||||
|
||||
if (!PopStatementBCE(cx, bce))
|
||||
return false;
|
||||
|
||||
if (Emit1(cx, bce, JSOP_DEBUGLEAVEBLOCK) < 0)
|
||||
if (Emit1(cx, bce, stmt->isBlockScope ? JSOP_DEBUGLEAVEBLOCK : JSOP_LEAVEWITH) < 0)
|
||||
return false;
|
||||
|
||||
bce->blockScopeList.recordEnd(blockScopeIndex, bce->offset());
|
||||
|
||||
if (blockOnChain) {
|
||||
if (stmt->isBlockScope && stmt->staticScope->as<StaticBlockObject>().needsClone()) {
|
||||
if (Emit1(cx, bce, JSOP_POPBLOCKSCOPE) < 0)
|
||||
return false;
|
||||
}
|
||||
@ -1120,8 +1146,7 @@ EmitAliasedVarOp(ExclusiveContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *
|
||||
while (!b->containsVarAtDepth(depth)) {
|
||||
if (b->needsClone())
|
||||
skippedScopes++;
|
||||
b = b->enclosingBlock();
|
||||
JS_ASSERT(b);
|
||||
b = &b->enclosingNestedScope()->as<StaticBlockObject>();
|
||||
}
|
||||
if (!AssignHops(bce, pn, skippedScopes, &sc))
|
||||
return false;
|
||||
@ -1736,6 +1761,7 @@ CheckSideEffects(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool
|
||||
CheckSideEffects(cx, bce, pn->pn_kid3, answer);
|
||||
|
||||
case PN_BINARY:
|
||||
case PN_BINARY_OBJ:
|
||||
if (pn->isAssignment()) {
|
||||
/*
|
||||
* Assignment is presumed to be useful, even if the next operation
|
||||
@ -1888,7 +1914,7 @@ BytecodeEmitter::needsImplicitThis()
|
||||
} else {
|
||||
JSObject *scope = sc->asGlobalSharedContext()->scopeChain();
|
||||
while (scope) {
|
||||
if (scope->is<WithObject>())
|
||||
if (scope->is<DynamicWithObject>())
|
||||
return true;
|
||||
scope = scope->enclosingScope();
|
||||
}
|
||||
@ -2719,7 +2745,7 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
if (pn->pn_right->isKind(PNK_LEXICALSCOPE)) {
|
||||
if (!LeaveBlockScope(cx, bce))
|
||||
if (!LeaveNestedScope(cx, bce, &stmtInfo))
|
||||
return false;
|
||||
EMIT_UINT16_IMM_OP(JSOP_POPN, blockObj->slotCount());
|
||||
} else {
|
||||
@ -4269,7 +4295,7 @@ EmitLet(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pnLet)
|
||||
if (!EmitTree(cx, bce, letBody->pn_expr))
|
||||
return false;
|
||||
|
||||
if (!LeaveBlockScope(cx, bce))
|
||||
if (!LeaveNestedScope(cx, bce, &stmtInfo))
|
||||
return false;
|
||||
|
||||
JSOp leaveOp = letBody->getOp();
|
||||
@ -4305,7 +4331,7 @@ EmitLexicalScope(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (!EmitTree(cx, bce, pn->pn_expr))
|
||||
return false;
|
||||
|
||||
if (!LeaveBlockScope(cx, bce))
|
||||
if (!LeaveNestedScope(cx, bce, &stmtInfo))
|
||||
return false;
|
||||
|
||||
EMIT_UINT16_IMM_OP(JSOP_POPN, slots);
|
||||
@ -4319,15 +4345,13 @@ EmitWith(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
if (!EmitTree(cx, bce, pn->pn_left))
|
||||
return false;
|
||||
PushStatementBCE(bce, &stmtInfo, STMT_WITH, bce->offset());
|
||||
if (Emit1(cx, bce, JSOP_ENTERWITH) < 0)
|
||||
if (!EnterNestedScope(cx, bce, &stmtInfo, pn->pn_binary_obj, STMT_WITH))
|
||||
return false;
|
||||
|
||||
if (!EmitTree(cx, bce, pn->pn_right))
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_LEAVEWITH) < 0)
|
||||
if (!LeaveNestedScope(cx, bce, &stmtInfo))
|
||||
return false;
|
||||
return PopStatementBCE(cx, bce);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -4474,7 +4498,7 @@ EmitForOf(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
return false;
|
||||
|
||||
if (letDecl) {
|
||||
if (!LeaveBlockScope(cx, bce))
|
||||
if (!LeaveNestedScope(cx, bce, &letStmt))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4637,7 +4661,7 @@ EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
|
||||
return false;
|
||||
|
||||
if (letDecl) {
|
||||
if (!LeaveBlockScope(cx, bce))
|
||||
if (!LeaveNestedScope(cx, bce, &letStmt))
|
||||
return false;
|
||||
EMIT_UINT16_IMM_OP(JSOP_POPN, blockObjCount);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ ContainsVarOrConst(ParseNode *pn)
|
||||
return pnt;
|
||||
return ContainsVarOrConst(pn->pn_kid3);
|
||||
case PN_BINARY:
|
||||
case PN_BINARY_OBJ:
|
||||
/*
|
||||
* Limit recursion if pn is a binary expression, which can't contain a
|
||||
* var statement.
|
||||
@ -327,6 +328,7 @@ Fold(ExclusiveContext *cx, ParseNode **pnp,
|
||||
break;
|
||||
|
||||
case PN_BINARY:
|
||||
case PN_BINARY_OBJ:
|
||||
if (pn->isKind(PNK_OR) || pn->isKind(PNK_AND)) {
|
||||
// Propagate Condition context through logical connectives.
|
||||
SyntacticContext kidsc = SyntacticContext::Other;
|
||||
|
@ -385,8 +385,10 @@ class FullParseHandler
|
||||
return new_<UnaryNode>(PNK_RETURN, JSOP_RETURN, pos, expr);
|
||||
}
|
||||
|
||||
ParseNode *newWithStatement(uint32_t begin, ParseNode *expr, ParseNode *body) {
|
||||
return new_<BinaryNode>(PNK_WITH, JSOP_NOP, TokenPos(begin, body->pn_pos.end), expr, body);
|
||||
ParseNode *newWithStatement(uint32_t begin, ParseNode *expr, ParseNode *body,
|
||||
ObjectBox *staticWith) {
|
||||
return new_<BinaryObjNode>(PNK_WITH, JSOP_NOP, TokenPos(begin, body->pn_pos.end),
|
||||
expr, body, staticWith);
|
||||
}
|
||||
|
||||
ParseNode *newLabeledStatement(PropertyName *label, ParseNode *stmt, uint32_t begin) {
|
||||
|
@ -310,6 +310,7 @@ class NameResolver
|
||||
return false;
|
||||
break;
|
||||
case PN_BINARY:
|
||||
case PN_BINARY_OBJ:
|
||||
if (!resolve(cur->pn_left, prefix))
|
||||
return false;
|
||||
|
||||
|
@ -170,6 +170,7 @@ PushNodeChildren(ParseNode *pn, NodeStack *stack)
|
||||
stack->pushUnlessNull(pn->pn_kid3);
|
||||
break;
|
||||
case PN_BINARY:
|
||||
case PN_BINARY_OBJ:
|
||||
if (pn->pn_left != pn->pn_right)
|
||||
stack->pushUnlessNull(pn->pn_left);
|
||||
stack->pushUnlessNull(pn->pn_right);
|
||||
@ -382,6 +383,15 @@ Parser<FullParseHandler>::cloneParseTree(ParseNode *opn)
|
||||
pn->pn_iflags = opn->pn_iflags;
|
||||
break;
|
||||
|
||||
case PN_BINARY_OBJ:
|
||||
NULLCHECK(pn->pn_left = cloneParseTree(opn->pn_left));
|
||||
if (opn->pn_right != opn->pn_left)
|
||||
NULLCHECK(pn->pn_right = cloneParseTree(opn->pn_right));
|
||||
else
|
||||
pn->pn_right = pn->pn_left;
|
||||
pn->pn_binary_obj = opn->pn_binary_obj;
|
||||
break;
|
||||
|
||||
case PN_UNARY:
|
||||
NULLCHECK(pn->pn_kid = cloneParseTree(opn->pn_kid));
|
||||
break;
|
||||
@ -548,6 +558,9 @@ ParseNode::dump(int indent)
|
||||
case PN_BINARY:
|
||||
((BinaryNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_BINARY_OBJ:
|
||||
((BinaryObjNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_TERNARY:
|
||||
((TernaryNode *) this)->dump(indent);
|
||||
break;
|
||||
@ -618,6 +631,18 @@ BinaryNode::dump(int indent)
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
void
|
||||
BinaryObjNode::dump(int indent)
|
||||
{
|
||||
const char *name = parseNodeNames[getKind()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_left, indent);
|
||||
IndentNewLine(indent);
|
||||
DumpParseTree(pn_right, indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
void
|
||||
TernaryNode::dump(int indent)
|
||||
{
|
||||
|
@ -288,7 +288,7 @@ enum ParseNodeKind
|
||||
* pn_kid3: catch block statements
|
||||
* PNK_BREAK name pn_atom: label or null
|
||||
* PNK_CONTINUE name pn_atom: label or null
|
||||
* PNK_WITH binary pn_left: head expr, pn_right: body
|
||||
* PNK_WITH binary-obj pn_left: head expr; pn_right: body; pn_binary_obj: StaticWithObject
|
||||
* PNK_VAR, list pn_head: list of PNK_NAME or PNK_ASSIGN nodes
|
||||
* PNK_CONST each name node has either
|
||||
* pn_used: false
|
||||
@ -420,6 +420,7 @@ enum ParseNodeArity
|
||||
PN_NULLARY, /* 0 kids, only pn_atom/pn_dval/etc. */
|
||||
PN_UNARY, /* one kid, plus a couple of scalars */
|
||||
PN_BINARY, /* two kids, plus a couple of scalars */
|
||||
PN_BINARY_OBJ, /* two kids, plus an objbox */
|
||||
PN_TERNARY, /* three kids */
|
||||
PN_CODE, /* module or function definition node */
|
||||
PN_LIST, /* generic singly linked list */
|
||||
@ -516,7 +517,10 @@ class ParseNode
|
||||
struct { /* two kids if binary */
|
||||
ParseNode *left;
|
||||
ParseNode *right;
|
||||
unsigned iflags; /* JSITER_* flags for PNK_FOR node */
|
||||
union {
|
||||
unsigned iflags; /* JSITER_* flags for PNK_FOR node */
|
||||
ObjectBox *objbox; /* Only for PN_BINARY_OBJ */
|
||||
};
|
||||
} binary;
|
||||
struct { /* one kid if unary */
|
||||
ParseNode *kid;
|
||||
@ -570,6 +574,7 @@ class ParseNode
|
||||
#define pn_right pn_u.binary.right
|
||||
#define pn_pval pn_u.binary.pval
|
||||
#define pn_iflags pn_u.binary.iflags
|
||||
#define pn_binary_obj pn_u.binary.objbox
|
||||
#define pn_kid pn_u.unary.kid
|
||||
#define pn_prologue pn_u.unary.prologue
|
||||
#define pn_atom pn_u.name.atom
|
||||
@ -905,6 +910,30 @@ struct BinaryNode : public ParseNode
|
||||
#endif
|
||||
};
|
||||
|
||||
struct BinaryObjNode : public ParseNode
|
||||
{
|
||||
BinaryObjNode(ParseNodeKind kind, JSOp op, const TokenPos &pos, ParseNode *left, ParseNode *right,
|
||||
ObjectBox *objbox)
|
||||
: ParseNode(kind, op, PN_BINARY_OBJ, pos)
|
||||
{
|
||||
pn_left = left;
|
||||
pn_right = right;
|
||||
pn_binary_obj = objbox;
|
||||
}
|
||||
|
||||
static inline BinaryObjNode *create(ParseNodeKind kind, FullParseHandler *handler) {
|
||||
return (BinaryObjNode *) ParseNode::create(kind, PN_BINARY_OBJ, handler);
|
||||
}
|
||||
|
||||
static bool test(const ParseNode &node) {
|
||||
return node.isArity(PN_BINARY_OBJ);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct TernaryNode : public ParseNode
|
||||
{
|
||||
TernaryNode(ParseNodeKind kind, JSOp op, ParseNode *kid1, ParseNode *kid2, ParseNode *kid3)
|
||||
|
@ -535,7 +535,7 @@ FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunct
|
||||
//
|
||||
JSObject *scope = outerpc->sc->asGlobalSharedContext()->scopeChain();
|
||||
while (scope) {
|
||||
if (scope->is<WithObject>())
|
||||
if (scope->is<DynamicWithObject>())
|
||||
inWith = true;
|
||||
scope = scope->enclosingScope();
|
||||
}
|
||||
@ -2774,7 +2774,7 @@ static void
|
||||
PopStatementPC(TokenStream &ts, ParseContext<ParseHandler> *pc)
|
||||
{
|
||||
RootedNestedScopeObject scopeObj(ts.context(), pc->topStmt->staticScope);
|
||||
JS_ASSERT(!!scopeObj == (pc->topStmt->isBlockScope));
|
||||
JS_ASSERT(!!scopeObj == pc->topStmt->isNestedScope);
|
||||
|
||||
FinishPopStatement(pc);
|
||||
|
||||
@ -3196,7 +3196,8 @@ Parser<ParseHandler>::pushLexicalScope(HandleStaticBlockObject blockObj, StmtInf
|
||||
|
||||
PushStatementPC(pc, stmt, STMT_BLOCK);
|
||||
blockObj->initEnclosingNestedScopeFromParser(pc->staticScope);
|
||||
FinishPushBlockScope(pc, stmt, *blockObj.get());
|
||||
FinishPushNestedScope(pc, stmt, *blockObj.get());
|
||||
stmt->isBlockScope = true;
|
||||
|
||||
Node pn = handler.newLexicalScope(blockbox);
|
||||
if (!pn)
|
||||
@ -3593,7 +3594,7 @@ Parser<FullParseHandler>::letDeclaration()
|
||||
* lacks the SIF_SCOPE flag, it must be a try, catch, or finally
|
||||
* block.
|
||||
*/
|
||||
stmt->isBlockScope = true;
|
||||
stmt->isBlockScope = stmt->isNestedScope = true;
|
||||
stmt->downScope = pc->topScopeStmt;
|
||||
pc->topScopeStmt = stmt;
|
||||
|
||||
@ -4896,9 +4897,16 @@ Parser<FullParseHandler>::withStatement()
|
||||
|
||||
StmtInfoPC stmtInfo(context);
|
||||
PushStatementPC(pc, &stmtInfo, STMT_WITH);
|
||||
Rooted<StaticWithObject *> staticWith(context, StaticWithObject::create(context));
|
||||
if (!staticWith)
|
||||
return null();
|
||||
staticWith->initEnclosingNestedScopeFromParser(pc->staticScope);
|
||||
FinishPushNestedScope(pc, &stmtInfo, *staticWith);
|
||||
|
||||
Node innerBlock = statement();
|
||||
if (!innerBlock)
|
||||
return null();
|
||||
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
pc->sc->setBindingsAccessedDynamically();
|
||||
@ -4914,7 +4922,10 @@ Parser<FullParseHandler>::withStatement()
|
||||
handler.deoptimizeUsesWithin(lexdep, TokenPos(begin, pos().begin));
|
||||
}
|
||||
|
||||
return handler.newWithStatement(begin, objectExpr, innerBlock);
|
||||
ObjectBox *staticWithBox = newObjectBox(staticWith);
|
||||
if (!staticWithBox)
|
||||
return null();
|
||||
return handler.newWithStatement(begin, objectExpr, innerBlock, staticWithBox);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -5860,6 +5871,7 @@ CompExprTransplanter::transplant(ParseNode *pn)
|
||||
break;
|
||||
|
||||
case PN_BINARY:
|
||||
case PN_BINARY_OBJ:
|
||||
if (!transplant(pn->pn_left))
|
||||
return false;
|
||||
|
||||
|
@ -389,22 +389,30 @@ enum StmtType {
|
||||
// work with both types.
|
||||
|
||||
struct StmtInfoBase {
|
||||
uint16_t type; /* statement type */
|
||||
// Statement type (StmtType).
|
||||
uint16_t type;
|
||||
|
||||
/*
|
||||
* True if type is STMT_BLOCK, STMT_TRY, STMT_SWITCH, or
|
||||
* STMT_FINALLY and the block contains at least one let-declaration.
|
||||
*/
|
||||
// True if type is STMT_BLOCK, STMT_TRY, STMT_SWITCH, or STMT_FINALLY and
|
||||
// the block contains at least one let-declaration, or if type is
|
||||
// STMT_CATCH.
|
||||
bool isBlockScope:1;
|
||||
|
||||
/* for (let ...) induced block scope */
|
||||
// True if isBlockScope or type == STMT_WITH.
|
||||
bool isNestedScope:1;
|
||||
|
||||
// for (let ...) induced block scope
|
||||
bool isForLetBlock:1;
|
||||
|
||||
RootedAtom label; /* name of LABEL */
|
||||
Rooted<NestedScopeObject *> staticScope; /* scope object */
|
||||
// Block label.
|
||||
RootedAtom label;
|
||||
|
||||
// Compile-time scope chain node for this scope. Only set if
|
||||
// isNestedScope.
|
||||
Rooted<NestedScopeObject *> staticScope;
|
||||
|
||||
StmtInfoBase(ExclusiveContext *cx)
|
||||
: isBlockScope(false), isForLetBlock(false), label(cx), staticScope(cx)
|
||||
: isBlockScope(false), isNestedScope(false), isForLetBlock(false),
|
||||
label(cx), staticScope(cx)
|
||||
{}
|
||||
|
||||
bool maybeScope() const {
|
||||
@ -412,12 +420,12 @@ struct StmtInfoBase {
|
||||
}
|
||||
|
||||
bool linksScope() const {
|
||||
return (STMT_WITH <= type && type <= STMT_CATCH) || isBlockScope;
|
||||
return isNestedScope;
|
||||
}
|
||||
|
||||
StaticBlockObject& staticBlock() const {
|
||||
JS_ASSERT(isNestedScope);
|
||||
JS_ASSERT(isBlockScope);
|
||||
JS_ASSERT(staticScope);
|
||||
return staticScope->as<StaticBlockObject>();
|
||||
}
|
||||
|
||||
@ -437,6 +445,7 @@ PushStatement(ContextT *ct, typename ContextT::StmtInfo *stmt, StmtType type)
|
||||
{
|
||||
stmt->type = type;
|
||||
stmt->isBlockScope = false;
|
||||
stmt->isNestedScope = false;
|
||||
stmt->isForLetBlock = false;
|
||||
stmt->label = nullptr;
|
||||
stmt->staticScope = nullptr;
|
||||
@ -452,9 +461,9 @@ PushStatement(ContextT *ct, typename ContextT::StmtInfo *stmt, StmtType type)
|
||||
|
||||
template <class ContextT>
|
||||
void
|
||||
FinishPushBlockScope(ContextT *ct, typename ContextT::StmtInfo *stmt, NestedScopeObject &staticScope)
|
||||
FinishPushNestedScope(ContextT *ct, typename ContextT::StmtInfo *stmt, NestedScopeObject &staticScope)
|
||||
{
|
||||
stmt->isBlockScope = true;
|
||||
stmt->isNestedScope = true;
|
||||
stmt->downScope = ct->topScopeStmt;
|
||||
ct->topScopeStmt = stmt;
|
||||
ct->staticScope = &staticScope;
|
||||
@ -472,8 +481,10 @@ FinishPopStatement(ContextT *ct)
|
||||
ct->topStmt = stmt->down;
|
||||
if (stmt->linksScope()) {
|
||||
ct->topScopeStmt = stmt->downScope;
|
||||
if (stmt->isBlockScope)
|
||||
ct->staticScope = stmt->staticBlock().enclosingBlock();
|
||||
if (stmt->isNestedScope) {
|
||||
JS_ASSERT(stmt->staticScope);
|
||||
ct->staticScope = stmt->staticScope->enclosingNestedScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,8 @@ def main(argv):
|
||||
op.add_option('--localLib', dest='local_lib', action='store',
|
||||
type='string',
|
||||
help='The location of libraries to push -- preferably stripped')
|
||||
op.add_option('--repeat', type=int, default=1,
|
||||
help='Repeat tests the given number of times.')
|
||||
|
||||
options, args = op.parse_args(argv)
|
||||
if len(args) < 1:
|
||||
|
@ -98,3 +98,4 @@ assertEq(asmLink(asmCompileCached("g","ffis", USE_ASM + "var x=ffis.x|0; functio
|
||||
var i32 = new Int32Array(4096);
|
||||
i32[4] = 42;
|
||||
assertEq(asmLink(asmCompileCached("g","ffis","buf", USE_ASM + "var i32=new g.Int32Array(buf); function f(i) { i=i|0; return i32[i>>2]|0 } return f"), this, null, i32.buffer)(4*4), 42);
|
||||
assertEq(asmLink(asmCompileCached('glob', USE_ASM + 'var x=glob.Math.PI; function f() { return +x } return f'), this)(), Math.PI);
|
||||
|
@ -86,3 +86,17 @@ assertAsmTypeFail('glob', USE_ASM + 'var im=glob.Math.imul; function f(i) { i=i|
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var im=glob.Math.imul; function f(i) { i=i|0; i = im(i,i); } return f');
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var abs=glob.Math.abs; function f(i) { i=i|0; +abs(i|0); } return f');
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; abs(d)|0; } return f');
|
||||
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var tau=glob.Math.TAU; function f() {} return f');
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var pi=glob.Math.PI; function f() { return pi | 0 } return f');
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var pi=glob.Math.PI; function f() { return +pi() } return f');
|
||||
assertAsmTypeFail('glob', USE_ASM + 'var pi=glob.Math.PI; function f() { pi = +3; } return f');
|
||||
assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {});
|
||||
assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {Math: {}});
|
||||
assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {Math: {PI: Math.cos}});
|
||||
assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {Math: {PI: Math.SQRT2}});
|
||||
|
||||
for (var c of ['E', 'LN10', 'LN2', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT2']) {
|
||||
var f = asmLink(asmCompile('glob', USE_ASM + 'var x=glob.Math.' + c +'; function f() { return +x } return f'), this);
|
||||
assertEq(f(), eval('Math.' + c));
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
# include "vtune/VTuneWrapper.h"
|
||||
#endif
|
||||
|
||||
#include "jsmath.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsworkers.h"
|
||||
#include "prmjtime.h"
|
||||
@ -936,7 +937,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
FuncPtrTable,
|
||||
FFI,
|
||||
ArrayView,
|
||||
MathBuiltin
|
||||
MathBuiltinFunction
|
||||
};
|
||||
|
||||
private:
|
||||
@ -951,7 +952,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
uint32_t funcPtrTableIndex_;
|
||||
uint32_t ffiIndex_;
|
||||
ArrayBufferView::ViewType viewType_;
|
||||
AsmJSMathBuiltin mathBuiltin_;
|
||||
AsmJSMathBuiltinFunction mathBuiltinFunc_;
|
||||
} u;
|
||||
|
||||
friend class ModuleCompiler;
|
||||
@ -994,9 +995,9 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
JS_ASSERT(which_ == ArrayView);
|
||||
return u.viewType_;
|
||||
}
|
||||
AsmJSMathBuiltin mathBuiltin() const {
|
||||
JS_ASSERT(which_ == MathBuiltin);
|
||||
return u.mathBuiltin_;
|
||||
AsmJSMathBuiltinFunction mathBuiltinFunction() const {
|
||||
JS_ASSERT(which_ == MathBuiltinFunction);
|
||||
return u.mathBuiltinFunc_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1063,6 +1064,25 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
|
||||
typedef HashMap<ExitDescriptor, unsigned, ExitDescriptor> ExitMap;
|
||||
|
||||
struct MathBuiltin
|
||||
{
|
||||
enum Kind { Function, Constant };
|
||||
Kind kind;
|
||||
|
||||
union {
|
||||
double cst;
|
||||
AsmJSMathBuiltinFunction func;
|
||||
} u;
|
||||
|
||||
MathBuiltin() : kind(Kind(-1)) {}
|
||||
MathBuiltin(double cst) : kind(Constant) {
|
||||
u.cst = cst;
|
||||
}
|
||||
MathBuiltin(AsmJSMathBuiltinFunction func) : kind(Function) {
|
||||
u.func = func;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
struct SlowFunction
|
||||
{
|
||||
@ -1072,7 +1092,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
unsigned column;
|
||||
};
|
||||
|
||||
typedef HashMap<PropertyName*, AsmJSMathBuiltin> MathNameMap;
|
||||
typedef HashMap<PropertyName*, MathBuiltin> MathNameMap;
|
||||
typedef HashMap<PropertyName*, Global*> GlobalMap;
|
||||
typedef js::Vector<Func*> FuncVector;
|
||||
typedef js::Vector<AsmJSGlobalAccess> GlobalAccessVector;
|
||||
@ -1106,10 +1126,18 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
|
||||
DebugOnly<bool> finishedFunctionBodies_;
|
||||
|
||||
bool addStandardLibraryMathName(const char *name, AsmJSMathBuiltin builtin) {
|
||||
bool addStandardLibraryMathName(const char *name, AsmJSMathBuiltinFunction func) {
|
||||
JSAtom *atom = Atomize(cx_, name, strlen(name));
|
||||
if (!atom)
|
||||
return false;
|
||||
MathBuiltin builtin(func);
|
||||
return standardLibraryMathNames_.putNew(atom->asPropertyName(), builtin);
|
||||
}
|
||||
bool addStandardLibraryMathName(const char *name, double cst) {
|
||||
JSAtom *atom = Atomize(cx_, name, strlen(name));
|
||||
if (!atom)
|
||||
return false;
|
||||
MathBuiltin builtin(cst);
|
||||
return standardLibraryMathNames_.putNew(atom->asPropertyName(), builtin);
|
||||
}
|
||||
|
||||
@ -1175,7 +1203,15 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
!addStandardLibraryMathName("abs", AsmJSMathBuiltin_abs) ||
|
||||
!addStandardLibraryMathName("atan2", AsmJSMathBuiltin_atan2) ||
|
||||
!addStandardLibraryMathName("imul", AsmJSMathBuiltin_imul) ||
|
||||
!addStandardLibraryMathName("fround", AsmJSMathBuiltin_fround))
|
||||
!addStandardLibraryMathName("fround", AsmJSMathBuiltin_fround) ||
|
||||
!addStandardLibraryMathName("E", M_E) ||
|
||||
!addStandardLibraryMathName("LN10", M_LN10) ||
|
||||
!addStandardLibraryMathName("LN2", M_LN2) ||
|
||||
!addStandardLibraryMathName("LOG2E", M_LOG2E) ||
|
||||
!addStandardLibraryMathName("LOG10E", M_LOG10E) ||
|
||||
!addStandardLibraryMathName("PI", M_PI) ||
|
||||
!addStandardLibraryMathName("SQRT1_2", M_SQRT1_2) ||
|
||||
!addStandardLibraryMathName("SQRT2", M_SQRT2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -1289,7 +1325,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
FuncPtrTable &funcPtrTable(unsigned i) {
|
||||
return funcPtrTables_[i];
|
||||
}
|
||||
bool lookupStandardLibraryMathName(PropertyName *name, AsmJSMathBuiltin *mathBuiltin) const {
|
||||
bool lookupStandardLibraryMathName(PropertyName *name, MathBuiltin *mathBuiltin) const {
|
||||
if (MathNameMap::Ptr p = standardLibraryMathNames_.lookup(name)) {
|
||||
*mathBuiltin = p->value();
|
||||
return true;
|
||||
@ -1390,18 +1426,17 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
global->u.viewType_ = vt;
|
||||
return globals_.putNew(varName, global);
|
||||
}
|
||||
bool addMathBuiltin(PropertyName *varName, AsmJSMathBuiltin mathBuiltin, PropertyName *fieldName) {
|
||||
if (!module_->addMathBuiltin(mathBuiltin, fieldName))
|
||||
bool addMathBuiltinFunction(PropertyName *varName, AsmJSMathBuiltinFunction func, PropertyName *fieldName) {
|
||||
if (!module_->addMathBuiltinFunction(func, fieldName))
|
||||
return false;
|
||||
Global *global = moduleLifo_.new_<Global>(Global::MathBuiltin);
|
||||
Global *global = moduleLifo_.new_<Global>(Global::MathBuiltinFunction);
|
||||
if (!global)
|
||||
return false;
|
||||
global->u.mathBuiltin_ = mathBuiltin;
|
||||
global->u.mathBuiltinFunc_ = func;
|
||||
return globals_.putNew(varName, global);
|
||||
}
|
||||
bool addGlobalConstant(PropertyName *varName, double constant, PropertyName *fieldName) {
|
||||
if (!module_->addGlobalConstant(constant, fieldName))
|
||||
return false;
|
||||
private:
|
||||
bool addGlobalDoubleConstant(PropertyName *varName, double constant) {
|
||||
Global *global = moduleLifo_.new_<Global>(Global::ConstantLiteral);
|
||||
if (!global)
|
||||
return false;
|
||||
@ -1409,6 +1444,17 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
global->u.varOrConst.type_ = VarType::Double;
|
||||
return globals_.putNew(varName, global);
|
||||
}
|
||||
public:
|
||||
bool addMathBuiltinConstant(PropertyName *varName, double constant, PropertyName *fieldName) {
|
||||
if (!module_->addMathBuiltinConstant(constant, fieldName))
|
||||
return false;
|
||||
return addGlobalDoubleConstant(varName, constant);
|
||||
}
|
||||
bool addGlobalConstant(PropertyName *varName, double constant, PropertyName *fieldName) {
|
||||
if (!module_->addGlobalConstant(constant, fieldName))
|
||||
return false;
|
||||
return addGlobalDoubleConstant(varName, constant);
|
||||
}
|
||||
bool addExportedFunction(const Func *func, PropertyName *maybeFieldName) {
|
||||
AsmJSModule::ArgCoercionVector argCoercions;
|
||||
const VarTypeVector &args = func->sig().args();
|
||||
@ -1774,8 +1820,8 @@ IsFloatCoercion(ModuleCompiler &m, ParseNode *pn, ParseNode **coercedExpr)
|
||||
|
||||
const ModuleCompiler::Global *global = m.lookupGlobal(callee->name());
|
||||
if (!global ||
|
||||
global->which() != ModuleCompiler::Global::MathBuiltin ||
|
||||
global->mathBuiltin() != AsmJSMathBuiltin_fround)
|
||||
global->which() != ModuleCompiler::Global::MathBuiltinFunction ||
|
||||
global->mathBuiltinFunction() != AsmJSMathBuiltin_fround)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3104,11 +3150,19 @@ CheckGlobalDotImport(ModuleCompiler &m, PropertyName *varName, ParseNode *initNo
|
||||
if (!IsUseOfName(global, m.module().globalArgumentName()) || math != m.cx()->names().Math)
|
||||
return m.fail(base, "expecting global.Math");
|
||||
|
||||
AsmJSMathBuiltin mathBuiltin;
|
||||
ModuleCompiler::MathBuiltin mathBuiltin;
|
||||
if (!m.lookupStandardLibraryMathName(field, &mathBuiltin))
|
||||
return m.failName(initNode, "'%s' is not a standard Math builtin", field);
|
||||
|
||||
return m.addMathBuiltin(varName, mathBuiltin, field);
|
||||
switch (mathBuiltin.kind) {
|
||||
case ModuleCompiler::MathBuiltin::Function:
|
||||
return m.addMathBuiltinFunction(varName, mathBuiltin.u.func, field);
|
||||
case ModuleCompiler::MathBuiltin::Constant:
|
||||
return m.addMathBuiltinConstant(varName, mathBuiltin.u.cst, field);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
MOZ_ASSUME_UNREACHABLE("unexpected or uninitialized math builtin type");
|
||||
}
|
||||
|
||||
if (IsUseOfName(base, m.module().globalArgumentName())) {
|
||||
@ -3366,7 +3420,7 @@ CheckVarRef(FunctionCompiler &f, ParseNode *varRef, MDefinition **def, Type *typ
|
||||
break;
|
||||
case ModuleCompiler::Global::Function:
|
||||
case ModuleCompiler::Global::FFI:
|
||||
case ModuleCompiler::Global::MathBuiltin:
|
||||
case ModuleCompiler::Global::MathBuiltinFunction:
|
||||
case ModuleCompiler::Global::FuncPtrTable:
|
||||
case ModuleCompiler::Global::ArrayView:
|
||||
return f.failName(varRef, "'%s' may not be accessed by ordinary expressions", name);
|
||||
@ -4021,12 +4075,12 @@ CheckIsMaybeFloat(FunctionCompiler &f, ParseNode *argNode, Type type)
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin mathBuiltin,
|
||||
CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltinFunction func,
|
||||
RetType retType, MDefinition **def, Type *type)
|
||||
{
|
||||
unsigned arity = 0;
|
||||
AsmJSImmKind doubleCallee, floatCallee;
|
||||
switch (mathBuiltin) {
|
||||
switch (func) {
|
||||
case AsmJSMathBuiltin_imul: return CheckMathIMul(f, callNode, retType, def, type);
|
||||
case AsmJSMathBuiltin_abs: return CheckMathAbs(f, callNode, retType, def, type);
|
||||
case AsmJSMathBuiltin_sqrt: return CheckMathSqrt(f, callNode, retType, def, type);
|
||||
@ -4043,7 +4097,7 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin
|
||||
case AsmJSMathBuiltin_log: arity = 1; doubleCallee = AsmJSImm_LogD; floatCallee = AsmJSImm_LogF; break;
|
||||
case AsmJSMathBuiltin_pow: arity = 2; doubleCallee = AsmJSImm_PowD; floatCallee = AsmJSImm_Invalid; break;
|
||||
case AsmJSMathBuiltin_atan2: arity = 2; doubleCallee = AsmJSImm_ATan2D; floatCallee = AsmJSImm_Invalid; break;
|
||||
default: MOZ_ASSUME_UNREACHABLE("unexpected mathBuiltin");
|
||||
default: MOZ_ASSUME_UNREACHABLE("unexpected mathBuiltin function");
|
||||
}
|
||||
|
||||
if (retType == RetType::Float && floatCallee == AsmJSImm_Invalid)
|
||||
@ -4088,8 +4142,8 @@ CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **d
|
||||
switch (global->which()) {
|
||||
case ModuleCompiler::Global::FFI:
|
||||
return CheckFFICall(f, call, global->ffiIndex(), retType, def, type);
|
||||
case ModuleCompiler::Global::MathBuiltin:
|
||||
return CheckMathBuiltinCall(f, call, global->mathBuiltin(), retType, def, type);
|
||||
case ModuleCompiler::Global::MathBuiltinFunction:
|
||||
return CheckMathBuiltinCall(f, call, global->mathBuiltinFunction(), retType, def, type);
|
||||
case ModuleCompiler::Global::ConstantLiteral:
|
||||
case ModuleCompiler::Global::ConstantImport:
|
||||
case ModuleCompiler::Global::Variable:
|
||||
|
@ -143,7 +143,7 @@ ValidateArrayView(JSContext *cx, AsmJSModule::Global &global, HandleValue global
|
||||
}
|
||||
|
||||
static bool
|
||||
ValidateMathBuiltin(JSContext *cx, AsmJSModule::Global &global, HandleValue globalVal)
|
||||
ValidateMathBuiltinFunction(JSContext *cx, AsmJSModule::Global &global, HandleValue globalVal)
|
||||
{
|
||||
RootedValue v(cx);
|
||||
if (!GetDataProperty(cx, globalVal, cx->names().Math, &v))
|
||||
@ -153,7 +153,7 @@ ValidateMathBuiltin(JSContext *cx, AsmJSModule::Global &global, HandleValue glob
|
||||
return false;
|
||||
|
||||
Native native = nullptr;
|
||||
switch (global.mathBuiltin()) {
|
||||
switch (global.mathBuiltinFunction()) {
|
||||
case AsmJSMathBuiltin_sin: native = math_sin; break;
|
||||
case AsmJSMathBuiltin_cos: native = math_cos; break;
|
||||
case AsmJSMathBuiltin_tan: native = math_tan; break;
|
||||
@ -173,21 +173,26 @@ ValidateMathBuiltin(JSContext *cx, AsmJSModule::Global &global, HandleValue glob
|
||||
}
|
||||
|
||||
if (!IsNativeFunction(v, native))
|
||||
return LinkFail(cx, "bad Math.* builtin");
|
||||
return LinkFail(cx, "bad Math.* builtin function");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ValidateGlobalConstant(JSContext *cx, AsmJSModule::Global &global, HandleValue globalVal)
|
||||
ValidateConstant(JSContext *cx, AsmJSModule::Global &global, HandleValue globalVal)
|
||||
{
|
||||
RootedPropertyName field(cx, global.constantName());
|
||||
RootedValue v(cx);
|
||||
if (!GetDataProperty(cx, globalVal, field, &v))
|
||||
return false;
|
||||
RootedValue v(cx, globalVal);
|
||||
|
||||
if (global.constantKind() == AsmJSModule::Global::MathConstant) {
|
||||
if (!GetDataProperty(cx, v, cx->names().Math, &v))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetDataProperty(cx, v, field, &v))
|
||||
return false;
|
||||
if (!v.isNumber())
|
||||
return LinkFail(cx, "global constant value needs to be a number");
|
||||
return LinkFail(cx, "math / global constant value needs to be a number");
|
||||
|
||||
// NaN != NaN
|
||||
if (IsNaN(global.constantValue())) {
|
||||
@ -269,12 +274,12 @@ DynamicallyLinkModule(JSContext *cx, CallArgs args, AsmJSModule &module)
|
||||
if (!ValidateArrayView(cx, global, globalVal, bufferVal))
|
||||
return false;
|
||||
break;
|
||||
case AsmJSModule::Global::MathBuiltin:
|
||||
if (!ValidateMathBuiltin(cx, global, globalVal))
|
||||
case AsmJSModule::Global::MathBuiltinFunction:
|
||||
if (!ValidateMathBuiltinFunction(cx, global, globalVal))
|
||||
return false;
|
||||
break;
|
||||
case AsmJSModule::Global::Constant:
|
||||
if (!ValidateGlobalConstant(cx, global, globalVal))
|
||||
if (!ValidateConstant(cx, global, globalVal))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ enum AsmJSCoercion
|
||||
};
|
||||
|
||||
// The asm.js spec recognizes this set of builtin Math functions.
|
||||
enum AsmJSMathBuiltin
|
||||
enum AsmJSMathBuiltinFunction
|
||||
{
|
||||
AsmJSMathBuiltin_sin, AsmJSMathBuiltin_cos, AsmJSMathBuiltin_tan,
|
||||
AsmJSMathBuiltin_asin, AsmJSMathBuiltin_acos, AsmJSMathBuiltin_atan,
|
||||
@ -97,8 +97,9 @@ class AsmJSModule
|
||||
class Global
|
||||
{
|
||||
public:
|
||||
enum Which { Variable, FFI, ArrayView, MathBuiltin, Constant };
|
||||
enum Which { Variable, FFI, ArrayView, MathBuiltinFunction, Constant };
|
||||
enum VarInitKind { InitConstant, InitImport };
|
||||
enum ConstantKind { GlobalConstant, MathConstant };
|
||||
|
||||
private:
|
||||
struct Pod {
|
||||
@ -114,8 +115,11 @@ class AsmJSModule
|
||||
} var;
|
||||
uint32_t ffiIndex_;
|
||||
ArrayBufferView::ViewType viewType_;
|
||||
AsmJSMathBuiltin mathBuiltin_;
|
||||
double constantValue_;
|
||||
AsmJSMathBuiltinFunction mathBuiltinFunc_;
|
||||
struct {
|
||||
ConstantKind kind_;
|
||||
double value_;
|
||||
} constant;
|
||||
} u;
|
||||
} pod;
|
||||
PropertyName *name_;
|
||||
@ -179,20 +183,24 @@ class AsmJSModule
|
||||
return pod.u.viewType_;
|
||||
}
|
||||
PropertyName *mathName() const {
|
||||
JS_ASSERT(pod.which_ == MathBuiltin);
|
||||
JS_ASSERT(pod.which_ == MathBuiltinFunction);
|
||||
return name_;
|
||||
}
|
||||
AsmJSMathBuiltin mathBuiltin() const {
|
||||
JS_ASSERT(pod.which_ == MathBuiltin);
|
||||
return pod.u.mathBuiltin_;
|
||||
AsmJSMathBuiltinFunction mathBuiltinFunction() const {
|
||||
JS_ASSERT(pod.which_ == MathBuiltinFunction);
|
||||
return pod.u.mathBuiltinFunc_;
|
||||
}
|
||||
PropertyName *constantName() const {
|
||||
JS_ASSERT(pod.which_ == Constant);
|
||||
return name_;
|
||||
}
|
||||
ConstantKind constantKind() const {
|
||||
JS_ASSERT(pod.which_ == Constant);
|
||||
return pod.u.constant.kind_;
|
||||
}
|
||||
double constantValue() const {
|
||||
JS_ASSERT(pod.which_ == Constant);
|
||||
return pod.u.constantValue_;
|
||||
return pod.u.constant.value_;
|
||||
}
|
||||
|
||||
size_t serializedSize() const;
|
||||
@ -488,14 +496,21 @@ class AsmJSModule
|
||||
g.pod.u.viewType_ = vt;
|
||||
return globals_.append(g);
|
||||
}
|
||||
bool addMathBuiltin(AsmJSMathBuiltin mathBuiltin, PropertyName *field) {
|
||||
Global g(Global::MathBuiltin, field);
|
||||
g.pod.u.mathBuiltin_ = mathBuiltin;
|
||||
bool addMathBuiltinFunction(AsmJSMathBuiltinFunction func, PropertyName *field) {
|
||||
Global g(Global::MathBuiltinFunction, field);
|
||||
g.pod.u.mathBuiltinFunc_ = func;
|
||||
return globals_.append(g);
|
||||
}
|
||||
bool addMathBuiltinConstant(double value, PropertyName *field) {
|
||||
Global g(Global::Constant, field);
|
||||
g.pod.u.constant.value_ = value;
|
||||
g.pod.u.constant.kind_ = Global::MathConstant;
|
||||
return globals_.append(g);
|
||||
}
|
||||
bool addGlobalConstant(double value, PropertyName *name) {
|
||||
Global g(Global::Constant, name);
|
||||
g.pod.u.constantValue_ = value;
|
||||
g.pod.u.constant.value_ = value;
|
||||
g.pod.u.constant.kind_ = Global::GlobalConstant;
|
||||
return globals_.append(g);
|
||||
}
|
||||
bool addFuncPtrTable(unsigned numElems, uint32_t *globalDataOffset) {
|
||||
|
@ -2650,6 +2650,43 @@ BaselineCompiler::emit_JSOP_DEBUGLEAVEBLOCK()
|
||||
return callVM(DebugLeaveBlockInfo);
|
||||
}
|
||||
|
||||
typedef bool (*EnterWithFn)(JSContext *, BaselineFrame *, HandleValue, Handle<StaticWithObject *>);
|
||||
static const VMFunction EnterWithInfo = FunctionInfo<EnterWithFn>(jit::EnterWith);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_ENTERWITH()
|
||||
{
|
||||
StaticWithObject &withObj = script->getObject(pc)->as<StaticWithObject>();
|
||||
|
||||
// Pop "with" object to R0.
|
||||
frame.popRegsAndSync(1);
|
||||
|
||||
// Call a stub to push the object onto the scope chain.
|
||||
prepareVMCall();
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R1.scratchReg());
|
||||
|
||||
pushArg(ImmGCPtr(&withObj));
|
||||
pushArg(R0);
|
||||
pushArg(R1.scratchReg());
|
||||
|
||||
return callVM(EnterWithInfo);
|
||||
}
|
||||
|
||||
typedef bool (*LeaveWithFn)(JSContext *, BaselineFrame *);
|
||||
static const VMFunction LeaveWithInfo = FunctionInfo<LeaveWithFn>(jit::LeaveWith);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_LEAVEWITH()
|
||||
{
|
||||
// Call a stub to pop the with object from the scope chain.
|
||||
prepareVMCall();
|
||||
|
||||
masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
|
||||
pushArg(R0.scratchReg());
|
||||
|
||||
return callVM(LeaveWithInfo);
|
||||
}
|
||||
|
||||
typedef bool (*GetAndClearExceptionFn)(JSContext *, MutableHandleValue);
|
||||
static const VMFunction GetAndClearExceptionInfo =
|
||||
FunctionInfo<GetAndClearExceptionFn>(GetAndClearException);
|
||||
|
@ -27,6 +27,8 @@ namespace jit {
|
||||
_(JSOP_POP) \
|
||||
_(JSOP_POPN) \
|
||||
_(JSOP_POPNV) \
|
||||
_(JSOP_ENTERWITH) \
|
||||
_(JSOP_LEAVEWITH) \
|
||||
_(JSOP_DUP) \
|
||||
_(JSOP_DUP2) \
|
||||
_(JSOP_SWAP) \
|
||||
|
@ -33,6 +33,16 @@ BaselineFrame::popOffScopeChain()
|
||||
scopeChain_ = &scopeChain_->as<ScopeObject>().enclosingScope();
|
||||
}
|
||||
|
||||
inline void
|
||||
BaselineFrame::popWith(JSContext *cx)
|
||||
{
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
|
||||
DebugScopes::onPopWith(this);
|
||||
|
||||
JS_ASSERT(scopeChain()->is<DynamicWithObject>());
|
||||
popOffScopeChain();
|
||||
}
|
||||
|
||||
inline bool
|
||||
BaselineFrame::pushBlock(JSContext *cx, Handle<StaticBlockObject *> block)
|
||||
{
|
||||
|
@ -110,6 +110,8 @@ class BaselineFrame
|
||||
inline void pushOnScopeChain(ScopeObject &scope);
|
||||
inline void popOffScopeChain();
|
||||
|
||||
inline void popWith(JSContext *cx);
|
||||
|
||||
CalleeToken calleeToken() const {
|
||||
uint8_t *pointer = (uint8_t *)this + Size() + offsetOfCalleeToken();
|
||||
return *(CalleeToken *)pointer;
|
||||
|
@ -5663,7 +5663,7 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!scopeChain->is<ScopeObject>() || scopeChain->is<WithObject>())
|
||||
if (!scopeChain->is<ScopeObject>() || scopeChain->is<DynamicWithObject>())
|
||||
return true;
|
||||
|
||||
// Check for an 'own' property on the scope. There is no need to
|
||||
|
@ -347,6 +347,9 @@ JitRuntime::handleAccessViolation(JSRuntime *rt, void *faultingAddress)
|
||||
// to SEGV while still inside the signal handler, and the process will terminate.
|
||||
JSRuntime::AutoLockForOperationCallback lock(rt);
|
||||
|
||||
// Ion code in the runtime faulted after it was made inaccessible. Reset
|
||||
// the code privileges and patch all loop backedges to perform an interrupt
|
||||
// check instead.
|
||||
ensureIonCodeAccessible(rt);
|
||||
return true;
|
||||
}
|
||||
@ -362,18 +365,14 @@ JitRuntime::ensureIonCodeAccessible(JSRuntime *rt)
|
||||
JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
|
||||
#endif
|
||||
|
||||
if (!ionCodeProtected_)
|
||||
return;
|
||||
|
||||
// Ion code in the runtime faulted after it was made inaccessible. Reset
|
||||
// the code privileges and patch all loop backedges to perform an interrupt
|
||||
// check instead.
|
||||
ionAlloc_->toggleAllCodeAsAccessible(true);
|
||||
ionCodeProtected_ = false;
|
||||
if (ionCodeProtected_) {
|
||||
ionAlloc_->toggleAllCodeAsAccessible(true);
|
||||
ionCodeProtected_ = false;
|
||||
}
|
||||
|
||||
if (rt->interrupt) {
|
||||
// The interrupt handler needs to be invoked by this thread, but we
|
||||
// are inside a signal handler and have no idea what is above us on the
|
||||
// The interrupt handler needs to be invoked by this thread, but we may
|
||||
// be inside a signal handler and have no idea what is above us on the
|
||||
// stack (probably we are executing Ion code at an arbitrary point, but
|
||||
// we could be elsewhere, say repatching a jump for an IonCache).
|
||||
// Patch all backedges in the runtime so they will invoke the interrupt
|
||||
|
@ -512,7 +512,7 @@ HandleExceptionBaseline(JSContext *cx, const IonFrameIterator &frame, ResumeFrom
|
||||
|
||||
// Unwind scope chain (pop block objects).
|
||||
if (cx->isExceptionPending())
|
||||
UnwindScope(cx, si, tn->stackDepth);
|
||||
UnwindScope(cx, si, script->main() + tn->start);
|
||||
|
||||
// Compute base pointer and stack pointer.
|
||||
rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
|
||||
|
@ -735,7 +735,7 @@ DebugEpilogue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool ok)
|
||||
{
|
||||
// Unwind scope chain to stack depth 0.
|
||||
ScopeIter si(frame, pc, cx);
|
||||
UnwindScope(cx, si, 0);
|
||||
UnwindScope(cx, si, frame->script()->main());
|
||||
|
||||
// If ScriptDebugEpilogue returns |true| we have to return the frame's
|
||||
// return value. If it returns |false|, the debugger threw an exception.
|
||||
@ -931,6 +931,19 @@ DebugLeaveBlock(JSContext *cx, BaselineFrame *frame, jsbytecode *pc)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EnterWith(JSContext *cx, BaselineFrame *frame, HandleValue val, Handle<StaticWithObject *> templ)
|
||||
{
|
||||
return EnterWithOperation(cx, frame, val, templ);
|
||||
}
|
||||
|
||||
bool
|
||||
LeaveWith(JSContext *cx, BaselineFrame *frame)
|
||||
{
|
||||
frame->popWith(cx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InitBaselineFrameForOsr(BaselineFrame *frame, StackFrame *interpFrame, uint32_t numStackValues)
|
||||
{
|
||||
|
@ -16,6 +16,7 @@ namespace js {
|
||||
|
||||
class DeclEnvObject;
|
||||
class ForkJoinContext;
|
||||
class StaticWithObject;
|
||||
|
||||
namespace jit {
|
||||
|
||||
@ -273,6 +274,7 @@ template <> struct TypeToDataType<HandleObject> { static const DataType result =
|
||||
template <> struct TypeToDataType<HandleString> { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<HandlePropertyName> { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<HandleFunction> { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<StaticWithObject *> > { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<StaticBlockObject *> > { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<HandleScript> { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<HandleValue> { static const DataType result = Type_Handle; };
|
||||
@ -298,6 +300,9 @@ template <> struct TypeToArgProperties<HandlePropertyName> {
|
||||
template <> struct TypeToArgProperties<HandleFunction> {
|
||||
static const uint32_t result = TypeToArgProperties<JSFunction *>::result | VMFunction::ByRef;
|
||||
};
|
||||
template <> struct TypeToArgProperties<Handle<StaticWithObject *> > {
|
||||
static const uint32_t result = TypeToArgProperties<StaticWithObject *>::result | VMFunction::ByRef;
|
||||
};
|
||||
template <> struct TypeToArgProperties<Handle<StaticBlockObject *> > {
|
||||
static const uint32_t result = TypeToArgProperties<StaticBlockObject *>::result | VMFunction::ByRef;
|
||||
};
|
||||
@ -652,6 +657,10 @@ JSObject *InitRestParameter(JSContext *cx, uint32_t length, Value *rest, HandleO
|
||||
bool HandleDebugTrap(JSContext *cx, BaselineFrame *frame, uint8_t *retAddr, bool *mustReturn);
|
||||
bool OnDebuggerStatement(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustReturn);
|
||||
|
||||
bool EnterWith(JSContext *cx, BaselineFrame *frame, HandleValue val,
|
||||
Handle<StaticWithObject *> templ);
|
||||
bool LeaveWith(JSContext *cx, BaselineFrame *frame);
|
||||
|
||||
bool PushBlockScope(JSContext *cx, BaselineFrame *frame, Handle<StaticBlockObject *> block);
|
||||
bool PopBlockScope(JSContext *cx, BaselineFrame *frame);
|
||||
bool DebugLeaveBlock(JSContext *cx, BaselineFrame *frame, jsbytecode *pc);
|
||||
|
@ -3777,7 +3777,9 @@ MacroAssemblerARMCompat::callWithABI(void *fun, MoveOp::Type result)
|
||||
case MoveOp::FLOAT32: passedArgTypes_ |= ArgType_Float32; break;
|
||||
default: MOZ_ASSUME_UNREACHABLE("Invalid return type");
|
||||
}
|
||||
#ifdef DEBUG
|
||||
AssertValidABIFunctionType(passedArgTypes_);
|
||||
#endif
|
||||
ABIFunctionType type = ABIFunctionType(passedArgTypes_);
|
||||
fun = Simulator::RedirectNativeFunction(fun, type);
|
||||
#endif
|
||||
|
@ -3679,24 +3679,30 @@ JSScript::makeTypes(JSContext *cx)
|
||||
|
||||
unsigned count = TypeScript::NumTypeSets(this);
|
||||
|
||||
types = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(StackTypeSet) * count));
|
||||
if (!types) {
|
||||
TypeScript *typeScript = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(StackTypeSet) * count));
|
||||
if (!typeScript) {
|
||||
cx->compartment()->types.setPendingNukeTypes(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
new(types) TypeScript();
|
||||
new(typeScript) TypeScript();
|
||||
|
||||
TypeSet *typeArray = types->typeArray();
|
||||
TypeSet *typeArray = typeScript->typeArray();
|
||||
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
new (&typeArray[i]) StackTypeSet();
|
||||
|
||||
{
|
||||
AutoLockForCompilation lock(cx);
|
||||
types = typeScript;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (unsigned i = 0; i < nTypeSets(); i++)
|
||||
for (unsigned i = 0; i < nTypeSets(); i++) {
|
||||
InferSpew(ISpewOps, "typeSet: %sT%p%s bytecode%u #%u",
|
||||
InferSpewColor(&typeArray[i]), &typeArray[i], InferSpewColorReset(),
|
||||
i, id());
|
||||
}
|
||||
TypeSet *thisTypes = TypeScript::ThisTypes(this);
|
||||
InferSpew(ISpewOps, "typeSet: %sT%p%s this #%u",
|
||||
InferSpewColor(thisTypes), thisTypes, InferSpewColorReset(),
|
||||
|
@ -597,7 +597,7 @@ TypeScript::BytecodeTypes(JSScript *script, jsbytecode *pc, uint32_t *hint, TYPE
|
||||
uint32_t offset = script->pcToOffset(pc);
|
||||
|
||||
// See if this pc is the next typeset opcode after the last one looked up.
|
||||
if (bytecodeMap[*hint + 1] == offset && (*hint + 1) < script->nTypeSets()) {
|
||||
if ((*hint + 1) < script->nTypeSets() && bytecodeMap[*hint + 1] == offset) {
|
||||
(*hint)++;
|
||||
return typeArray + *hint;
|
||||
}
|
||||
|
@ -49,28 +49,6 @@ using mozilla::SpecificNaN;
|
||||
using JS::ToNumber;
|
||||
using JS::GenericNaN;
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.7182818284590452354
|
||||
#endif
|
||||
#ifndef M_LOG2E
|
||||
#define M_LOG2E 1.4426950408889634074
|
||||
#endif
|
||||
#ifndef M_LOG10E
|
||||
#define M_LOG10E 0.43429448190325182765
|
||||
#endif
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_LN10
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#endif
|
||||
#ifndef M_SQRT2
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#endif
|
||||
#ifndef M_SQRT1_2
|
||||
#define M_SQRT1_2 0.70710678118654752440
|
||||
#endif
|
||||
|
||||
static const JSConstDoubleSpec math_constants[] = {
|
||||
{M_E, "E", 0, {0,0,0}},
|
||||
{M_LOG2E, "LOG2E", 0, {0,0,0}},
|
||||
|
@ -11,6 +11,31 @@
|
||||
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#ifndef M_E
|
||||
# define M_E 2.7182818284590452354
|
||||
#endif
|
||||
#ifndef M_LOG2E
|
||||
# define M_LOG2E 1.4426950408889634074
|
||||
#endif
|
||||
#ifndef M_LOG10E
|
||||
# define M_LOG10E 0.43429448190325182765
|
||||
#endif
|
||||
#ifndef M_LN2
|
||||
# define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_LN10
|
||||
# define M_LN10 2.30258509299404568402
|
||||
#endif
|
||||
#ifndef M_SQRT2
|
||||
# define M_SQRT2 1.41421356237309504880
|
||||
#endif
|
||||
#ifndef M_SQRT1_2
|
||||
# define M_SQRT1_2 0.70710678118654752440
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
typedef double (*UnaryFunType)(double);
|
||||
|
@ -5952,4 +5952,3 @@ JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::Objects
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,8 +433,9 @@ SaveSharedScriptData(ExclusiveContext *, Handle<JSScript *>, SharedScriptData *,
|
||||
|
||||
enum XDRClassKind {
|
||||
CK_BlockObject = 0,
|
||||
CK_JSFunction = 1,
|
||||
CK_JSObject = 2
|
||||
CK_WithObject = 1,
|
||||
CK_JSFunction = 2,
|
||||
CK_JSObject = 3
|
||||
};
|
||||
|
||||
template<XDRMode mode>
|
||||
@ -766,6 +767,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
JSObject *obj = *objp;
|
||||
if (obj->is<BlockObject>())
|
||||
classk = CK_BlockObject;
|
||||
else if (obj->is<StaticWithObject>())
|
||||
classk = CK_WithObject;
|
||||
else if (obj->is<JSFunction>())
|
||||
classk = CK_JSFunction;
|
||||
else if (obj->is<JSObject>() || obj->is<ArrayObject>())
|
||||
@ -778,32 +781,40 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
return false;
|
||||
|
||||
switch (classk) {
|
||||
case CK_BlockObject: {
|
||||
case CK_BlockObject:
|
||||
case CK_WithObject: {
|
||||
/* Code the nested block's enclosing scope. */
|
||||
uint32_t blockEnclosingScopeIndex = 0;
|
||||
uint32_t enclosingStaticScopeIndex = 0;
|
||||
if (mode == XDR_ENCODE) {
|
||||
NestedScopeObject &scope = (*objp)->as<NestedScopeObject>();
|
||||
if (NestedScopeObject *enclosing = scope.enclosingNestedScope())
|
||||
blockEnclosingScopeIndex = FindScopeObjectIndex(script, *enclosing);
|
||||
enclosingStaticScopeIndex = FindScopeObjectIndex(script, *enclosing);
|
||||
else
|
||||
blockEnclosingScopeIndex = UINT32_MAX;
|
||||
enclosingStaticScopeIndex = UINT32_MAX;
|
||||
}
|
||||
if (!xdr->codeUint32(&blockEnclosingScopeIndex))
|
||||
if (!xdr->codeUint32(&enclosingStaticScopeIndex))
|
||||
return false;
|
||||
Rooted<JSObject*> blockEnclosingScope(cx);
|
||||
Rooted<JSObject*> enclosingStaticScope(cx);
|
||||
if (mode == XDR_DECODE) {
|
||||
if (blockEnclosingScopeIndex != UINT32_MAX) {
|
||||
JS_ASSERT(blockEnclosingScopeIndex < i);
|
||||
blockEnclosingScope = script->objects()->vector[blockEnclosingScopeIndex];
|
||||
if (enclosingStaticScopeIndex != UINT32_MAX) {
|
||||
JS_ASSERT(enclosingStaticScopeIndex < i);
|
||||
enclosingStaticScope = script->objects()->vector[enclosingStaticScopeIndex];
|
||||
} else {
|
||||
blockEnclosingScope = fun;
|
||||
enclosingStaticScope = fun;
|
||||
}
|
||||
}
|
||||
|
||||
Rooted<StaticBlockObject*> tmp(cx, static_cast<StaticBlockObject *>(objp->get()));
|
||||
if (!XDRStaticBlockObject(xdr, blockEnclosingScope, tmp.address()))
|
||||
return false;
|
||||
*objp = tmp;
|
||||
if (classk == CK_BlockObject) {
|
||||
Rooted<StaticBlockObject*> tmp(cx, static_cast<StaticBlockObject *>(objp->get()));
|
||||
if (!XDRStaticBlockObject(xdr, enclosingStaticScope, tmp.address()))
|
||||
return false;
|
||||
*objp = tmp;
|
||||
} else {
|
||||
Rooted<StaticWithObject*> tmp(cx, static_cast<StaticWithObject *>(objp->get()));
|
||||
if (!XDRStaticWithObject(xdr, enclosingStaticScope, tmp.address()))
|
||||
return false;
|
||||
*objp = tmp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,8 @@ class ReferenceFinder {
|
||||
/* Certain classes of object are for internal use only. */
|
||||
if (object->is<BlockObject>() ||
|
||||
object->is<CallObject>() ||
|
||||
object->is<WithObject>() ||
|
||||
object->is<StaticWithObject>() ||
|
||||
object->is<DynamicWithObject>() ||
|
||||
object->is<DeclEnvObject>()) {
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
@ -416,10 +416,11 @@ def run_tests_parallel(tests, prefix, options):
|
||||
|
||||
# This queue will contain the return value of the function
|
||||
# processing the test results.
|
||||
total_tests = len(tests) * options.repeat
|
||||
result_process_return_queue = queue_manager.Queue()
|
||||
result_process = Process(target=process_test_results_parallel,
|
||||
args=(async_test_result_queue, result_process_return_queue,
|
||||
notify_queue, len(tests), options))
|
||||
notify_queue, total_tests, options))
|
||||
result_process.start()
|
||||
|
||||
# Ensure that a SIGTERM is handled the same way as SIGINT
|
||||
@ -441,15 +442,16 @@ def run_tests_parallel(tests, prefix, options):
|
||||
try:
|
||||
testcnt = 0
|
||||
# Initially start as many jobs as allowed to run parallel
|
||||
for i in range(min(options.max_jobs,len(tests))):
|
||||
for i in range(min(options.max_jobs,total_tests)):
|
||||
notify_queue.put(True)
|
||||
|
||||
# For every item in the notify queue, start one new worker.
|
||||
# Every completed worker adds a new item to this queue.
|
||||
while notify_queue.get():
|
||||
if (testcnt < len(tests)):
|
||||
if (testcnt < total_tests):
|
||||
# Start one new worker
|
||||
worker_process = Process(target=wrap_parallel_run_test, args=(tests[testcnt], prefix, async_test_result_queue, options))
|
||||
test = tests[testcnt % len(tests)]
|
||||
worker_process = Process(target=wrap_parallel_run_test, args=(test, prefix, async_test_result_queue, options))
|
||||
worker_processes.append(worker_process)
|
||||
worker_process.start()
|
||||
testcnt += 1
|
||||
@ -604,17 +606,19 @@ def process_test_results(results, num_tests, options):
|
||||
return print_test_summary(num_tests, failures, complete, doing, options)
|
||||
|
||||
def get_serial_results(tests, prefix, options):
|
||||
for test in tests:
|
||||
yield run_test(test, prefix, options)
|
||||
for i in xrange(0, options.repeat):
|
||||
for test in tests:
|
||||
yield run_test(test, prefix, options)
|
||||
|
||||
def run_tests(tests, prefix, options):
|
||||
gen = get_serial_results(tests, prefix, options)
|
||||
ok = process_test_results(gen, len(tests), options)
|
||||
ok = process_test_results(gen, len(tests) * options.repeat, options)
|
||||
return ok
|
||||
|
||||
def get_remote_results(tests, device, prefix, options):
|
||||
for test in tests:
|
||||
yield run_test_remote(test, device, prefix, options)
|
||||
for i in xrange(0, options.repeat):
|
||||
for test in tests:
|
||||
yield run_test_remote(test, device, prefix, options)
|
||||
|
||||
def push_libs(options, device):
|
||||
# This saves considerable time in pushing unnecessary libraries
|
||||
@ -668,7 +672,7 @@ def run_tests_remote(tests, prefix, options):
|
||||
|
||||
# Run all tests.
|
||||
gen = get_remote_results(tests, dm, prefix, options)
|
||||
ok = process_test_results(gen, len(tests), options)
|
||||
ok = process_test_results(gen, len(tests) * options.repeat, options)
|
||||
return ok
|
||||
|
||||
def parse_jitflags(options):
|
||||
|
@ -5591,7 +5591,8 @@ IsDeclarative(Env *env)
|
||||
static bool
|
||||
IsWith(Env *env)
|
||||
{
|
||||
return env->is<DebugScopeObject>() && env->as<DebugScopeObject>().scope().is<WithObject>();
|
||||
return env->is<DebugScopeObject>() &&
|
||||
env->as<DebugScopeObject>().scope().is<DynamicWithObject>();
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -5641,7 +5642,7 @@ DebuggerEnv_getObject(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
JSObject *obj;
|
||||
if (IsWith(env)) {
|
||||
obj = &env->as<DebugScopeObject>().scope().as<WithObject>().object();
|
||||
obj = &env->as<DebugScopeObject>().scope().as<DynamicWithObject>().object();
|
||||
} else {
|
||||
obj = env;
|
||||
JS_ASSERT(!obj->is<DebugScopeObject>());
|
||||
|
@ -183,8 +183,8 @@ FetchName(JSContext *cx, HandleObject obj, HandleObject obj2, HandlePropertyName
|
||||
return false;
|
||||
} else {
|
||||
Rooted<JSObject*> normalized(cx, obj);
|
||||
if (normalized->getClass() == &WithObject::class_ && !shape->hasDefaultGetter())
|
||||
normalized = &normalized->as<WithObject>().object();
|
||||
if (normalized->is<DynamicWithObject>() && !shape->hasDefaultGetter())
|
||||
normalized = &normalized->as<DynamicWithObject>().object();
|
||||
if (shape->isDataDescriptor() && shape->hasDefaultGetter()) {
|
||||
/* Fast path for Object instance properties. */
|
||||
JS_ASSERT(shape->hasSlot());
|
||||
|
@ -831,9 +831,11 @@ js::TypeOfValue(const Value &v)
|
||||
* Enter the new with scope using an object at sp[-1] and associate the depth
|
||||
* of the with block with sp + stackIndex.
|
||||
*/
|
||||
static bool
|
||||
EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, uint32_t stackDepth)
|
||||
bool
|
||||
js::EnterWithOperation(JSContext *cx, AbstractFramePtr frame, HandleValue val,
|
||||
HandleObject staticWith)
|
||||
{
|
||||
JS_ASSERT(staticWith->is<StaticWithObject>());
|
||||
RootedObject obj(cx);
|
||||
if (val.isObject()) {
|
||||
obj = &val.toObject();
|
||||
@ -844,7 +846,7 @@ EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, uint32_t stack
|
||||
}
|
||||
|
||||
RootedObject scopeChain(cx, frame.scopeChain());
|
||||
WithObject *withobj = WithObject::create(cx, obj, scopeChain, stackDepth);
|
||||
DynamicWithObject *withobj = DynamicWithObject::create(cx, obj, scopeChain, staticWith);
|
||||
if (!withobj)
|
||||
return false;
|
||||
|
||||
@ -852,23 +854,25 @@ EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, uint32_t stack
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Unwind block and scope chains to match the given depth. */
|
||||
// Unwind scope chain and iterator to match the static scope corresponding to
|
||||
// the given bytecode position.
|
||||
void
|
||||
js::UnwindScope(JSContext *cx, ScopeIter &si, uint32_t stackDepth)
|
||||
js::UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc)
|
||||
{
|
||||
for (; !si.done(); ++si) {
|
||||
if (si.done())
|
||||
return;
|
||||
|
||||
Rooted<NestedScopeObject *> staticScope(cx, si.frame().script()->getStaticScope(pc));
|
||||
|
||||
for (; si.staticScope() != staticScope; ++si) {
|
||||
switch (si.type()) {
|
||||
case ScopeIter::Block:
|
||||
if (si.staticBlock().stackDepth() < stackDepth)
|
||||
return;
|
||||
if (cx->compartment()->debugMode())
|
||||
DebugScopes::onPopBlock(cx, si);
|
||||
if (si.staticBlock().needsClone())
|
||||
si.frame().popBlock(cx);
|
||||
break;
|
||||
case ScopeIter::With:
|
||||
if (si.scope().as<WithObject>().stackDepth() < stackDepth)
|
||||
return;
|
||||
si.frame().popWith(cx);
|
||||
break;
|
||||
case ScopeIter::Call:
|
||||
@ -881,7 +885,7 @@ js::UnwindScope(JSContext *cx, ScopeIter &si, uint32_t stackDepth)
|
||||
static void
|
||||
ForcedReturn(JSContext *cx, ScopeIter &si, FrameRegs ®s)
|
||||
{
|
||||
UnwindScope(cx, si, 0);
|
||||
UnwindScope(cx, si, regs.fp()->script()->main());
|
||||
regs.setToEndOfScript();
|
||||
}
|
||||
|
||||
@ -1006,7 +1010,7 @@ HandleError(JSContext *cx, FrameRegs ®s)
|
||||
for (TryNoteIter tni(cx, regs); !tni.done(); ++tni) {
|
||||
JSTryNote *tn = *tni;
|
||||
|
||||
UnwindScope(cx, si, tn->stackDepth);
|
||||
UnwindScope(cx, si, regs.fp()->script()->main() + tn->start);
|
||||
|
||||
/*
|
||||
* Set pc to the first bytecode after the the try note to point
|
||||
@ -1727,13 +1731,6 @@ END_CASE(JSOP_POP)
|
||||
CASE(JSOP_POPN)
|
||||
JS_ASSERT(GET_UINT16(REGS.pc) <= REGS.stackDepth());
|
||||
REGS.sp -= GET_UINT16(REGS.pc);
|
||||
#ifdef DEBUG
|
||||
if (NestedScopeObject *scope = script->getStaticScope(REGS.pc + JSOP_POPN_LENGTH)) {
|
||||
JS_ASSERT(scope->is<StaticBlockObject>());
|
||||
StaticBlockObject &blockObj = scope->as<StaticBlockObject>();
|
||||
JS_ASSERT(REGS.stackDepth() >= blockObj.stackDepth() + blockObj.slotCount());
|
||||
}
|
||||
#endif
|
||||
END_CASE(JSOP_POPN)
|
||||
|
||||
CASE(JSOP_POPNV)
|
||||
@ -1742,13 +1739,6 @@ CASE(JSOP_POPNV)
|
||||
Value val = REGS.sp[-1];
|
||||
REGS.sp -= GET_UINT16(REGS.pc);
|
||||
REGS.sp[-1] = val;
|
||||
#ifdef DEBUG
|
||||
if (NestedScopeObject *scope = script->getStaticScope(REGS.pc + JSOP_POPNV_LENGTH)) {
|
||||
JS_ASSERT(scope->is<StaticBlockObject>());
|
||||
StaticBlockObject &blockObj = scope->as<StaticBlockObject>();
|
||||
JS_ASSERT(REGS.stackDepth() >= blockObj.stackDepth() + blockObj.slotCount());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
END_CASE(JSOP_POPNV)
|
||||
|
||||
@ -1759,28 +1749,18 @@ END_CASE(JSOP_SETRVAL)
|
||||
CASE(JSOP_ENTERWITH)
|
||||
{
|
||||
RootedValue &val = rootValue0;
|
||||
RootedObject &staticWith = rootObject0;
|
||||
val = REGS.sp[-1];
|
||||
REGS.sp--;
|
||||
staticWith = script->getObject(REGS.pc);
|
||||
|
||||
if (!EnterWith(cx, REGS.fp(), val, REGS.stackDepth() - 1))
|
||||
if (!EnterWithOperation(cx, REGS.fp(), val, staticWith))
|
||||
goto error;
|
||||
|
||||
/*
|
||||
* We must ensure that different "with" blocks have different stack depth
|
||||
* associated with them. This allows the try handler search to properly
|
||||
* recover the scope chain. Thus we must keep the stack at least at the
|
||||
* current level.
|
||||
*
|
||||
* We set sp[-1] to the current "with" object to help asserting the
|
||||
* enter/leave balance in [leavewith].
|
||||
*/
|
||||
REGS.sp[-1].setObject(*REGS.fp()->scopeChain());
|
||||
}
|
||||
END_CASE(JSOP_ENTERWITH)
|
||||
|
||||
CASE(JSOP_LEAVEWITH)
|
||||
JS_ASSERT(REGS.sp[-1].toObject() == *REGS.fp()->scopeChain());
|
||||
REGS.fp()->popWith(cx);
|
||||
REGS.sp--;
|
||||
END_CASE(JSOP_LEAVEWITH)
|
||||
|
||||
CASE(JSOP_RETURN)
|
||||
|
@ -318,9 +318,10 @@ TypeOfValue(const Value &v);
|
||||
extern bool
|
||||
HasInstance(JSContext *cx, HandleObject obj, HandleValue v, bool *bp);
|
||||
|
||||
/* Unwind block and scope chains to match the given depth. */
|
||||
// Unwind scope chain and iterator to match the static scope corresponding to
|
||||
// the given bytecode position.
|
||||
extern void
|
||||
UnwindScope(JSContext *cx, ScopeIter &si, uint32_t stackDepth);
|
||||
UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc);
|
||||
|
||||
/*
|
||||
* Unwind for an uncatchable exception. This means not running finalizers, etc;
|
||||
@ -450,6 +451,10 @@ bool
|
||||
InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandlePropertyName name,
|
||||
HandleObject val);
|
||||
|
||||
bool
|
||||
EnterWithOperation(JSContext *cx, AbstractFramePtr frame, HandleValue val, HandleObject staticWith);
|
||||
|
||||
|
||||
bool
|
||||
InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandleValue idval,
|
||||
HandleObject val);
|
||||
|
@ -49,8 +49,8 @@
|
||||
/* Long-standing JavaScript bytecodes. */ \
|
||||
macro(JSOP_UNDEFINED, 1, js_undefined_str, "", 1, 0, 1, JOF_BYTE) \
|
||||
macro(JSOP_UNUSED2, 2, "unused2", NULL, 1, 1, 0, JOF_BYTE) \
|
||||
macro(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, JOF_BYTE) \
|
||||
macro(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, JOF_BYTE) \
|
||||
macro(JSOP_ENTERWITH, 3, "enterwith", NULL, 5, 1, 0, JOF_OBJECT) \
|
||||
macro(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 0, 0, JOF_BYTE) \
|
||||
macro(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, JOF_BYTE) \
|
||||
macro(JSOP_GOTO, 6, "goto", NULL, 5, 0, 0, JOF_JUMP) \
|
||||
macro(JSOP_IFEQ, 7, "ifeq", NULL, 5, 1, 0, JOF_JUMP|JOF_DETECTING) \
|
||||
|
@ -56,7 +56,7 @@ StaticScopeIter<allowGC>::operator++(int)
|
||||
} else {
|
||||
onNamedLambda = true;
|
||||
}
|
||||
JS_ASSERT_IF(obj, obj->template is<StaticBlockObject>() || obj->template is<JSFunction>());
|
||||
JS_ASSERT_IF(obj, obj->template is<NestedScopeObject>() || obj->template is<JSFunction>());
|
||||
JS_ASSERT_IF(onNamedLambda, obj->template is<JSFunction>());
|
||||
}
|
||||
|
||||
@ -66,7 +66,8 @@ StaticScopeIter<allowGC>::hasDynamicScopeObject() const
|
||||
{
|
||||
return obj->template is<StaticBlockObject>()
|
||||
? obj->template as<StaticBlockObject>().needsClone()
|
||||
: obj->template as<JSFunction>().isHeavyweight();
|
||||
: (obj->template is<StaticWithObject>() ||
|
||||
obj->template as<JSFunction>().isHeavyweight());
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
@ -88,7 +89,9 @@ StaticScopeIter<allowGC>::type() const
|
||||
{
|
||||
if (onNamedLambda)
|
||||
return NAMED_LAMBDA;
|
||||
return obj->template is<StaticBlockObject>() ? BLOCK : FUNCTION;
|
||||
return obj->template is<StaticBlockObject>()
|
||||
? BLOCK
|
||||
: (obj->template is<StaticWithObject>() ? WITH : FUNCTION);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
@ -99,6 +102,14 @@ StaticScopeIter<allowGC>::block() const
|
||||
return obj->template as<StaticBlockObject>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline StaticWithObject &
|
||||
StaticScopeIter<allowGC>::staticWith() const
|
||||
{
|
||||
JS_ASSERT(type() == WITH);
|
||||
return obj->template as<StaticWithObject>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline JSScript *
|
||||
StaticScopeIter<allowGC>::funScript() const
|
||||
|
@ -346,14 +346,72 @@ DeclEnvObject::create(JSContext *cx, HandleObject enclosing, HandleFunction call
|
||||
return &obj->as<DeclEnvObject>();
|
||||
}
|
||||
|
||||
WithObject *
|
||||
WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, uint32_t depth)
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRStaticWithObject(XDRState<mode> *xdr, HandleObject enclosingScope, StaticWithObject **objp)
|
||||
{
|
||||
RootedTypeObject type(cx, cx->getNewType(&class_, proto.get()));
|
||||
if (mode == XDR_DECODE) {
|
||||
JSContext *cx = xdr->cx();
|
||||
Rooted<StaticWithObject*> obj(cx, StaticWithObject::create(cx));
|
||||
if (!obj)
|
||||
return false;
|
||||
obj->initEnclosingNestedScope(enclosingScope);
|
||||
*objp = obj;
|
||||
}
|
||||
// For encoding, there is nothing to do. The only information that is
|
||||
// encoded by a StaticWithObject is its presence on the scope chain, and the
|
||||
// script XDR handler already takes care of that.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template bool
|
||||
js::XDRStaticWithObject(XDRState<XDR_ENCODE> *, HandleObject, StaticWithObject **);
|
||||
|
||||
template bool
|
||||
js::XDRStaticWithObject(XDRState<XDR_DECODE> *, HandleObject, StaticWithObject **);
|
||||
|
||||
StaticWithObject *
|
||||
StaticWithObject::create(ExclusiveContext *cx)
|
||||
{
|
||||
RootedTypeObject type(cx, cx->getNewType(&class_, nullptr));
|
||||
if (!type)
|
||||
return nullptr;
|
||||
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &class_, TaggedProto(proto),
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &class_, TaggedProto(nullptr),
|
||||
nullptr, nullptr, FINALIZE_KIND));
|
||||
if (!shape)
|
||||
return nullptr;
|
||||
|
||||
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, type));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
return &obj->as<StaticWithObject>();
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
CloneStaticWithObject(JSContext *cx, HandleObject enclosingScope, Handle<StaticWithObject*> srcWith)
|
||||
{
|
||||
Rooted<StaticWithObject*> clone(cx, StaticWithObject::create(cx));
|
||||
if (!clone)
|
||||
return nullptr;
|
||||
|
||||
clone->initEnclosingNestedScope(enclosingScope);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
DynamicWithObject *
|
||||
DynamicWithObject::create(JSContext *cx, HandleObject object, HandleObject enclosing,
|
||||
HandleObject staticWith)
|
||||
{
|
||||
JS_ASSERT(staticWith->is<StaticWithObject>());
|
||||
RootedTypeObject type(cx, cx->getNewType(&class_, staticWith.get()));
|
||||
if (!type)
|
||||
return nullptr;
|
||||
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &class_, TaggedProto(staticWith),
|
||||
&enclosing->global(), nullptr,
|
||||
FINALIZE_KIND));
|
||||
if (!shape)
|
||||
@ -363,23 +421,22 @@ WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, ui
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
obj->as<ScopeObject>().setEnclosingScope(enclosing);
|
||||
obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(depth));
|
||||
|
||||
JSObject *thisp = JSObject::thisObject(cx, proto);
|
||||
JSObject *thisp = JSObject::thisObject(cx, object);
|
||||
if (!thisp)
|
||||
return nullptr;
|
||||
|
||||
obj->as<ScopeObject>().setEnclosingScope(enclosing);
|
||||
obj->setFixedSlot(OBJECT_SLOT, ObjectValue(*object));
|
||||
obj->setFixedSlot(THIS_SLOT, ObjectValue(*thisp));
|
||||
|
||||
return &obj->as<WithObject>();
|
||||
return &obj->as<DynamicWithObject>();
|
||||
}
|
||||
|
||||
static bool
|
||||
with_LookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::lookupGeneric(cx, actual, id, objp, propp);
|
||||
}
|
||||
|
||||
@ -413,7 +470,7 @@ static bool
|
||||
with_GetGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::getGeneric(cx, actual, actual, id, vp);
|
||||
}
|
||||
|
||||
@ -447,7 +504,7 @@ static bool
|
||||
with_SetGeneric(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, bool strict)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::setGeneric(cx, actual, actual, id, vp, strict);
|
||||
}
|
||||
|
||||
@ -455,7 +512,7 @@ static bool
|
||||
with_SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
MutableHandleValue vp, bool strict)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::setProperty(cx, actual, actual, name, vp, strict);
|
||||
}
|
||||
|
||||
@ -463,7 +520,7 @@ static bool
|
||||
with_SetElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
MutableHandleValue vp, bool strict)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::setElement(cx, actual, actual, index, vp, strict);
|
||||
}
|
||||
|
||||
@ -471,21 +528,21 @@ static bool
|
||||
with_SetSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
|
||||
MutableHandleValue vp, bool strict)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::setSpecial(cx, actual, actual, sid, vp, strict);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::getGenericAttributes(cx, actual, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::setGenericAttributes(cx, actual, id, attrsp);
|
||||
}
|
||||
|
||||
@ -493,7 +550,7 @@ static bool
|
||||
with_DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
bool *succeeded)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::deleteProperty(cx, actual, name, succeeded);
|
||||
}
|
||||
|
||||
@ -501,7 +558,7 @@ static bool
|
||||
with_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
bool *succeeded)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::deleteElement(cx, actual, index, succeeded);
|
||||
}
|
||||
|
||||
@ -509,27 +566,33 @@ static bool
|
||||
with_DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
|
||||
bool *succeeded)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return JSObject::deleteSpecial(cx, actual, sid, succeeded);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_Enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
|
||||
MutableHandleValue statep, MutableHandleId idp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::enumerate(cx, actual, enum_op, statep, idp);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
with_ThisObject(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return &obj->as<WithObject>().withThis();
|
||||
return &obj->as<DynamicWithObject>().withThis();
|
||||
}
|
||||
|
||||
const Class WithObject::class_ = {
|
||||
const Class StaticWithObject::class_ = {
|
||||
"WithTemplate",
|
||||
JSCLASS_IMPLEMENTS_BARRIERS |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(StaticWithObject::RESERVED_SLOTS) |
|
||||
JSCLASS_IS_ANONYMOUS,
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_DeletePropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
const Class DynamicWithObject::class_ = {
|
||||
"With",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(WithObject::RESERVED_SLOTS) |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(DynamicWithObject::RESERVED_SLOTS) |
|
||||
JSCLASS_IS_ANONYMOUS,
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_DeletePropertyStub, /* delProperty */
|
||||
@ -569,7 +632,7 @@ const Class WithObject::class_ = {
|
||||
with_DeleteSpecial,
|
||||
nullptr, nullptr, /* watch/unwatch */
|
||||
nullptr, /* slice */
|
||||
with_Enumerate,
|
||||
nullptr, /* enumerate (native enumeration of target doesn't work) */
|
||||
with_ThisObject,
|
||||
}
|
||||
};
|
||||
@ -845,9 +908,13 @@ CloneStaticBlockObject(JSContext *cx, HandleObject enclosingScope, Handle<Static
|
||||
JSObject *
|
||||
js::CloneNestedScopeObject(JSContext *cx, HandleObject enclosingScope, Handle<NestedScopeObject*> srcBlock)
|
||||
{
|
||||
JS_ASSERT(srcBlock->is<StaticBlockObject>());
|
||||
Rooted<StaticBlockObject *> blockObj(cx, &srcBlock->as<StaticBlockObject>());
|
||||
return CloneStaticBlockObject(cx, enclosingScope, blockObj);
|
||||
if (srcBlock->is<StaticBlockObject>()) {
|
||||
Rooted<StaticBlockObject *> blockObj(cx, &srcBlock->as<StaticBlockObject>());
|
||||
return CloneStaticBlockObject(cx, enclosingScope, blockObj);
|
||||
} else {
|
||||
Rooted<StaticWithObject *> withObj(cx, &srcBlock->as<StaticWithObject>());
|
||||
return CloneStaticWithObject(cx, enclosingScope, withObj);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -929,14 +996,17 @@ ScopeIter::operator++()
|
||||
frame_ = NullFramePtr();
|
||||
break;
|
||||
case Block:
|
||||
staticScope_ = staticScope_->as<StaticBlockObject>().enclosingBlock();
|
||||
JS_ASSERT(staticScope_ && staticScope_->is<StaticBlockObject>());
|
||||
staticScope_ = staticScope_->as<StaticBlockObject>().enclosingNestedScope();
|
||||
if (hasScopeObject_)
|
||||
cur_ = &cur_->as<ClonedBlockObject>().enclosingScope();
|
||||
settle();
|
||||
break;
|
||||
case With:
|
||||
JS_ASSERT(staticScope_ && staticScope_->is<StaticWithObject>());
|
||||
JS_ASSERT(hasScopeObject_);
|
||||
cur_ = &cur_->as<WithObject>().enclosingScope();
|
||||
staticScope_ = staticScope_->as<StaticWithObject>().enclosingNestedScope();
|
||||
cur_ = &cur_->as<DynamicWithObject>().enclosingScope();
|
||||
settle();
|
||||
break;
|
||||
case StrictEvalScope:
|
||||
@ -976,6 +1046,8 @@ ScopeIter::settle()
|
||||
*/
|
||||
if (frame_.isNonEvalFunctionFrame() && !frame_.fun()->isHeavyweight()) {
|
||||
if (staticScope_) {
|
||||
// If staticScope_ were a StaticWithObject, the function would be
|
||||
// heavyweight.
|
||||
JS_ASSERT(staticScope_->is<StaticBlockObject>());
|
||||
type_ = Block;
|
||||
hasScopeObject_ = staticScope_->as<StaticBlockObject>().needsClone();
|
||||
@ -998,18 +1070,18 @@ ScopeIter::settle()
|
||||
} else if (frame_.isStrictEvalFrame() && !frame_.hasCallObj()) {
|
||||
JS_ASSERT(cur_ == frame_.evalPrevScopeChain(cx));
|
||||
frame_ = NullFramePtr();
|
||||
} else if (cur_->is<WithObject>()) {
|
||||
JS_ASSERT_IF(frame_.isFunctionFrame(), frame_.fun()->isHeavyweight());
|
||||
JS_ASSERT_IF(staticScope_, staticScope_->as<StaticBlockObject>().needsClone());
|
||||
JS_ASSERT_IF(staticScope_,
|
||||
staticScope_->as<StaticBlockObject>().stackDepth() <
|
||||
cur_->as<WithObject>().stackDepth());
|
||||
type_ = With;
|
||||
hasScopeObject_ = true;
|
||||
} else if (staticScope_) {
|
||||
type_ = Block;
|
||||
hasScopeObject_ = staticScope_->as<StaticBlockObject>().needsClone();
|
||||
JS_ASSERT_IF(hasScopeObject_, cur_->as<ClonedBlockObject>().staticBlock() == *staticScope_);
|
||||
if (staticScope_->is<StaticWithObject>()) {
|
||||
JS_ASSERT(cur_);
|
||||
JS_ASSERT(cur_->as<DynamicWithObject>().staticScope() == staticScope_);
|
||||
type_ = With;
|
||||
hasScopeObject_ = true;
|
||||
} else {
|
||||
type_ = Block;
|
||||
hasScopeObject_ = staticScope_->as<StaticBlockObject>().needsClone();
|
||||
JS_ASSERT_IF(hasScopeObject_,
|
||||
cur_->as<ClonedBlockObject>().staticBlock() == *staticScope_);
|
||||
}
|
||||
} else if (cur_->is<CallObject>()) {
|
||||
CallObject &callobj = cur_->as<CallObject>();
|
||||
type_ = callobj.isForEval() ? StrictEvalScope : Call;
|
||||
@ -1211,7 +1283,7 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
}
|
||||
|
||||
/* The rest of the internal scopes do not have unaliased vars. */
|
||||
JS_ASSERT(scope->is<DeclEnvObject>() || scope->is<WithObject>() ||
|
||||
JS_ASSERT(scope->is<DeclEnvObject>() || scope->is<DynamicWithObject>() ||
|
||||
scope->as<CallObject>().isForEval());
|
||||
return false;
|
||||
}
|
||||
@ -1385,7 +1457,15 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetPropertyNames(cx, scope, flags, &props))
|
||||
// DynamicWithObject isn't a very good proxy. It doesn't have a
|
||||
// JSNewEnumerateOp implementation, because if it just delegated to the
|
||||
// target object, the object would indicate that native enumeration is
|
||||
// the thing to do, but native enumeration over the DynamicWithObject
|
||||
// wrapper yields no properties. So instead here we hack around the
|
||||
// issue, and punch a hole through to the with object target.
|
||||
Rooted<JSObject*> target(cx, (scope->is<DynamicWithObject>()
|
||||
? &scope->as<DynamicWithObject>().object() : scope));
|
||||
if (!GetPropertyNames(cx, target, flags, &props))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -1928,7 +2008,7 @@ DebugScopes::onPopWith(AbstractFramePtr frame)
|
||||
{
|
||||
DebugScopes *scopes = frame.compartment()->debugScopes;
|
||||
if (scopes)
|
||||
scopes->liveScopes.remove(&frame.scopeChain()->as<WithObject>());
|
||||
scopes->liveScopes.remove(&frame.scopeChain()->as<DynamicWithObject>());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -18,6 +18,8 @@ namespace js {
|
||||
|
||||
namespace frontend { struct Definition; }
|
||||
|
||||
class StaticWithObject;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
@ -65,14 +67,16 @@ class StaticScopeIter
|
||||
: obj(cx, obj), onNamedLambda(false)
|
||||
{
|
||||
JS_STATIC_ASSERT(allowGC == CanGC);
|
||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<StaticWithObject>() ||
|
||||
obj->is<JSFunction>());
|
||||
}
|
||||
|
||||
StaticScopeIter(JSObject *obj)
|
||||
: obj((ExclusiveContext *) nullptr, obj), onNamedLambda(false)
|
||||
{
|
||||
JS_STATIC_ASSERT(allowGC == NoGC);
|
||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<StaticWithObject>() ||
|
||||
obj->is<JSFunction>());
|
||||
}
|
||||
|
||||
bool done() const;
|
||||
@ -82,10 +86,11 @@ class StaticScopeIter
|
||||
bool hasDynamicScopeObject() const;
|
||||
Shape *scopeShape() const;
|
||||
|
||||
enum Type { BLOCK, FUNCTION, NAMED_LAMBDA };
|
||||
enum Type { WITH, BLOCK, FUNCTION, NAMED_LAMBDA };
|
||||
Type type() const;
|
||||
|
||||
StaticBlockObject &block() const;
|
||||
StaticWithObject &staticWith() const;
|
||||
JSScript *funScript() const;
|
||||
};
|
||||
|
||||
@ -159,9 +164,11 @@ ScopeCoordinateFunctionScript(JSScript *script, jsbytecode *pc);
|
||||
* \ CallObject Scope of entire function or strict eval
|
||||
* \
|
||||
* NestedScopeObject Scope created for a statement
|
||||
* \ \
|
||||
* \ WithObject with
|
||||
* \
|
||||
* \ \ \
|
||||
* \ \ StaticWithObject Template for "with" object in static scope chain
|
||||
* \ \
|
||||
* \ DynamicWithObject Run-time "with" object on scope chain
|
||||
* \
|
||||
* BlockObject Shared interface of cloned/static block objects
|
||||
* \ \
|
||||
* \ ClonedBlockObject let, switch, catch, for
|
||||
@ -301,21 +308,22 @@ class DeclEnvObject : public ScopeObject
|
||||
|
||||
class NestedScopeObject : public ScopeObject
|
||||
{
|
||||
protected:
|
||||
static const unsigned DEPTH_SLOT = 1;
|
||||
|
||||
public:
|
||||
/* Return the abstract stack depth right before entering this nested scope. */
|
||||
uint32_t stackDepth() const {
|
||||
return getReservedSlot(DEPTH_SLOT).toPrivateUint32();
|
||||
}
|
||||
|
||||
/*
|
||||
* A refinement of enclosingScope that returns nullptr if the enclosing
|
||||
* scope is not a NestedScopeObject.
|
||||
*/
|
||||
inline NestedScopeObject *enclosingNestedScope() const;
|
||||
|
||||
// Return true if this object is a compile-time scope template.
|
||||
inline bool isStatic() { return !getProto(); }
|
||||
|
||||
// Return the static scope corresponding to this scope chain object.
|
||||
inline NestedScopeObject* staticScope() {
|
||||
JS_ASSERT(!isStatic());
|
||||
return &getProto()->as<NestedScopeObject>();
|
||||
}
|
||||
|
||||
// At compile-time it's possible for the scope chain to be null.
|
||||
JSObject *enclosingScopeForStaticScopeIter() {
|
||||
return getReservedSlot(SCOPE_CHAIN_SLOT).toObjectOrNull();
|
||||
@ -342,12 +350,23 @@ class NestedScopeObject : public ScopeObject
|
||||
}
|
||||
};
|
||||
|
||||
class WithObject : public NestedScopeObject
|
||||
// With scope template objects on the static scope chain.
|
||||
class StaticWithObject : public NestedScopeObject
|
||||
{
|
||||
static const unsigned THIS_SLOT = 2;
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = 1;
|
||||
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2_BACKGROUND;
|
||||
|
||||
/* Use WithObject::object() instead. */
|
||||
JSObject *getProto() const;
|
||||
static const Class class_;
|
||||
|
||||
static StaticWithObject *create(ExclusiveContext *cx);
|
||||
};
|
||||
|
||||
// With scope objects on the run-time scope chain.
|
||||
class DynamicWithObject : public NestedScopeObject
|
||||
{
|
||||
static const unsigned OBJECT_SLOT = 1;
|
||||
static const unsigned THIS_SLOT = 2;
|
||||
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = 3;
|
||||
@ -355,28 +374,40 @@ class WithObject : public NestedScopeObject
|
||||
|
||||
static const Class class_;
|
||||
|
||||
static WithObject *
|
||||
create(JSContext *cx, HandleObject proto, HandleObject enclosing, uint32_t depth);
|
||||
static DynamicWithObject *
|
||||
create(JSContext *cx, HandleObject object, HandleObject enclosing, HandleObject staticWith);
|
||||
|
||||
StaticWithObject& staticWith() const {
|
||||
return getProto()->as<StaticWithObject>();
|
||||
}
|
||||
|
||||
/* Return the 'o' in 'with (o)'. */
|
||||
JSObject &object() const {
|
||||
return getReservedSlot(OBJECT_SLOT).toObject();
|
||||
}
|
||||
|
||||
/* Return object for the 'this' class hook. */
|
||||
JSObject &withThis() const {
|
||||
return getReservedSlot(THIS_SLOT).toObject();
|
||||
}
|
||||
|
||||
/* Return the 'o' in 'with (o)'. */
|
||||
JSObject &object() const {
|
||||
return *JSObject::getProto();
|
||||
}
|
||||
};
|
||||
|
||||
class BlockObject : public NestedScopeObject
|
||||
{
|
||||
protected:
|
||||
static const unsigned DEPTH_SLOT = 1;
|
||||
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = 2;
|
||||
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4_BACKGROUND;
|
||||
|
||||
static const Class class_;
|
||||
|
||||
/* Return the abstract stack depth right before entering this nested scope. */
|
||||
uint32_t stackDepth() const {
|
||||
return getReservedSlot(DEPTH_SLOT).toPrivateUint32();
|
||||
}
|
||||
|
||||
/* Return the number of variables associated with this block. */
|
||||
uint32_t slotCount() const {
|
||||
return propertyCountForCompilation();
|
||||
@ -412,12 +443,6 @@ class StaticBlockObject : public BlockObject
|
||||
public:
|
||||
static StaticBlockObject *create(ExclusiveContext *cx);
|
||||
|
||||
/*
|
||||
* A refinement of enclosingScope that returns nullptr if the enclosing
|
||||
* static scope is a JSFunction.
|
||||
*/
|
||||
inline StaticBlockObject *enclosingBlock() const;
|
||||
|
||||
/*
|
||||
* Return whether this StaticBlockObject contains a variable stored at
|
||||
* the given stack depth (i.e., fp->base()[depth]).
|
||||
@ -520,6 +545,11 @@ bool
|
||||
XDRStaticBlockObject(XDRState<mode> *xdr, HandleObject enclosingScope,
|
||||
StaticBlockObject **objp);
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRStaticWithObject(XDRState<mode> *xdr, HandleObject enclosingScope,
|
||||
StaticWithObject **objp);
|
||||
|
||||
extern JSObject *
|
||||
CloneNestedScopeObject(JSContext *cx, HandleObject enclosingScope, Handle<NestedScopeObject*> src);
|
||||
|
||||
@ -598,6 +628,7 @@ class ScopeIter
|
||||
Type type() const { JS_ASSERT(!done()); return type_; }
|
||||
bool hasScopeObject() const { JS_ASSERT(!done()); return hasScopeObject_; }
|
||||
ScopeObject &scope() const;
|
||||
NestedScopeObject* staticScope() const { return staticScope_; }
|
||||
|
||||
StaticBlockObject &staticBlock() const {
|
||||
JS_ASSERT(type() == Block);
|
||||
@ -806,7 +837,7 @@ template<>
|
||||
inline bool
|
||||
JSObject::is<js::NestedScopeObject>() const
|
||||
{
|
||||
return is<js::BlockObject>() || is<js::WithObject>();
|
||||
return is<js::BlockObject>() || is<js::StaticWithObject>() || is<js::DynamicWithObject>();
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -867,13 +898,6 @@ NestedScopeObject::enclosingNestedScope() const
|
||||
return obj && obj->is<NestedScopeObject>() ? &obj->as<NestedScopeObject>() : nullptr;
|
||||
}
|
||||
|
||||
inline StaticBlockObject *
|
||||
StaticBlockObject::enclosingBlock() const
|
||||
{
|
||||
JSObject *obj = getReservedSlot(SCOPE_CHAIN_SLOT).toObjectOrNull();
|
||||
return obj && obj->is<StaticBlockObject>() ? &obj->as<StaticBlockObject>() : nullptr;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
AnalyzeEntrainedVariables(JSContext *cx, HandleScript script);
|
||||
|
@ -133,8 +133,8 @@ Shape::set(JSContext* cx, HandleObject obj, HandleObject receiver, bool strict,
|
||||
* |with (it) color='red';| ends up here.
|
||||
* Avoid exposing the With object to native setters.
|
||||
*/
|
||||
if (obj->is<WithObject>()) {
|
||||
RootedObject nobj(cx, &obj->as<WithObject>().object());
|
||||
if (obj->is<DynamicWithObject>()) {
|
||||
RootedObject nobj(cx, &obj->as<DynamicWithObject>().object());
|
||||
return CallJSPropertyOpSetter(cx, self->setterOp(), nobj, id, strict, vp);
|
||||
}
|
||||
|
||||
|
@ -803,10 +803,15 @@ AbstractFramePtr::popBlock(JSContext *cx) const
|
||||
inline void
|
||||
AbstractFramePtr::popWith(JSContext *cx) const
|
||||
{
|
||||
if (isStackFrame())
|
||||
if (isStackFrame()) {
|
||||
asStackFrame()->popWith(cx);
|
||||
else
|
||||
MOZ_ASSUME_UNREACHABLE("Invalid frame");
|
||||
return;
|
||||
}
|
||||
#ifdef JS_ION
|
||||
asBaselineFrame()->popWith(cx);
|
||||
#else
|
||||
MOZ_ASSUME_UNREACHABLE("Invalid frame");
|
||||
#endif
|
||||
}
|
||||
|
||||
Activation::Activation(JSContext *cx, Kind kind)
|
||||
|
@ -182,18 +182,15 @@ AssertDynamicScopeMatchesStaticScope(JSContext *cx, JSScript *script, JSObject *
|
||||
RootedObject enclosingScope(cx, script->enclosingStaticScope());
|
||||
for (StaticScopeIter<NoGC> i(enclosingScope); !i.done(); i++) {
|
||||
if (i.hasDynamicScopeObject()) {
|
||||
/*
|
||||
* 'with' does not participate in the static scope of the script,
|
||||
* but it does in the dynamic scope, so skip them here.
|
||||
*/
|
||||
while (scope->is<WithObject>())
|
||||
scope = &scope->as<WithObject>().enclosingScope();
|
||||
|
||||
switch (i.type()) {
|
||||
case StaticScopeIter<NoGC>::BLOCK:
|
||||
JS_ASSERT(i.block() == scope->as<ClonedBlockObject>().staticBlock());
|
||||
JS_ASSERT(&i.block() == scope->as<ClonedBlockObject>().staticScope());
|
||||
scope = &scope->as<ClonedBlockObject>().enclosingScope();
|
||||
break;
|
||||
case StaticScopeIter<NoGC>::WITH:
|
||||
JS_ASSERT(&i.staticWith() == scope->as<DynamicWithObject>().staticScope());
|
||||
scope = &scope->as<DynamicWithObject>().enclosingScope();
|
||||
break;
|
||||
case StaticScopeIter<NoGC>::FUNCTION:
|
||||
JS_ASSERT(scope->as<CallObject>().callee().nonLazyScript() == i.funScript());
|
||||
scope = &scope->as<CallObject>().enclosingScope();
|
||||
@ -350,7 +347,7 @@ StackFrame::popWith(JSContext *cx)
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
|
||||
DebugScopes::onPopWith(this);
|
||||
|
||||
JS_ASSERT(scopeChain()->is<WithObject>());
|
||||
JS_ASSERT(scopeChain()->is<DynamicWithObject>());
|
||||
popOffScopeChain();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ namespace js {
|
||||
* and saved versions. If deserialization fails, the data should be
|
||||
* invalidated if possible.
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 165);
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 166);
|
||||
|
||||
class XDRBuffer {
|
||||
public:
|
||||
|
@ -2036,12 +2036,8 @@ nsPrintEngine::UpdateSelectionAndShrinkPrintObject(nsPrintObject* aPO,
|
||||
// Limit the shrink-to-fit scaling for some text-ish type of documents.
|
||||
nsAutoString contentType;
|
||||
aPO->mPresShell->GetDocument()->GetContentType(contentType);
|
||||
bool applyLimit = contentType.EqualsLiteral("application/xhtml+xml");
|
||||
if (contentType.Length() > 5) {
|
||||
contentType.Truncate(5);
|
||||
}
|
||||
applyLimit = applyLimit || contentType.EqualsLiteral("text/");
|
||||
if (applyLimit) {
|
||||
if (contentType.EqualsLiteral("application/xhtml+xml") ||
|
||||
StringBeginsWith(contentType, NS_LITERAL_STRING("text/"))) {
|
||||
int32_t limitPercent =
|
||||
Preferences::GetInt("print.shrink-to-fit.scale-limit-percent", 20);
|
||||
limitPercent = std::max(0, limitPercent);
|
||||
|
@ -2,7 +2,9 @@
|
||||
# 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/.
|
||||
|
||||
DIST_FILES := package-name.txt.in
|
||||
DIST_FILES := \
|
||||
package-name.txt.in \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(findstring -march=armv7,$(OS_CFLAGS)))
|
||||
MIN_CPU_VERSION=7
|
||||
@ -163,9 +165,35 @@ PP_TARGETS += preprocessed_package
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
not_android_res_files := \
|
||||
*.mkdir.done* \
|
||||
*.DS_Store* \
|
||||
$(NULL)
|
||||
|
||||
# This uses the fact that Android resource directories list all
|
||||
# resource files one subdirectory below the parent resource directory.
|
||||
android_res_files := $(wildcard $(addsuffix /*,$(wildcard $(addsuffix /*,$(ANDROID_RES_DIRS)))))
|
||||
android_res_files := $(filter-out $(not_android_res_files),$(wildcard $(addsuffix /*,$(wildcard $(addsuffix /*,$(ANDROID_RES_DIRS))))))
|
||||
|
||||
# For GeckoView, we want a zip of an Android res/ directory that
|
||||
# merges the contents of all the ANDROID_RES_DIRS. The inner res/
|
||||
# directory must have the Android resource two-layer hierarchy.
|
||||
|
||||
# The following helper zips files in a directory into a zip file while
|
||||
# maintaining the directory structure rooted below the directory.
|
||||
# (adding or creating said file as appropriate). For example, if the
|
||||
# dir contains dir/subdir/file, calling with directory dir would
|
||||
# create a zip containing subdir/file. Note: the trailing newline is
|
||||
# necessary.
|
||||
|
||||
# $(1): zip file to add to (or create).
|
||||
# $(2): directory to zip contents of.
|
||||
define zip_directory_with_relative_paths
|
||||
cd $(2) && zip -q $(1) -r * -x $(not_android_res_files)
|
||||
|
||||
endef
|
||||
|
||||
geckoview_resources.zip: $(android_res_files) $(GLOBAL_DEPS)
|
||||
$(foreach dir,$(ANDROID_RES_DIRS),$(call zip_directory_with_relative_paths,$(CURDIR)/$@,$(dir)))
|
||||
|
||||
$(ANDROID_GENERATED_RESFILES): $(call mkdir_deps,$(sort $(dir $(ANDROID_GENERATED_RESFILES))))
|
||||
|
||||
@ -241,7 +269,8 @@ fennec_ids.txt: $(gecko_package_dir)/R.java fennec-ids-generator.py
|
||||
# Override the Java settings with some specific android settings
|
||||
include $(topsrcdir)/config/android-common.mk
|
||||
|
||||
libs:: classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp fennec_ids.txt
|
||||
libs:: geckoview_resources.zip classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp fennec_ids.txt
|
||||
$(INSTALL) geckoview_resources.zip $(FINAL_TARGET)
|
||||
$(INSTALL) classes.dex $(FINAL_TARGET)
|
||||
@(diff jni-stubs.inc $(topsrcdir)/mozglue/android/jni-stubs.inc >/dev/null && diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null) || \
|
||||
(echo '*** Error: The generated JNI code has changed. Please run cp $(CURDIR)/jni-stubs.inc $(topsrcdir)/mozglue/android && cp $(CURDIR)/GeneratedJNIWrappers.* $(topsrcdir)/widget/android and repeat the build.' && exit 1)
|
||||
|
@ -12,7 +12,6 @@ GECKOVIEW_LIBRARY_FILES := \
|
||||
build.xml \
|
||||
$(NULL)
|
||||
|
||||
|
||||
PP_TARGETS = properties
|
||||
|
||||
properties = local.properties.in
|
||||
@ -32,26 +31,31 @@ GARBAGE_DIRS = \
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_ABS_DIST = $(abspath $(DIST))
|
||||
|
||||
package: $(properties_deps)
|
||||
# Make directory for the zips
|
||||
$(MKDIR) -p $(DIST)/geckoview_library
|
||||
$(MKDIR) -p $(_ABS_DIST)/geckoview_library
|
||||
|
||||
# Zip the assets
|
||||
cd $(DIST)/fennec; \
|
||||
$(ZIP) -r ../geckoview_library/geckoview_assets.zip assets
|
||||
# Zip the assets into $(DIST)/geckoview_library/geckoview_assets.zip
|
||||
cd $(_ABS_DIST)/fennec && \
|
||||
$(ZIP) -q -r $(_ABS_DIST)/geckoview_library/geckoview_assets.zip assets
|
||||
|
||||
# Make empty directories to fit an Android project structure
|
||||
$(MKDIR) -p bin gen libs/$(ABI_DIR) src
|
||||
$(MKDIR) -p bin gen libs/$(ANDROID_CPU_ARCH) src
|
||||
|
||||
# Copy the JARs
|
||||
cp ../base/*.jar libs/
|
||||
cp $(DEPTH)/mobile/android/base/*.jar libs/
|
||||
|
||||
# Copy the SOs
|
||||
cp $(DIST)/bin/libmozglue.so $(DIST)/bin/lib/libplugin-container.so libs/$(ABI_DIR)/
|
||||
cp $(_ABS_DIST)/bin/libmozglue.so $(_ABS_DIST)/bin/lib/libplugin-container.so libs/$(ANDROID_CPU_ARCH)/
|
||||
|
||||
# Copy the resources
|
||||
cp -R ../base/res .
|
||||
$(RM) -rf res
|
||||
$(MKDIR) -p res
|
||||
cd res && \
|
||||
$(UNZIP) -q -u -o $(_ABS_DIST)/bin/geckoview_resources.zip
|
||||
|
||||
# Zip the directory
|
||||
cd ..; \
|
||||
$(ZIP) -r ../../dist/geckoview_library/geckoview_library.zip geckoview_library --exclude geckoview_library/backend.mk geckoview_library/Makefile
|
||||
cd $(DEPTH)/mobile/android && \
|
||||
$(ZIP) -q -r $(_ABS_DIST)/geckoview_library/geckoview_library.zip geckoview_library -x geckoview_library/backend.mk geckoview_library/Makefile
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2008-2014 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -773,6 +773,7 @@ public final class ElementName
|
||||
public static final ElementName EXPONENTIALE = new ElementName("exponentiale", "exponentiale", TreeBuilder.OTHER);
|
||||
public static final ElementName FETURBULENCE = new ElementName("feturbulence", "feTurbulence", TreeBuilder.OTHER);
|
||||
public static final ElementName FEPOINTLIGHT = new ElementName("fepointlight", "fePointLight", TreeBuilder.OTHER);
|
||||
public static final ElementName FEDROPSHADOW = new ElementName("fedropshadow", "feDropShadow", TreeBuilder.OTHER);
|
||||
public static final ElementName FEMORPHOLOGY = new ElementName("femorphology", "feMorphology", TreeBuilder.OTHER);
|
||||
public static final ElementName OUTERPRODUCT = new ElementName("outerproduct", "outerproduct", TreeBuilder.OTHER);
|
||||
public static final ElementName ANIMATEMOTION = new ElementName("animatemotion", "animateMotion", TreeBuilder.OTHER);
|
||||
@ -1167,6 +1168,7 @@ public final class ElementName
|
||||
EXPONENTIALE,
|
||||
FETURBULENCE,
|
||||
FEPOINTLIGHT,
|
||||
FEDROPSHADOW,
|
||||
FEMORPHOLOGY,
|
||||
OUTERPRODUCT,
|
||||
ANIMATEMOTION,
|
||||
@ -1562,6 +1564,7 @@ public final class ElementName
|
||||
408072233,
|
||||
409112005,
|
||||
409608425,
|
||||
409713793,
|
||||
409771500,
|
||||
419040932,
|
||||
437730612,
|
||||
|
@ -1027,6 +1027,8 @@ HTML5_ATOM(feturbulence, "feturbulence")
|
||||
HTML5_ATOM(feTurbulence, "feTurbulence")
|
||||
HTML5_ATOM(fepointlight, "fepointlight")
|
||||
HTML5_ATOM(fePointLight, "fePointLight")
|
||||
HTML5_ATOM(fedropshadow, "fedropshadow")
|
||||
HTML5_ATOM(feDropShadow, "feDropShadow")
|
||||
HTML5_ATOM(femorphology, "femorphology")
|
||||
HTML5_ATOM(feMorphology, "feMorphology")
|
||||
HTML5_ATOM(outerproduct, "outerproduct")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2008-2014 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -498,6 +498,7 @@ nsHtml5ElementName* nsHtml5ElementName::ELT_DATATEMPLATE = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_EXPONENTIALE = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_FETURBULENCE = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_FEPOINTLIGHT = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_FEDROPSHADOW = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_FEMORPHOLOGY = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_OUTERPRODUCT = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_ANIMATEMOTION = nullptr;
|
||||
@ -528,7 +529,7 @@ nsHtml5ElementName* nsHtml5ElementName::ELT_FESPECULARLIGHTING = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_DOMAINOFAPPLICATION = nullptr;
|
||||
nsHtml5ElementName* nsHtml5ElementName::ELT_FECOMPONENTTRANSFER = nullptr;
|
||||
nsHtml5ElementName** nsHtml5ElementName::ELEMENT_NAMES = 0;
|
||||
static int32_t const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148317229, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189107250, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 255641645, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282498697, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289591340, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 342310196, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 };
|
||||
static int32_t const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148317229, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189107250, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 255641645, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282498697, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289591340, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 342310196, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409713793, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 };
|
||||
staticJArray<int32_t,int32_t> nsHtml5ElementName::ELEMENT_HASHES = { ELEMENT_HASHES_DATA, MOZ_ARRAY_LENGTH(ELEMENT_HASHES_DATA) };
|
||||
void
|
||||
nsHtml5ElementName::initializeStatics()
|
||||
@ -898,6 +899,7 @@ nsHtml5ElementName::initializeStatics()
|
||||
ELT_EXPONENTIALE = new nsHtml5ElementName(nsHtml5Atoms::exponentiale, nsHtml5Atoms::exponentiale, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_FETURBULENCE = new nsHtml5ElementName(nsHtml5Atoms::feturbulence, nsHtml5Atoms::feTurbulence, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_FEPOINTLIGHT = new nsHtml5ElementName(nsHtml5Atoms::fepointlight, nsHtml5Atoms::fePointLight, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_FEDROPSHADOW = new nsHtml5ElementName(nsHtml5Atoms::fedropshadow, nsHtml5Atoms::feDropShadow, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_FEMORPHOLOGY = new nsHtml5ElementName(nsHtml5Atoms::femorphology, nsHtml5Atoms::feMorphology, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_OUTERPRODUCT = new nsHtml5ElementName(nsHtml5Atoms::outerproduct, nsHtml5Atoms::outerproduct, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_ANIMATEMOTION = new nsHtml5ElementName(nsHtml5Atoms::animatemotion, nsHtml5Atoms::animateMotion, NS_HTML5TREE_BUILDER_OTHER);
|
||||
@ -927,7 +929,7 @@ nsHtml5ElementName::initializeStatics()
|
||||
ELT_FESPECULARLIGHTING = new nsHtml5ElementName(nsHtml5Atoms::fespecularlighting, nsHtml5Atoms::feSpecularLighting, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_DOMAINOFAPPLICATION = new nsHtml5ElementName(nsHtml5Atoms::domainofapplication, nsHtml5Atoms::domainofapplication, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELT_FECOMPONENTTRANSFER = new nsHtml5ElementName(nsHtml5Atoms::fecomponenttransfer, nsHtml5Atoms::feComponentTransfer, NS_HTML5TREE_BUILDER_OTHER);
|
||||
ELEMENT_NAMES = new nsHtml5ElementName*[393];
|
||||
ELEMENT_NAMES = new nsHtml5ElementName*[394];
|
||||
ELEMENT_NAMES[0] = ELT_A;
|
||||
ELEMENT_NAMES[1] = ELT_B;
|
||||
ELEMENT_NAMES[2] = ELT_G;
|
||||
@ -1292,35 +1294,36 @@ nsHtml5ElementName::initializeStatics()
|
||||
ELEMENT_NAMES[361] = ELT_EXPONENTIALE;
|
||||
ELEMENT_NAMES[362] = ELT_FETURBULENCE;
|
||||
ELEMENT_NAMES[363] = ELT_FEPOINTLIGHT;
|
||||
ELEMENT_NAMES[364] = ELT_FEMORPHOLOGY;
|
||||
ELEMENT_NAMES[365] = ELT_OUTERPRODUCT;
|
||||
ELEMENT_NAMES[366] = ELT_ANIMATEMOTION;
|
||||
ELEMENT_NAMES[367] = ELT_COLOR_PROFILE;
|
||||
ELEMENT_NAMES[368] = ELT_FONT_FACE_SRC;
|
||||
ELEMENT_NAMES[369] = ELT_FONT_FACE_URI;
|
||||
ELEMENT_NAMES[370] = ELT_FOREIGNOBJECT;
|
||||
ELEMENT_NAMES[371] = ELT_FECOLORMATRIX;
|
||||
ELEMENT_NAMES[372] = ELT_MISSING_GLYPH;
|
||||
ELEMENT_NAMES[373] = ELT_MMULTISCRIPTS;
|
||||
ELEMENT_NAMES[374] = ELT_SCALARPRODUCT;
|
||||
ELEMENT_NAMES[375] = ELT_VECTORPRODUCT;
|
||||
ELEMENT_NAMES[376] = ELT_ANNOTATION_XML;
|
||||
ELEMENT_NAMES[377] = ELT_DEFINITION_SRC;
|
||||
ELEMENT_NAMES[378] = ELT_FONT_FACE_NAME;
|
||||
ELEMENT_NAMES[379] = ELT_FEGAUSSIANBLUR;
|
||||
ELEMENT_NAMES[380] = ELT_FEDISTANTLIGHT;
|
||||
ELEMENT_NAMES[381] = ELT_LINEARGRADIENT;
|
||||
ELEMENT_NAMES[382] = ELT_NATURALNUMBERS;
|
||||
ELEMENT_NAMES[383] = ELT_RADIALGRADIENT;
|
||||
ELEMENT_NAMES[384] = ELT_ANIMATETRANSFORM;
|
||||
ELEMENT_NAMES[385] = ELT_CARTESIANPRODUCT;
|
||||
ELEMENT_NAMES[386] = ELT_FONT_FACE_FORMAT;
|
||||
ELEMENT_NAMES[387] = ELT_FECONVOLVEMATRIX;
|
||||
ELEMENT_NAMES[388] = ELT_FEDIFFUSELIGHTING;
|
||||
ELEMENT_NAMES[389] = ELT_FEDISPLACEMENTMAP;
|
||||
ELEMENT_NAMES[390] = ELT_FESPECULARLIGHTING;
|
||||
ELEMENT_NAMES[391] = ELT_DOMAINOFAPPLICATION;
|
||||
ELEMENT_NAMES[392] = ELT_FECOMPONENTTRANSFER;
|
||||
ELEMENT_NAMES[364] = ELT_FEDROPSHADOW;
|
||||
ELEMENT_NAMES[365] = ELT_FEMORPHOLOGY;
|
||||
ELEMENT_NAMES[366] = ELT_OUTERPRODUCT;
|
||||
ELEMENT_NAMES[367] = ELT_ANIMATEMOTION;
|
||||
ELEMENT_NAMES[368] = ELT_COLOR_PROFILE;
|
||||
ELEMENT_NAMES[369] = ELT_FONT_FACE_SRC;
|
||||
ELEMENT_NAMES[370] = ELT_FONT_FACE_URI;
|
||||
ELEMENT_NAMES[371] = ELT_FOREIGNOBJECT;
|
||||
ELEMENT_NAMES[372] = ELT_FECOLORMATRIX;
|
||||
ELEMENT_NAMES[373] = ELT_MISSING_GLYPH;
|
||||
ELEMENT_NAMES[374] = ELT_MMULTISCRIPTS;
|
||||
ELEMENT_NAMES[375] = ELT_SCALARPRODUCT;
|
||||
ELEMENT_NAMES[376] = ELT_VECTORPRODUCT;
|
||||
ELEMENT_NAMES[377] = ELT_ANNOTATION_XML;
|
||||
ELEMENT_NAMES[378] = ELT_DEFINITION_SRC;
|
||||
ELEMENT_NAMES[379] = ELT_FONT_FACE_NAME;
|
||||
ELEMENT_NAMES[380] = ELT_FEGAUSSIANBLUR;
|
||||
ELEMENT_NAMES[381] = ELT_FEDISTANTLIGHT;
|
||||
ELEMENT_NAMES[382] = ELT_LINEARGRADIENT;
|
||||
ELEMENT_NAMES[383] = ELT_NATURALNUMBERS;
|
||||
ELEMENT_NAMES[384] = ELT_RADIALGRADIENT;
|
||||
ELEMENT_NAMES[385] = ELT_ANIMATETRANSFORM;
|
||||
ELEMENT_NAMES[386] = ELT_CARTESIANPRODUCT;
|
||||
ELEMENT_NAMES[387] = ELT_FONT_FACE_FORMAT;
|
||||
ELEMENT_NAMES[388] = ELT_FECONVOLVEMATRIX;
|
||||
ELEMENT_NAMES[389] = ELT_FEDIFFUSELIGHTING;
|
||||
ELEMENT_NAMES[390] = ELT_FEDISPLACEMENTMAP;
|
||||
ELEMENT_NAMES[391] = ELT_FESPECULARLIGHTING;
|
||||
ELEMENT_NAMES[392] = ELT_DOMAINOFAPPLICATION;
|
||||
ELEMENT_NAMES[393] = ELT_FECOMPONENTTRANSFER;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1691,6 +1694,7 @@ nsHtml5ElementName::releaseStatics()
|
||||
delete ELT_EXPONENTIALE;
|
||||
delete ELT_FETURBULENCE;
|
||||
delete ELT_FEPOINTLIGHT;
|
||||
delete ELT_FEDROPSHADOW;
|
||||
delete ELT_FEMORPHOLOGY;
|
||||
delete ELT_OUTERPRODUCT;
|
||||
delete ELT_ANIMATEMOTION;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2008-2014 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -442,6 +442,7 @@ class nsHtml5ElementName
|
||||
static nsHtml5ElementName* ELT_EXPONENTIALE;
|
||||
static nsHtml5ElementName* ELT_FETURBULENCE;
|
||||
static nsHtml5ElementName* ELT_FEPOINTLIGHT;
|
||||
static nsHtml5ElementName* ELT_FEDROPSHADOW;
|
||||
static nsHtml5ElementName* ELT_FEMORPHOLOGY;
|
||||
static nsHtml5ElementName* ELT_OUTERPRODUCT;
|
||||
static nsHtml5ElementName* ELT_ANIMATEMOTION;
|
||||
|
@ -181,7 +181,7 @@ def main(args, env, cwd, fh=sys.stderr):
|
||||
|
||||
if not required or performed:
|
||||
if performed and env.get('TINDERBOX_OUTPUT'):
|
||||
print('TinderboxPrint: auto clobber')
|
||||
print('TinderboxPrint: auto clobber', file=fh)
|
||||
return 0
|
||||
|
||||
print(message, file=fh)
|
||||
|
@ -75,7 +75,7 @@ class MozconfigLoader(ProcessExecutionMixin):
|
||||
|
||||
return os.path.join(our_dir, 'mozconfig_loader')
|
||||
|
||||
def find_mozconfig(self):
|
||||
def find_mozconfig(self, env=os.environ):
|
||||
"""Find the active mozconfig file for the current environment.
|
||||
|
||||
This emulates the logic in mozconfig-find.
|
||||
@ -91,10 +91,10 @@ class MozconfigLoader(ProcessExecutionMixin):
|
||||
"""
|
||||
# Check for legacy methods first.
|
||||
|
||||
if 'MOZ_MYCONFIG' in os.environ:
|
||||
if 'MOZ_MYCONFIG' in env:
|
||||
raise MozconfigFindException(MOZ_MYCONFIG_ERROR)
|
||||
|
||||
env_path = os.environ.get('MOZCONFIG', None)
|
||||
env_path = env.get('MOZCONFIG', None)
|
||||
if env_path is not None:
|
||||
if not os.path.exists(env_path):
|
||||
raise MozconfigFindException(
|
||||
@ -128,7 +128,7 @@ class MozconfigLoader(ProcessExecutionMixin):
|
||||
deprecated_paths = [os.path.join(self.topsrcdir, s) for s in
|
||||
self.DEPRECATED_TOPSRCDIR_PATHS]
|
||||
|
||||
home = os.environ.get('HOME', None)
|
||||
home = env.get('HOME', None)
|
||||
if home is not None:
|
||||
deprecated_paths.extend([os.path.join(home, s) for s in
|
||||
self.DEPRECATED_HOME_PATHS])
|
||||
|
@ -8,7 +8,7 @@
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
|
||||
import mozbuild.mozconfig as mozconfig
|
||||
|
||||
def build_dict(config, env=os.environ):
|
||||
"""
|
||||
@ -27,10 +27,9 @@ def build_dict(config, env=os.environ):
|
||||
d = {}
|
||||
d['topsrcdir'] = config.topsrcdir
|
||||
|
||||
if 'MOZCONFIG' in env:
|
||||
mozconfig = env["MOZCONFIG"]
|
||||
mozconfig = os.path.join(config.topsrcdir, mozconfig)
|
||||
d['mozconfig'] = os.path.normpath(mozconfig)
|
||||
the_mozconfig = mozconfig.MozconfigLoader(config.topsrcdir).find_mozconfig(env)
|
||||
if the_mozconfig:
|
||||
d['mozconfig'] = the_mozconfig
|
||||
|
||||
# os
|
||||
o = substs["OS_TARGET"]
|
||||
|
@ -19,6 +19,8 @@ from mozbuild.mozinfo import (
|
||||
write_mozinfo,
|
||||
)
|
||||
|
||||
from mozfile.mozfile import NamedTemporaryFile
|
||||
|
||||
|
||||
class Base(object):
|
||||
def _config(self, substs={}):
|
||||
@ -238,16 +240,20 @@ class TestWriteMozinfo(unittest.TestCase, Base):
|
||||
TARGET_CPU='i386',
|
||||
MOZ_WIDGET_TOOLKIT='windows',
|
||||
))
|
||||
c.topsrcdir = '/tmp'
|
||||
write_mozinfo(self.f, c, {'MOZCONFIG': 'foo'})
|
||||
with open(self.f) as f:
|
||||
d = json.load(f)
|
||||
self.assertEqual('win', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual('windows', d['toolkit'])
|
||||
self.assertEqual('/tmp', d['topsrcdir'])
|
||||
self.assertEqual(os.path.normpath('/tmp/foo'), d['mozconfig'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
tempdir = tempfile.tempdir
|
||||
c.topsrcdir = tempdir
|
||||
with NamedTemporaryFile(dir=os.path.normpath(c.topsrcdir)) as mozconfig:
|
||||
mozconfig.write('unused contents')
|
||||
mozconfig.flush()
|
||||
write_mozinfo(self.f, c, {'MOZCONFIG': mozconfig.name})
|
||||
with open(self.f) as f:
|
||||
d = json.load(f)
|
||||
self.assertEqual('win', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual('windows', d['toolkit'])
|
||||
self.assertEqual(tempdir, d['topsrcdir'])
|
||||
self.assertEqual(mozconfig.name, d['mozconfig'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
def test_fileobj(self):
|
||||
"""
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"talos.zip": {
|
||||
"url": "http://talos-bundles.pvt.build.mozilla.org/zips/talos.e78104c1f552.zip",
|
||||
"url": "http://talos-bundles.pvt.build.mozilla.org/zips/talos.79702830f03d.zip",
|
||||
"path": ""
|
||||
},
|
||||
"global": {
|
||||
"talos_repo": "https://hg.mozilla.org/build/talos",
|
||||
"talos_revision": "087bbbe3bc3d"
|
||||
"talos_revision": "79702830f03d"
|
||||
},
|
||||
"suites": {
|
||||
"chromez": {
|
||||
|
@ -18,6 +18,7 @@
|
||||
defaultButton="cancel"
|
||||
ondialogaccept="return g_dialog.appPickerOK();"
|
||||
ondialogcancel="return g_dialog.appPickerCancel();"
|
||||
aria-describedby="content-description suggested-filename"
|
||||
persist="screenX screenY">
|
||||
|
||||
<script type="application/javascript" src="chrome://global/content/appPicker.js"/>
|
||||
@ -30,7 +31,7 @@
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<label id="sendto-message" value="&SendMsg.label;" for="app-picker-listbox"/>
|
||||
<label id="sendto-message" value="&SendMsg.label;" control="app-picker-listbox"/>
|
||||
|
||||
<listbox id="app-picker-listbox" rows="5"
|
||||
ondblclick="g_dialog.appDoubleClick();"/>
|
||||
|
@ -23,6 +23,7 @@
|
||||
ondialogaccept="return doOKButton();"
|
||||
title="&dialog.title;"
|
||||
buttons="disclosure"
|
||||
aria-describedby="dialog-header"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script src="cookieAcceptDialog.js" type="application/javascript"/>
|
||||
@ -69,42 +70,42 @@
|
||||
|
||||
<row align="center">
|
||||
<hbox align="center" pack="end">
|
||||
<label value="&props.name.label;"/>
|
||||
<label value="&props.name.label;" control="ifl_name"/>
|
||||
</hbox>
|
||||
<textbox id="ifl_name" readonly="true" class="plain"/>
|
||||
</row>
|
||||
|
||||
<row align="center">
|
||||
<hbox align="center" pack="end">
|
||||
<label value="&props.value.label;"/>
|
||||
<label value="&props.value.label;" control="ifl_value"/>
|
||||
</hbox>
|
||||
<textbox id="ifl_value" readonly="true" class="plain"/>
|
||||
</row>
|
||||
|
||||
<row align="center">
|
||||
<hbox align="center" pack="end">
|
||||
<label id="ifl_isDomain" value="&props.domain.label;"/>
|
||||
<label id="ifl_isDomain" value="&props.domain.label;" control="ifl_host"/>
|
||||
</hbox>
|
||||
<textbox id="ifl_host" readonly="true" class="plain"/>
|
||||
</row>
|
||||
|
||||
<row align="center">
|
||||
<hbox align="center" pack="end">
|
||||
<label value="&props.path.label;"/>
|
||||
<label value="&props.path.label;" control="ifl_path"/>
|
||||
</hbox>
|
||||
<textbox id="ifl_path" readonly="true" class="plain"/>
|
||||
</row>
|
||||
|
||||
<row align="center">
|
||||
<hbox align="center" pack="end">
|
||||
<label value="&props.secure.label;"/>
|
||||
<label value="&props.secure.label;" control="ifl_isSecure"/>
|
||||
</hbox>
|
||||
<textbox id="ifl_isSecure" readonly="true" class="plain"/>
|
||||
</row>
|
||||
|
||||
<row align="center">
|
||||
<hbox align="center" pack="end">
|
||||
<label value="&props.expires.label;"/>
|
||||
<label value="&props.expires.label;" control="ifl_expires"/>
|
||||
</hbox>
|
||||
<textbox id="ifl_expires" readonly="true" class="plain"/>
|
||||
</row>
|
||||
|
@ -243,6 +243,7 @@ var PrintUtils = {
|
||||
document.documentElement.setAttribute("onclose", "PrintUtils.exitPrintPreview(); return false;");
|
||||
|
||||
// disable chrome shortcuts...
|
||||
window.addEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.addEventListener("keypress", this.onKeyPressPP, true);
|
||||
|
||||
var browser = this._callback.getPrintPreviewBrowser();
|
||||
@ -255,6 +256,7 @@ var PrintUtils = {
|
||||
|
||||
exitPrintPreview: function ()
|
||||
{
|
||||
window.removeEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.removeEventListener("keypress", this.onKeyPressPP, true);
|
||||
|
||||
// restore the old close handler
|
||||
@ -279,6 +281,14 @@ var PrintUtils = {
|
||||
this._callback.onExit();
|
||||
},
|
||||
|
||||
onKeyDownPP: function (aEvent)
|
||||
{
|
||||
// Esc exits the PP
|
||||
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
|
||||
PrintUtils.exitPrintPreview();
|
||||
}
|
||||
},
|
||||
|
||||
onKeyPressPP: function (aEvent)
|
||||
{
|
||||
var closeKey;
|
||||
@ -288,8 +298,8 @@ var PrintUtils = {
|
||||
closeKey = aEvent["DOM_VK_"+closeKey];
|
||||
} catch (e) {}
|
||||
var isModif = aEvent.ctrlKey || aEvent.metaKey;
|
||||
// ESC and Ctrl-W exits the PP
|
||||
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE || isModif &&
|
||||
// Ctrl-W exits the PP
|
||||
if (isModif &&
|
||||
(aEvent.charCode == closeKey || aEvent.charCode == closeKey + 32)) {
|
||||
PrintUtils.exitPrintPreview();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
title="&window.title;"
|
||||
windowtype="Preferences:ConfigManager"
|
||||
role="application"
|
||||
aria-describedby="warningTitle warningText"
|
||||
width="750"
|
||||
height="500"
|
||||
disablefastfind="true"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#endif
|
||||
screenX="" screenY=""
|
||||
persist="screenX screenY"
|
||||
aria-describedby="intro location whichIs type from source unknownPrompt"
|
||||
ondialogaccept="return dialog.onOK()"
|
||||
ondialogcancel="return dialog.onCancel()">
|
||||
|
||||
@ -35,7 +36,7 @@
|
||||
<stringbundle id="strings" src="chrome://mozapps/locale/downloads/unknownContentType.properties"/>
|
||||
|
||||
<vbox flex="1" id="container">
|
||||
<description>&intro2.label;</description>
|
||||
<description id="intro">&intro2.label;</description>
|
||||
<separator class="thin"/>
|
||||
<hbox align="start" class="small-indent">
|
||||
<image id="contentTypeImage"/>
|
||||
@ -43,7 +44,7 @@
|
||||
<description id="location" class="plain" crop="start" flex="1"/>
|
||||
<separator class="thin"/>
|
||||
<hbox align="center">
|
||||
<label value="&whichIs.label;"/>
|
||||
<label id="whichIs" value="&whichIs.label;"/>
|
||||
<textbox id="type" class="plain" readonly="true" flex="1" noinitialfocus="true"/>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
@ -56,7 +57,7 @@
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox align="center" id="basicBox" collapsed="true">
|
||||
<label value="&unknownPromptText.label;" flex="1"/>
|
||||
<label id="unknownPrompt" value="&unknownPromptText.label;" flex="1"/>
|
||||
</hbox>
|
||||
|
||||
<groupbox flex="1" id="normalBox">
|
||||
|
@ -13,6 +13,7 @@
|
||||
onload="dialog.initialize();"
|
||||
style="min-width: &window.emWidth;; min-height: &window.emHeight;;"
|
||||
persist="width height screenX screenY"
|
||||
aria-describedby="description-text"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script src="chrome://mozapps/content/handling/dialog.js" type="application/javascript"/>
|
||||
@ -28,7 +29,7 @@
|
||||
</hbox>
|
||||
|
||||
<vbox flex="1">
|
||||
<label id="item-action-text" for="items"/>
|
||||
<label id="item-action-text" control="items"/>
|
||||
<richlistbox id="items" flex="1"
|
||||
ondblclick="dialog.onDblClick();"
|
||||
onselect="dialog.updateOKButton();">
|
||||
@ -40,7 +41,7 @@
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
|
||||
<checkbox id="remember" oncommand="dialog.onCheck();"/>
|
||||
<checkbox id="remember" aria-describedby="remember-text" oncommand="dialog.onCheck();"/>
|
||||
<description id="remember-text"/>
|
||||
|
||||
</dialog>
|
||||
|
@ -348,16 +348,6 @@ UPLOAD_EXTRA_FILES += gecko-unsigned-unaligned.apk
|
||||
|
||||
DIST_FILES += $(MOZ_CHILD_PROCESS_NAME)
|
||||
|
||||
ifeq ($(CPU_ARCH),x86)
|
||||
ABI_DIR = x86
|
||||
else
|
||||
ifdef MOZ_THUMB2
|
||||
ABI_DIR = armeabi-v7a
|
||||
else
|
||||
ABI_DIR = armeabi
|
||||
endif
|
||||
endif
|
||||
|
||||
GECKO_APP_AP_PATH = $(abspath $(DEPTH)/mobile/android/base)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
@ -401,7 +391,7 @@ endif
|
||||
ifdef NIGHTLY_BUILD
|
||||
ifndef MOZ_DISABLE_GECKOVIEW
|
||||
INNER_MAKE_GECKOVIEW_LIBRARY= \
|
||||
$(MAKE) -C ../mobile/android/geckoview_library package ABI_DIR=$(ABI_DIR)
|
||||
$(MAKE) -C ../mobile/android/geckoview_library package
|
||||
else
|
||||
INNER_MAKE_GECKOVIEW_LIBRARY=echo 'GeckoView library packaging is disabled'
|
||||
endif
|
||||
@ -470,8 +460,8 @@ INNER_MAKE_PACKAGE = \
|
||||
diff $(GECKO_APP_AP_PATH)/R.txt $(GECKO_APP_AP_PATH)/gecko-nodeps/R.txt >/dev/null || \
|
||||
(echo "*** Error: The R.txt that was built and the R.txt that is being packaged are not the same. Rebuild mobile/android/base and re-package." && exit 1)) && \
|
||||
( cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && \
|
||||
mkdir -p lib/$(ABI_DIR) && \
|
||||
mv libmozglue.so $(MOZ_CHILD_PROCESS_NAME) lib/$(ABI_DIR) && \
|
||||
mkdir -p lib/$(ANDROID_CPU_ARCH) && \
|
||||
mv libmozglue.so $(MOZ_CHILD_PROCESS_NAME) lib/$(ANDROID_CPU_ARCH) && \
|
||||
unzip -o $(_ABS_DIST)/gecko.ap_ && \
|
||||
rm $(_ABS_DIST)/gecko.ap_ && \
|
||||
$(ZIP) $(if $(MOZ_ENABLE_SZIP),-0 )$(_ABS_DIST)/gecko.ap_ $(ASSET_SO_LIBRARIES) && \
|
||||
@ -499,9 +489,9 @@ INNER_UNMAKE_PACKAGE = \
|
||||
mkdir $(MOZ_PKG_DIR) && \
|
||||
( cd $(MOZ_PKG_DIR) && \
|
||||
$(UNZIP) $(UNPACKAGE) && \
|
||||
mv lib/$(ABI_DIR)/libmozglue.so . && \
|
||||
mv lib/$(ABI_DIR)/*plugin-container* $(MOZ_CHILD_PROCESS_NAME) && \
|
||||
rm -rf lib/$(ABI_DIR) \
|
||||
mv lib/$(ANDROID_CPU_ARCH)/libmozglue.so . && \
|
||||
mv lib/$(ANDROID_CPU_ARCH)/*plugin-container* $(MOZ_CHILD_PROCESS_NAME) && \
|
||||
rm -rf lib/$(ANDROID_CPU_ARCH) && \
|
||||
rm -rf res \
|
||||
$(if $(filter-out ./,$(OMNIJAR_DIR)), \
|
||||
&& mv $(OMNIJAR_DIR)$(OMNIJAR_NAME) $(OMNIJAR_NAME)) )
|
||||
|
Loading…
Reference in New Issue
Block a user