mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
21dc4a9b86
@ -800,11 +800,12 @@ getParentCB(AtkObject *aAtkObj)
|
||||
atkParent = parent ? AccessibleWrap::GetAtkObject(parent) : nullptr;
|
||||
} else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
|
||||
ProxyAccessible* parent = proxy->Parent();
|
||||
if (parent)
|
||||
if (parent) {
|
||||
atkParent = GetWrapperFor(parent);
|
||||
|
||||
// Otherwise this should be the proxy for the tab's top level document.
|
||||
atkParent = AccessibleWrap::GetAtkObject(proxy->OuterDocOfRemoteBrowser());
|
||||
} else {
|
||||
// Otherwise this should be the proxy for the tab's top level document.
|
||||
atkParent = AccessibleWrap::GetAtkObject(proxy->OuterDocOfRemoteBrowser());
|
||||
}
|
||||
}
|
||||
|
||||
if (atkParent)
|
||||
|
@ -456,7 +456,7 @@ DocAccessible::Shutdown()
|
||||
|
||||
// XXX thinking about ordering?
|
||||
if (IPCAccessibilityActive()) {
|
||||
DocAccessibleChild::Send__delete__(mIPCDoc);
|
||||
mIPCDoc->Shutdown();
|
||||
MOZ_ASSERT(!mIPCDoc);
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,9 @@ DocAccessibleChild::IdToAccessible(const uint64_t& aID) const
|
||||
if (!aID)
|
||||
return mDoc;
|
||||
|
||||
if (!mDoc)
|
||||
return nullptr;
|
||||
|
||||
return mDoc->GetAccessibleByUniqueID(reinterpret_cast<void*>(aID));
|
||||
}
|
||||
|
||||
@ -225,7 +228,7 @@ DocAccessibleChild::RecvRelationByType(const uint64_t& aID,
|
||||
const uint32_t& aType,
|
||||
nsTArray<uint64_t>* aTargets)
|
||||
{
|
||||
Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID);
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (!acc)
|
||||
return true;
|
||||
|
||||
@ -258,7 +261,7 @@ bool
|
||||
DocAccessibleChild::RecvRelations(const uint64_t& aID,
|
||||
nsTArray<RelationTargets>* aRelations)
|
||||
{
|
||||
Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID);
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (!acc)
|
||||
return true;
|
||||
|
||||
|
@ -32,10 +32,21 @@ public:
|
||||
{ MOZ_COUNT_CTOR(DocAccessibleChild); }
|
||||
~DocAccessibleChild()
|
||||
{
|
||||
mDoc->SetIPCDoc(nullptr);
|
||||
// Shutdown() should have been called, but maybe it isn't if the process is
|
||||
// killed?
|
||||
MOZ_ASSERT(!mDoc);
|
||||
if (mDoc)
|
||||
mDoc->SetIPCDoc(nullptr);
|
||||
MOZ_COUNT_DTOR(DocAccessibleChild);
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
mDoc->SetIPCDoc(nullptr);
|
||||
mDoc = nullptr;
|
||||
SendShutdown();
|
||||
}
|
||||
|
||||
void ShowEvent(AccShowEvent* aShowEvent);
|
||||
|
||||
/*
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/a11y/Platform.h"
|
||||
#include "ProxyAccessible.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@ -186,6 +187,18 @@ DocAccessibleParent::ShutdownAccessibles(ProxyEntry* entry, void*)
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleParent::RecvShutdown()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (!static_cast<dom::TabParent*>(Manager())->IsDestroyed()) {
|
||||
return PDocAccessibleParent::Send__delete__(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessibleParent::Destroy()
|
||||
{
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
mParentDoc = nullptr;
|
||||
}
|
||||
|
||||
virtual bool RecvShutdown() override;
|
||||
void Destroy();
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ prio(normal upto high) sync protocol PDocAccessible
|
||||
manager PBrowser;
|
||||
|
||||
parent:
|
||||
__delete__();
|
||||
Shutdown();
|
||||
|
||||
/*
|
||||
* Notify the parent process the document in the child process is firing an
|
||||
@ -67,6 +67,8 @@ parent:
|
||||
BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
|
||||
|
||||
child:
|
||||
__delete__();
|
||||
|
||||
// Accessible
|
||||
prio(high) sync State(uint64_t aID) returns(uint64_t states);
|
||||
prio(high) sync Name(uint64_t aID) returns(nsString name);
|
||||
|
@ -1924,3 +1924,8 @@ pref("browser.pocket.useLocaleList", true);
|
||||
pref("browser.pocket.enabledLocales", "en-US de es-ES ja ja-JP-mac ru");
|
||||
|
||||
pref("view_source.tab", true);
|
||||
|
||||
// Enable Service Workers for desktop on non-release builds
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("dom.serviceWorkers.enabled", true);
|
||||
#endif
|
||||
|
Binary file not shown.
Binary file not shown.
@ -96,6 +96,7 @@ http://example.net:80 privileged
|
||||
http://prefixexample.com:80
|
||||
|
||||
https://example.com:443 privileged
|
||||
https://example.org:443 privileged
|
||||
https://test1.example.com:443 privileged
|
||||
https://test2.example.com:443 privileged
|
||||
https://sub1.test1.example.com:443 privileged
|
||||
|
@ -247,6 +247,7 @@ nsString* nsContentUtils::sModifierSeparator = nullptr;
|
||||
bool nsContentUtils::sInitialized = false;
|
||||
bool nsContentUtils::sIsFullScreenApiEnabled = false;
|
||||
bool nsContentUtils::sTrustedFullScreenOnly = true;
|
||||
bool nsContentUtils::sIsCutCopyAllowed = true;
|
||||
bool nsContentUtils::sIsPerformanceTimingEnabled = false;
|
||||
bool nsContentUtils::sIsResourceTimingEnabled = false;
|
||||
bool nsContentUtils::sIsUserTimingLoggingEnabled = false;
|
||||
@ -514,6 +515,9 @@ nsContentUtils::Init()
|
||||
Preferences::AddBoolVarCache(&sTrustedFullScreenOnly,
|
||||
"full-screen-api.allow-trusted-requests-only");
|
||||
|
||||
Preferences::AddBoolVarCache(&sIsCutCopyAllowed,
|
||||
"dom.allow_cut_copy", true);
|
||||
|
||||
Preferences::AddBoolVarCache(&sIsPerformanceTimingEnabled,
|
||||
"dom.enable_performance", true);
|
||||
|
||||
@ -6632,7 +6636,8 @@ nsContentUtils::IsRequestFullScreenAllowed()
|
||||
bool
|
||||
nsContentUtils::IsCutCopyAllowed()
|
||||
{
|
||||
return EventStateManager::IsHandlingUserInput() ||
|
||||
return (!IsCutCopyRestricted() &&
|
||||
EventStateManager::IsHandlingUserInput()) ||
|
||||
IsCallerChrome();
|
||||
}
|
||||
|
||||
|
@ -1863,6 +1863,15 @@ public:
|
||||
*/
|
||||
static bool IsRequestFullScreenAllowed();
|
||||
|
||||
/**
|
||||
* Returns true if calling execCommand with 'cut' or 'copy' arguments
|
||||
* is restricted to chrome code.
|
||||
*/
|
||||
static bool IsCutCopyRestricted()
|
||||
{
|
||||
return !sIsCutCopyAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if calling execCommand with 'cut' or 'copy' arguments is
|
||||
* allowed in the current context. These are only allowed if the user initiated
|
||||
@ -2434,6 +2443,7 @@ private:
|
||||
static bool sAllowXULXBL_for_file;
|
||||
static bool sIsFullScreenApiEnabled;
|
||||
static bool sTrustedFullScreenOnly;
|
||||
static bool sIsCutCopyAllowed;
|
||||
static uint32_t sHandlingInputTimeout;
|
||||
static bool sIsPerformanceTimingEnabled;
|
||||
static bool sIsResourceTimingEnabled;
|
||||
|
32
dom/cache/DBSchema.cpp
vendored
32
dom/cache/DBSchema.cpp
vendored
@ -29,11 +29,11 @@ namespace dom {
|
||||
namespace cache {
|
||||
namespace db {
|
||||
|
||||
const int32_t kMaxWipeSchemaVersion = 10;
|
||||
const int32_t kMaxWipeSchemaVersion = 11;
|
||||
|
||||
namespace {
|
||||
|
||||
const int32_t kLatestSchemaVersion = 10;
|
||||
const int32_t kLatestSchemaVersion = 11;
|
||||
const int32_t kMaxEntriesPerStatement = 255;
|
||||
|
||||
const uint32_t kPageSize = 4 * 1024;
|
||||
@ -301,6 +301,10 @@ CreateSchema(mozIStorageConnection* aConn)
|
||||
"response_headers_guard INTEGER NOT NULL, "
|
||||
"response_body_id TEXT NULL, "
|
||||
"response_security_info_id INTEGER NULL REFERENCES security_info(id), "
|
||||
"response_redirected INTEGER NOT NULL, "
|
||||
// Note that response_redirected_url is either going to be empty, or
|
||||
// it's going to be a URL different than response_url.
|
||||
"response_redirected_url TEXT NOT NULL, "
|
||||
"cache_id INTEGER NOT NULL REFERENCES caches(id) ON DELETE CASCADE"
|
||||
");"
|
||||
));
|
||||
@ -1468,6 +1472,8 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
"response_headers_guard, "
|
||||
"response_body_id, "
|
||||
"response_security_info_id, "
|
||||
"response_redirected, "
|
||||
"response_redirected_url, "
|
||||
"cache_id "
|
||||
") VALUES ("
|
||||
":request_method, "
|
||||
@ -1488,6 +1494,8 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
":response_headers_guard, "
|
||||
":response_body_id, "
|
||||
":response_security_info_id, "
|
||||
":response_redirected, "
|
||||
":response_redirected_url, "
|
||||
":cache_id "
|
||||
");"
|
||||
), getter_AddRefs(state));
|
||||
@ -1567,6 +1575,14 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_redirected"),
|
||||
aResponse.channelInfo().redirected() ? 1 : 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("response_redirected_url"),
|
||||
aResponse.channelInfo().redirectedURI());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
@ -1658,6 +1674,8 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
"entries.response_status_text, "
|
||||
"entries.response_headers_guard, "
|
||||
"entries.response_body_id, "
|
||||
"entries.response_redirected, "
|
||||
"entries.response_redirected_url, "
|
||||
"security_info.data "
|
||||
"FROM entries "
|
||||
"LEFT OUTER JOIN security_info "
|
||||
@ -1705,7 +1723,15 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
|
||||
rv = state->GetBlobAsUTF8String(6, aSavedResponseOut->mValue.channelInfo().securityInfo());
|
||||
int32_t redirected;
|
||||
rv = state->GetInt32(6, &redirected);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedResponseOut->mValue.channelInfo().redirected() = !!redirected;
|
||||
|
||||
rv = state->GetUTF8String(7, aSavedResponseOut->mValue.channelInfo().redirectedURI());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->GetBlobAsUTF8String(8, aSavedResponseOut->mValue.channelInfo().securityInfo());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsIPresShell.h"
|
||||
@ -1081,18 +1082,44 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent)
|
||||
rv = frame->GetPointFromOffset(range->StartOffset(), &posInFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aEvent->mReply.mWritingMode = frame->GetWritingMode();
|
||||
bool isVertical = aEvent->mReply.mWritingMode.IsVertical();
|
||||
|
||||
nsRect rect;
|
||||
rect.x = posInFrame.x;
|
||||
rect.y = posInFrame.y;
|
||||
rect.width = caretRect.width;
|
||||
rect.height = frame->GetSize().height;
|
||||
|
||||
nscoord fontHeight = 0;
|
||||
float inflation = nsLayoutUtils::FontSizeInflationFor(frame);
|
||||
nsRefPtr<nsFontMetrics> fontMetrics;
|
||||
rv = nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fontMetrics),
|
||||
inflation);
|
||||
if (NS_WARN_IF(!fontMetrics)) {
|
||||
// If we cannot get font height, use frame size instead.
|
||||
fontHeight = isVertical ? frame->GetSize().width : frame->GetSize().height;
|
||||
} else {
|
||||
fontHeight = fontMetrics->MaxAscent() + fontMetrics->MaxDescent();
|
||||
}
|
||||
if (isVertical) {
|
||||
rect.width = fontHeight;
|
||||
rect.height = caretRect.height;
|
||||
} else {
|
||||
rect.width = caretRect.width;
|
||||
rect.height = fontHeight;
|
||||
}
|
||||
|
||||
rv = ConvertToRootViewRelativeOffset(frame, rect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped(
|
||||
rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
|
||||
aEvent->mReply.mWritingMode = frame->GetWritingMode();
|
||||
// If the caret rect is empty, let's make it non-empty rect.
|
||||
if (!aEvent->mReply.mRect.width) {
|
||||
aEvent->mReply.mRect.width = 1;
|
||||
}
|
||||
if (!aEvent->mReply.mRect.height) {
|
||||
aEvent->mReply.mRect.height = 1;
|
||||
}
|
||||
aEvent->mSucceeded = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/ipc/ChannelInfo.h"
|
||||
#include "nsIJARChannel.h"
|
||||
#include "nsJARChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -20,6 +21,7 @@ using namespace mozilla::dom;
|
||||
void
|
||||
ChannelInfo::InitFromChannel(nsIChannel* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mInited, "Cannot initialize the object twice");
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
@ -28,6 +30,20 @@ ChannelInfo::InitFromChannel(nsIChannel* aChannel)
|
||||
SetSecurityInfo(securityInfo);
|
||||
}
|
||||
|
||||
nsLoadFlags loadFlags = 0;
|
||||
aChannel->GetLoadFlags(&loadFlags);
|
||||
mRedirected = (loadFlags & nsIChannel::LOAD_REPLACE);
|
||||
if (mRedirected) {
|
||||
// Save the spec and not the nsIURI object itself, since those objects are
|
||||
// not thread-safe, and releasing them somewhere other than the main thread
|
||||
// is not possible.
|
||||
nsCOMPtr<nsIURI> redirectedURI;
|
||||
aChannel->GetURI(getter_AddRefs(redirectedURI));
|
||||
if (redirectedURI) {
|
||||
redirectedURI->GetSpec(mRedirectedURISpec);
|
||||
}
|
||||
}
|
||||
|
||||
mInited = true;
|
||||
}
|
||||
|
||||
@ -37,6 +53,8 @@ ChannelInfo::InitFromIPCChannelInfo(const ipc::IPCChannelInfo& aChannelInfo)
|
||||
MOZ_ASSERT(!mInited, "Cannot initialize the object twice");
|
||||
|
||||
mSecurityInfo = aChannelInfo.securityInfo();
|
||||
mRedirectedURISpec = aChannelInfo.redirectedURI();
|
||||
mRedirected = aChannelInfo.redirected();
|
||||
|
||||
mInited = true;
|
||||
}
|
||||
@ -56,16 +74,22 @@ ChannelInfo::SetSecurityInfo(nsISupports* aSecurityInfo)
|
||||
nsresult
|
||||
ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mInited);
|
||||
|
||||
// These pointers may be null at this point. They must be checked before
|
||||
// being dereferenced.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
nsCOMPtr<nsIJARChannel> jarChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
|
||||
if (!mSecurityInfo.IsEmpty()) {
|
||||
nsCOMPtr<nsISupports> infoObj;
|
||||
nsresult rv = NS_DeserializeObject(mSecurityInfo, getter_AddRefs(infoObj));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
if (httpChannel) {
|
||||
net::HttpBaseChannel* httpBaseChannel =
|
||||
static_cast<net::HttpBaseChannel*>(httpChannel.get());
|
||||
@ -74,8 +98,6 @@ ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel)
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIJARChannel> jarChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
if (NS_WARN_IF(!jarChannel)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -84,6 +106,30 @@ ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel)
|
||||
}
|
||||
}
|
||||
|
||||
if (mRedirected) {
|
||||
nsLoadFlags flags = 0;
|
||||
aChannel->GetLoadFlags(&flags);
|
||||
flags |= nsIChannel::LOAD_REPLACE;
|
||||
aChannel->SetLoadFlags(flags);
|
||||
|
||||
nsCOMPtr<nsIURI> redirectedURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(redirectedURI),
|
||||
mRedirectedURISpec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (httpChannel) {
|
||||
net::HttpBaseChannel* httpBaseChannel =
|
||||
static_cast<net::HttpBaseChannel*>(httpChannel.get());
|
||||
httpBaseChannel->OverrideURI(redirectedURI);
|
||||
} else {
|
||||
if (NS_WARN_IF(!jarChannel)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
static_cast<nsJARChannel*>(jarChannel.get())->OverrideURI(redirectedURI);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -98,6 +144,8 @@ ChannelInfo::AsIPCChannelInfo() const
|
||||
IPCChannelInfo ipcInfo;
|
||||
|
||||
ipcInfo.securityInfo() = mSecurityInfo;
|
||||
ipcInfo.redirectedURI() = mRedirectedURISpec;
|
||||
ipcInfo.redirected() = mRedirected;
|
||||
|
||||
return ipcInfo;
|
||||
}
|
||||
|
@ -8,8 +8,10 @@
|
||||
#define mozilla_dom_ChannelInfo_h
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIChannel;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
@ -42,12 +44,15 @@ public:
|
||||
|
||||
ChannelInfo()
|
||||
: mInited(false)
|
||||
, mRedirected(false)
|
||||
{
|
||||
}
|
||||
|
||||
ChannelInfo(const ChannelInfo& aRHS)
|
||||
: mSecurityInfo(aRHS.mSecurityInfo)
|
||||
, mRedirectedURISpec(aRHS.mRedirectedURISpec)
|
||||
, mInited(aRHS.mInited)
|
||||
, mRedirected(aRHS.mRedirected)
|
||||
{
|
||||
}
|
||||
|
||||
@ -55,7 +60,9 @@ public:
|
||||
operator=(const ChannelInfo& aRHS)
|
||||
{
|
||||
mSecurityInfo = aRHS.mSecurityInfo;
|
||||
mRedirectedURISpec = aRHS.mRedirectedURISpec;
|
||||
mInited = aRHS.mInited;
|
||||
mRedirected = aRHS.mRedirected;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -78,7 +85,9 @@ private:
|
||||
|
||||
private:
|
||||
nsCString mSecurityInfo;
|
||||
nsCString mRedirectedURISpec;
|
||||
bool mInited;
|
||||
bool mRedirected;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -8,6 +8,8 @@ namespace ipc {
|
||||
struct IPCChannelInfo
|
||||
{
|
||||
nsCString securityInfo;
|
||||
nsCString redirectedURI;
|
||||
bool redirected;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
@ -85,7 +85,10 @@ class ImageLoadTask : public nsRunnable
|
||||
public:
|
||||
explicit ImageLoadTask(HTMLImageElement *aElement) :
|
||||
mElement(aElement)
|
||||
{}
|
||||
{
|
||||
mDocument = aElement->OwnerDoc();
|
||||
mDocument->BlockOnload();
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
@ -93,12 +96,14 @@ public:
|
||||
mElement->mPendingImageLoadTask = nullptr;
|
||||
mElement->LoadSelectedImage(true, true);
|
||||
}
|
||||
mDocument->UnblockOnload(false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~ImageLoadTask() {}
|
||||
nsRefPtr<HTMLImageElement> mElement;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
};
|
||||
|
||||
HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
|
@ -3569,12 +3569,22 @@ nsHTMLDocument::QueryCommandSupported(const nsAString & commandID,
|
||||
bool
|
||||
nsHTMLDocument::QueryCommandSupported(const nsAString& commandID)
|
||||
{
|
||||
// Gecko technically supports the paste command, but non-privileged content
|
||||
// will be unable to call it. For that reason, we report that paste is
|
||||
// not supported to this non-privileged content (as it effectively is).
|
||||
bool restricted = commandID.LowerCaseEqualsLiteral("paste");
|
||||
if (restricted && !nsContentUtils::IsCallerChrome()) {
|
||||
return false;
|
||||
// Gecko technically supports all the clipboard commands including
|
||||
// cut/copy/paste, but non-privileged content will be unable to call
|
||||
// paste, and depending on the pref "dom.allow_cut_copy", cut and copy
|
||||
// may also be disallowed to be called from non-privileged content.
|
||||
// For that reason, we report the support status of corresponding
|
||||
// command accordingly.
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
if (commandID.LowerCaseEqualsLiteral("paste")) {
|
||||
return false;
|
||||
}
|
||||
if (nsContentUtils::IsCutCopyRestricted()) {
|
||||
if (commandID.LowerCaseEqualsLiteral("cut") ||
|
||||
commandID.LowerCaseEqualsLiteral("copy")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// commandID is supported if it can be converted to a Midas command
|
||||
|
@ -594,5 +594,4 @@ support-files = file_bug871161-1.html file_bug871161-2.html
|
||||
[test_window_open_close.html]
|
||||
skip-if = buildapp == 'b2g' # bug 1129014
|
||||
[test_img_complete.html]
|
||||
[test_viewport_resize.html]
|
||||
skip-if = os == 'win' || os == 'mac' # bug 1163911
|
||||
[test_viewport_resize.html]
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/dom/Date.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/DetailedPromise.h"
|
||||
#include "mozilla/dom/MediaKeySessionBinding.h"
|
||||
#include "mozilla/dom/MediaKeysBinding.h"
|
||||
#include "mozilla/dom/MediaKeyMessageEventBinding.h"
|
||||
|
@ -104,3 +104,4 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet'
|
||||
[test_bug1012662_editor.html]
|
||||
[test_bug1012662_noeditor.html]
|
||||
[test_bug1161721.html]
|
||||
[test_bug1170911.html]
|
||||
|
90
dom/tests/mochitest/general/test_bug1170911.html
Normal file
90
dom/tests/mochitest/general/test_bug1170911.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1012662
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1170911</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1170911">Mozilla Bug 1170911</a>
|
||||
<p id="display"></p>
|
||||
|
||||
<div id="content">
|
||||
<textarea>textarea text</textarea>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script>
|
||||
const TEXTAREA = document.querySelector('textarea');
|
||||
const TEXTAREA_VALUE = TEXTAREA.value;
|
||||
|
||||
function doTest() {
|
||||
is(document.queryCommandSupported("copy"), false,
|
||||
"Copy support should have been disabled");
|
||||
is(document.queryCommandSupported("cut"), false,
|
||||
"Cut support should have been disabled");
|
||||
|
||||
document.addEventListener("keydown", tryCopy);
|
||||
synthesizeKey("Q", {});
|
||||
}
|
||||
|
||||
function tryCopy(evt) {
|
||||
evt.preventDefault();
|
||||
document.removeEventListener("keydown", tryCopy);
|
||||
TEXTAREA.setSelectionRange(0, TEXTAREA_VALUE.length);
|
||||
TEXTAREA.focus();
|
||||
|
||||
SimpleTest.waitForClipboard(null, function () {
|
||||
is(document.queryCommandEnabled("copy"), false,
|
||||
"Copy should not be allowed when dom.allow_cut_copy is off");
|
||||
is(document.execCommand("copy"), false,
|
||||
"Copy should not be executed when dom.allow_cut_copy is off");
|
||||
is(TEXTAREA.value, TEXTAREA_VALUE,
|
||||
"Content in the textarea shouldn't be changed");
|
||||
TEXTAREA.value = TEXTAREA_VALUE;
|
||||
},
|
||||
/* success fn */ SimpleTest.finish,
|
||||
/* failure fn */ function () {
|
||||
document.addEventListener("keydown", tryCut);
|
||||
synthesizeKey("Q", {});
|
||||
},
|
||||
/* flavor */ undefined,
|
||||
/* timeout */ undefined,
|
||||
/* expect failure */ true);
|
||||
}
|
||||
|
||||
function tryCut(evt) {
|
||||
evt.preventDefault();
|
||||
document.removeEventListener("keydown", tryCut);
|
||||
TEXTAREA.setSelectionRange(0, TEXTAREA_VALUE.length);
|
||||
TEXTAREA.focus();
|
||||
|
||||
SimpleTest.waitForClipboard(null, function () {
|
||||
is(document.queryCommandEnabled("cut"), false,
|
||||
"Cut should not be allowed when dom.allow_cut_copy is off");
|
||||
is(document.execCommand("cut"), false,
|
||||
"Cut should not be executed when dom.allow_cut_copy is off");
|
||||
is(TEXTAREA.value, TEXTAREA_VALUE,
|
||||
"Content in the textarea shouldn't be changed");
|
||||
},
|
||||
/* success fn */ SimpleTest.finish,
|
||||
/* failure fn */ SimpleTest.finish,
|
||||
/* flavor */ undefined,
|
||||
/* timeout */ undefined,
|
||||
/* expect failure */ true);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.allow_cut_copy", false]]}, doTest);
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -917,11 +917,11 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Selection",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ServiceWorker", disabled: true, b2g: false},
|
||||
{name: "ServiceWorker", release: false, b2g: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ServiceWorkerContainer", disabled: true, b2g: false},
|
||||
{name: "ServiceWorkerContainer", release: false, b2g: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ServiceWorkerRegistration", disabled: true, b2g: false},
|
||||
{name: "ServiceWorkerRegistration", release: false, b2g: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SettingsLock",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
Binary file not shown.
@ -17,6 +17,10 @@ function runTests() {
|
||||
return testFetchAppResource('test_custom_content_type',
|
||||
'customContentType', 'text/html');
|
||||
})
|
||||
.then(testRedirectedResponse)
|
||||
.then(testRedirectedHttpsResponse)
|
||||
.then(testCachedRedirectedResponse)
|
||||
.then(testCachedRedirectedHttpsResponse)
|
||||
.then(done);
|
||||
}
|
||||
</script>
|
||||
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
real index
|
@ -0,0 +1 @@
|
||||
Access-Control-Allow-Origin: *
|
@ -0,0 +1,5 @@
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
||||
response.setHeader("Location", "https://example.org/tests/dom/workers/test/serviceworkers/app-protocol/realindex.html", false);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
||||
response.setHeader("Location", "http://example.org/tests/dom/workers/test/serviceworkers/app-protocol/realindex.html", false);
|
||||
}
|
@ -1,3 +1,20 @@
|
||||
const kHTTPRedirect = "http://example.com/tests/dom/workers/test/serviceworkers/app-protocol/redirect.sjs";
|
||||
const kHTTPSRedirect = "https://example.com/tests/dom/workers/test/serviceworkers/app-protocol/redirect-https.sjs";
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
self.caches.open("origin-app-cache")
|
||||
.then(c => {
|
||||
return Promise.all(
|
||||
[
|
||||
c.add(kHTTPRedirect),
|
||||
c.add(kHTTPSRedirect),
|
||||
]
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
if (event.request.url.indexOf('foo.txt') >= 0) {
|
||||
event.respondWith(new Response('swresponse', {
|
||||
@ -17,4 +34,30 @@ self.addEventListener('fetch', (event) => {
|
||||
headers: {'Content-Type': 'text/html'}
|
||||
}));
|
||||
}
|
||||
|
||||
if (event.request.url.indexOf('redirected.html') >= 0) {
|
||||
event.respondWith(fetch(kHTTPRedirect));
|
||||
}
|
||||
|
||||
if (event.request.url.indexOf('redirected-https.html') >= 0) {
|
||||
event.respondWith(fetch(kHTTPSRedirect));
|
||||
}
|
||||
|
||||
if (event.request.url.indexOf('redirected-cached.html') >= 0) {
|
||||
event.respondWith(
|
||||
self.caches.open("origin-app-cache")
|
||||
.then(c => {
|
||||
return c.match(kHTTPRedirect);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (event.request.url.indexOf('redirected-https-cached.html') >= 0) {
|
||||
event.respondWith(
|
||||
self.caches.open("origin-app-cache")
|
||||
.then(c => {
|
||||
return c.match(kHTTPSRedirect);
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -37,3 +37,36 @@ function testFetchAppResource(aUrl,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testRedirectedResponse() {
|
||||
return testRedirectedResponseWorker("redirected", "IFRAMELOADED");
|
||||
}
|
||||
|
||||
function testRedirectedHttpsResponse() {
|
||||
return testRedirectedResponseWorker("redirected-https", "HTTPSIFRAMELOADED");
|
||||
}
|
||||
|
||||
function testCachedRedirectedResponse() {
|
||||
return testRedirectedResponseWorker("redirected-cached", "IFRAMELOADED");
|
||||
}
|
||||
|
||||
function testCachedRedirectedHttpsResponse() {
|
||||
return testRedirectedResponseWorker("redirected-https-cached", "HTTPSIFRAMELOADED");
|
||||
}
|
||||
|
||||
function testRedirectedResponseWorker(aFrameId, aAlert) {
|
||||
// Because of the CSP policies applied to privileged apps, we cannot run
|
||||
// inline script inside realindex.html, and loading a script from the app://
|
||||
// URI is also not an option, so we let the parent iframe which has access
|
||||
// to the SpecialPowers API use those privileges to access the document.
|
||||
var iframe = document.createElement("iframe");
|
||||
document.body.appendChild(iframe);
|
||||
iframe.src = aFrameId + ".html";
|
||||
iframe.id = aFrameId;
|
||||
return new Promise(resolve => {
|
||||
iframe.addEventListener("load", event => {
|
||||
alert(aAlert);
|
||||
resolve();
|
||||
}, false);
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
||||
response.setHeader("Location", "https://example.org/tests/dom/workers/test/serviceworkers/fetch/origin/https/realindex.html", false);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
var prefix = "/tests/dom/workers/test/serviceworkers/fetch/origin/https/";
|
||||
|
||||
self.addEventListener("install", function(event) {
|
||||
event.waitUntil(
|
||||
self.caches.open("origin-cache")
|
||||
.then(c => {
|
||||
return c.add(prefix + 'index-https.sjs');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", function(event) {
|
||||
if (event.request.url.indexOf("index-cached-https.sjs") >= 0) {
|
||||
event.respondWith(
|
||||
self.caches.open("origin-cache")
|
||||
.then(c => {
|
||||
return c.match(prefix + 'index-https.sjs');
|
||||
})
|
||||
);
|
||||
} else {
|
||||
event.respondWith(fetch(event.request));
|
||||
}
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
window.opener.postMessage({status: "domain", data: document.domain}, "*");
|
||||
window.opener.postMessage({status: "origin", data: location.origin}, "*");
|
||||
window.opener.postMessage({status: "done"}, "*");
|
||||
</script>
|
@ -0,0 +1 @@
|
||||
Access-Control-Allow-Origin: https://example.com
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
function ok(v, msg) {
|
||||
window.parent.postMessage({status: "ok", result: !!v, message: msg}, "*");
|
||||
}
|
||||
|
||||
function done(reg) {
|
||||
ok(reg.active, "The active worker should be available.");
|
||||
window.parent.postMessage({status: "registrationdone"}, "*");
|
||||
}
|
||||
|
||||
navigator.serviceWorker.ready.then(done);
|
||||
navigator.serviceWorker.register("origin_test.js", {scope: "."});
|
||||
</script>
|
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
navigator.serviceWorker.getRegistration(".").then(function(registration) {
|
||||
registration.unregister().then(function(success) {
|
||||
if (success) {
|
||||
window.parent.postMessage({status: "unregistrationdone"}, "*");
|
||||
}
|
||||
}, function(e) {
|
||||
dump("Unregistering the SW failed with " + e + "\n");
|
||||
});
|
||||
});
|
||||
</script>
|
@ -0,0 +1,4 @@
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
||||
response.setHeader("Location", "https://example.org/tests/dom/workers/test/serviceworkers/fetch/origin/realindex.html", false);
|
||||
}
|
4
dom/workers/test/serviceworkers/fetch/origin/index.sjs
Normal file
4
dom/workers/test/serviceworkers/fetch/origin/index.sjs
Normal file
@ -0,0 +1,4 @@
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
||||
response.setHeader("Location", "http://example.org/tests/dom/workers/test/serviceworkers/fetch/origin/realindex.html", false);
|
||||
}
|
35
dom/workers/test/serviceworkers/fetch/origin/origin_test.js
Normal file
35
dom/workers/test/serviceworkers/fetch/origin/origin_test.js
Normal file
@ -0,0 +1,35 @@
|
||||
var prefix = "/tests/dom/workers/test/serviceworkers/fetch/origin/";
|
||||
|
||||
self.addEventListener("install", function(event) {
|
||||
event.waitUntil(
|
||||
self.caches.open("origin-cache")
|
||||
.then(c => {
|
||||
return Promise.all(
|
||||
[
|
||||
c.add(prefix + 'index.sjs'),
|
||||
c.add(prefix + 'index-to-https.sjs'),
|
||||
]
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", function(event) {
|
||||
if (event.request.url.indexOf("index-cached.sjs") >= 0) {
|
||||
event.respondWith(
|
||||
self.caches.open("origin-cache")
|
||||
.then(c => {
|
||||
return c.match(prefix + 'index.sjs');
|
||||
})
|
||||
);
|
||||
} else if (event.request.url.indexOf("index-to-https-cached.sjs") >= 0) {
|
||||
event.respondWith(
|
||||
self.caches.open("origin-cache")
|
||||
.then(c => {
|
||||
return c.match(prefix + 'index-to-https.sjs');
|
||||
})
|
||||
);
|
||||
} else {
|
||||
event.respondWith(fetch(event.request));
|
||||
}
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
window.opener.postMessage({status: "domain", data: document.domain}, "*");
|
||||
window.opener.postMessage({status: "origin", data: location.origin}, "*");
|
||||
window.opener.postMessage({status: "done"}, "*");
|
||||
</script>
|
@ -0,0 +1 @@
|
||||
Access-Control-Allow-Origin: http://mochi.test:8888
|
14
dom/workers/test/serviceworkers/fetch/origin/register.html
Normal file
14
dom/workers/test/serviceworkers/fetch/origin/register.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
function ok(v, msg) {
|
||||
window.parent.postMessage({status: "ok", result: !!v, message: msg}, "*");
|
||||
}
|
||||
|
||||
function done(reg) {
|
||||
ok(reg.active, "The active worker should be available.");
|
||||
window.parent.postMessage({status: "registrationdone"}, "*");
|
||||
}
|
||||
|
||||
navigator.serviceWorker.ready.then(done);
|
||||
navigator.serviceWorker.register("origin_test.js", {scope: "."});
|
||||
</script>
|
12
dom/workers/test/serviceworkers/fetch/origin/unregister.html
Normal file
12
dom/workers/test/serviceworkers/fetch/origin/unregister.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
navigator.serviceWorker.getRegistration(".").then(function(registration) {
|
||||
registration.unregister().then(function(success) {
|
||||
if (success) {
|
||||
window.parent.postMessage({status: "unregistrationdone"}, "*");
|
||||
}
|
||||
}, function(e) {
|
||||
dump("Unregistering the SW failed with " + e + "\n");
|
||||
});
|
||||
});
|
||||
</script>
|
@ -47,6 +47,19 @@ support-files =
|
||||
fetch/https/clonedresponse/register.html
|
||||
fetch/https/clonedresponse/unregister.html
|
||||
fetch/https/clonedresponse/https_test.js
|
||||
fetch/origin/index.sjs
|
||||
fetch/origin/index-to-https.sjs
|
||||
fetch/origin/realindex.html
|
||||
fetch/origin/realindex.html^headers^
|
||||
fetch/origin/register.html
|
||||
fetch/origin/unregister.html
|
||||
fetch/origin/origin_test.js
|
||||
fetch/origin/https/index-https.sjs
|
||||
fetch/origin/https/realindex.html
|
||||
fetch/origin/https/realindex.html^headers^
|
||||
fetch/origin/https/register.html
|
||||
fetch/origin/https/unregister.html
|
||||
fetch/origin/https/origin_test.js
|
||||
fetch/requesturl/index.html
|
||||
fetch/requesturl/redirect.sjs
|
||||
fetch/requesturl/redirector.html
|
||||
@ -159,3 +172,9 @@ support-files =
|
||||
[test_skip_waiting.html]
|
||||
[test_strict_mode_error.html]
|
||||
[test_cross_origin_url_after_redirect.html]
|
||||
[test_origin_after_redirect.html]
|
||||
[test_origin_after_redirect_cached.html]
|
||||
[test_origin_after_redirect_to_https.html]
|
||||
[test_origin_after_redirect_to_https_cached.html]
|
||||
[test_https_origin_after_redirect.html]
|
||||
[test_https_origin_after_redirect_cached.html]
|
||||
|
@ -28,7 +28,8 @@ function setup() {
|
||||
['dom.mozBrowserFramesEnabled', true],
|
||||
['dom.serviceWorkers.exemptFromPerDomainMax', true],
|
||||
['dom.serviceWorkers.enabled', true],
|
||||
['dom.serviceWorkers.testing.enabled', true]
|
||||
['dom.serviceWorkers.testing.enabled', true],
|
||||
['dom.caches.enabled', true],
|
||||
]}, () => {
|
||||
SpecialPowers.pushPermissions([
|
||||
{ 'type': 'webapps-manage', 'allow': 1, 'context': document },
|
||||
@ -103,6 +104,18 @@ function loadControlled() {
|
||||
ok(true, "Message from app: " + message);
|
||||
} else if (/KO/.exec(message)) {
|
||||
ok(false, "Message from app: " + message);
|
||||
} else if (/HTTPSIFRAMELOADED/.exec(message)) {
|
||||
let doc = SpecialPowers.wrap(iframe).contentDocument;
|
||||
let innerDoc = SpecialPowers.wrap(doc.getElementById("redirected-https").contentDocument);
|
||||
let innerLocation = innerDoc.defaultView.location;
|
||||
is(innerDoc.domain, "example.org", "Correct domain expected (https)");
|
||||
is(innerLocation.origin, "https://example.org", "Correct origin expected (https)");
|
||||
} else if (/IFRAMELOADED/.exec(message)) {
|
||||
let doc = SpecialPowers.wrap(iframe).contentDocument;
|
||||
let innerDoc = SpecialPowers.wrap(doc.getElementById("redirected").contentDocument);
|
||||
let innerLocation = innerDoc.defaultView.location;
|
||||
is(innerDoc.domain, "example.org", "Correct domain expected");
|
||||
is(innerLocation.origin, "http://example.org", "Correct origin expected");
|
||||
} else if (/DONE/.exec(message)) {
|
||||
ok(true, "Messaging from app complete");
|
||||
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
|
||||
|
@ -0,0 +1,56 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test the origin of a redirected response from a service worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
iframe = document.querySelector("iframe");
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/origin/https/register.html";
|
||||
var win;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "registrationdone") {
|
||||
win = window.open("https://example.com/tests/dom/workers/test/serviceworkers/fetch/origin/https/index-https.sjs", "mywindow", "width=100,height=100");
|
||||
} else if (e.data.status == "domain") {
|
||||
is(e.data.data, "example.org", "Correct domain expected");
|
||||
} else if (e.data.status == "origin") {
|
||||
is(e.data.data, "https://example.org", "Correct origin expected");
|
||||
} else if (e.data.status == "done") {
|
||||
win.close();
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/origin/https/unregister.html";
|
||||
} else if (e.data.status == "unregistrationdone") {
|
||||
window.onmessage = null;
|
||||
ok(true, "Test finished successfully");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.caches.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,56 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test the origin of a redirected response from a service worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
iframe = document.querySelector("iframe");
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/origin/https/register.html";
|
||||
var win;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "registrationdone") {
|
||||
win = window.open("https://example.com/tests/dom/workers/test/serviceworkers/fetch/origin/https/index-cached-https.sjs", "mywindow", "width=100,height=100");
|
||||
} else if (e.data.status == "domain") {
|
||||
is(e.data.data, "example.org", "Correct domain expected");
|
||||
} else if (e.data.status == "origin") {
|
||||
is(e.data.data, "https://example.org", "Correct origin expected");
|
||||
} else if (e.data.status == "done") {
|
||||
win.close();
|
||||
iframe.src = "https://example.com/tests/dom/workers/test/serviceworkers/fetch/origin/https/unregister.html";
|
||||
} else if (e.data.status == "unregistrationdone") {
|
||||
window.onmessage = null;
|
||||
ok(true, "Test finished successfully");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.caches.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test the origin of a redirected response from a service worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
iframe = document.querySelector("iframe");
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/register.html";
|
||||
var win;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "registrationdone") {
|
||||
win = window.open("/tests/dom/workers/test/serviceworkers/fetch/origin/index.sjs", "mywindow", "width=100,height=100");
|
||||
} else if (e.data.status == "domain") {
|
||||
is(e.data.data, "example.org", "Correct domain expected");
|
||||
} else if (e.data.status == "origin") {
|
||||
is(e.data.data, "http://example.org", "Correct origin expected");
|
||||
} else if (e.data.status == "done") {
|
||||
win.close();
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/unregister.html";
|
||||
} else if (e.data.status == "unregistrationdone") {
|
||||
window.onmessage = null;
|
||||
ok(true, "Test finished successfully");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.caches.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test the origin of a redirected response from a service worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
iframe = document.querySelector("iframe");
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/register.html";
|
||||
var win;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "registrationdone") {
|
||||
win = window.open("/tests/dom/workers/test/serviceworkers/fetch/origin/index-cached.sjs", "mywindow", "width=100,height=100");
|
||||
} else if (e.data.status == "domain") {
|
||||
is(e.data.data, "example.org", "Correct domain expected");
|
||||
} else if (e.data.status == "origin") {
|
||||
is(e.data.data, "http://example.org", "Correct origin expected");
|
||||
} else if (e.data.status == "done") {
|
||||
win.close();
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/unregister.html";
|
||||
} else if (e.data.status == "unregistrationdone") {
|
||||
window.onmessage = null;
|
||||
ok(true, "Test finished successfully");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.caches.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test the origin of a redirected response from a service worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
iframe = document.querySelector("iframe");
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/register.html";
|
||||
var win;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "registrationdone") {
|
||||
win = window.open("/tests/dom/workers/test/serviceworkers/fetch/origin/index-to-https.sjs", "mywindow", "width=100,height=100");
|
||||
} else if (e.data.status == "domain") {
|
||||
is(e.data.data, "example.org", "Correct domain expected");
|
||||
} else if (e.data.status == "origin") {
|
||||
is(e.data.data, "https://example.org", "Correct origin expected");
|
||||
} else if (e.data.status == "done") {
|
||||
win.close();
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/unregister.html";
|
||||
} else if (e.data.status == "unregistrationdone") {
|
||||
window.onmessage = null;
|
||||
ok(true, "Test finished successfully");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.caches.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test the origin of a redirected response from a service worker</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var iframe;
|
||||
function runTest() {
|
||||
iframe = document.querySelector("iframe");
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/register.html";
|
||||
var win;
|
||||
window.onmessage = function(e) {
|
||||
if (e.data.status == "ok") {
|
||||
ok(e.data.result, e.data.message);
|
||||
} else if (e.data.status == "registrationdone") {
|
||||
win = window.open("/tests/dom/workers/test/serviceworkers/fetch/origin/index-to-https-cached.sjs", "mywindow", "width=100,height=100");
|
||||
} else if (e.data.status == "domain") {
|
||||
is(e.data.data, "example.org", "Correct domain expected");
|
||||
} else if (e.data.status == "origin") {
|
||||
is(e.data.data, "https://example.org", "Correct origin expected");
|
||||
} else if (e.data.status == "done") {
|
||||
win.close();
|
||||
iframe.src = "/tests/dom/workers/test/serviceworkers/fetch/origin/unregister.html";
|
||||
} else if (e.data.status == "unregistrationdone") {
|
||||
window.onmessage = null;
|
||||
ok(true, "Test finished successfully");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function() {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.caches.enabled", true],
|
||||
]}, runTest);
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -157,7 +157,7 @@ var interfaceNamesInGlobalScope =
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Response",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "ServiceWorkerRegistration", disabled: true, b2g: false },
|
||||
{ name: "ServiceWorkerRegistration", release: false, b2g: false },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"TextDecoder",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -2246,7 +2246,7 @@ gfxPlatform::OptimalFormatForContent(gfxContentType aContent)
|
||||
*/
|
||||
static bool sLayersSupportsD3D9 = false;
|
||||
static bool sLayersSupportsD3D11 = false;
|
||||
static bool sANGLESupportsD3D11 = false;
|
||||
bool gANGLESupportsD3D11 = false;
|
||||
static bool sLayersSupportsHardwareVideoDecoding = false;
|
||||
static bool sLayersHardwareVideoDecodingFailed = false;
|
||||
static bool sBufferRotationCheckPref = true;
|
||||
@ -2291,7 +2291,7 @@ InitLayersAccelerationPrefs()
|
||||
}
|
||||
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_11_ANGLE, &status))) {
|
||||
if (status == nsIGfxInfo::FEATURE_STATUS_OK) {
|
||||
sANGLESupportsD3D11 = true;
|
||||
gANGLESupportsD3D11 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2347,7 +2347,7 @@ bool
|
||||
gfxPlatform::CanUseDirect3D11ANGLE()
|
||||
{
|
||||
MOZ_ASSERT(sLayersAccelerationPrefsInitialized);
|
||||
return sANGLESupportsD3D11;
|
||||
return gANGLESupportsD3D11;
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,6 +131,8 @@ enum eGfxLog {
|
||||
// when searching through pref langs, max number of pref langs
|
||||
const uint32_t kMaxLenPrefLangList = 32;
|
||||
|
||||
extern bool gANGLESupportsD3D11;
|
||||
|
||||
#define UNINITIALIZED_VALUE (-1)
|
||||
|
||||
inline const char*
|
||||
|
@ -577,7 +577,12 @@ static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
|
||||
mozilla::TimeStamp previousVsync = display->mPreviousTimestamp;
|
||||
display->mPreviousTimestamp = nextVsync;
|
||||
mozilla::TimeStamp now = TimeStamp::Now();
|
||||
MOZ_ASSERT(nextVsync > previousVsync);
|
||||
if (nextVsync <= previousVsync) {
|
||||
TimeDuration next = nextVsync - now;
|
||||
TimeDuration prev = now - previousVsync;
|
||||
printf_stderr("Next from now: %f, prev from now: %f\n", next.ToMilliseconds(), prev.ToMilliseconds());
|
||||
MOZ_ASSERT(false, "Next vsync less than previous vsync\n");
|
||||
}
|
||||
|
||||
// Bug 1158321 - The VsyncCallback can sometimes execute before the reported
|
||||
// vsync time. In those cases, normalize the timestamp to Now() as sending
|
||||
|
@ -1718,12 +1718,14 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DisplayLink: could not parse version\n"));
|
||||
#endif
|
||||
gANGLESupportsD3D11 = false;
|
||||
return false;
|
||||
}
|
||||
if (displayLinkModuleVersion <= V(8,6,1,36484)) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DisplayLink: too old version\n"));
|
||||
#endif
|
||||
gANGLESupportsD3D11 = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,19 @@ const expectedString = "Hello\nWorld";
|
||||
|
||||
function run_test() {
|
||||
var failures = false;
|
||||
var encodingConverter = CreateScriptableConverter();
|
||||
|
||||
var decoders = [
|
||||
var encoders = [
|
||||
"Big5",
|
||||
"Big5-HKSCS",
|
||||
"EUC-JP",
|
||||
"EUC-KR",
|
||||
"gb18030",
|
||||
"gbk",
|
||||
"IBM866",
|
||||
"ISO-2022-JP",
|
||||
"ISO-8859-1",
|
||||
"ISO-8859-2",
|
||||
"ISO-8859-3",
|
||||
"ISO-8859-4",
|
||||
"ISO-8859-5",
|
||||
@ -27,7 +31,6 @@ function run_test() {
|
||||
"ISO-8859-14",
|
||||
"ISO-8859-15",
|
||||
"ISO-8859-16",
|
||||
"ISO-8859-2",
|
||||
"KOI8-R",
|
||||
"KOI8-U",
|
||||
"Shift_JIS",
|
||||
@ -41,23 +44,18 @@ function run_test() {
|
||||
"windows-1257",
|
||||
"windows-1258",
|
||||
"windows-874",
|
||||
"macintosh",
|
||||
"x-mac-cyrillic",
|
||||
"x-user-defined",
|
||||
"UTF-8"
|
||||
];
|
||||
|
||||
var counter = 0;
|
||||
while (counter < decoders.length) {
|
||||
++counter;
|
||||
var charset = decoders[counter];
|
||||
|
||||
while (counter < encoders.length) {
|
||||
var charset = encoders[counter++];
|
||||
dump("testing " + counter + " " + charset + "\n");
|
||||
|
||||
try {
|
||||
encodingConverter.charset = charset;
|
||||
} catch(e) {
|
||||
dump("Warning: couldn't set encoder charset to " + charset + "\n");
|
||||
continue;
|
||||
}
|
||||
encodingConverter.charset = charset;
|
||||
var codepageString = encodingConverter.ConvertFromUnicode(inString) +
|
||||
encodingConverter.Finish();
|
||||
if (codepageString != expectedString) {
|
||||
|
@ -4,6 +4,7 @@ load('CharsetConversionTests.js');
|
||||
|
||||
function run_test() {
|
||||
var failures = false;
|
||||
var decodingConverter = CreateScriptableConverter();
|
||||
|
||||
var decoders = [
|
||||
"Big5",
|
||||
@ -13,6 +14,8 @@ function run_test() {
|
||||
"gb18030",
|
||||
"IBM866",
|
||||
"ISO-2022-JP",
|
||||
"ISO-8859-1",
|
||||
"ISO-8859-2",
|
||||
"ISO-8859-3",
|
||||
"ISO-8859-4",
|
||||
"ISO-8859-5",
|
||||
@ -25,7 +28,6 @@ function run_test() {
|
||||
"ISO-8859-14",
|
||||
"ISO-8859-15",
|
||||
"ISO-8859-16",
|
||||
"ISO-8859-2",
|
||||
"KOI8-R",
|
||||
"KOI8-U",
|
||||
"Shift_JIS",
|
||||
@ -39,22 +41,18 @@ function run_test() {
|
||||
"windows-1257",
|
||||
"windows-1258",
|
||||
"windows-874",
|
||||
"macintosh",
|
||||
"x-mac-cyrillic",
|
||||
"x-user-defined",
|
||||
"UTF-8"
|
||||
];
|
||||
|
||||
var counter = 0;
|
||||
while (counter < decoders.length) {
|
||||
++counter;
|
||||
var charset = decoders[counter];
|
||||
var charset = decoders[counter++];
|
||||
dump("testing " + counter + " " + charset + "\n");
|
||||
|
||||
try {
|
||||
decodingConverter.charset = charset;
|
||||
} catch(e) {
|
||||
dump("Warning: couldn't set decoder charset to " + charset + "\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
decodingConverter.charset = charset;
|
||||
for (var i = 0x80; i < 0x100; ++i) {
|
||||
var inString = String.fromCharCode(i);
|
||||
var outString;
|
||||
|
@ -6,7 +6,7 @@ load('CharsetConversionTests.js');
|
||||
|
||||
const inString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u20AC\u4E02\u4E04\u4E05\u4E06\u4E0F\u4E12\u4E17\u4E1F\u4E20\u4E21\u4E23\u4E26\u4E29\u4E2E\u4E2F\u4E31\u4E33\u4E35\u4E37\u4E3C\u4E40\u4E41\u4E42\u4E44\u4E46\u4E4A\u4E51\u4E55\u4E57\u4E5A\u4E5B\u4E62\u4E63\u4E64\u4E65\u4E67\u4E68\u4E6A\u4E6B\u4E6C\u4E6D\u4E6E\u4E6F\u4E72\u4E74\u4E75\u4E76\u4E77\u4E78\u4E79\u4E7A\u4E7B\u4E7C\u4E7D\u4E7F\u4E80\u4E81\u4E82\u4E83\u4E84\u4E85\u4E87\u4E8A\uFFFD";
|
||||
|
||||
const expectedString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x80\x81@\x81A\x81B\x81C\x81D\x81E\x81F\x81G\x81H\x81I\x81J\x81K\x81L\x81M\x81N\x81O\x81P\x81Q\x81R\x81S\x81T\x81U\x81V\x81W\x81X\x81Y\x81Z\x81[\x81\\\x81]\x81^\x81_\x81`\x81a\x81b\x81c\x81d\x81e\x81f\x81g\x81h\x81i\x81j\x81k\x81l\x81m\x81n\x81o\x81p\x81q\x81r\x81s\x81t\x81u\x81v\x81w\x81x\x81y\x81z\x81{\x81|\x81}\x81~";
|
||||
const expectedString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x80\x81@\x81A\x81B\x81C\x81D\x81E\x81F\x81G\x81H\x81I\x81J\x81K\x81L\x81M\x81N\x81O\x81P\x81Q\x81R\x81S\x81T\x81U\x81V\x81W\x81X\x81Y\x81Z\x81[\x81\\\x81]\x81^\x81_\x81`\x81a\x81b\x81c\x81d\x81e\x81f\x81g\x81h\x81i\x81j\x81k\x81l\x81m\x81n\x81o\x81p\x81q\x81r\x81s\x81t\x81u\x81v\x81w\x81x\x81y\x81z\x81{\x81|\x81}\x81~?";
|
||||
|
||||
const aliases = [ "gbk", "x-gbk" ];
|
||||
|
||||
|
77
intl/uconv/tests/unit/test_unmapped.js
Normal file
77
intl/uconv/tests/unit/test_unmapped.js
Normal file
@ -0,0 +1,77 @@
|
||||
// Tests encoding of unmapped characters
|
||||
load('CharsetConversionTests.js');
|
||||
|
||||
const inString = "\u2764";
|
||||
const expectedString = "?";
|
||||
|
||||
function run_test() {
|
||||
var failures = false;
|
||||
var encodingConverter = CreateScriptableConverter();
|
||||
|
||||
// this list excludes codepages that can represent all Unicode
|
||||
var encoders = [
|
||||
"Big5",
|
||||
"Big5-HKSCS",
|
||||
"EUC-JP",
|
||||
"EUC-KR",
|
||||
"gbk",
|
||||
"IBM866",
|
||||
"ISO-2022-JP",
|
||||
"ISO-8859-3",
|
||||
"ISO-8859-4",
|
||||
"ISO-8859-5",
|
||||
"ISO-8859-6",
|
||||
"ISO-8859-7",
|
||||
"ISO-8859-8",
|
||||
"ISO-8859-8-I",
|
||||
"ISO-8859-10",
|
||||
"ISO-8859-13",
|
||||
"ISO-8859-14",
|
||||
"ISO-8859-15",
|
||||
"ISO-8859-16",
|
||||
"ISO-8859-2",
|
||||
"KOI8-R",
|
||||
"KOI8-U",
|
||||
"Shift_JIS",
|
||||
"windows-1250",
|
||||
"windows-1251",
|
||||
"windows-1252",
|
||||
"windows-1253",
|
||||
"windows-1254",
|
||||
"windows-1255",
|
||||
"windows-1256",
|
||||
"windows-1257",
|
||||
"windows-1258",
|
||||
"windows-874",
|
||||
"x-mac-cyrillic"
|
||||
];
|
||||
|
||||
var counter = 0;
|
||||
while (counter < encoders.length) {
|
||||
var charset = encoders[counter++];
|
||||
|
||||
dump("testing " + counter + " " + charset + "\n");
|
||||
encodingConverter.charset = charset;
|
||||
var codepageString = encodingConverter.ConvertFromUnicode(inString) +
|
||||
encodingConverter.Finish();
|
||||
if (codepageString != expectedString) {
|
||||
dump(charset + " encoding failed\n");
|
||||
for (var i = 0; i < expectedString.length; ++i) {
|
||||
if (i >= codepageString.length) {
|
||||
dump("output length " + codepageString.length +
|
||||
" less than expected length " + expectedString.length + "\n");
|
||||
break;
|
||||
}
|
||||
if (codepageString.charAt(i) != expectedString.charAt(i)) {
|
||||
dump(i.toString(16) + ": 0x" +
|
||||
codepageString.charCodeAt(i).toString(16) + " != " +
|
||||
expectedString.charCodeAt(i).toString(16) + "\n");
|
||||
}
|
||||
}
|
||||
failures = true;
|
||||
}
|
||||
}
|
||||
if (failures) {
|
||||
do_throw("test failed\n");
|
||||
}
|
||||
}
|
@ -120,3 +120,4 @@ support-files =
|
||||
[test_utf8_illegals.js]
|
||||
[test_input_stream.js]
|
||||
[test_bug1008832.js]
|
||||
[test_unmapped.js]
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -79,30 +79,35 @@ void nsUnicodeToGB18030::Create4BytesEncoder()
|
||||
m4BytesEncoder = new nsUnicodeTo4BytesGB18030();
|
||||
}
|
||||
|
||||
bool nsUnicodeToGB18030::EncodeSurrogate(
|
||||
char16_t aSurrogateHigh,
|
||||
char16_t aSurrogateLow,
|
||||
char* aOut)
|
||||
nsresult nsUnicodeToGB18030::EncodeSurrogate(char16_t aSurrogateHigh,
|
||||
char16_t aSurrogateLow,
|
||||
char* aOut,
|
||||
int32_t aDestLength,
|
||||
int32_t aBufferLength)
|
||||
{
|
||||
if( NS_IS_HIGH_SURROGATE(aSurrogateHigh) &&
|
||||
if( NS_IS_HIGH_SURROGATE(aSurrogateHigh) &&
|
||||
NS_IS_LOW_SURROGATE(aSurrogateLow) )
|
||||
{
|
||||
// notice that idx does not include the 0x10000
|
||||
// notice that idx does not include the 0x10000
|
||||
uint32_t idx = ((aSurrogateHigh - (char16_t)0xD800) << 10 ) |
|
||||
(aSurrogateLow - (char16_t) 0xDC00);
|
||||
|
||||
if (aDestLength + 4 > aBufferLength) {
|
||||
return NS_OK_UENC_MOREOUTPUT;
|
||||
}
|
||||
|
||||
unsigned char *out = (unsigned char*) aOut;
|
||||
// notice this is from 0x90 for supplment planes
|
||||
out[0] = (idx / (10*126*10)) + 0x90;
|
||||
// notice this is from 0x90 for supplementary planes
|
||||
out[0] = (idx / (10*126*10)) + 0x90;
|
||||
idx %= (10*126*10);
|
||||
out[1] = (idx / (10*126)) + 0x30;
|
||||
idx %= (10*126);
|
||||
out[2] = (idx / (10)) + 0x81;
|
||||
out[3] = (idx % 10) + 0x30;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_UENC_NOMAPPING;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsUnicodeToGBK [implementation]
|
||||
@ -122,70 +127,66 @@ void nsUnicodeToGBK::Create4BytesEncoder()
|
||||
{
|
||||
m4BytesEncoder = nullptr;
|
||||
}
|
||||
bool nsUnicodeToGBK::TryExtensionEncoder(
|
||||
char16_t aChar,
|
||||
char* aOut,
|
||||
int32_t *aOutLen
|
||||
)
|
||||
|
||||
nsresult nsUnicodeToGBK::TryExtensionEncoder(char16_t aChar,
|
||||
char* aOut,
|
||||
int32_t *aOutLen)
|
||||
{
|
||||
if( NS_IS_HIGH_SURROGATE(aChar) ||
|
||||
if( NS_IS_HIGH_SURROGATE(aChar) ||
|
||||
NS_IS_LOW_SURROGATE(aChar) )
|
||||
{
|
||||
// performance tune for surrogate characters
|
||||
return false;
|
||||
return NS_ERROR_UENC_NOMAPPING;
|
||||
}
|
||||
if(! mExtensionEncoder )
|
||||
CreateExtensionEncoder();
|
||||
if(mExtensionEncoder)
|
||||
if(mExtensionEncoder)
|
||||
{
|
||||
int32_t len = 1;
|
||||
nsresult res = NS_OK;
|
||||
res = mExtensionEncoder->Convert(&aChar, &len, aOut, aOutLen);
|
||||
if(NS_SUCCEEDED(res) && (*aOutLen > 0))
|
||||
return true;
|
||||
return mExtensionEncoder->Convert(&aChar, &len, aOut, aOutLen);
|
||||
}
|
||||
return false;
|
||||
return NS_ERROR_UENC_NOMAPPING;
|
||||
}
|
||||
|
||||
bool nsUnicodeToGBK::Try4BytesEncoder(
|
||||
nsresult nsUnicodeToGBK::Try4BytesEncoder(
|
||||
char16_t aChar,
|
||||
char* aOut,
|
||||
int32_t *aOutLen
|
||||
)
|
||||
{
|
||||
if( NS_IS_HIGH_SURROGATE(aChar) ||
|
||||
if( NS_IS_HIGH_SURROGATE(aChar) ||
|
||||
NS_IS_LOW_SURROGATE(aChar) )
|
||||
{
|
||||
// performance tune for surrogate characters
|
||||
return false;
|
||||
return NS_ERROR_UENC_NOMAPPING;
|
||||
}
|
||||
if(! m4BytesEncoder )
|
||||
Create4BytesEncoder();
|
||||
if(m4BytesEncoder)
|
||||
if(m4BytesEncoder)
|
||||
{
|
||||
int32_t len = 1;
|
||||
nsresult res = NS_OK;
|
||||
res = m4BytesEncoder->Convert(&aChar, &len, aOut, aOutLen);
|
||||
NS_ASSERTION(NS_FAILED(res) || ((1 == len) && (4 == *aOutLen)),
|
||||
"unexpect conversion length");
|
||||
if(NS_SUCCEEDED(res) && (*aOutLen > 0))
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
return false;
|
||||
return NS_ERROR_UENC_NOMAPPING;
|
||||
}
|
||||
bool nsUnicodeToGBK::EncodeSurrogate(
|
||||
char16_t aSurrogateHigh,
|
||||
char16_t aSurrogateLow,
|
||||
char* aOut)
|
||||
{
|
||||
return false; // GBK cannot encode Surrogate, let the subclass encode it.
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsUnicodeToGBK::ConvertNoBuff(
|
||||
const char16_t * aSrc,
|
||||
int32_t * aSrcLength,
|
||||
char * aDest,
|
||||
int32_t * aDestLength)
|
||||
nsresult nsUnicodeToGBK::EncodeSurrogate(char16_t aSurrogateHigh,
|
||||
char16_t aSurrogateLow,
|
||||
char* aOut,
|
||||
int32_t aDestLength,
|
||||
int32_t aBufferLength)
|
||||
{
|
||||
return NS_ERROR_UENC_NOMAPPING; // GBK cannot encode Surrogate, let the subclass encode it.
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsUnicodeToGBK::ConvertNoBuffNoErr(const char16_t * aSrc,
|
||||
int32_t * aSrcLength,
|
||||
char * aDest,
|
||||
int32_t * aDestLength)
|
||||
{
|
||||
int32_t iSrcLength = 0;
|
||||
int32_t iDestLength = 0;
|
||||
@ -217,59 +218,56 @@ NS_IMETHODIMP nsUnicodeToGBK::ConvertNoBuff(
|
||||
iDestLength +=2;
|
||||
} else {
|
||||
int32_t aOutLen = 2;
|
||||
// make sure we still have 2 bytes for output first
|
||||
if(iDestLength+2 > *aDestLength)
|
||||
{
|
||||
res = NS_OK_UENC_MOREOUTPUT;
|
||||
break;
|
||||
}
|
||||
// we cannot map in the common mapping. Let's try to
|
||||
// call the delegated 2 byte converter for the gbk or gb18030
|
||||
// unique 2 byte mapping
|
||||
if(TryExtensionEncoder(unicode, aDest, &aOutLen))
|
||||
{
|
||||
res = TryExtensionEncoder(unicode, aDest, &aOutLen);
|
||||
if (res == NS_OK) {
|
||||
iDestLength += aOutLen;
|
||||
aDest += aOutLen;
|
||||
} else if (res == NS_OK_UENC_MOREOUTPUT) {
|
||||
break;
|
||||
} else {
|
||||
// make sure we still have 4 bytes for output first
|
||||
if(iDestLength+4 > *aDestLength)
|
||||
{
|
||||
res = NS_OK_UENC_MOREOUTPUT;
|
||||
break;
|
||||
}
|
||||
// we still cannot map. Let's try to
|
||||
// call the delegated GB18030 4 byte converter
|
||||
// call the delegated GB18030 4 byte converter
|
||||
aOutLen = 4;
|
||||
if( NS_IS_HIGH_SURROGATE(unicode) )
|
||||
{
|
||||
if((iSrcLength+1) < *aSrcLength ) {
|
||||
if(EncodeSurrogate(aSrc[0],aSrc[1], aDest)) {
|
||||
res = EncodeSurrogate(aSrc[0],aSrc[1], aDest,
|
||||
iDestLength, *aDestLength);
|
||||
if (res == NS_OK) {
|
||||
// since we got a surrogate pair, we need to increment src.
|
||||
iSrcLength++ ;
|
||||
iSrcLength++ ;
|
||||
aSrc++;
|
||||
iDestLength += aOutLen;
|
||||
aDest += aOutLen;
|
||||
} else {
|
||||
// only get a high surrogate, but not a low surrogate
|
||||
res = NS_ERROR_UENC_NOMAPPING;
|
||||
iSrcLength++; // include length of the unmapped character
|
||||
if (res == NS_ERROR_UENC_NOMAPPING) {
|
||||
// only get a high surrogate, but not a low surrogate
|
||||
iSrcLength++; // include length of the unmapped character
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mSurrogateHigh = aSrc[0];
|
||||
res = NS_OK;
|
||||
break; // this will go to afterwhileloop
|
||||
}
|
||||
} else {
|
||||
if( NS_IS_LOW_SURROGATE(unicode) )
|
||||
{
|
||||
if(NS_IS_HIGH_SURROGATE(mSurrogateHigh)) {
|
||||
if(EncodeSurrogate(mSurrogateHigh, aSrc[0], aDest)) {
|
||||
res = EncodeSurrogate(mSurrogateHigh, aSrc[0], aDest,
|
||||
iDestLength, *aDestLength);
|
||||
if (res == NS_OK) {
|
||||
iDestLength += aOutLen;
|
||||
aDest += aOutLen;
|
||||
} else {
|
||||
// only get a high surrogate, but not a low surrogate
|
||||
res = NS_ERROR_UENC_NOMAPPING;
|
||||
iSrcLength++; // include length of the unmapped character
|
||||
if (res == NS_ERROR_UENC_NOMAPPING) {
|
||||
// only get a high surrogate, but not a low surrogate
|
||||
iSrcLength++; // include length of the unmapped character
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -279,22 +277,23 @@ NS_IMETHODIMP nsUnicodeToGBK::ConvertNoBuff(
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(Try4BytesEncoder(unicode, aDest, &aOutLen))
|
||||
{
|
||||
res = Try4BytesEncoder(unicode, aDest, &aOutLen);
|
||||
if (res == NS_OK) {
|
||||
NS_ASSERTION((aOutLen == 4), "we should always generate 4 bytes here");
|
||||
iDestLength += aOutLen;
|
||||
aDest += aOutLen;
|
||||
} else {
|
||||
res = NS_ERROR_UENC_NOMAPPING;
|
||||
iSrcLength++; // include length of the unmapped character
|
||||
if (res == NS_ERROR_UENC_NOMAPPING) {
|
||||
iSrcLength++; // include length of the unmapped character
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
iSrcLength++ ; // Each unicode char just count as one in char16_t string;
|
||||
iSrcLength++ ; // Each unicode char just count as one in char16_t string;
|
||||
mSurrogateHigh = 0;
|
||||
aSrc++;
|
||||
if ( iDestLength >= (*aDestLength) && (iSrcLength < *aSrcLength) )
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -35,16 +35,10 @@ protected:
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Subclassing of nsEncoderSupport class [declaration]
|
||||
NS_IMETHOD ConvertNoBuff(const char16_t * aSrc,
|
||||
int32_t * aSrcLength,
|
||||
char * aDest,
|
||||
int32_t * aDestLength);
|
||||
|
||||
NS_IMETHOD ConvertNoBuffNoErr(const char16_t * aSrc, int32_t * aSrcLength,
|
||||
char * aDest, int32_t * aDestLength)
|
||||
{
|
||||
return NS_OK;
|
||||
} // just make it not abstract;
|
||||
NS_IMETHOD ConvertNoBuffNoErr(const char16_t * aSrc,
|
||||
int32_t * aSrcLength,
|
||||
char * aDest,
|
||||
int32_t * aDestLength);
|
||||
|
||||
virtual void CreateExtensionEncoder();
|
||||
virtual void Create4BytesEncoder();
|
||||
@ -54,9 +48,11 @@ protected:
|
||||
protected:
|
||||
char16_t mSurrogateHigh;
|
||||
nsGBKConvUtil mUtil;
|
||||
bool TryExtensionEncoder(char16_t aChar, char* aDest, int32_t* aOutLen);
|
||||
bool Try4BytesEncoder(char16_t aChar, char* aDest, int32_t* aOutLen);
|
||||
virtual bool EncodeSurrogate(char16_t aSurrogateHigh, char16_t aSurrogateLow, char* aDest);
|
||||
nsresult TryExtensionEncoder(char16_t aChar, char* aDest, int32_t* aOutLen);
|
||||
nsresult Try4BytesEncoder(char16_t aChar, char* aDest, int32_t* aOutLen);
|
||||
virtual nsresult EncodeSurrogate(char16_t aSurrogateHigh,
|
||||
char16_t aSurrogateLow, char* aDest,
|
||||
int32_t aDestLength, int32_t aBufferLength);
|
||||
};
|
||||
|
||||
class nsUnicodeToGB18030: public nsUnicodeToGBK
|
||||
@ -67,7 +63,9 @@ public:
|
||||
protected:
|
||||
virtual void CreateExtensionEncoder();
|
||||
virtual void Create4BytesEncoder();
|
||||
virtual bool EncodeSurrogate(char16_t aSurrogateHigh, char16_t aSurrogateLow, char* aDest);
|
||||
virtual nsresult EncodeSurrogate(char16_t aSurrogateHigh,
|
||||
char16_t aSurrogateLow, char* aDest,
|
||||
int32_t aDestLength, int32_t aBufferLength);
|
||||
};
|
||||
|
||||
#endif /* nsUnicodeToGBK_h___ */
|
||||
|
145
ipc/chromium/src/base/third_party/purify/pure.h
vendored
145
ipc/chromium/src/base/third_party/purify/pure.h
vendored
@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Header file of Pure API function declarations.
|
||||
*
|
||||
* (C) Copyright IBM Corporation. 2006, 2006. All Rights Reserved.
|
||||
* You may recompile and redistribute these definitions as required.
|
||||
*
|
||||
* Version 1.0
|
||||
*/
|
||||
|
||||
#if defined(PURIFY) || defined(QUANTIFY)
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Don't include this file directly, use purify.h instead.
|
||||
// If you need something that's not there, add it.
|
||||
#ifdef PURIFY_PRIVATE_INCLUDE
|
||||
|
||||
#define PURE_H_VERSION 1
|
||||
#include <stddef.h>
|
||||
|
||||
//////////////////////////////
|
||||
// API's Specific to Purify //
|
||||
//////////////////////////////
|
||||
|
||||
// TRUE when Purify is running.
|
||||
int __cdecl PurifyIsRunning(void) ;
|
||||
//
|
||||
// Print a string to the viewer.
|
||||
//
|
||||
int __cdecl PurePrintf(const char *fmt, ...) ;
|
||||
int __cdecl PurifyPrintf(const char *fmt, ...) ;
|
||||
//
|
||||
// Purify functions for leak and memory-in-use functionalty.
|
||||
//
|
||||
size_t __cdecl PurifyNewInuse(void) ;
|
||||
size_t __cdecl PurifyAllInuse(void) ;
|
||||
size_t __cdecl PurifyClearInuse(void) ;
|
||||
size_t __cdecl PurifyNewLeaks(void) ;
|
||||
size_t __cdecl PurifyAllLeaks(void) ;
|
||||
size_t __cdecl PurifyClearLeaks(void) ;
|
||||
//
|
||||
// Purify functions for handle leakage.
|
||||
//
|
||||
size_t __cdecl PurifyAllHandlesInuse(void) ;
|
||||
size_t __cdecl PurifyNewHandlesInuse(void) ;
|
||||
//
|
||||
// Functions that tell you about the state of memory.
|
||||
//
|
||||
size_t __cdecl PurifyDescribe(void *addr) ;
|
||||
size_t __cdecl PurifyWhatColors(void *addr, size_t size) ;
|
||||
//
|
||||
// Functions to test the state of memory. If the memory is not
|
||||
// accessable, an error is signaled just as if there were a memory
|
||||
// reference and the function returns false.
|
||||
//
|
||||
int __cdecl PurifyAssertIsReadable(const void *addr, size_t size) ; // size used to be an int, until IA64 came along
|
||||
int __cdecl PurifyAssertIsWritable(const void *addr, size_t size) ;
|
||||
//
|
||||
// Functions to test the state of memory. If the memory is not
|
||||
// accessable, these functions return false. No error is signaled.
|
||||
//
|
||||
int __cdecl PurifyIsReadable(const void *addr, size_t size) ;
|
||||
int __cdecl PurifyIsWritable(const void *addr, size_t size) ;
|
||||
int __cdecl PurifyIsInitialized(const void *addr, size_t size) ;
|
||||
//
|
||||
// Functions to set the state of memory.
|
||||
//
|
||||
void __cdecl PurifyMarkAsInitialized(void *addr, size_t size) ;
|
||||
void __cdecl PurifyMarkAsUninitialized(void *addr, size_t size) ;
|
||||
//
|
||||
// Functions to do late detection of ABWs, FMWs, IPWs.
|
||||
//
|
||||
#define PURIFY_HEAP_CRT (HANDLE) ~(__int64) 1 /* 0xfffffffe */
|
||||
#define PURIFY_HEAP_ALL (HANDLE) ~(__int64) 2 /* 0xfffffffd */
|
||||
#define PURIFY_HEAP_BLOCKS_LIVE 0x80000000
|
||||
#define PURIFY_HEAP_BLOCKS_DEFERRED_FREE 0x40000000
|
||||
#define PURIFY_HEAP_BLOCKS_ALL (PURIFY_HEAP_BLOCKS_LIVE|PURIFY_HEAP_BLOCKS_DEFERRED_FREE)
|
||||
int __cdecl PurifyHeapValidate(unsigned int hHeap, unsigned int dwFlags, const void *addr) ;
|
||||
int __cdecl PurifySetLateDetectScanCounter(int counter);
|
||||
int __cdecl PurifySetLateDetectScanInterval(int seconds);
|
||||
//
|
||||
// Functions to support pool allocators
|
||||
//
|
||||
void __cdecl PurifySetPoolId(const void *mem, int id);
|
||||
int __cdecl PurifyGetPoolId(const void *mem);
|
||||
void __cdecl PurifySetUserData(const void *mem, void *data);
|
||||
void * __cdecl PurifyGetUserData(const void *mem);
|
||||
void __cdecl PurifyMapPool(int id, void(*fn)());
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// API's Specific to Quantify //
|
||||
////////////////////////////////
|
||||
|
||||
// TRUE when Quantify is running.
|
||||
int __cdecl QuantifyIsRunning(void) ;
|
||||
|
||||
//
|
||||
// Functions for controlling collection
|
||||
//
|
||||
int __cdecl QuantifyDisableRecordingData(void) ;
|
||||
int __cdecl QuantifyStartRecordingData(void) ;
|
||||
int __cdecl QuantifyStopRecordingData(void) ;
|
||||
int __cdecl QuantifyClearData(void) ;
|
||||
int __cdecl QuantifyIsRecordingData(void) ;
|
||||
|
||||
// Add a comment to the dataset
|
||||
int __cdecl QuantifyAddAnnotation(char *) ;
|
||||
|
||||
// Save the current data, creating a "checkpoint" dataset
|
||||
int __cdecl QuantifySaveData(void) ;
|
||||
|
||||
// Set the name of the current thread in the viewer
|
||||
int __cdecl QuantifySetThreadName(char *) ;
|
||||
|
||||
////////////////////////////////
|
||||
// API's Specific to Coverage //
|
||||
////////////////////////////////
|
||||
|
||||
// TRUE when Coverage is running.
|
||||
int __cdecl CoverageIsRunning(void) ;
|
||||
//
|
||||
// Functions for controlling collection
|
||||
//
|
||||
int __cdecl CoverageDisableRecordingData(void) ;
|
||||
int __cdecl CoverageStartRecordingData(void) ;
|
||||
int __cdecl CoverageStopRecordingData(void) ;
|
||||
int __cdecl CoverageClearData(void) ;
|
||||
int __cdecl CoverageIsRecordingData(void) ;
|
||||
// Add a comment to the dataset
|
||||
int __cdecl CoverageAddAnnotation(char *) ;
|
||||
|
||||
// Save the current data, creating a "checkpoint" dataset
|
||||
int __cdecl CoverageSaveData(void) ;
|
||||
|
||||
|
||||
#endif // PURIFY_PRIVATE_INCLUDE
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(PURIFY) || defined(QUANTIFY)
|
152
ipc/chromium/src/base/third_party/purify/pure_api.c
vendored
152
ipc/chromium/src/base/third_party/purify/pure_api.c
vendored
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Header file of Pure API function declarations.
|
||||
*
|
||||
* Explicitly no copyright.
|
||||
* You may recompile and redistribute these definitions as required.
|
||||
*
|
||||
* NOTE1: In some situations when compiling with MFC, you should
|
||||
* enable the setting 'Not using precompiled headers' in Visual C++
|
||||
* to avoid a compiler diagnostic.
|
||||
*
|
||||
* NOTE2: This file works through the use of deep magic. Calls to functions
|
||||
* in this file are replaced with calls into the OCI runtime system
|
||||
* when an instrumented version of this program is run.
|
||||
*
|
||||
* NOTE3: The static vars avoidGy_n (where n is a unique number) are used
|
||||
* to prevent optimizing the functions away when compiler option
|
||||
* /Gy is set. This is needed so that NOTE2 works properly.
|
||||
*/
|
||||
|
||||
// Chromium note: We used to only compile this code if PURIFY was defined,
|
||||
// because we did special builds with all optimizations turned off for Purify.
|
||||
// However, for profiling with Quantify, we want most/all optimizations turned
|
||||
// on so that we measure something closer to real execution.
|
||||
|
||||
#ifdef _WINDOWS // we only use Purify/Quantify on Windows
|
||||
|
||||
#pragma once
|
||||
extern int errno;
|
||||
typedef int ptrdiff_t;
|
||||
typedef unsigned int size_t;
|
||||
typedef unsigned short wchar_t;
|
||||
static int avoidGy_1 = 0;
|
||||
static int avoidGy_2 = 0;
|
||||
static int avoidGy_3 = 0;
|
||||
static int avoidGy_4 = 0;
|
||||
static int avoidGy_5 = 0;
|
||||
static int avoidGy_6 = 0;
|
||||
static int avoidGy_7 = 0;
|
||||
static int avoidGy_8 = 0;
|
||||
static int avoidGy_9 = 0;
|
||||
static int avoidGy_10 = 0;
|
||||
static int avoidGy_11 = 0;
|
||||
static int avoidGy_12 = 0;
|
||||
static int avoidGy_13 = 0;
|
||||
static int avoidGy_14 = 0;
|
||||
static int avoidGy_15 = 0;
|
||||
static int avoidGy_16 = 0;
|
||||
static int avoidGy_17 = 0;
|
||||
static int avoidGy_18 = 0;
|
||||
static int avoidGy_19 = 0;
|
||||
static int avoidGy_20 = 0;
|
||||
static int avoidGy_21 = 0;
|
||||
static int avoidGy_22 = 0;
|
||||
static int avoidGy_23 = 0;
|
||||
static int avoidGy_24 = 0;
|
||||
static int avoidGy_25 = 0;
|
||||
static int avoidGy_26 = 0;
|
||||
static int avoidGy_27 = 0;
|
||||
static int avoidGy_28 = 0;
|
||||
static int avoidGy_29 = 0;
|
||||
static int avoidGy_30 = 0;
|
||||
static int avoidGy_31 = 0;
|
||||
static int avoidGy_32 = 0;
|
||||
static int avoidGy_33 = 0;
|
||||
static int avoidGy_34 = 0;
|
||||
static int avoidGy_35 = 0;
|
||||
static int avoidGy_36 = 0;
|
||||
static int avoidGy_37 = 0;
|
||||
static int avoidGy_38 = 0;
|
||||
static int avoidGy_39 = 0;
|
||||
static int avoidGy_40 = 0;
|
||||
static int avoidGy_41 = 0;
|
||||
static int avoidGy_42 = 0;
|
||||
static int avoidGy_43 = 0;
|
||||
static int avoidGy_44 = 0;
|
||||
static int avoidGy_45 = 0;
|
||||
static int avoidGy_46 = 0;
|
||||
static int avoidGy_47 = 0;
|
||||
static int avoidGy_48 = 0;
|
||||
static int avoidGy_49 = 0;
|
||||
static int avoidGy_50 = 0;
|
||||
static int avoidGy_51 = 0;
|
||||
static int avoidGy_52 = 0;
|
||||
static int avoidGy_53 = 0;
|
||||
static int avoidGy_54 = 0;
|
||||
static int avoidGy_55 = 0;
|
||||
static int avoidGy_56 = 0;
|
||||
static int avoidGy_57 = 0;
|
||||
static int avoidGy_58 = 0;
|
||||
static int avoidGy_59 = 0;
|
||||
static int avoidGy_60 = 0;
|
||||
static int avoidGy_61 = 0;
|
||||
static int avoidGy_62 = 0;
|
||||
static int avoidGy_63 = 0;
|
||||
static int avoidGy_64 = 0;
|
||||
static int avoidGy_65 = 0;
|
||||
static int avoidGy_PL_01 = 0;
|
||||
static int avoidGy_PL_02 = 0;
|
||||
__declspec(dllexport) int __cdecl PurePrintf(const char *fmt, ...) { if(!++avoidGy_1); fmt; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyIsRunning(void) { if(!++avoidGy_2); return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyPrintf(const char *fmt, ...) { if(!++avoidGy_3); fmt; return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyNewInuse(void) { if(!++avoidGy_4); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyAllInuse(void) { if(!++avoidGy_5); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyClearInuse(void) { if(!++avoidGy_6); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyNewLeaks(void) { if(!++avoidGy_7); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyAllLeaks(void) { if(!++avoidGy_8); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyClearLeaks(void) { if(!++avoidGy_9); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyAllHandlesInuse(void) { if(!++avoidGy_10); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyNewHandlesInuse(void) { if(!++avoidGy_11); return 0; }
|
||||
__declspec(dllexport) size_t __cdecl PurifyDescribe(void *addr) { if(!++avoidGy_12); addr; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyWhatColors(void *addr, size_t size) { if(!++avoidGy_13); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyAssertIsReadable(const void *addr, size_t size) { if(!++avoidGy_14); addr; size; return 1; }
|
||||
__declspec(dllexport) int __cdecl PurifyAssertIsWritable(const void *addr, size_t size) { if(!++avoidGy_15); addr; size; return 1; }
|
||||
__declspec(dllexport) int __cdecl PurifyIsReadable(const void *addr, size_t size) { if(!++avoidGy_16); addr; size; return 1; }
|
||||
__declspec(dllexport) int __cdecl PurifyIsWritable(const void *addr, size_t size) { if(!++avoidGy_17); addr; size; return 1; }
|
||||
__declspec(dllexport) int __cdecl PurifyIsInitialized(const void *addr, size_t size) { if(!++avoidGy_18); addr; size; return 1; }
|
||||
__declspec(dllexport) int __cdecl PurifyRed(void *addr, size_t size) { if(!++avoidGy_19); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyGreen(void *addr, size_t size) { if(!++avoidGy_20); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyYellow(void *addr, size_t size) { if(!++avoidGy_21); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyBlue(void *addr, size_t size) { if(!++avoidGy_22); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyMarkAsInitialized(void *addr, size_t size) { if(!++avoidGy_23); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyMarkAsUninitialized(void *addr, size_t size) { if(!++avoidGy_24); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyMarkForTrap(void *addr, size_t size) { if(!++avoidGy_25); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyMarkForNoTrap(void *addr, size_t size) { if(!++avoidGy_26); addr; size; return 0; }
|
||||
__declspec(dllexport) int __cdecl PurifyHeapValidate(unsigned int hHeap, unsigned int dwFlags, const void *addr)
|
||||
{ if(!++avoidGy_27); hHeap; dwFlags; addr; return 1; }
|
||||
__declspec(dllexport) int __cdecl PurifySetLateDetectScanCounter(int counter) { if(!++avoidGy_28); counter; return 0; };
|
||||
__declspec(dllexport) int __cdecl PurifySetLateDetectScanInterval(int seconds) { if(!++avoidGy_29); seconds; return 0; };
|
||||
__declspec(dllexport) void __cdecl PurifySetPoolId(const void *mem, int id) { if(!++avoidGy_61); mem; id; return; };
|
||||
__declspec(dllexport) int __cdecl PurifyGetPoolId(const void *mem) { if(!++avoidGy_62); mem; return 0; };
|
||||
__declspec(dllexport) void __cdecl PurifySetUserData(const void *mem, void *data) { if(!++avoidGy_63); mem; data; return; };
|
||||
__declspec(dllexport) void * __cdecl PurifyGetUserData(const void *mem) { if(!++avoidGy_64); mem; return 0; };
|
||||
__declspec(dllexport) void __cdecl PurifyMapPool(int id, void(*fn)()) { if(!++avoidGy_65); id; fn; return; };
|
||||
__declspec(dllexport) int __cdecl CoverageIsRunning(void) { if(!++avoidGy_30); return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageDisableRecordingData(void) { if(!++avoidGy_31); return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageStartRecordingData(void) { if(!++avoidGy_32); return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageStopRecordingData(void) { if(!++avoidGy_33); return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageClearData(void) { if(!++avoidGy_34); return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageIsRecordingData(void) { if(!++avoidGy_35); return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageAddAnnotation(char *str) { if(!++avoidGy_36); str; return 0; }
|
||||
__declspec(dllexport) int __cdecl CoverageSaveData(void) { if(!++avoidGy_37); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyIsRunning(void) { if(!++avoidGy_42); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyDisableRecordingData(void) { if(!++avoidGy_43); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyStartRecordingData(void) { if(!++avoidGy_44); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyStopRecordingData(void) { if(!++avoidGy_45); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyClearData(void) { if(!++avoidGy_46); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyIsRecordingData(void) { if(!++avoidGy_47); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifyAddAnnotation(char *str) { if(!++avoidGy_48); str; return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifySaveData(void) { if(!++avoidGy_49); return 0; }
|
||||
__declspec(dllexport) int __cdecl QuantifySetThreadName(const char *szName) { if(!++avoidGy_50) ; szName; return 0; }
|
||||
|
||||
#endif // _WINDOWS
|
@ -147,7 +147,7 @@ public:
|
||||
};
|
||||
|
||||
template<class ListenerT>
|
||||
class /*NS_INTERFACE_CLASS*/ IProtocolManager
|
||||
class IProtocolManager
|
||||
{
|
||||
public:
|
||||
enum ActorDestroyReason {
|
||||
|
@ -125,17 +125,11 @@ class CxxCodeGen(CodePrinter, Visitor):
|
||||
def visitClass(self, c):
|
||||
if c.specializes is not None:
|
||||
self.printdentln('template<>')
|
||||
|
||||
|
||||
if c.struct:
|
||||
self.printdent('struct')
|
||||
else:
|
||||
self.printdent('class')
|
||||
if c.interface:
|
||||
# FIXME/cjones: turn this "on" when we get the analysis
|
||||
self.write(' /*NS_INTERFACE_CLASS*/')
|
||||
if c.abstract:
|
||||
# FIXME/cjones: turn this "on" when we get the analysis
|
||||
self.write(' /*NS_ABSTRACT_CLASS*/')
|
||||
self.write(' '+ c.name)
|
||||
if c.final:
|
||||
self.write(' final')
|
||||
|
3
js/src/jit-test/tests/basic/bug1170355.js
Normal file
3
js/src/jit-test/tests/basic/bug1170355.js
Normal file
@ -0,0 +1,3 @@
|
||||
x = Array(4294967295);
|
||||
x[1] = 0;
|
||||
Array.prototype.shift.call(x);
|
@ -325,14 +325,19 @@ VirtualRegister::setInitialDefinition(CodePosition from)
|
||||
}
|
||||
|
||||
LiveRange*
|
||||
VirtualRegister::rangeFor(CodePosition pos) const
|
||||
VirtualRegister::rangeFor(CodePosition pos, bool preferRegister /* = false */) const
|
||||
{
|
||||
LiveRange* found = nullptr;
|
||||
for (LiveRange::RegisterLinkIterator iter = rangesBegin(); iter; iter++) {
|
||||
LiveRange* range = LiveRange::get(*iter);
|
||||
if (range->covers(pos))
|
||||
return range;
|
||||
if (range->covers(pos)) {
|
||||
if (!preferRegister || range->bundle()->allocation().isRegister())
|
||||
return range;
|
||||
if (!found)
|
||||
found = range;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return found;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1706,7 +1711,7 @@ BacktrackingAllocator::resolveControlFlow()
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
LiveRange* predecessorRange = reg.rangeFor(start.previous());
|
||||
LiveRange* predecessorRange = reg.rangeFor(start.previous(), /* preferRegister = */ true);
|
||||
if (start.subpos() == CodePosition::INPUT) {
|
||||
if (!moveInput(ins->toInstruction(), predecessorRange, range, reg.type()))
|
||||
return false;
|
||||
@ -1742,7 +1747,7 @@ BacktrackingAllocator::resolveControlFlow()
|
||||
MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1);
|
||||
|
||||
LAllocation* input = phi->getOperand(k);
|
||||
LiveRange* from = vreg(input).rangeFor(exitOf(predecessor));
|
||||
LiveRange* from = vreg(input).rangeFor(exitOf(predecessor), /* preferRegister = */ true);
|
||||
MOZ_ASSERT(from);
|
||||
|
||||
if (!moveAtExit(predecessor, from, to, def->type()))
|
||||
@ -1767,7 +1772,7 @@ BacktrackingAllocator::resolveControlFlow()
|
||||
if (to->covers(exitOf(predecessor)))
|
||||
continue;
|
||||
|
||||
LiveRange* from = reg.rangeFor(exitOf(predecessor));
|
||||
LiveRange* from = reg.rangeFor(exitOf(predecessor), /* preferRegister = */ true);
|
||||
|
||||
if (mSuccessor->numPredecessors() > 1) {
|
||||
MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1);
|
||||
@ -2326,11 +2331,12 @@ BacktrackingAllocator::minimalDef(LiveRange* range, LNode* ins)
|
||||
}
|
||||
|
||||
bool
|
||||
BacktrackingAllocator::minimalUse(LiveRange* range, LNode* ins)
|
||||
BacktrackingAllocator::minimalUse(LiveRange* range, UsePosition* use)
|
||||
{
|
||||
// Whether this is a minimal range capturing a use at ins.
|
||||
// Whether this is a minimal range capturing |use|.
|
||||
LNode* ins = insData[use->pos];
|
||||
return (range->from() == inputOf(ins)) &&
|
||||
(range->to() == outputOf(ins) || range->to() == outputOf(ins).next());
|
||||
(range->to() == (use->use->usedAtStart() ? outputOf(ins) : outputOf(ins).next()));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2368,12 +2374,12 @@ BacktrackingAllocator::minimalBundle(LiveBundle* bundle, bool* pfixed)
|
||||
if (fixed)
|
||||
return false;
|
||||
fixed = true;
|
||||
if (minimalUse(range, insData[iter->pos]))
|
||||
if (minimalUse(range, *iter))
|
||||
minimal = true;
|
||||
break;
|
||||
|
||||
case LUse::REGISTER:
|
||||
if (minimalUse(range, insData[iter->pos]))
|
||||
if (minimalUse(range, *iter))
|
||||
minimal = true;
|
||||
break;
|
||||
|
||||
|
@ -524,7 +524,7 @@ class VirtualRegister
|
||||
LiveRange* lastRange() const {
|
||||
return LiveRange::get(ranges_.back());
|
||||
}
|
||||
LiveRange* rangeFor(CodePosition pos) const;
|
||||
LiveRange* rangeFor(CodePosition pos, bool preferRegister = false) const;
|
||||
void removeRange(LiveRange* range);
|
||||
void addRange(LiveRange* range);
|
||||
|
||||
@ -707,7 +707,7 @@ class BacktrackingAllocator : protected RegisterAllocator
|
||||
struct PrintLiveRange;
|
||||
|
||||
bool minimalDef(LiveRange* range, LNode* ins);
|
||||
bool minimalUse(LiveRange* range, LNode* ins);
|
||||
bool minimalUse(LiveRange* range, UsePosition* use);
|
||||
bool minimalBundle(LiveBundle* bundle, bool* pfixed = nullptr);
|
||||
|
||||
// Heuristic methods.
|
||||
|
@ -2208,8 +2208,14 @@ CodeGenerator::visitMoveGroup(LMoveGroup* group)
|
||||
masm.propagateOOM(resolver.resolve());
|
||||
|
||||
MoveEmitter emitter(masm);
|
||||
|
||||
#ifdef JS_CODEGEN_X86
|
||||
if (group->maybeScratchRegister().isGeneralReg())
|
||||
emitter.setScratchRegister(group->maybeScratchRegister().toGeneralReg()->reg());
|
||||
else
|
||||
resolver.sortMemoryToMemoryMoves();
|
||||
#endif
|
||||
|
||||
emitter.emit(resolver);
|
||||
emitter.finish();
|
||||
}
|
||||
|
@ -119,14 +119,10 @@ class LMoveGroup : public LInstructionHelper<0, 0, 0>
|
||||
void setScratchRegister(Register reg) {
|
||||
scratchRegister_ = LGeneralReg(reg);
|
||||
}
|
||||
#endif
|
||||
LAllocation maybeScratchRegister() {
|
||||
#ifdef JS_CODEGEN_X86
|
||||
return scratchRegister_;
|
||||
#else
|
||||
return LAllocation();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
bool uses(Register reg) {
|
||||
for (size_t i = 0; i < numMoves(); i++) {
|
||||
|
@ -201,14 +201,90 @@ MoveResolver::addOrderedMove(const MoveOp& move)
|
||||
}
|
||||
}
|
||||
|
||||
if (existing.to().aliases(move.from()) ||
|
||||
existing.to().aliases(move.to()) ||
|
||||
existing.from().aliases(move.to()) ||
|
||||
existing.from().aliases(move.from()))
|
||||
{
|
||||
if (existing.aliases(move))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return orderedMoves_.append(move);
|
||||
}
|
||||
|
||||
void
|
||||
MoveResolver::reorderMove(size_t from, size_t to)
|
||||
{
|
||||
MOZ_ASSERT(from != to);
|
||||
|
||||
MoveOp op = orderedMoves_[from];
|
||||
if (from < to) {
|
||||
for (size_t i = from; i < to; i++)
|
||||
orderedMoves_[i] = orderedMoves_[i + 1];
|
||||
} else {
|
||||
for (size_t i = from; i > to; i--)
|
||||
orderedMoves_[i] = orderedMoves_[i - 1];
|
||||
}
|
||||
orderedMoves_[to] = op;
|
||||
}
|
||||
|
||||
void
|
||||
MoveResolver::sortMemoryToMemoryMoves()
|
||||
{
|
||||
// Try to reorder memory->memory moves so that they are executed right
|
||||
// before a move that clobbers some register. This will allow the move
|
||||
// emitter to use that clobbered register as a scratch register for the
|
||||
// memory->memory move, if necessary.
|
||||
for (size_t i = 0; i < orderedMoves_.length(); i++) {
|
||||
const MoveOp& base = orderedMoves_[i];
|
||||
if (!base.from().isMemory() || !base.to().isMemory())
|
||||
continue;
|
||||
if (base.type() != MoveOp::GENERAL && base.type() != MoveOp::INT32)
|
||||
continue;
|
||||
|
||||
// Look for an earlier move clobbering a register.
|
||||
bool found = false;
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
const MoveOp& previous = orderedMoves_[j];
|
||||
if (previous.aliases(base) || previous.isCycleBegin() || previous.isCycleEnd())
|
||||
break;
|
||||
|
||||
if (previous.to().isGeneralReg()) {
|
||||
reorderMove(i, j);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
// Look for a later move clobbering a register.
|
||||
if (i + 1 < orderedMoves_.length()) {
|
||||
bool found = false, skippedRegisterUse = false;
|
||||
for (size_t j = i + 1; j < orderedMoves_.length(); j++) {
|
||||
const MoveOp& later = orderedMoves_[j];
|
||||
if (later.aliases(base) || later.isCycleBegin() || later.isCycleEnd())
|
||||
break;
|
||||
|
||||
if (later.to().isGeneralReg()) {
|
||||
if (skippedRegisterUse) {
|
||||
reorderMove(i, j);
|
||||
found = true;
|
||||
} else {
|
||||
// There is no move that uses a register between the
|
||||
// original memory->memory move and this move that
|
||||
// clobbers a register. The move should already be able
|
||||
// to use a scratch register, so don't shift anything
|
||||
// around.
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (later.from().isGeneralReg())
|
||||
skippedRegisterUse = true;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
// Redo the search for memory->memory moves at the current
|
||||
// index, so we don't skip the move just shifted back.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +197,12 @@ class MoveOp
|
||||
MOZ_ASSERT(isCycleBegin());
|
||||
return endCycleType_;
|
||||
}
|
||||
bool aliases(const MoveOperand& op) const {
|
||||
return from().aliases(op) || to().aliases(op);
|
||||
}
|
||||
bool aliases(const MoveOp& other) const {
|
||||
return aliases(other.from()) || aliases(other.to());
|
||||
}
|
||||
};
|
||||
|
||||
class MoveResolver
|
||||
@ -229,8 +235,6 @@ class MoveResolver
|
||||
typedef InlineList<MoveResolver::PendingMove>::iterator PendingMoveIterator;
|
||||
|
||||
private:
|
||||
// Moves that are definitely unblocked (constants to registers). These are
|
||||
// emitted last.
|
||||
js::Vector<MoveOp, 16, SystemAllocPolicy> orderedMoves_;
|
||||
int numCycles_;
|
||||
int curCycles_;
|
||||
@ -241,6 +245,7 @@ class MoveResolver
|
||||
PendingMove* findBlockingMove(const PendingMove* last);
|
||||
PendingMove* findCycledMove(PendingMoveIterator* stack, PendingMoveIterator end, const PendingMove* first);
|
||||
bool addOrderedMove(const MoveOp& move);
|
||||
void reorderMove(size_t from, size_t to);
|
||||
|
||||
// Internal reset function. Does not clear lists.
|
||||
void resetState();
|
||||
@ -257,6 +262,7 @@ class MoveResolver
|
||||
// cycle resolution algorithm. Calling addMove() again resets the resolver.
|
||||
bool addMove(const MoveOperand& from, const MoveOperand& to, MoveOp::Type type);
|
||||
bool resolve();
|
||||
void sortMemoryToMemoryMoves();
|
||||
|
||||
size_t numMoves() const {
|
||||
return orderedMoves_.length();
|
||||
|
@ -11,6 +11,8 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::Maybe;
|
||||
|
||||
MoveEmitterX86::MoveEmitterX86(MacroAssembler& masm)
|
||||
: inCycle_(false),
|
||||
masm(masm),
|
||||
@ -101,11 +103,19 @@ MoveEmitterX86::emit(const MoveResolver& moves)
|
||||
{
|
||||
#if defined(JS_CODEGEN_X86) && defined(DEBUG)
|
||||
// Clobber any scratch register we have, to make regalloc bugs more visible.
|
||||
if (hasScratchRegister())
|
||||
masm.mov(ImmWord(0xdeadbeef), scratchRegister());
|
||||
if (scratchRegister_.isSome())
|
||||
masm.mov(ImmWord(0xdeadbeef), scratchRegister_.value());
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < moves.numMoves(); i++) {
|
||||
#if defined(JS_CODEGEN_X86) && defined(DEBUG)
|
||||
if (!scratchRegister_.isSome()) {
|
||||
Maybe<Register> reg = findScratchRegister(moves, i);
|
||||
if (reg.isSome())
|
||||
masm.mov(ImmWord(0xdeadbeef), reg.value());
|
||||
}
|
||||
#endif
|
||||
|
||||
const MoveOp& move = moves.getMove(i);
|
||||
const MoveOperand& from = move.from();
|
||||
const MoveOperand& to = move.to();
|
||||
@ -144,10 +154,10 @@ MoveEmitterX86::emit(const MoveResolver& moves)
|
||||
emitDoubleMove(from, to);
|
||||
break;
|
||||
case MoveOp::INT32:
|
||||
emitInt32Move(from, to);
|
||||
emitInt32Move(from, to, moves, i);
|
||||
break;
|
||||
case MoveOp::GENERAL:
|
||||
emitGeneralMove(from, to);
|
||||
emitGeneralMove(from, to, moves, i);
|
||||
break;
|
||||
case MoveOp::INT32X4:
|
||||
emitInt32X4Move(from, to);
|
||||
@ -363,7 +373,8 @@ MoveEmitterX86::completeCycle(const MoveOperand& to, MoveOp::Type type)
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterX86::emitInt32Move(const MoveOperand& from, const MoveOperand& to)
|
||||
MoveEmitterX86::emitInt32Move(const MoveOperand& from, const MoveOperand& to,
|
||||
const MoveResolver& moves, size_t i)
|
||||
{
|
||||
if (from.isGeneralReg()) {
|
||||
masm.move32(from.reg(), toOperand(to));
|
||||
@ -373,10 +384,10 @@ MoveEmitterX86::emitInt32Move(const MoveOperand& from, const MoveOperand& to)
|
||||
} else {
|
||||
// Memory to memory gpr move.
|
||||
MOZ_ASSERT(from.isMemory());
|
||||
if (hasScratchRegister()) {
|
||||
Register reg = scratchRegister();
|
||||
masm.load32(toAddress(from), reg);
|
||||
masm.move32(reg, toOperand(to));
|
||||
Maybe<Register> reg = findScratchRegister(moves, i);
|
||||
if (reg.isSome()) {
|
||||
masm.load32(toAddress(from), reg.value());
|
||||
masm.move32(reg.value(), toOperand(to));
|
||||
} else {
|
||||
// No scratch register available; bounce it off the stack.
|
||||
masm.Push(toOperand(from));
|
||||
@ -386,7 +397,8 @@ MoveEmitterX86::emitInt32Move(const MoveOperand& from, const MoveOperand& to)
|
||||
}
|
||||
|
||||
void
|
||||
MoveEmitterX86::emitGeneralMove(const MoveOperand& from, const MoveOperand& to)
|
||||
MoveEmitterX86::emitGeneralMove(const MoveOperand& from, const MoveOperand& to,
|
||||
const MoveResolver& moves, size_t i)
|
||||
{
|
||||
if (from.isGeneralReg()) {
|
||||
masm.mov(from.reg(), toOperand(to));
|
||||
@ -398,10 +410,10 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand& from, const MoveOperand& to)
|
||||
masm.lea(toOperand(from), to.reg());
|
||||
} else if (from.isMemory()) {
|
||||
// Memory to memory gpr move.
|
||||
if (hasScratchRegister()) {
|
||||
Register reg = scratchRegister();
|
||||
masm.loadPtr(toAddress(from), reg);
|
||||
masm.mov(reg, toOperand(to));
|
||||
Maybe<Register> reg = findScratchRegister(moves, i);
|
||||
if (reg.isSome()) {
|
||||
masm.loadPtr(toAddress(from), reg.value());
|
||||
masm.mov(reg.value(), toOperand(to));
|
||||
} else {
|
||||
// No scratch register available; bounce it off the stack.
|
||||
masm.Push(toOperand(from));
|
||||
@ -410,10 +422,10 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand& from, const MoveOperand& to)
|
||||
} else {
|
||||
// Effective address to memory move.
|
||||
MOZ_ASSERT(from.isEffectiveAddress());
|
||||
if (hasScratchRegister()) {
|
||||
Register reg = scratchRegister();
|
||||
masm.lea(toOperand(from), reg);
|
||||
masm.mov(reg, toOperand(to));
|
||||
Maybe<Register> reg = findScratchRegister(moves, i);
|
||||
if (reg.isSome()) {
|
||||
masm.lea(toOperand(from), reg.value());
|
||||
masm.mov(reg.value(), toOperand(to));
|
||||
} else {
|
||||
// This is tricky without a scratch reg. We can't do an lea. Bounce the
|
||||
// base register off the stack, then add the offset in place. Note that
|
||||
@ -523,3 +535,34 @@ MoveEmitterX86::finish()
|
||||
masm.freeStack(masm.framePushed() - pushedAtStart_);
|
||||
}
|
||||
|
||||
Maybe<Register>
|
||||
MoveEmitterX86::findScratchRegister(const MoveResolver& moves, size_t initial)
|
||||
{
|
||||
#ifdef JS_CODEGEN_X86
|
||||
if (scratchRegister_.isSome())
|
||||
return scratchRegister_;
|
||||
|
||||
// All registers are either in use by this move group or are live
|
||||
// afterwards. Look through the remaining moves for a register which is
|
||||
// clobbered before it is used, and is thus dead at this point.
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
for (size_t i = initial; i < moves.numMoves(); i++) {
|
||||
const MoveOp& move = moves.getMove(i);
|
||||
if (move.from().isGeneralReg())
|
||||
regs.takeUnchecked(move.from().reg());
|
||||
else if (move.from().isMemoryOrEffectiveAddress())
|
||||
regs.takeUnchecked(move.from().base());
|
||||
if (move.to().isGeneralReg()) {
|
||||
if (i != initial && !move.isCycleBegin() && regs.has(move.to().reg()))
|
||||
return mozilla::Some(move.to().reg());
|
||||
regs.takeUnchecked(move.to().reg());
|
||||
} else if (move.to().isMemoryOrEffectiveAddress()) {
|
||||
regs.takeUnchecked(move.to().base());
|
||||
}
|
||||
}
|
||||
|
||||
return mozilla::Nothing();
|
||||
#else
|
||||
return mozilla::Some(ScratchReg);
|
||||
#endif
|
||||
}
|
||||
|
@ -40,8 +40,10 @@ class MoveEmitterX86
|
||||
bool* allGeneralRegs, bool* allFloatRegs);
|
||||
bool maybeEmitOptimizedCycle(const MoveResolver& moves, size_t i,
|
||||
bool allGeneralRegs, bool allFloatRegs, size_t swapCount);
|
||||
void emitInt32Move(const MoveOperand& from, const MoveOperand& to);
|
||||
void emitGeneralMove(const MoveOperand& from, const MoveOperand& to);
|
||||
void emitInt32Move(const MoveOperand& from, const MoveOperand& to,
|
||||
const MoveResolver& moves, size_t i);
|
||||
void emitGeneralMove(const MoveOperand& from, const MoveOperand& to,
|
||||
const MoveResolver& moves, size_t i);
|
||||
void emitFloat32Move(const MoveOperand& from, const MoveOperand& to);
|
||||
void emitDoubleMove(const MoveOperand& from, const MoveOperand& to);
|
||||
void emitFloat32X4Move(const MoveOperand& from, const MoveOperand& to);
|
||||
@ -61,22 +63,7 @@ class MoveEmitterX86
|
||||
#endif
|
||||
}
|
||||
|
||||
bool hasScratchRegister() {
|
||||
#ifdef JS_CODEGEN_X86
|
||||
return scratchRegister_.isSome();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
Register scratchRegister() {
|
||||
MOZ_ASSERT(hasScratchRegister());
|
||||
#ifdef JS_CODEGEN_X86
|
||||
return scratchRegister_.value();
|
||||
#else
|
||||
return ScratchReg;
|
||||
#endif
|
||||
}
|
||||
mozilla::Maybe<Register> findScratchRegister(const MoveResolver& moves, size_t i);
|
||||
};
|
||||
|
||||
typedef MoveEmitterX86 MoveEmitter;
|
||||
|
@ -49,7 +49,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
||||
JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_PERMANENT | JSPROP_SHARED,
|
||||
Getter));
|
||||
|
||||
CHECK(JS_GetPropertyDescriptor(cx, obj, "foo", &desc));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "foo", &desc));
|
||||
|
||||
// Note that JSPROP_READONLY is meaningless for accessor properties.
|
||||
CHECK(CheckDescriptor(desc, AccessorDescriptor, false, true, false));
|
||||
@ -58,7 +58,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
||||
CHECK(JS_DefineProperty(cx, obj, "bar", defineValue,
|
||||
JSPROP_IGNORE_ENUMERATE | JSPROP_SHARED,
|
||||
Getter));
|
||||
CHECK(JS_GetPropertyDescriptor(cx, obj, "bar", &desc));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "bar", &desc));
|
||||
CHECK(CheckDescriptor(desc, AccessorDescriptor, false, true, true));
|
||||
|
||||
// Rewrite the descriptor to now be enumerable, leaving the configurability
|
||||
@ -66,7 +66,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
||||
CHECK(JS_DefineProperty(cx, obj, "bar", defineValue,
|
||||
JSPROP_IGNORE_PERMANENT | JSPROP_ENUMERATE | JSPROP_SHARED,
|
||||
Getter));
|
||||
CHECK(JS_GetPropertyDescriptor(cx, obj, "bar", &desc));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "bar", &desc));
|
||||
CHECK(CheckDescriptor(desc, AccessorDescriptor, true, true, true));
|
||||
|
||||
// Now try the same game with a value property
|
||||
@ -75,13 +75,13 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
||||
JSPROP_IGNORE_ENUMERATE |
|
||||
JSPROP_IGNORE_READONLY |
|
||||
JSPROP_IGNORE_PERMANENT));
|
||||
CHECK(JS_GetPropertyDescriptor(cx, obj, "baz", &desc));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "baz", &desc));
|
||||
CHECK(CheckDescriptor(desc, DataDescriptor, false, false, false));
|
||||
|
||||
// Now again with a configurable property
|
||||
CHECK(JS_DefineProperty(cx, obj, "quux", defineValue,
|
||||
JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY));
|
||||
CHECK(JS_GetPropertyDescriptor(cx, obj, "quux", &desc));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "quux", &desc));
|
||||
CHECK(CheckDescriptor(desc, DataDescriptor, false, false, true));
|
||||
|
||||
// Just make it writable. Leave the old value and everything else alone.
|
||||
@ -91,7 +91,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
||||
JSPROP_IGNORE_PERMANENT |
|
||||
JSPROP_IGNORE_VALUE));
|
||||
|
||||
CHECK(JS_GetPropertyDescriptor(cx, obj, "quux", &desc));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "quux", &desc));
|
||||
CHECK(CheckDescriptor(desc, DataDescriptor, false, true, true));
|
||||
CHECK_SAME(JS::ObjectValue(*obj), desc.value());
|
||||
|
||||
|
@ -2169,7 +2169,10 @@ js::array_shift(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!SetLengthProperty(cx, obj, newlen))
|
||||
return false;
|
||||
|
||||
return SuppressDeletedProperty(cx, obj, INT_TO_JSID(newlen));
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, newlen, &id))
|
||||
return false;
|
||||
return SuppressDeletedProperty(cx, obj, id);
|
||||
}
|
||||
|
||||
/* Steps 5, 10. */
|
||||
|
10
js/src/tests/ecma_6/Class/newTargetNonFunction.js
Normal file
10
js/src/tests/ecma_6/Class/newTargetNonFunction.js
Normal file
@ -0,0 +1,10 @@
|
||||
// Make sure that we can plumb new.target, even if the results are going to
|
||||
// throw.
|
||||
|
||||
assertThrowsInstanceOf(() => new ""(...Array()), TypeError);
|
||||
|
||||
assertThrowsInstanceOf(() => new ""(), TypeError);
|
||||
assertThrowsInstanceOf(() => new ""(1), TypeError);
|
||||
|
||||
if (typeof reportCompare === 'function')
|
||||
reportCompare(0,0,"OK");
|
@ -4587,10 +4587,8 @@ js::SpreadCallOperation(JSContext* cx, HandleScript script, jsbytecode* pc, Hand
|
||||
if (!GetElements(cx, aobj, length, args.array()))
|
||||
return false;
|
||||
|
||||
if (constructing) {
|
||||
MOZ_ASSERT(newTarget.isObject());
|
||||
if (constructing)
|
||||
args.newTarget().set(newTarget);
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case JSOP_SPREADNEW:
|
||||
|
@ -1261,25 +1261,33 @@ nsGridContainerFrame::ReflowChildren(GridItemCSSOrderIterator& aIter,
|
||||
} else {
|
||||
cb = aContentArea;
|
||||
}
|
||||
nsHTMLReflowState childRS(pc, aReflowState, child, cb.Size(wm));
|
||||
WritingMode childWM = child->GetWritingMode();
|
||||
LogicalSize childCBSize = cb.Size(wm).ConvertTo(childWM, wm);
|
||||
nsHTMLReflowState childRS(pc, aReflowState, child, childCBSize);
|
||||
const LogicalMargin margin = childRS.ComputedLogicalMargin();
|
||||
if (childRS.ComputedBSize() == NS_AUTOHEIGHT && MOZ_LIKELY(isGridItem)) {
|
||||
// XXX the start of an align-self:stretch impl. Needs min-/max-bsize
|
||||
// clamping though, and check the prop value is actually 'stretch'!
|
||||
LogicalMargin bp = childRS.ComputedLogicalBorderPadding();
|
||||
bp.ApplySkipSides(child->GetLogicalSkipSides());
|
||||
nscoord bSize = cb.BSize(wm) - bp.BStartEnd(wm) - margin.BStartEnd(wm);
|
||||
nscoord bSize = childCBSize.BSize(childWM) - bp.BStartEnd(childWM) -
|
||||
margin.BStartEnd(childWM);
|
||||
childRS.SetComputedBSize(std::max(bSize, 0));
|
||||
}
|
||||
LogicalPoint childPos = cb.Origin(wm);
|
||||
childPos.I(wm) += margin.IStart(wm);
|
||||
childPos.B(wm) += margin.BStart(wm);
|
||||
// We need the width of the child before we can correctly convert
|
||||
// the writing-mode of its origin, so we reflow at (0, 0) and then
|
||||
// pass the correct position to FinishReflowChild.
|
||||
nsHTMLReflowMetrics childSize(childRS);
|
||||
nsReflowStatus childStatus;
|
||||
ReflowChild(child, pc, childSize, childRS, wm, childPos,
|
||||
containerWidth, 0, childStatus);
|
||||
ReflowChild(child, pc, childSize, childRS, childWM, LogicalPoint(childWM),
|
||||
0, 0, childStatus);
|
||||
LogicalPoint childPos =
|
||||
cb.Origin(wm).ConvertTo(childWM, wm, containerWidth - childSize.Width() -
|
||||
margin.LeftRight(childWM));
|
||||
childPos.I(childWM) += margin.IStart(childWM);
|
||||
childPos.B(childWM) += margin.BStart(childWM);
|
||||
childRS.ApplyRelativePositioning(&childPos, containerWidth);
|
||||
FinishReflowChild(child, pc, childSize, &childRS, wm, childPos,
|
||||
FinishReflowChild(child, pc, childSize, &childRS, childWM, childPos,
|
||||
containerWidth, 0);
|
||||
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, child);
|
||||
// XXX deal with 'childStatus' not being COMPLETE
|
||||
|
45
layout/reftests/css-grid/grid-item-dir-001-ref.html
Normal file
45
layout/reftests/css-grid/grid-item-dir-001-ref.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style type="text/css">
|
||||
.grid {
|
||||
border: 1px solid gray;
|
||||
font-size: 0;
|
||||
}
|
||||
.grid > div {
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
}
|
||||
#a { background: #006; height: 46px; width: 96px; }
|
||||
#b { background: #009; height: 46px; width: 146px; }
|
||||
#c { background: #00c; height: 46px; width: 46px; }
|
||||
#d { background: #00f; height: 46px; width: 16px; }
|
||||
#e { background: #060; height: 96px; width: 96px; }
|
||||
#f { background: #090; height: 96px; width: 146px; }
|
||||
#g { background: #0c0; height: 96px; width: 46px; }
|
||||
#h { background: #0f0; height: 96px; width: 16px; }
|
||||
#i { background: #600; height: 16px; width: 96px; }
|
||||
#j { background: #900; height: 16px; width: 146px; }
|
||||
#k { background: #c00; height: 16px; width: 46px; }
|
||||
#l { background: #f00; height: 16px; width: 16px; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class=grid>
|
||||
<div id=a></div>
|
||||
<div id=b></div>
|
||||
<div id=c></div>
|
||||
<div id=d></div><br>
|
||||
<div id=e></div>
|
||||
<div id=f></div>
|
||||
<div id=g></div>
|
||||
<div id=h></div><br>
|
||||
<div id=i></div>
|
||||
<div id=j></div>
|
||||
<div id=k></div>
|
||||
<div id=l></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
46
layout/reftests/css-grid/grid-item-dir-001.html
Normal file
46
layout/reftests/css-grid/grid-item-dir-001.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style type="text/css">
|
||||
.grid {
|
||||
display: grid;
|
||||
border: 1px solid gray;
|
||||
grid-template-columns: 100px 150px 50px 20px;
|
||||
grid-template-rows: 50px 100px 20px;
|
||||
}
|
||||
.grid > div {
|
||||
margin: 2px;
|
||||
}
|
||||
#a { background: #006; }
|
||||
#b { background: #009; }
|
||||
#c { background: #00c; }
|
||||
#d { background: #00f; }
|
||||
#e { background: #060; }
|
||||
#f { background: #090; }
|
||||
#g { background: #0c0; }
|
||||
#h { background: #0f0; }
|
||||
#i { background: #600; }
|
||||
#j { background: #900; }
|
||||
#k { background: #c00; }
|
||||
#l { background: #f00; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class=grid>
|
||||
<div id=a></div>
|
||||
<div id=b></div>
|
||||
<div id=c></div>
|
||||
<div id=d></div>
|
||||
<div id=e dir=rtl></div>
|
||||
<div id=f dir=rtl></div>
|
||||
<div id=g dir=rtl></div>
|
||||
<div id=h dir=rtl></div>
|
||||
<div id=i></div>
|
||||
<div id=j dir=rtl></div>
|
||||
<div id=k></div>
|
||||
<div id=l dir=rtl></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -25,3 +25,4 @@ pref(layout.css.vertical-text.enabled,true) == rtl-grid-placement-auto-row-spars
|
||||
pref(layout.css.vertical-text.enabled,true) == vlr-grid-placement-auto-row-sparse-001.html vlr-grid-placement-auto-row-sparse-001-ref.html
|
||||
pref(layout.css.vertical-text.enabled,true) == vrl-grid-placement-auto-row-sparse-001.html vrl-grid-placement-auto-row-sparse-001-ref.html
|
||||
== grid-relpos-items-001.html grid-relpos-items-001-ref.html
|
||||
== grid-item-dir-001.html grid-item-dir-001-ref.html
|
||||
|
@ -243,7 +243,11 @@ ErrorReporter::AddToError(const nsString &aErrorText)
|
||||
// for all errors on that line. That causes the text of the line to
|
||||
// be shared among all the nsIScriptError objects.
|
||||
if (mErrorLine.IsEmpty() || mErrorLineNumber != mPrevErrorLineNumber) {
|
||||
mErrorLine = mScanner->GetCurrentLine();
|
||||
// Be careful here: the error line might be really long and OOM
|
||||
// when we try to make a copy here. If so, just leave it empty.
|
||||
if (!mErrorLine.Assign(mScanner->GetCurrentLine(), fallible)) {
|
||||
mErrorLine.Truncate();
|
||||
}
|
||||
mPrevErrorLineNumber = mErrorLineNumber;
|
||||
}
|
||||
} else {
|
||||
|
@ -159,6 +159,7 @@ nsTableFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
NS_PRECONDITION(!mCellMap, "Init called twice");
|
||||
NS_PRECONDITION(!mTableLayoutStrategy, "Init called twice");
|
||||
NS_PRECONDITION(!aPrevInFlow ||
|
||||
aPrevInFlow->GetType() == nsGkAtoms::tableFrame,
|
||||
"prev-in-flow must be of same type");
|
||||
@ -171,24 +172,20 @@ nsTableFrame::Init(nsIContent* aContent,
|
||||
bool borderCollapse = (NS_STYLE_BORDER_COLLAPSE == tableStyle->mBorderCollapse);
|
||||
SetBorderCollapse(borderCollapse);
|
||||
|
||||
// Create the cell map if this frame is the first-in-flow.
|
||||
if (!aPrevInFlow) {
|
||||
// If we're the first-in-flow, we manage the cell map & layout strategy that
|
||||
// get used by our continuation chain:
|
||||
mCellMap = new nsTableCellMap(*this, borderCollapse);
|
||||
}
|
||||
|
||||
if (aPrevInFlow) {
|
||||
if (IsAutoLayout()) {
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this);
|
||||
} else {
|
||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
||||
}
|
||||
} else {
|
||||
// set my width, because all frames in a table flow are the same width and
|
||||
// code in nsTableOuterFrame depends on this being set
|
||||
mRect.width = aPrevInFlow->GetSize().width;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(!mTableLayoutStrategy, "strategy was created before Init was called");
|
||||
// create the strategy
|
||||
if (IsAutoLayout())
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this);
|
||||
else
|
||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
||||
}
|
||||
}
|
||||
|
||||
nsTableFrame::~nsTableFrame()
|
||||
@ -305,8 +302,7 @@ nsTableFrame::UnregisterPositionedTablePart(nsIFrame* aFrame,
|
||||
static_cast<FrameTArray*>(props.Get(PositionedTablePartArray()));
|
||||
|
||||
// Remove the frame.
|
||||
MOZ_ASSERT(positionedParts &&
|
||||
positionedParts->IndexOf(aFrame) != FrameTArray::NoIndex,
|
||||
MOZ_ASSERT(positionedParts && positionedParts->Contains(aFrame),
|
||||
"Asked to unregister a positioned table part that wasn't registered");
|
||||
if (positionedParts) {
|
||||
positionedParts->RemoveElement(aFrame);
|
||||
@ -1792,7 +1788,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (!GetPrevInFlow() && !mTableLayoutStrategy) {
|
||||
NS_ASSERTION(false, "strategy should have been created in Init");
|
||||
NS_ERROR("strategy should have been created in Init");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1892,7 +1888,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
|
||||
}
|
||||
else {
|
||||
// Calculate the overflow area contribution from our children.
|
||||
for (nsIFrame* kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
|
||||
for (nsIFrame* kid : mFrames) {
|
||||
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kid);
|
||||
}
|
||||
}
|
||||
@ -2051,7 +2047,7 @@ nsTableFrame::GetFirstBodyRowGroupFrame()
|
||||
nsIFrame* headerFrame = nullptr;
|
||||
nsIFrame* footerFrame = nullptr;
|
||||
|
||||
for (nsIFrame* kidFrame = mFrames.FirstChild(); nullptr != kidFrame; ) {
|
||||
for (nsIFrame* kidFrame : mFrames) {
|
||||
const nsStyleDisplay* childDisplay = kidFrame->StyleDisplay();
|
||||
|
||||
// We expect the header and footer row group frames to be first, and we only
|
||||
@ -2075,9 +2071,6 @@ nsTableFrame::GetFirstBodyRowGroupFrame()
|
||||
} else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
|
||||
return kidFrame;
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -2170,8 +2163,7 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding)
|
||||
NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedWidth called on next in flow");
|
||||
nscoord width = GetColSpacing(GetColCount());
|
||||
width += aBorderPadding.left + aBorderPadding.right;
|
||||
for (nsIFrame* groupFrame = mColGroups.FirstChild(); groupFrame;
|
||||
groupFrame = groupFrame->GetNextSibling()) {
|
||||
for (nsIFrame* groupFrame : mColGroups) {
|
||||
const nsStyleVisibility* groupVis = groupFrame->StyleVisibility();
|
||||
bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
|
||||
nsTableColGroupFrame* cgFrame = (nsTableColGroupFrame*)groupFrame;
|
||||
@ -3200,8 +3192,7 @@ nsTableFrame::ReflowColGroups(nsRenderingContext *aRenderingContext)
|
||||
if (!GetPrevInFlow() && !HaveReflowedColGroups()) {
|
||||
nsHTMLReflowMetrics kidMet(GetWritingMode());
|
||||
nsPresContext *presContext = PresContext();
|
||||
for (nsIFrame* kidFrame = mColGroups.FirstChild(); kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling()) {
|
||||
for (nsIFrame* kidFrame : mColGroups) {
|
||||
if (NS_SUBTREE_DIRTY(kidFrame)) {
|
||||
// The column groups don't care about dimensions or reflow states.
|
||||
nsHTMLReflowState
|
||||
@ -3223,7 +3214,7 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState,
|
||||
{
|
||||
nsTableCellMap* cellMap = GetCellMap();
|
||||
if (!cellMap) {
|
||||
NS_ASSERTION(false, "never ever call me until the cell map is built!");
|
||||
NS_ERROR("never ever call me until the cell map is built!");
|
||||
aDesiredSize.Height() = 0;
|
||||
return;
|
||||
}
|
||||
@ -3267,7 +3258,7 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState,
|
||||
// unconstrained row group.
|
||||
DistributeHeightToRows(aReflowState, tableSpecifiedHeight - desiredHeight);
|
||||
// this might have changed the overflow area incorporate the childframe overflow area.
|
||||
for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) {
|
||||
for (nsIFrame* kidFrame : mFrames) {
|
||||
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame);
|
||||
}
|
||||
desiredHeight = tableSpecifiedHeight;
|
||||
@ -3875,8 +3866,7 @@ nsTableFrame::Dump(bool aDumpRows,
|
||||
}
|
||||
}
|
||||
printf("\n colgroups->");
|
||||
for (nsIFrame* childFrame = mColGroups.FirstChild(); childFrame;
|
||||
childFrame = childFrame->GetNextSibling()) {
|
||||
for (nsIFrame* childFrame : mColGroups) {
|
||||
if (nsGkAtoms::tableColGroupFrame == childFrame->GetType()) {
|
||||
nsTableColGroupFrame* colGroupFrame = (nsTableColGroupFrame *)childFrame;
|
||||
colGroupFrame->Dump(1);
|
||||
@ -4407,7 +4397,7 @@ BCMapCellInfo::SetInfo(nsTableRowFrame* aNewRow,
|
||||
NS_ASSERTION(mEndRow, "spanned row not found");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(false, "error in cell map");
|
||||
NS_ERROR("error in cell map");
|
||||
mRowSpan = 1;
|
||||
mEndRow = mStartRow;
|
||||
}
|
||||
@ -6996,7 +6986,7 @@ BCVerticalSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
owner = mFirstRowGroup;
|
||||
break;
|
||||
case eAjaRowOwner:
|
||||
NS_ASSERTION(false, "program error"); // and fall through
|
||||
NS_ERROR("program error"); // and fall through
|
||||
case eRowOwner:
|
||||
NS_ASSERTION(aIter.IsTableLeftMost() || aIter.IsTableRightMost(),
|
||||
"row can own border only at table edge");
|
||||
|
@ -17,29 +17,54 @@ namespace mozilla {
|
||||
|
||||
class DataBuffer {
|
||||
public:
|
||||
DataBuffer() : data_(nullptr), len_(0) {}
|
||||
DataBuffer() : data_(nullptr), len_(0), capacity_(0) {}
|
||||
DataBuffer(const uint8_t *data, size_t len) {
|
||||
Assign(data, len);
|
||||
Assign(data, len, len);
|
||||
}
|
||||
DataBuffer(const uint8_t *data, size_t len, size_t capacity) {
|
||||
Assign(data, len, capacity);
|
||||
}
|
||||
|
||||
void Assign(const uint8_t *data, size_t len) {
|
||||
Allocate(len);
|
||||
// to ensure extra space for expansion
|
||||
void Assign(const uint8_t *data, size_t len, size_t capacity) {
|
||||
MOZ_RELEASE_ASSERT(len <= capacity);
|
||||
Allocate(capacity); // sets len_ = capacity
|
||||
memcpy(static_cast<void *>(data_.get()),
|
||||
static_cast<const void *>(data), len);
|
||||
len_ = len;
|
||||
}
|
||||
|
||||
void Allocate(size_t len) {
|
||||
data_.reset(new uint8_t[len ? len : 1]); // Don't depend on new [0].
|
||||
void Allocate(size_t capacity) {
|
||||
data_.reset(new uint8_t[capacity ? capacity : 1]); // Don't depend on new [0].
|
||||
len_ = capacity_ = capacity;
|
||||
}
|
||||
|
||||
void EnsureCapacity(size_t capacity) {
|
||||
if (capacity_ < capacity) {
|
||||
uint8_t *new_data = new uint8_t[ capacity ? capacity : 1];
|
||||
memcpy(static_cast<void *>(new_data),
|
||||
static_cast<const void *>(data_.get()), len_);
|
||||
data_.reset(new_data); // after copying! Deletes old data
|
||||
capacity_ = capacity;
|
||||
}
|
||||
}
|
||||
|
||||
// used when something writes to the buffer (having checked
|
||||
// capacity() or used EnsureCapacity()) and increased the length.
|
||||
void SetLength(size_t len) {
|
||||
MOZ_RELEASE_ASSERT(len <= capacity_);
|
||||
len_ = len;
|
||||
}
|
||||
|
||||
const uint8_t *data() const { return data_.get(); }
|
||||
uint8_t *data() { return data_.get(); }
|
||||
size_t len() const { return len_; }
|
||||
size_t capacity() const { return capacity_; }
|
||||
|
||||
private:
|
||||
UniquePtr<uint8_t[]> data_;
|
||||
size_t len_;
|
||||
size_t capacity_;
|
||||
|
||||
DISALLOW_COPY_ASSIGN(DataBuffer);
|
||||
};
|
||||
|
@ -69,7 +69,6 @@ WebrtcAudioConduit::~WebrtcAudioConduit()
|
||||
{
|
||||
delete mRecvCodecList[i];
|
||||
}
|
||||
delete mCurSendCodecConfig;
|
||||
|
||||
// The first one of a pair to be deleted shuts down media for both
|
||||
if(mPtrVoEXmedia)
|
||||
@ -360,10 +359,12 @@ WebrtcAudioConduit::ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig)
|
||||
int error = 0;//webrtc engine errors
|
||||
webrtc::CodecInst cinst;
|
||||
|
||||
//validate codec param
|
||||
if((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError)
|
||||
{
|
||||
return condError;
|
||||
//validate codec param
|
||||
if((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError)
|
||||
{
|
||||
return condError;
|
||||
}
|
||||
}
|
||||
|
||||
condError = StopTransmitting();
|
||||
@ -411,16 +412,17 @@ WebrtcAudioConduit::ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig)
|
||||
return condError;
|
||||
}
|
||||
|
||||
//Copy the applied config for future reference.
|
||||
delete mCurSendCodecConfig;
|
||||
|
||||
mCurSendCodecConfig = new AudioCodecConfig(codecConfig->mType,
|
||||
codecConfig->mName,
|
||||
codecConfig->mFreq,
|
||||
codecConfig->mPacSize,
|
||||
codecConfig->mChannels,
|
||||
codecConfig->mRate);
|
||||
{
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
|
||||
//Copy the applied config for future reference.
|
||||
mCurSendCodecConfig = new AudioCodecConfig(codecConfig->mType,
|
||||
codecConfig->mName,
|
||||
codecConfig->mFreq,
|
||||
codecConfig->mPacSize,
|
||||
codecConfig->mChannels,
|
||||
codecConfig->mRate);
|
||||
}
|
||||
return kMediaConduitNoError;
|
||||
}
|
||||
|
||||
@ -1018,7 +1020,7 @@ WebrtcAudioConduit::CheckCodecForMatch(const AudioCodecConfig* codecInfo) const
|
||||
*/
|
||||
MediaConduitErrorCode
|
||||
WebrtcAudioConduit::ValidateCodecConfig(const AudioCodecConfig* codecInfo,
|
||||
bool send) const
|
||||
bool send)
|
||||
{
|
||||
bool codecAppliedAlready = false;
|
||||
|
||||
@ -1045,6 +1047,8 @@ WebrtcAudioConduit::ValidateCodecConfig(const AudioCodecConfig* codecInfo,
|
||||
//check if we have the same codec already applied
|
||||
if(send)
|
||||
{
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
|
||||
codecAppliedAlready = CheckCodecsForMatch(mCurSendCodecConfig,codecInfo);
|
||||
} else {
|
||||
codecAppliedAlready = CheckCodecForMatch(codecInfo);
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
mEngineTransmitting(false),
|
||||
mEngineReceiving(false),
|
||||
mChannel(-1),
|
||||
mCurSendCodecConfig(nullptr),
|
||||
mCodecMutex("AudioConduit codec db"),
|
||||
mCaptureDelay(150),
|
||||
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
|
||||
mLastTimestamp(0),
|
||||
@ -245,7 +245,7 @@ private:
|
||||
bool CheckCodecsForMatch(const AudioCodecConfig* curCodecConfig,
|
||||
const AudioCodecConfig* codecInfo) const;
|
||||
//Checks the codec to be applied
|
||||
MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send) const;
|
||||
MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send);
|
||||
|
||||
//Utility function to dump recv codec database
|
||||
void DumpCodecDB() const;
|
||||
@ -277,7 +277,9 @@ private:
|
||||
|
||||
int mChannel;
|
||||
RecvCodecList mRecvCodecList;
|
||||
AudioCodecConfig* mCurSendCodecConfig;
|
||||
|
||||
Mutex mCodecMutex; // protects mCurSendCodecConfig
|
||||
nsAutoPtr<AudioCodecConfig> mCurSendCodecConfig;
|
||||
|
||||
// Current "capture" delay (really output plus input delay)
|
||||
int32_t mCaptureDelay;
|
||||
|
@ -74,7 +74,7 @@ WebrtcVideoConduit::WebrtcVideoConduit():
|
||||
mEngineReceiving(false),
|
||||
mChannel(-1),
|
||||
mCapId(-1),
|
||||
mCurSendCodecConfig(nullptr),
|
||||
mCodecMutex("VideoConduit codec db"),
|
||||
mSendingWidth(0),
|
||||
mSendingHeight(0),
|
||||
mReceivingWidth(640),
|
||||
@ -101,8 +101,6 @@ WebrtcVideoConduit::~WebrtcVideoConduit()
|
||||
delete mRecvCodecList[i];
|
||||
}
|
||||
|
||||
delete mCurSendCodecConfig;
|
||||
|
||||
// The first one of a pair to be deleted shuts down media for both
|
||||
//Deal with External Capturer
|
||||
if(mPtrViECapture)
|
||||
@ -236,8 +234,9 @@ bool WebrtcVideoConduit::GetVideoEncoderStats(double* framerateMean,
|
||||
// unchanged resolution, but adjust bandwidth limits to match camera fps
|
||||
CSFLogDebug(logTag, "Encoder frame rate changed from %f to %f",
|
||||
(mLastFramerateTenths/10.0), *framerateMean);
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
mLastFramerateTenths = *framerateMean * 10;
|
||||
SelectSendResolution(mSendingWidth, mSendingHeight, true);
|
||||
SelectSendResolution(mSendingWidth, mSendingHeight);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -595,6 +594,12 @@ WebrtcVideoConduit::ConfigureCodecMode(webrtc::VideoCodecMode mode)
|
||||
/**
|
||||
* Note: Setting the send-codec on the Video Engine will restart the encoder,
|
||||
* sets up new SSRC and reset RTP_RTCP module with the new codec setting.
|
||||
*
|
||||
* Note: this is called from MainThread, and the codec settings are read on
|
||||
* videoframe delivery threads (i.e in SendVideoFrame(). With
|
||||
* renegotiation/reconfiguration, this now needs a lock! Alternatively
|
||||
* changes could be queued until the next frame is delivered using an
|
||||
* Atomic pointer and swaps.
|
||||
*/
|
||||
MediaConduitErrorCode
|
||||
WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
@ -608,16 +613,12 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
|
||||
memset(&video_codec, 0, sizeof(video_codec));
|
||||
|
||||
//validate basic params
|
||||
if((condError = ValidateCodecConfig(codecConfig,true)) != kMediaConduitNoError)
|
||||
{
|
||||
return condError;
|
||||
}
|
||||
|
||||
//Check if we have same codec already applied
|
||||
if(CheckCodecsForMatch(mCurSendCodecConfig, codecConfig))
|
||||
{
|
||||
CSFLogDebug(logTag, "%s Codec has been applied already ", __FUNCTION__);
|
||||
//validate basic params
|
||||
if((condError = ValidateCodecConfig(codecConfig,true)) != kMediaConduitNoError)
|
||||
{
|
||||
return condError;
|
||||
}
|
||||
}
|
||||
|
||||
condError = StopTransmitting();
|
||||
@ -709,10 +710,12 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
return condError;
|
||||
}
|
||||
|
||||
//Copy the applied config for future reference.
|
||||
delete mCurSendCodecConfig;
|
||||
{
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
|
||||
mCurSendCodecConfig = new VideoCodecConfig(*codecConfig);
|
||||
//Copy the applied config for future reference.
|
||||
mCurSendCodecConfig = new VideoCodecConfig(*codecConfig);
|
||||
}
|
||||
|
||||
mPtrRTP->SetRembStatus(mChannel, true, false);
|
||||
|
||||
@ -997,11 +1000,12 @@ WebrtcVideoConduit::SelectBandwidth(webrtc::VideoCodec& vie_codec,
|
||||
|
||||
// XXX we need to figure out how to feed back changes in preferred capture
|
||||
// resolution to the getUserMedia source
|
||||
// Invoked under lock of mCodecMutex!
|
||||
bool
|
||||
WebrtcVideoConduit::SelectSendResolution(unsigned short width,
|
||||
unsigned short height,
|
||||
bool force)
|
||||
unsigned short height)
|
||||
{
|
||||
mCodecMutex.AssertCurrentThreadOwns();
|
||||
// XXX This will do bandwidth-resolution adaptation as well - bug 877954
|
||||
|
||||
// Limit resolution to max-fs while keeping same aspect ratio as the
|
||||
@ -1071,15 +1075,25 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
|
||||
|
||||
// Adapt to getUserMedia resolution changes
|
||||
// check if we need to reconfigure the sending resolution.
|
||||
// force tells us to do it regardless, such as when the FPS changes
|
||||
if (mSendingWidth != width || mSendingHeight != height || force)
|
||||
bool changed = false;
|
||||
if (mSendingWidth != width || mSendingHeight != height)
|
||||
{
|
||||
// This will avoid us continually retrying this operation if it fails.
|
||||
// If the resolution changes, we'll try again. In the meantime, we'll
|
||||
// keep using the old size in the encoder.
|
||||
mSendingWidth = width;
|
||||
mSendingHeight = height;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// uses mSendingWidth/Height
|
||||
unsigned int framerate = SelectSendFrameRate(mSendingFramerate);
|
||||
if (mSendingFramerate != framerate) {
|
||||
mSendingFramerate = framerate;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
// Get current vie codec.
|
||||
webrtc::VideoCodec vie_codec;
|
||||
int32_t err;
|
||||
@ -1089,10 +1103,13 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
|
||||
CSFLogError(logTag, "%s: GetSendCodec failed, err %d", __FUNCTION__, err);
|
||||
return false;
|
||||
}
|
||||
if (vie_codec.width != width || vie_codec.height != height || force)
|
||||
// Likely spurious unless there was some error, but rarely checked
|
||||
if (vie_codec.width != width || vie_codec.height != height ||
|
||||
vie_codec.maxFramerate != mSendingFramerate)
|
||||
{
|
||||
vie_codec.width = width;
|
||||
vie_codec.height = height;
|
||||
vie_codec.maxFramerate = mSendingFramerate;
|
||||
SelectBandwidth(vie_codec, width, height);
|
||||
|
||||
if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0)
|
||||
@ -1101,19 +1118,22 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
|
||||
__FUNCTION__, width, height, err);
|
||||
return false;
|
||||
}
|
||||
CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u, bitrate %u:%u",
|
||||
__FUNCTION__, width, height,
|
||||
CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u @ %ufps, bitrate %u:%u",
|
||||
__FUNCTION__, width, height, mSendingFramerate,
|
||||
vie_codec.minBitrate, vie_codec.maxBitrate);
|
||||
} // else no change; mSendingWidth likely was 0
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// TODO(ruil2@cisco.com):combine SelectSendResolution with SelectSendFrameRate Bug 1132318
|
||||
bool
|
||||
WebrtcVideoConduit::SelectSendFrameRate(unsigned int framerate)
|
||||
|
||||
// Invoked under lock of mCodecMutex!
|
||||
unsigned int
|
||||
WebrtcVideoConduit::SelectSendFrameRate(unsigned int framerate) const
|
||||
{
|
||||
mCodecMutex.AssertCurrentThreadOwns();
|
||||
unsigned int new_framerate = framerate;
|
||||
|
||||
// Limit frame rate based on max-mbps
|
||||
mSendingFramerate = framerate;
|
||||
if (mCurSendCodecConfig && mCurSendCodecConfig->mMaxMBPS)
|
||||
{
|
||||
unsigned int cur_fs, mb_width, mb_height, max_fps;
|
||||
@ -1124,39 +1144,15 @@ WebrtcVideoConduit::SelectSendFrameRate(unsigned int framerate)
|
||||
cur_fs = mb_width * mb_height;
|
||||
max_fps = mCurSendCodecConfig->mMaxMBPS/cur_fs;
|
||||
if (max_fps < mSendingFramerate) {
|
||||
mSendingFramerate = max_fps;
|
||||
new_framerate = max_fps;
|
||||
}
|
||||
|
||||
if (mCurSendCodecConfig->mMaxFrameRate != 0 &&
|
||||
mCurSendCodecConfig->mMaxFrameRate < mSendingFramerate) {
|
||||
mSendingFramerate = mCurSendCodecConfig->mMaxFrameRate;
|
||||
new_framerate = mCurSendCodecConfig->mMaxFrameRate;
|
||||
}
|
||||
}
|
||||
if (mSendingFramerate != framerate)
|
||||
{
|
||||
// Get current vie codec.
|
||||
webrtc::VideoCodec vie_codec;
|
||||
int32_t err;
|
||||
|
||||
if ((err = mPtrViECodec->GetSendCodec(mChannel, vie_codec)) != 0)
|
||||
{
|
||||
CSFLogError(logTag, "%s: GetSendCodec failed, err %d", __FUNCTION__, err);
|
||||
return false;
|
||||
}
|
||||
if (vie_codec.maxFramerate != mSendingFramerate)
|
||||
{
|
||||
vie_codec.maxFramerate = mSendingFramerate;
|
||||
if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0)
|
||||
{
|
||||
CSFLogError(logTag, "%s: SetSendCodec(%u) failed, err %d",
|
||||
__FUNCTION__, mSendingFramerate, err);
|
||||
return false;
|
||||
}
|
||||
CSFLogDebug(logTag, "%s: Encoder framerate changed to %u",
|
||||
__FUNCTION__, mSendingFramerate);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return new_framerate;
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
@ -1221,13 +1217,12 @@ WebrtcVideoConduit::SendVideoFrame(unsigned char* video_frame,
|
||||
return kMediaConduitSessionNotInited;
|
||||
}
|
||||
|
||||
if (!SelectSendResolution(width, height, false))
|
||||
{
|
||||
return kMediaConduitCaptureError;
|
||||
}
|
||||
if (!SelectSendFrameRate(mSendingFramerate))
|
||||
{
|
||||
return kMediaConduitCaptureError;
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
if (!SelectSendResolution(width, height))
|
||||
{
|
||||
return kMediaConduitCaptureError;
|
||||
}
|
||||
}
|
||||
// insert the frame to video engine in I420 format only
|
||||
MOZ_ASSERT(mPtrExtCapture);
|
||||
@ -1609,7 +1604,7 @@ WebrtcVideoConduit::CheckCodecForMatch(const VideoCodecConfig* codecInfo) const
|
||||
*/
|
||||
MediaConduitErrorCode
|
||||
WebrtcVideoConduit::ValidateCodecConfig(const VideoCodecConfig* codecInfo,
|
||||
bool send) const
|
||||
bool send)
|
||||
{
|
||||
bool codecAppliedAlready = false;
|
||||
|
||||
@ -1629,6 +1624,8 @@ WebrtcVideoConduit::ValidateCodecConfig(const VideoCodecConfig* codecInfo,
|
||||
//check if we have the same codec already applied
|
||||
if(send)
|
||||
{
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
|
||||
codecAppliedAlready = CheckCodecsForMatch(mCurSendCodecConfig,codecInfo);
|
||||
} else {
|
||||
codecAppliedAlready = CheckCodecForMatch(codecInfo);
|
||||
|
@ -145,15 +145,15 @@ public:
|
||||
* @param force: force setting the codec config if framerate may require a bandwidth change
|
||||
*/
|
||||
bool SelectSendResolution(unsigned short width,
|
||||
unsigned short height,
|
||||
bool force);
|
||||
unsigned short height);
|
||||
|
||||
/**
|
||||
* Function to select and change the encoding frame rate based on incoming frame rate
|
||||
* and max-mbps setting.
|
||||
* @param framerate
|
||||
* @param current framerate
|
||||
* @result new framerate
|
||||
*/
|
||||
bool SelectSendFrameRate(unsigned int framerate);
|
||||
unsigned int SelectSendFrameRate(unsigned int framerate) const;
|
||||
|
||||
/**
|
||||
* Function to deliver a capture video frame for encoding and transport
|
||||
@ -306,7 +306,7 @@ private:
|
||||
const VideoCodecConfig* codecInfo) const;
|
||||
|
||||
//Checks the codec to be applied
|
||||
MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send) const;
|
||||
MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send);
|
||||
|
||||
//Utility function to dump recv codec database
|
||||
void DumpCodecDB() const;
|
||||
@ -337,7 +337,10 @@ private:
|
||||
int mChannel; // Video Channel for this conduit
|
||||
int mCapId; // Capturer for this conduit
|
||||
RecvCodecList mRecvCodecList;
|
||||
VideoCodecConfig* mCurSendCodecConfig;
|
||||
|
||||
Mutex mCodecMutex; // protects mCurrSendCodecConfig
|
||||
nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig;
|
||||
|
||||
unsigned short mSendingWidth;
|
||||
unsigned short mSendingHeight;
|
||||
unsigned short mReceivingWidth;
|
||||
|
@ -750,109 +750,85 @@ nsresult MediaPipeline::PipelineTransport::SendRtpPacket(
|
||||
const void *data, int len) {
|
||||
|
||||
nsAutoPtr<DataBuffer> buf(new DataBuffer(static_cast<const uint8_t *>(data),
|
||||
len));
|
||||
len, len + SRTP_MAX_EXPANSION));
|
||||
|
||||
RUN_ON_THREAD(sts_thread_,
|
||||
WrapRunnable(
|
||||
RefPtr<MediaPipeline::PipelineTransport>(this),
|
||||
&MediaPipeline::PipelineTransport::SendRtpPacket_s,
|
||||
buf),
|
||||
&MediaPipeline::PipelineTransport::SendRtpRtcpPacket_s,
|
||||
buf, true),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtpPacket_s(
|
||||
nsAutoPtr<DataBuffer> data) {
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
if (!pipeline_)
|
||||
return NS_OK; // Detached
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtpRtcpPacket_s(
|
||||
nsAutoPtr<DataBuffer> data,
|
||||
bool is_rtp) {
|
||||
|
||||
if (!pipeline_->rtp_.send_srtp_) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Couldn't write RTP packet; SRTP not set up yet");
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
if (!pipeline_) {
|
||||
return NS_OK; // Detached
|
||||
}
|
||||
TransportInfo& transport = is_rtp ? pipeline_->rtp_ : pipeline_->rtcp_;
|
||||
|
||||
if (!transport.send_srtp_) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Couldn't write RTP/RTCP packet; SRTP not set up yet");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(pipeline_->rtp_.transport_);
|
||||
NS_ENSURE_TRUE(pipeline_->rtp_.transport_, NS_ERROR_NULL_POINTER);
|
||||
MOZ_ASSERT(transport.transport_);
|
||||
NS_ENSURE_TRUE(transport.transport_, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// libsrtp enciphers in place, so we need a new, big enough
|
||||
// buffer.
|
||||
// XXX. allocates and deletes one buffer per packet sent.
|
||||
// Bug 822129
|
||||
int max_len = data->len() + SRTP_MAX_EXPANSION;
|
||||
ScopedDeletePtr<unsigned char> inner_data(
|
||||
new unsigned char[max_len]);
|
||||
memcpy(inner_data, data->data(), data->len());
|
||||
// libsrtp enciphers in place, so we need a big enough buffer.
|
||||
MOZ_ASSERT(data->capacity() >= data->len() + SRTP_MAX_EXPANSION);
|
||||
|
||||
int out_len;
|
||||
nsresult res = pipeline_->rtp_.send_srtp_->ProtectRtp(inner_data,
|
||||
data->len(),
|
||||
max_len,
|
||||
&out_len);
|
||||
if (!NS_SUCCEEDED(res))
|
||||
nsresult res;
|
||||
if (is_rtp) {
|
||||
res = transport.send_srtp_->ProtectRtp(data->data(),
|
||||
data->len(),
|
||||
data->capacity(),
|
||||
&out_len);
|
||||
} else {
|
||||
res = transport.send_srtp_->ProtectRtcp(data->data(),
|
||||
data->len(),
|
||||
data->capacity(),
|
||||
&out_len);
|
||||
}
|
||||
if (!NS_SUCCEEDED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending RTP packet.");
|
||||
pipeline_->increment_rtp_packets_sent(out_len);
|
||||
return pipeline_->SendPacket(pipeline_->rtp_.transport_, inner_data,
|
||||
out_len);
|
||||
// paranoia; don't have uninitialized bytes included in data->len()
|
||||
data->SetLength(out_len);
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending " <<
|
||||
(is_rtp ? "RTP" : "RTCP") << " packet");
|
||||
if (is_rtp) {
|
||||
pipeline_->increment_rtp_packets_sent(out_len);
|
||||
} else {
|
||||
pipeline_->increment_rtcp_packets_sent();
|
||||
}
|
||||
return pipeline_->SendPacket(transport.transport_, data->data(), out_len);
|
||||
}
|
||||
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtcpPacket(
|
||||
const void *data, int len) {
|
||||
|
||||
nsAutoPtr<DataBuffer> buf(new DataBuffer(static_cast<const uint8_t *>(data),
|
||||
len));
|
||||
len, len + SRTP_MAX_EXPANSION));
|
||||
|
||||
RUN_ON_THREAD(sts_thread_,
|
||||
WrapRunnable(
|
||||
RefPtr<MediaPipeline::PipelineTransport>(this),
|
||||
&MediaPipeline::PipelineTransport::SendRtcpPacket_s,
|
||||
buf),
|
||||
&MediaPipeline::PipelineTransport::SendRtpRtcpPacket_s,
|
||||
buf, false),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtcpPacket_s(
|
||||
nsAutoPtr<DataBuffer> data) {
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
if (!pipeline_)
|
||||
return NS_OK; // Detached
|
||||
|
||||
if (!pipeline_->rtcp_.send_srtp_) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Couldn't write RTCP packet; SRTCP not set up yet");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(pipeline_->rtcp_.transport_);
|
||||
NS_ENSURE_TRUE(pipeline_->rtcp_.transport_, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// libsrtp enciphers in place, so we need a new, big enough
|
||||
// buffer.
|
||||
// XXX. allocates and deletes one buffer per packet sent.
|
||||
// Bug 822129.
|
||||
int max_len = data->len() + SRTP_MAX_EXPANSION;
|
||||
ScopedDeletePtr<unsigned char> inner_data(
|
||||
new unsigned char[max_len]);
|
||||
memcpy(inner_data, data->data(), data->len());
|
||||
|
||||
int out_len;
|
||||
nsresult res = pipeline_->rtcp_.send_srtp_->ProtectRtcp(inner_data,
|
||||
data->len(),
|
||||
max_len,
|
||||
&out_len);
|
||||
|
||||
if (!NS_SUCCEEDED(res))
|
||||
return res;
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending RTCP packet.");
|
||||
pipeline_->increment_rtcp_packets_sent();
|
||||
return pipeline_->SendPacket(pipeline_->rtcp_.transport_, inner_data,
|
||||
out_len);
|
||||
}
|
||||
|
||||
void MediaPipelineTransmit::PipelineListener::
|
||||
UnsetTrackId(MediaStreamGraphImpl* graph) {
|
||||
#ifndef USE_FAKE_MEDIA_STREAMS
|
||||
|
@ -191,8 +191,8 @@ class MediaPipeline : public sigslot::has_slots<> {
|
||||
virtual nsresult SendRtcpPacket(const void* data, int len);
|
||||
|
||||
private:
|
||||
virtual nsresult SendRtpPacket_s(nsAutoPtr<DataBuffer> data);
|
||||
virtual nsresult SendRtcpPacket_s(nsAutoPtr<DataBuffer> data);
|
||||
nsresult SendRtpRtcpPacket_s(nsAutoPtr<DataBuffer> data,
|
||||
bool is_rtp);
|
||||
|
||||
MediaPipeline *pipeline_; // Raw pointer to avoid cycles
|
||||
nsCOMPtr<nsIEventTarget> sts_thread_;
|
||||
|
@ -22,9 +22,9 @@ namespace mozilla {
|
||||
#define SRTP_MASTER_SALT_LENGTH 14
|
||||
#define SRTP_TOTAL_KEY_LENGTH (SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH)
|
||||
|
||||
// For some reason libsrtp increases packet size by > 12 for RTCP even though
|
||||
// the doc claims otherwise.
|
||||
#define SRTP_MAX_EXPANSION 20
|
||||
// SRTCP requires an auth tag *plus* a 4-byte index-plus-'E'-bit value (see
|
||||
// RFC 3711)
|
||||
#define SRTP_MAX_EXPANSION (SRTP_MAX_TRAILER_LEN+4)
|
||||
|
||||
|
||||
class SrtpFlow {
|
||||
|
@ -370,6 +370,8 @@ public:
|
||||
bool IsDarkMatterMode() const { return mMode == DarkMatter; }
|
||||
bool IsCumulativeMode() const { return mMode == Cumulative; }
|
||||
|
||||
const char* ModeString() const;
|
||||
|
||||
const char* DMDEnvVar() const { return mDMDEnvVar; }
|
||||
|
||||
size_t SampleBelowSize() const { return mSampleBelowSize.mActual; }
|
||||
@ -1498,6 +1500,22 @@ Options::BadArg(const char* aArg)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char*
|
||||
Options::ModeString() const
|
||||
{
|
||||
switch (mMode) {
|
||||
case Live:
|
||||
return "live";
|
||||
case DarkMatter:
|
||||
return "dark-matter";
|
||||
case Cumulative:
|
||||
return "cumulative";
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
return "(unknown DMD mode)";
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// DMD start-up
|
||||
//---------------------------------------------------------------------------
|
||||
@ -1780,19 +1798,7 @@ AnalyzeImpl(UniquePtr<JSONWriteFunc> aWriter)
|
||||
writer.NullProperty("dmdEnvVar");
|
||||
}
|
||||
|
||||
const char* mode;
|
||||
if (gOptions->IsLiveMode()) {
|
||||
mode = "live";
|
||||
} else if (gOptions->IsDarkMatterMode()) {
|
||||
mode = "dark-matter";
|
||||
} else if (gOptions->IsCumulativeMode()) {
|
||||
mode = "cumulative";
|
||||
} else {
|
||||
MOZ_ASSERT(false);
|
||||
mode = "(unknown DMD mode)";
|
||||
}
|
||||
writer.StringProperty("mode", mode);
|
||||
|
||||
writer.StringProperty("mode", gOptions->ModeString());
|
||||
writer.IntProperty("sampleBelowSize", gOptions->SampleBelowSize());
|
||||
}
|
||||
writer.EndObject();
|
||||
@ -1818,7 +1824,6 @@ AnalyzeImpl(UniquePtr<JSONWriteFunc> aWriter)
|
||||
}
|
||||
writer.StringProperty("alloc", isc.ToIdString(b.AllocStackTrace()));
|
||||
if (gOptions->IsDarkMatterMode() && b.NumReports() > 0) {
|
||||
MOZ_ASSERT(gOptions->IsDarkMatterMode());
|
||||
writer.StartArrayProperty("reps");
|
||||
{
|
||||
if (b.ReportStackTrace1()) {
|
||||
|
@ -916,3 +916,8 @@ pref("consoleservice.logcat", false);
|
||||
#else
|
||||
pref("consoleservice.logcat", true);
|
||||
#endif
|
||||
|
||||
// Enable Service Workers for Android on non-release builds
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("dom.serviceWorkers.enabled", true);
|
||||
#endif
|
||||
|
@ -695,6 +695,16 @@ nsJARChannel::OverrideSecurityInfo(nsISupports* aSecurityInfo)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsJARChannel::OverrideURI(nsIURI* aRedirectedURI)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mLoadFlags & LOAD_REPLACE,
|
||||
"This can only happen if the LOAD_REPLACE flag is set");
|
||||
MOZ_RELEASE_ASSERT(ShouldIntercept(),
|
||||
"This can only be called on channels that can be intercepted");
|
||||
mAppURI = aRedirectedURI;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user