Merge inbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-07-07 16:37:07 -07:00
commit 0246d86e61
34 changed files with 724 additions and 297 deletions

View File

@ -1450,10 +1450,20 @@ WebConsoleFrame.prototype = {
errorMessage = errorMessage.initial;
}
let displayOrigin = aScriptError.sourceName;
// TLS errors are related to the connection and not the resource; therefore
// it makes sense to only display the protcol, host and port (prePath).
// This also means messages are grouped for a single origin.
if (aScriptError.category && aScriptError.category == "SHA-1 Signature") {
let sourceURI = Services.io.newURI(aScriptError.sourceName, null, null).QueryInterface(Ci.nsIURL);
displayOrigin = sourceURI.prePath;
}
// Create a new message
let msg = new Messages.Simple(errorMessage, {
location: {
url: aScriptError.sourceName,
url: displayOrigin,
line: aScriptError.lineNumber,
column: aScriptError.columnNumber
},

View File

@ -17,6 +17,7 @@
#include "nsBidiUtils.h"
#include "nsUnicharUtils.h"
#include "nsUTF8Utils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/SSE.h"
#include "nsTextFragmentImpl.h"
@ -30,6 +31,8 @@ static char* sSpaceSharedString[TEXTFRAG_MAX_NEWLINES + 1];
static char* sTabSharedString[TEXTFRAG_MAX_NEWLINES + 1];
static char sSingleCharSharedString[256];
using mozilla::CheckedUint32;
// static
nsresult
nsTextFragment::Init()
@ -105,12 +108,15 @@ nsTextFragment::operator=(const nsTextFragment& aOther)
m1b = aOther.m1b; // This will work even if aOther is using m2b
}
else {
size_t m2bSize = aOther.mState.mLength *
(aOther.mState.mIs2b ? sizeof(char16_t) : sizeof(char));
CheckedUint32 m2bSize = aOther.mState.mLength;
m2bSize *= (aOther.mState.mIs2b ? sizeof(char16_t) : sizeof(char));
m2b = nullptr;
if (m2bSize.isValid()) {
m2b = static_cast<char16_t*>(malloc(m2bSize.value()));
}
m2b = static_cast<char16_t*>(malloc(m2bSize));
if (m2b) {
memcpy(m2b, aOther.m2b, m2bSize);
memcpy(m2b, aOther.m2b, m2bSize.value());
} else {
// allocate a buffer for a single REPLACEMENT CHARACTER
m2b = static_cast<char16_t*>(moz_xmalloc(sizeof(char16_t)));
@ -255,12 +261,17 @@ nsTextFragment::SetTo(const char16_t* aBuffer, int32_t aLength, bool aUpdateBidi
if (first16bit != -1) { // aBuffer contains no non-8bit character
// Use ucs2 storage because we have to
size_t m2bSize = aLength * sizeof(char16_t);
m2b = (char16_t *)malloc(m2bSize);
CheckedUint32 m2bSize = aLength;
m2bSize *= sizeof(char16_t);
if (!m2bSize.isValid()) {
return false;
}
m2b = static_cast<char16_t*>(malloc(m2bSize.value()));
if (!m2b) {
return false;
}
memcpy(m2b, aBuffer, m2bSize);
memcpy(m2b, aBuffer, m2bSize.value());
mState.mIs2b = true;
if (aUpdateBidi) {
@ -269,7 +280,7 @@ nsTextFragment::SetTo(const char16_t* aBuffer, int32_t aLength, bool aUpdateBidi
} else {
// Use 1 byte storage because we can
char* buff = (char *)malloc(aLength * sizeof(char));
char* buff = static_cast<char*>(malloc(aLength));
if (!buff) {
return false;
}
@ -325,9 +336,21 @@ nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBi
// Should we optimize for aData.Length() == 0?
CheckedUint32 length = mState.mLength;
length += aLength;
if (!length.isValid()) {
return false;
}
if (mState.mIs2b) {
length *= sizeof(char16_t);
if (!length.isValid()) {
return false;
}
// Already a 2-byte string so the result will be too
char16_t* buff = (char16_t*)realloc(m2b, (mState.mLength + aLength) * sizeof(char16_t));
char16_t* buff = static_cast<char16_t*>(realloc(m2b, length.value()));
if (!buff) {
return false;
}
@ -347,10 +370,14 @@ nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBi
int32_t first16bit = FirstNon8Bit(aBuffer, aBuffer + aLength);
if (first16bit != -1) { // aBuffer contains no non-8bit character
length *= sizeof(char16_t);
if (!length.isValid()) {
return false;
}
// The old data was 1-byte, but the new is not so we have to expand it
// all to 2-byte
char16_t* buff =
(char16_t*)malloc((mState.mLength + aLength) * sizeof(char16_t));
char16_t* buff = static_cast<char16_t*>(malloc(length.value()));
if (!buff) {
return false;
}
@ -380,14 +407,13 @@ nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBi
// The new and the old data is all 1-byte
char* buff;
if (mState.mInHeap) {
buff = (char*)realloc(const_cast<char*>(m1b),
(mState.mLength + aLength) * sizeof(char));
buff = static_cast<char*>(realloc(const_cast<char*>(m1b), length.value()));
if (!buff) {
return false;
}
}
else {
buff = (char*)malloc((mState.mLength + aLength) * sizeof(char));
buff = static_cast<char*>(malloc(length.value()));
if (!buff) {
return false;
}

View File

@ -2349,28 +2349,33 @@ BackgroundRequestChild::Recv__delete__(const RequestResponse& aResponse)
* BackgroundCursorChild
******************************************************************************/
class BackgroundCursorChild::DelayedDeleteRunnable final
class BackgroundCursorChild::DelayedActionRunnable final
: public nsICancelableRunnable
{
using ActionFunc = void (BackgroundCursorChild::*)();
BackgroundCursorChild* mActor;
nsRefPtr<IDBRequest> mRequest;
ActionFunc mActionFunc;
public:
explicit
DelayedDeleteRunnable(BackgroundCursorChild* aActor)
DelayedActionRunnable(BackgroundCursorChild* aActor, ActionFunc aActionFunc)
: mActor(aActor)
, mRequest(aActor->mRequest)
, mActionFunc(aActionFunc)
{
MOZ_ASSERT(aActor);
aActor->AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
MOZ_ASSERT(mActionFunc);
}
// Does not need to be threadsafe since this only runs on one thread.
NS_DECL_ISUPPORTS
private:
~DelayedDeleteRunnable()
~DelayedActionRunnable()
{ }
NS_DECL_NSIRUNNABLE
@ -2510,7 +2515,8 @@ BackgroundCursorChild::HandleResponse(const void_t& aResponse)
DispatchSuccessEvent(&helper);
if (!mCursor) {
nsCOMPtr<nsIRunnable> deleteRunnable = new DelayedDeleteRunnable(this);
nsCOMPtr<nsIRunnable> deleteRunnable = new DelayedActionRunnable(
this, &BackgroundCursorChild::SendDeleteMeInternal);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToCurrentThread(deleteRunnable)));
}
}
@ -2745,19 +2751,20 @@ DispatchMutableFileResult(IDBRequest* aRequest,
}
}
NS_IMPL_ISUPPORTS(BackgroundCursorChild::DelayedDeleteRunnable,
NS_IMPL_ISUPPORTS(BackgroundCursorChild::DelayedActionRunnable,
nsIRunnable,
nsICancelableRunnable)
NS_IMETHODIMP
BackgroundCursorChild::
DelayedDeleteRunnable::Run()
DelayedActionRunnable::Run()
{
MOZ_ASSERT(mActor);
mActor->AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
MOZ_ASSERT(mActionFunc);
mActor->SendDeleteMeInternal();
(mActor->*mActionFunc)();
mActor = nullptr;
mRequest = nullptr;
@ -2767,7 +2774,7 @@ DelayedDeleteRunnable::Run()
NS_IMETHODIMP
BackgroundCursorChild::
DelayedDeleteRunnable::Cancel()
DelayedActionRunnable::Cancel()
{
if (NS_WARN_IF(!mActor)) {
return NS_ERROR_UNEXPECTED;

View File

@ -624,7 +624,7 @@ class BackgroundCursorChild final
friend class BackgroundTransactionChild;
friend class BackgroundVersionChangeTransactionChild;
class DelayedDeleteRunnable;
class DelayedActionRunnable;
IDBRequest* mRequest;
IDBTransaction* mTransaction;

View File

@ -7639,6 +7639,9 @@ protected:
virtual void
Cleanup() override;
nsresult
PopulateResponseFromStatement(DatabaseConnection::CachedStatement& aStmt);
};
class Cursor::OpenOp final
@ -13469,7 +13472,11 @@ TransactionBase::VerifyRequestParams(const CursorRequestParams& aParams) const
break;
case CursorRequestParams::TAdvanceParams:
break;
if (NS_WARN_IF(aParams.get_AdvanceParams().count() == 0)) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
default:
MOZ_CRASH("Should never get here!");
@ -24435,6 +24442,91 @@ CursorOpBase::Cleanup()
TransactionDatabaseOperationBase::Cleanup();
}
nsresult
Cursor::
CursorOpBase::PopulateResponseFromStatement(
DatabaseConnection::CachedStatement& aStmt)
{
Transaction()->AssertIsOnConnectionThread();
MOZ_ASSERT(mResponse.type() == CursorResponse::T__None);
MOZ_ASSERT(mFiles.IsEmpty());
nsresult rv = mCursor->mKey.SetFromStatement(aStmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
switch (mCursor->mType) {
case OpenCursorParams::TObjectStoreOpenCursorParams: {
StructuredCloneReadInfo cloneInfo;
rv = GetStructuredCloneReadInfoFromStatement(aStmt,
2,
1,
mCursor->mFileManager,
&cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = ObjectStoreCursorResponse();
auto& response = mResponse.get_ObjectStoreCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.key() = mCursor->mKey;
mFiles.SwapElements(cloneInfo.mFiles);
break;
}
case OpenCursorParams::TObjectStoreOpenKeyCursorParams: {
mResponse = ObjectStoreKeyCursorResponse(mCursor->mKey);
break;
}
case OpenCursorParams::TIndexOpenCursorParams: {
rv = mCursor->mObjectKey.SetFromStatement(aStmt, 1);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
StructuredCloneReadInfo cloneInfo;
rv = GetStructuredCloneReadInfoFromStatement(aStmt,
3,
2,
mCursor->mFileManager,
&cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = IndexCursorResponse();
auto& response = mResponse.get_IndexCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.key() = mCursor->mKey;
response.objectKey() = mCursor->mObjectKey;
mFiles.SwapElements(cloneInfo.mFiles);
break;
}
case OpenCursorParams::TIndexOpenKeyCursorParams: {
rv = mCursor->mObjectKey.SetFromStatement(aStmt, 1);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = IndexKeyCursorResponse(mCursor->mKey, mCursor->mObjectKey);
break;
}
default:
MOZ_CRASH("Should never get here!");
}
return NS_OK;
}
void
Cursor::
OpenOp::GetRangeKeyInfo(bool aLowerBound, Key* aKey, bool* aOpen)
@ -24512,6 +24604,8 @@ OpenOp::DoObjectStoreDatabaseWork(DatabaseConnection* aConnection)
MOZ_CRASH("Should never get here!");
}
// Note: Changing the number or order of SELECT columns in the query will
// require changes to CursorOpBase::PopulateResponseFromStatement.
nsCString firstQuery =
queryStart +
keyRangeClause +
@ -24549,17 +24643,7 @@ OpenOp::DoObjectStoreDatabaseWork(DatabaseConnection* aConnection)
return NS_OK;
}
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
StructuredCloneReadInfo cloneInfo;
rv = GetStructuredCloneReadInfoFromStatement(stmt,
2,
1,
mCursor->mFileManager,
&cloneInfo);
rv = PopulateResponseFromStatement(stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -24624,14 +24708,6 @@ OpenOp::DoObjectStoreDatabaseWork(DatabaseConnection* aConnection)
directionClause +
openLimit;
mResponse = ObjectStoreCursorResponse();
auto& response = mResponse.get_ObjectStoreCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.key() = mCursor->mKey;
mFiles.SwapElements(cloneInfo.mFiles);
return NS_OK;
}
@ -24687,6 +24763,8 @@ OpenOp::DoObjectStoreKeyDatabaseWork(DatabaseConnection* aConnection)
MOZ_CRASH("Should never get here!");
}
// Note: Changing the number or order of SELECT columns in the query will
// require changes to CursorOpBase::PopulateResponseFromStatement.
nsCString firstQuery =
queryStart +
keyRangeClause +
@ -24724,7 +24802,7 @@ OpenOp::DoObjectStoreKeyDatabaseWork(DatabaseConnection* aConnection)
return NS_OK;
}
rv = mCursor->mKey.SetFromStatement(stmt, 0);
rv = PopulateResponseFromStatement(stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -24788,8 +24866,6 @@ OpenOp::DoObjectStoreKeyDatabaseWork(DatabaseConnection* aConnection)
directionClause +
openLimit;
mResponse = ObjectStoreKeyCursorResponse(mCursor->mKey);
return NS_OK;
}
@ -24864,6 +24940,8 @@ OpenOp::DoIndexDatabaseWork(DatabaseConnection* aConnection)
"WHERE index_table.index_id = :") +
id;
// Note: Changing the number or order of SELECT columns in the query will
// require changes to CursorOpBase::PopulateResponseFromStatement.
nsCString firstQuery =
queryStart +
keyRangeClause +
@ -24901,22 +24979,7 @@ OpenOp::DoIndexDatabaseWork(DatabaseConnection* aConnection)
return NS_OK;
}
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = mCursor->mObjectKey.SetFromStatement(stmt, 1);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
StructuredCloneReadInfo cloneInfo;
rv = GetStructuredCloneReadInfoFromStatement(stmt,
3,
2,
mCursor->mFileManager,
&cloneInfo);
rv = PopulateResponseFromStatement(stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -25019,15 +25082,6 @@ OpenOp::DoIndexDatabaseWork(DatabaseConnection* aConnection)
MOZ_CRASH("Should never get here!");
}
mResponse = IndexCursorResponse();
auto& response = mResponse.get_IndexCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.key() = mCursor->mKey;
response.objectKey() = mCursor->mObjectKey;
mFiles.SwapElements(cloneInfo.mFiles);
return NS_OK;
}
@ -25093,6 +25147,8 @@ OpenOp::DoIndexKeyDatabaseWork(DatabaseConnection* aConnection)
NS_LITERAL_CSTRING(" WHERE index_id = :") +
id;
// Note: Changing the number or order of SELECT columns in the query will
// require changes to CursorOpBase::PopulateResponseFromStatement.
nsCString firstQuery =
queryStart +
keyRangeClause +
@ -25130,12 +25186,7 @@ OpenOp::DoIndexKeyDatabaseWork(DatabaseConnection* aConnection)
return NS_OK;
}
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = mCursor->mObjectKey.SetFromStatement(stmt, 1);
rv = PopulateResponseFromStatement(stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -25237,12 +25288,6 @@ OpenOp::DoIndexKeyDatabaseWork(DatabaseConnection* aConnection)
MOZ_CRASH("Should never get here!");
}
mResponse = IndexKeyCursorResponse();
auto& response = mResponse.get_IndexKeyCursorResponse();
response.key() = mCursor->mKey;
response.objectKey() = mCursor->mObjectKey;
return NS_OK;
}
@ -25347,8 +25392,10 @@ ContinueOp::DoDatabaseWork(DatabaseConnection* aConnection)
// greater than (or less than, if we're running a PREV cursor) or equal to the
// key that was specified.
nsAutoCString countString;
// Note: Changing the number or order of SELECT columns in the query will
// require changes to CursorOpBase::PopulateResponseFromStatement.
nsCString query;
nsAutoCString countString;
bool hasContinueKey = false;
uint32_t advanceCount;
@ -25367,6 +25414,7 @@ ContinueOp::DoDatabaseWork(DatabaseConnection* aConnection)
}
} else {
advanceCount = mParams.get_AdvanceParams().count();
MOZ_ASSERT(advanceCount > 0);
countString.AppendInt(advanceCount);
query = mCursor->mContinueQuery + countString;
@ -25429,108 +25477,17 @@ ContinueOp::DoDatabaseWork(DatabaseConnection* aConnection)
}
if (!hasResult) {
break;
mCursor->mKey.Unset();
mCursor->mRangeKey.Unset();
mCursor->mObjectKey.Unset();
mResponse = void_t();
return NS_OK;
}
}
if (!hasResult) {
mCursor->mKey.Unset();
mCursor->mRangeKey.Unset();
mCursor->mObjectKey.Unset();
mResponse = void_t();
return NS_OK;
}
switch (mCursor->mType) {
case OpenCursorParams::TObjectStoreOpenCursorParams: {
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
StructuredCloneReadInfo cloneInfo;
rv = GetStructuredCloneReadInfoFromStatement(stmt,
2,
1,
mCursor->mFileManager,
&cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = ObjectStoreCursorResponse();
auto& response = mResponse.get_ObjectStoreCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.key() = mCursor->mKey;
mFiles.SwapElements(cloneInfo.mFiles);
break;
}
case OpenCursorParams::TObjectStoreOpenKeyCursorParams: {
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = ObjectStoreKeyCursorResponse(mCursor->mKey);
break;
}
case OpenCursorParams::TIndexOpenCursorParams: {
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = mCursor->mObjectKey.SetFromStatement(stmt, 1);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
StructuredCloneReadInfo cloneInfo;
rv = GetStructuredCloneReadInfoFromStatement(stmt,
3,
2,
mCursor->mFileManager,
&cloneInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = IndexCursorResponse();
auto& response = mResponse.get_IndexCursorResponse();
response.cloneInfo().data().SwapElements(cloneInfo.mData);
response.key() = mCursor->mKey;
response.objectKey() = mCursor->mObjectKey;
mFiles.SwapElements(cloneInfo.mFiles);
break;
}
case OpenCursorParams::TIndexOpenKeyCursorParams: {
rv = mCursor->mKey.SetFromStatement(stmt, 0);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = mCursor->mObjectKey.SetFromStatement(stmt, 1);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResponse = IndexKeyCursorResponse(mCursor->mKey, mCursor->mObjectKey);
break;
}
default:
MOZ_CRASH("Should never get here!");
rv = PopulateResponseFromStatement(stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;

View File

@ -786,73 +786,73 @@ nsCSPDirective::toDomCSPStruct(mozilla::dom::CSP& outCSP) const
switch(mDirective) {
case nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE:
outCSP.mDefault_src.Construct();
outCSP.mDefault_src.Value() = srcs;
outCSP.mDefault_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE:
outCSP.mScript_src.Construct();
outCSP.mScript_src.Value() = srcs;
outCSP.mScript_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::OBJECT_SRC_DIRECTIVE:
outCSP.mObject_src.Construct();
outCSP.mObject_src.Value() = srcs;
outCSP.mObject_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE:
outCSP.mStyle_src.Construct();
outCSP.mStyle_src.Value() = srcs;
outCSP.mStyle_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::IMG_SRC_DIRECTIVE:
outCSP.mImg_src.Construct();
outCSP.mImg_src.Value() = srcs;
outCSP.mImg_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::MEDIA_SRC_DIRECTIVE:
outCSP.mMedia_src.Construct();
outCSP.mMedia_src.Value() = srcs;
outCSP.mMedia_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE:
outCSP.mFrame_src.Construct();
outCSP.mFrame_src.Value() = srcs;
outCSP.mFrame_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::FONT_SRC_DIRECTIVE:
outCSP.mFont_src.Construct();
outCSP.mFont_src.Value() = srcs;
outCSP.mFont_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::CONNECT_SRC_DIRECTIVE:
outCSP.mConnect_src.Construct();
outCSP.mConnect_src.Value() = srcs;
outCSP.mConnect_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::REPORT_URI_DIRECTIVE:
outCSP.mReport_uri.Construct();
outCSP.mReport_uri.Value() = srcs;
outCSP.mReport_uri.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE:
outCSP.mFrame_ancestors.Construct();
outCSP.mFrame_ancestors.Value() = srcs;
outCSP.mFrame_ancestors.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::WEB_MANIFEST_SRC_DIRECTIVE:
outCSP.mManifest_src.Construct();
outCSP.mManifest_src.Value() = srcs;
outCSP.mManifest_src.Value() = mozilla::Move(srcs);
return;
// not supporting REFLECTED_XSS_DIRECTIVE
case nsIContentSecurityPolicy::BASE_URI_DIRECTIVE:
outCSP.mBase_uri.Construct();
outCSP.mBase_uri.Value() = srcs;
outCSP.mBase_uri.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::FORM_ACTION_DIRECTIVE:
outCSP.mForm_action.Construct();
outCSP.mForm_action.Value() = srcs;
outCSP.mForm_action.Value() = mozilla::Move(srcs);
return;
// REFERRER_DIRECTIVE is handled in nsCSPPolicy::toDomCSPStruct()

View File

@ -18,11 +18,9 @@ namespace mozilla {
nsresult
SVGLengthList::CopyFrom(const SVGLengthList& rhs)
{
if (!mLengths.SetCapacity(rhs.Length(), fallible)) {
// Yes, we do want fallible alloc here
if (!mLengths.Assign(rhs.mLengths, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
mLengths = rhs.mLengths;
return NS_OK;
}

View File

@ -197,13 +197,10 @@ SVGMotionSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
const MotionSegmentArray& srcArr = ExtractMotionSegmentArray(aSrc);
MotionSegmentArray& dstArr = ExtractMotionSegmentArray(aDest);
// Ensure we have sufficient memory.
if (!dstArr.SetCapacity(srcArr.Length(), fallible)) {
if (!dstArr.Assign(srcArr, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
dstArr = srcArr; // Do the assignment.
return NS_OK;
}

View File

@ -17,11 +17,9 @@ namespace mozilla {
nsresult
SVGNumberList::CopyFrom(const SVGNumberList& rhs)
{
if (!mNumbers.SetCapacity(rhs.Length(), fallible)) {
// Yes, we do want fallible alloc here
if (!mNumbers.Assign(rhs.mNumbers, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
mNumbers = rhs.mNumbers;
return NS_OK;
}

View File

@ -34,11 +34,9 @@ static bool IsMoveto(uint16_t aSegType)
nsresult
SVGPathData::CopyFrom(const SVGPathData& rhs)
{
if (!mData.SetCapacity(rhs.mData.Length(), fallible)) {
// Yes, we do want fallible alloc here
if (!mData.Assign(rhs.mData, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
mData = rhs.mData;
return NS_OK;
}

View File

@ -16,11 +16,9 @@ namespace mozilla {
nsresult
SVGPointList::CopyFrom(const SVGPointList& rhs)
{
if (!SetCapacity(rhs.Length())) {
// Yes, we do want fallible alloc here
if (!mItems.Assign(rhs.mItems, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
mItems = rhs.mItems;
return NS_OK;
}

View File

@ -16,11 +16,9 @@ namespace mozilla {
nsresult
SVGStringList::CopyFrom(const SVGStringList& rhs)
{
if (!mStrings.SetCapacity(rhs.Length(), fallible)) {
// Yes, we do want fallible alloc here
if (!mStrings.Assign(rhs.mStrings, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
mStrings = rhs.mStrings;
mIsSet = true;
return NS_OK;
}

View File

@ -43,11 +43,9 @@ SVGTransformList::CopyFrom(const SVGTransformList& rhs)
nsresult
SVGTransformList::CopyFrom(const nsTArray<nsSVGTransform>& aTransformArray)
{
if (!mItems.SetCapacity(aTransformArray.Length(), fallible)) {
// Yes, we do want fallible alloc here
if (!mItems.Assign(aTransformArray, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
mItems = aTransformArray;
return NS_OK;
}

View File

@ -48,12 +48,9 @@ SVGTransformListSMILType::Assign(nsSMILValue& aDest,
const TransformArray* srcTransforms =
static_cast<const TransformArray*>(aSrc.mU.mPtr);
TransformArray* dstTransforms = static_cast<TransformArray*>(aDest.mU.mPtr);
// Before we assign, ensure we have sufficient memory
bool result = dstTransforms->SetCapacity(srcTransforms->Length(), fallible);
NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY);
*dstTransforms = *srcTransforms;
if (!dstTransforms->Assign(*srcTransforms, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}

View File

@ -1473,9 +1473,6 @@ MessageChannel::MaybeUndeferIncall()
IPC_ASSERT(mDeferred.top().interrupt_remote_stack_depth_guess() <= stackDepth,
"fatal logic error");
if (mDeferred.top().interrupt_remote_stack_depth_guess() < RemoteViewOfStackDepth(stackDepth))
return;
// maybe time to process this message
Message call = mDeferred.top();
mDeferred.pop();

View File

@ -0,0 +1,20 @@
namespace mozilla {
namespace _ipdltest {
intr protocol PTestRaceDeadlock {
both:
async StartRace();
parent:
intr Lose();
child:
intr Win();
intr Rpc();
async __delete__();
/* Tests that race resolution does not cause deadlocks */
};
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,130 @@
#include "TestRaceDeadlock.h"
#include "IPDLUnitTests.h" // fail etc.
// #define TEST_TIMEOUT 5000
using namespace mozilla::ipc;
typedef mozilla::ipc::MessageChannel::Message Message;
namespace mozilla {
namespace _ipdltest {
static RacyInterruptPolicy
MediateRace(const Message& parent, const Message& child)
{
return (PTestRaceDeadlock::Msg_Win__ID == parent.type()) ?
RIPParentWins : RIPChildWins;
}
//-----------------------------------------------------------------------------
// parent
TestRaceDeadlockParent::TestRaceDeadlockParent()
{
MOZ_COUNT_CTOR(TestRaceDeadlockParent);
}
TestRaceDeadlockParent::~TestRaceDeadlockParent()
{
MOZ_COUNT_DTOR(TestRaceDeadlockParent);
}
void
TestRaceDeadlockParent::Main()
{
Test1();
Close();
}
bool
TestRaceDeadlockParent::ShouldContinueFromReplyTimeout()
{
fail("This test should not hang");
GetIPCChannel()->CloseWithTimeout();
return false;
}
void
TestRaceDeadlockParent::Test1()
{
#if defined(TEST_TIMEOUT)
SetReplyTimeoutMs(TEST_TIMEOUT);
#endif
if (!SendStartRace()) {
fail("sending StartRace");
}
if (!CallRpc()) {
fail("calling Rpc");
}
}
bool
TestRaceDeadlockParent::AnswerLose()
{
return true;
}
RacyInterruptPolicy
TestRaceDeadlockParent::MediateInterruptRace(const Message& parent,
const Message& child)
{
return MediateRace(parent, child);
}
//-----------------------------------------------------------------------------
// child
TestRaceDeadlockChild::TestRaceDeadlockChild()
{
MOZ_COUNT_CTOR(TestRaceDeadlockChild);
}
TestRaceDeadlockChild::~TestRaceDeadlockChild()
{
MOZ_COUNT_DTOR(TestRaceDeadlockChild);
}
bool
TestRaceDeadlockParent::RecvStartRace()
{
if (!CallWin()) {
fail("calling Win");
}
return true;
}
bool
TestRaceDeadlockChild::RecvStartRace()
{
if (!SendStartRace()) {
fail("calling SendStartRace");
}
if (!CallLose()) {
fail("calling Lose");
}
return true;
}
bool
TestRaceDeadlockChild::AnswerWin()
{
return true;
}
bool
TestRaceDeadlockChild::AnswerRpc()
{
return true;
}
RacyInterruptPolicy
TestRaceDeadlockChild::MediateInterruptRace(const Message& parent,
const Message& child)
{
return MediateRace(parent, child);
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,75 @@
#ifndef mozilla__ipdltest_TestRaceDeadlock_h
#define mozilla__ipdltest_TestRaceDeadlock_h 1
#include "mozilla/_ipdltest/IPDLUnitTests.h"
#include "mozilla/_ipdltest/PTestRaceDeadlockParent.h"
#include "mozilla/_ipdltest/PTestRaceDeadlockChild.h"
namespace mozilla {
namespace _ipdltest {
class TestRaceDeadlockParent :
public PTestRaceDeadlockParent
{
public:
TestRaceDeadlockParent();
virtual ~TestRaceDeadlockParent();
static bool RunTestInProcesses() { return true; }
static bool RunTestInThreads() { return true; }
void Main();
protected:
virtual bool ShouldContinueFromReplyTimeout() override;
void Test1();
virtual bool RecvStartRace() override;
virtual bool AnswerLose() override;
virtual mozilla::ipc::RacyInterruptPolicy
MediateInterruptRace(const Message& parent, const Message& child) override;
virtual void ActorDestroy(ActorDestroyReason why) override
{
if (NormalShutdown != why)
fail("unexpected destruction!");
passed("ok");
QuitParent();
}
};
class TestRaceDeadlockChild :
public PTestRaceDeadlockChild
{
public:
TestRaceDeadlockChild();
virtual ~TestRaceDeadlockChild();
protected:
virtual bool RecvStartRace() override;
virtual bool AnswerWin() override;
virtual bool AnswerRpc() override;
virtual mozilla::ipc::RacyInterruptPolicy
MediateInterruptRace(const Message& parent, const Message& child) override;
virtual void ActorDestroy(ActorDestroyReason why) override
{
if (NormalShutdown != why)
fail("unexpected destruction!");
QuitChild();
}
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_TestRaceDeadlock_h

View File

@ -33,6 +33,7 @@ SOURCES += [
'TestMultiMgrs.cpp',
'TestNestedLoops.cpp',
'TestOpens.cpp',
'TestRaceDeadlock.cpp',
'TestRaceDeferral.cpp',
'TestRacyInterruptReplies.cpp',
'TestRacyReentry.cpp',
@ -102,6 +103,7 @@ IPDL_SOURCES += [
'PTestNestedLoops.ipdl',
'PTestOpens.ipdl',
'PTestOpensOpened.ipdl',
'PTestRaceDeadlock.ipdl',
'PTestRaceDeferral.ipdl',
'PTestRacyInterruptReplies.ipdl',
'PTestRacyReentry.ipdl',

View File

@ -7724,6 +7724,8 @@ IonBuilder::jsop_getelem()
}
obj = maybeUnboxForPropertyAccess(obj);
if (obj->type() == MIRType_Object)
obj = convertUnboxedObjects(obj);
bool emitted = false;
@ -8766,7 +8768,7 @@ IonBuilder::jsop_setelem()
MDefinition* value = current->pop();
MDefinition* index = current->pop();
MDefinition* object = current->pop();
MDefinition* object = convertUnboxedObjects(current->pop());
trackTypeInfo(TrackedTypeSite::Receiver, object->type(), object->resultTypeSet());
trackTypeInfo(TrackedTypeSite::Index, index->type(), index->resultTypeSet());
@ -9478,8 +9480,7 @@ IonBuilder::jsop_rest()
}
uint32_t
IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed,
BaselineInspector::ObjectGroupVector& convertUnboxedGroups)
IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed)
{
if (!types || types->unknownObject()) {
trackOptimizationOutcome(TrackedOutcome::NoTypeInfo);
@ -9503,21 +9504,6 @@ IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_
return UINT32_MAX;
}
// If we encounter a group for an unboxed property which has a
// corresponding native group, look for a definite slot in that native
// group, and force conversion of incoming objects to the native group.
if (key->isGroup() && key->group()->maybeUnboxedLayout()) {
if (ObjectGroup* nativeGroup = key->group()->unboxedLayout().nativeGroup()) {
if (!convertUnboxedGroups.append(key->group()))
CrashAtUnhandlableOOM("IonBuilder::getDefiniteSlot");
key = TypeSet::ObjectKey::get(nativeGroup);
if (key->unknownProperties()) {
trackOptimizationOutcome(TrackedOutcome::UnknownProperties);
return UINT32_MAX;
}
}
}
HeapTypeSetKey property = key->property(NameToId(name));
if (!property.maybeTypes() ||
!property.maybeTypes()->definiteProperty() ||
@ -10033,6 +10019,8 @@ IonBuilder::jsop_getprop(PropertyName* name)
}
obj = maybeUnboxForPropertyAccess(obj);
if (obj->type() == MIRType_Object)
obj = convertUnboxedObjects(obj);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, name, types);
@ -10513,12 +10501,43 @@ IonBuilder::getPropTryComplexPropOfTypedObject(bool* emitted,
fieldPrediction, fieldTypeObj);
}
MDefinition*
IonBuilder::convertUnboxedObjects(MDefinition* obj)
{
// If obj might be in any particular unboxed group which should be
// converted to a native representation, perform that conversion. This does
// not guarantee the object will not have such a group afterwards, if the
// object's possible groups are not precisely known.
TemporaryTypeSet* types = obj->resultTypeSet();
if (!types || types->unknownObject())
return obj;
BaselineInspector::ObjectGroupVector list(alloc());
for (size_t i = 0; i < types->getObjectCount(); i++) {
TypeSet::ObjectKey* key = obj->resultTypeSet()->getObject(i);
if (!key || !key->isGroup())
continue;
if (UnboxedLayout* layout = key->group()->maybeUnboxedLayout()) {
if (layout->nativeGroup() && !list.append(key->group()))
CrashAtUnhandlableOOM("IonBuilder::convertUnboxedObjects");
}
}
return convertUnboxedObjects(obj, list);
}
MDefinition*
IonBuilder::convertUnboxedObjects(MDefinition* obj,
const BaselineInspector::ObjectGroupVector& list)
{
for (size_t i = 0; i < list.length(); i++) {
obj = MConvertUnboxedObjectToNative::New(alloc(), obj, list[i]);
ObjectGroup* group = list[i];
if (TemporaryTypeSet* types = obj->resultTypeSet()) {
if (!types->hasType(TypeSet::ObjectType(group)))
continue;
}
obj = MConvertUnboxedObjectToNative::New(alloc(), obj, group);
current->add(obj->toInstruction());
}
return obj;
@ -10530,10 +10549,8 @@ IonBuilder::getPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName
{
MOZ_ASSERT(*emitted == false);
BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc());
uint32_t nfixed;
uint32_t slot = getDefiniteSlot(obj->resultTypeSet(), name, &nfixed, convertUnboxedGroups);
uint32_t slot = getDefiniteSlot(obj->resultTypeSet(), name, &nfixed);
if (slot == UINT32_MAX)
return true;
@ -10543,8 +10560,6 @@ IonBuilder::getPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName
obj = guard;
}
obj = convertUnboxedObjects(obj, convertUnboxedGroups);
MInstruction* load;
if (slot < nfixed) {
load = MLoadFixedSlot::New(alloc(), obj, slot);
@ -11151,7 +11166,7 @@ bool
IonBuilder::jsop_setprop(PropertyName* name)
{
MDefinition* value = current->pop();
MDefinition* obj = current->pop();
MDefinition* obj = convertUnboxedObjects(current->pop());
bool emitted = false;
startTrackingOptimizations();
@ -11450,10 +11465,8 @@ IonBuilder::setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,
return true;
}
BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc());
uint32_t nfixed;
uint32_t slot = getDefiniteSlot(obj->resultTypeSet(), name, &nfixed, convertUnboxedGroups);
uint32_t slot = getDefiniteSlot(obj->resultTypeSet(), name, &nfixed);
if (slot == UINT32_MAX)
return true;
@ -11471,8 +11484,6 @@ IonBuilder::setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,
writeBarrier |= property.needsBarrier(constraints());
}
obj = convertUnboxedObjects(obj, convertUnboxedGroups);
MInstruction* store;
if (slot < nfixed) {
store = MStoreFixedSlot::New(alloc(), obj, slot, value);
@ -12308,8 +12319,8 @@ IonBuilder::jsop_setaliasedvar(ScopeCoordinate sc)
bool
IonBuilder::jsop_in()
{
MDefinition* obj = current->peek(-1);
MDefinition* id = current->peek(-2);
MDefinition* obj = convertUnboxedObjects(current->pop());
MDefinition* id = current->pop();
do {
if (shouldAbortOnPreliminaryGroups(obj))
@ -12324,11 +12335,9 @@ IonBuilder::jsop_in()
if (ElementAccessHasExtraIndexedProperty(constraints(), obj))
break;
return jsop_in_dense(unboxedType);
return jsop_in_dense(obj, id, unboxedType);
} while (false);
current->pop();
current->pop();
MIn* ins = MIn::New(alloc(), id, obj);
current->add(ins);
@ -12338,11 +12347,8 @@ IonBuilder::jsop_in()
}
bool
IonBuilder::jsop_in_dense(JSValueType unboxedType)
IonBuilder::jsop_in_dense(MDefinition* obj, MDefinition* id, JSValueType unboxedType)
{
MDefinition* obj = current->pop();
MDefinition* id = current->pop();
bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj);
// Ensure id is an integer.

View File

@ -692,7 +692,7 @@ class IonBuilder
bool jsop_isnoiter();
bool jsop_iterend();
bool jsop_in();
bool jsop_in_dense(JSValueType unboxedType);
bool jsop_in_dense(MDefinition* obj, MDefinition* id, JSValueType unboxedType);
bool jsop_instanceof();
bool jsop_getaliasedvar(ScopeCoordinate sc);
bool jsop_setaliasedvar(ScopeCoordinate sc);
@ -927,8 +927,8 @@ class IonBuilder
JSObject* testSingletonProperty(JSObject* obj, PropertyName* name);
JSObject* testSingletonPropertyTypes(MDefinition* obj, PropertyName* name);
uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed,
BaselineInspector::ObjectGroupVector& convertUnboxedGroups);
uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed);
MDefinition* convertUnboxedObjects(MDefinition* obj);
MDefinition* convertUnboxedObjects(MDefinition* obj,
const BaselineInspector::ObjectGroupVector& list);
uint32_t getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name,

View File

@ -632,7 +632,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode)
OBJECT_FLAG_LENGTH_OVERFLOW |
OBJECT_FLAG_ITERATED;
MDefinition* obj = callInfo.thisArg();
MDefinition* obj = convertUnboxedObjects(callInfo.thisArg());
TemporaryTypeSet* thisTypes = obj->resultTypeSet();
if (!thisTypes)
return InliningStatus_NotInlined;
@ -758,7 +758,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
MDefinition* obj = callInfo.thisArg();
MDefinition* obj = convertUnboxedObjects(callInfo.thisArg());
MDefinition* value = callInfo.getArg(0);
if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
&obj, nullptr, &value, /* canModify = */ false))
@ -839,17 +839,20 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
MDefinition* thisArg = convertUnboxedObjects(callInfo.thisArg());
MDefinition* objArg = convertUnboxedObjects(callInfo.getArg(0));
// Ensure |this|, argument and result are objects.
if (getInlineReturnType() != MIRType_Object)
return InliningStatus_NotInlined;
if (callInfo.thisArg()->type() != MIRType_Object)
if (thisArg->type() != MIRType_Object)
return InliningStatus_NotInlined;
if (callInfo.getArg(0)->type() != MIRType_Object)
if (objArg->type() != MIRType_Object)
return InliningStatus_NotInlined;
// |this| and the argument must be dense arrays.
TemporaryTypeSet* thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet* argTypes = callInfo.getArg(0)->resultTypeSet();
TemporaryTypeSet* thisTypes = thisArg->resultTypeSet();
TemporaryTypeSet* argTypes = objArg->resultTypeSet();
if (!thisTypes || !argTypes)
return InliningStatus_NotInlined;
@ -874,10 +877,10 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo)
JSValueType unboxedType = JSVAL_TYPE_MAGIC;
if (clasp == &UnboxedArrayObject::class_) {
unboxedType = UnboxedArrayElementType(constraints(), callInfo.thisArg(), nullptr);
unboxedType = UnboxedArrayElementType(constraints(), thisArg, nullptr);
if (unboxedType == JSVAL_TYPE_MAGIC)
return InliningStatus_NotInlined;
if (unboxedType != UnboxedArrayElementType(constraints(), callInfo.getArg(0), nullptr))
if (unboxedType != UnboxedArrayElementType(constraints(), objArg, nullptr))
return InliningStatus_NotInlined;
}
@ -937,8 +940,7 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo)
callInfo.setImplicitlyUsedUnchecked();
MArrayConcat* ins = MArrayConcat::New(alloc(), constraints(),
callInfo.thisArg(), callInfo.getArg(0),
MArrayConcat* ins = MArrayConcat::New(alloc(), constraints(), thisArg, objArg,
templateObj,
templateObj->group()->initialHeap(constraints()),
unboxedType);
@ -958,10 +960,12 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
MDefinition* obj = convertUnboxedObjects(callInfo.thisArg());
// Ensure |this| and result are objects.
if (getInlineReturnType() != MIRType_Object)
return InliningStatus_NotInlined;
if (callInfo.thisArg()->type() != MIRType_Object)
if (obj->type() != MIRType_Object)
return InliningStatus_NotInlined;
// Arguments for the sliced region must be integers.
@ -975,7 +979,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
}
// |this| must be a dense array.
TemporaryTypeSet* thisTypes = callInfo.thisArg()->resultTypeSet();
TemporaryTypeSet* thisTypes = obj->resultTypeSet();
if (!thisTypes)
return InliningStatus_NotInlined;
@ -991,7 +995,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
JSValueType unboxedType = JSVAL_TYPE_MAGIC;
if (clasp == &UnboxedArrayObject::class_) {
unboxedType = UnboxedArrayElementType(constraints(), callInfo.thisArg(), nullptr);
unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr);
if (unboxedType == JSVAL_TYPE_MAGIC)
return InliningStatus_NotInlined;
}
@ -1038,18 +1042,18 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
if (callInfo.argc() > 1) {
end = callInfo.getArg(1);
} else if (clasp == &ArrayObject::class_) {
MElements* elements = MElements::New(alloc(), callInfo.thisArg());
MElements* elements = MElements::New(alloc(), obj);
current->add(elements);
end = MArrayLength::New(alloc(), elements);
current->add(end->toInstruction());
} else {
end = MUnboxedArrayLength::New(alloc(), callInfo.thisArg());
end = MUnboxedArrayLength::New(alloc(), obj);
current->add(end->toInstruction());
}
MArraySlice* ins = MArraySlice::New(alloc(), constraints(),
callInfo.thisArg(), begin, end,
obj, begin, end,
templateObj,
templateObj->group()->initialHeap(constraints()),
unboxedType);
@ -2114,7 +2118,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo)
if (callInfo.argc() != 3)
return InliningStatus_NotInlined;
MDefinition* obj = callInfo.getArg(0);
MDefinition* obj = convertUnboxedObjects(callInfo.getArg(0));
MDefinition* id = callInfo.getArg(1);
MDefinition* value = callInfo.getArg(2);

View File

@ -4757,6 +4757,35 @@ MArrayJoin::foldsTo(TempAllocator& alloc)
return MStringReplace::New(alloc, string, pattern, replacement);
}
MConvertUnboxedObjectToNative*
MConvertUnboxedObjectToNative::New(TempAllocator& alloc, MDefinition* obj, ObjectGroup* group)
{
MConvertUnboxedObjectToNative* res = new(alloc) MConvertUnboxedObjectToNative(obj, group);
ObjectGroup* nativeGroup = group->unboxedLayout().nativeGroup();
// Make a new type set for the result of this instruction which replaces
// the input group with the native group we will convert it to.
TemporaryTypeSet* types = obj->resultTypeSet();
if (types && !types->unknownObject()) {
TemporaryTypeSet* newTypes = types->cloneWithoutObjects(alloc.lifoAlloc());
if (newTypes) {
for (size_t i = 0; i < types->getObjectCount(); i++) {
TypeSet::ObjectKey* key = types->getObject(i);
if (!key)
continue;
if (key->unknownProperties() || !key->isGroup() || key->group() != group)
newTypes->addType(TypeSet::ObjectType(key), alloc.lifoAlloc());
else
newTypes->addType(TypeSet::ObjectType(nativeGroup), alloc.lifoAlloc());
}
res->setResultTypeSet(newTypes);
}
}
return res;
}
bool
jit::ElementAccessIsDenseNative(CompilerConstraintList* constraints,
MDefinition* obj, MDefinition* id)

View File

@ -9049,9 +9049,7 @@ class MConvertUnboxedObjectToNative
INSTRUCTION_HEADER(ConvertUnboxedObjectToNative)
static MConvertUnboxedObjectToNative* New(TempAllocator& alloc, MDefinition* obj,
ObjectGroup* group) {
return new(alloc) MConvertUnboxedObjectToNative(obj, group);
}
ObjectGroup* group);
MDefinition* object() const {
return getOperand(0);

View File

@ -0,0 +1,5 @@
<!DOCTYPE html>
<html>
<body>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<script>
var startPaintCount = 0;
function doTest() {
startPaintCount = window.mozPaintCount;
setTimeout(check, 200);
}
var calls = 0;
function check() {
calls++;
if ((window.mozPaintCount - startPaintCount) > 2) {
finishSuccess();
return;
}
if (calls > 10) {
finishFail();
return;
}
setTimeout(check, 200);
}
function finishSuccess() {
cleanup();
document.documentElement.className = "";
}
function finishFail() {
cleanup();
document.body.appendChild(document.createTextNode("FAIL FAIL FAIL"));
document.documentElement.className = "";
}
function cleanup() {
var src = document.getElementById("src");
var dest = document.getElementById("dest");
src.parentNode.removeChild(src);
dest.parentNode.removeChild(dest);
}
</script>
<style>
div {
width: 100px;
height: 100px;
position: absolute;
}
#src {
background-image: url('1114526-1.gif');
top: -500px;
}
#dest {
background-image: -moz-element(#src);
top: 100px;
}
</style>
</head>
<body>
<div id="src"></div>
<div id="dest"></div>
<script>
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</body>
</html>

View File

@ -1859,6 +1859,7 @@ test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.h
== 1105137-1.html 1105137-1-ref.html
fuzzy-if(d2d,36,304) HTTP(..) == 1116480-1-fakeitalic-overflow.html 1116480-1-fakeitalic-overflow-ref.html
== 1111753-1.html about:blank
== 1114526-1.html 1114526-1-ref.html
== 1119117-1a.html 1119117-1-ref.html
== 1119117-1b.html 1119117-1-ref.html
== 1120431-1.html 1120431-1-ref.html

View File

@ -1 +1 @@
0.0.19
0.0.20

View File

@ -25,12 +25,14 @@ set -x -e
: MOZHARNESS_REF ${MOZHARNESS_REF:=${MOZHARNESS_REV}}
: MOZHARNESS_HEAD_REV ${MOZHARNESS_HEAD_REV:=${MOZHARNESS_REV}}
: MOZHARNESS_HEAD_REF ${MOZHARNESS_HEAD_REF:=${MOZHARNESS_REF}}
: MOZHARNESS_DISABLE ${MOZHARNESS_DISABLE:=false}
: TOOLS_REPOSITORY ${TOOLS_REPOSITORY:=https://hg.mozilla.org/build/tools}
: TOOLS_BASE_REPOSITORY ${TOOLS_BASE_REPOSITORY:=${TOOLS_REPOSITORY}}
: TOOLS_HEAD_REPOSITORY ${TOOLS_HEAD_REPOSITORY:=${TOOLS_REPOSITORY}}
: TOOLS_HEAD_REV ${TOOLS_HEAD_REV:=default}
: TOOLS_HEAD_REF ${TOOLS_HEAD_REF:=${TOOLS_HEAD_REV}}
: TOOLS_DISABLE ${TOOLS_DISABLE:=false}
: MH_CUSTOM_BUILD_VARIANT_CFG ${MH_CUSTOM_BUILD_VARIANT_CFG}
: MH_BRANCH ${MH_BRANCH:=mozilla-central}
@ -41,13 +43,20 @@ set -x -e
set -v
# check out mozharness
tc-vcs checkout mozharness $MOZHARNESS_BASE_REPOSITORY $MOZHARNESS_HEAD_REPOSITORY $MOZHARNESS_HEAD_REV $MOZHARNESS_HEAD_REF
if [ ! "$MOZHARNESS_DISABLE" = "true" ]
then
tc-vcs checkout mozharness $MOZHARNESS_BASE_REPOSITORY $MOZHARNESS_HEAD_REPOSITORY $MOZHARNESS_HEAD_REV $MOZHARNESS_HEAD_REF
fi
# check out tools where mozharness expects it to be ($PWD/build/tools and $WORKSPACE/build/tools)
tc-vcs checkout $WORKSPACE/build/tools $TOOLS_BASE_REPOSITORY $TOOLS_HEAD_REPOSITORY $TOOLS_HEAD_REV $TOOLS_HEAD_REF
if [ ! -d build ]; then
mkdir -p build
ln -s $WORKSPACE/build/tools build/tools
if [ ! "$TOOLS_DISABLE" = true ]
then
tc-vcs checkout $WORKSPACE/build/tools $TOOLS_BASE_REPOSITORY $TOOLS_HEAD_REPOSITORY $TOOLS_HEAD_REV $TOOLS_HEAD_REF
if [ ! -d build ]; then
mkdir -p build
ln -s $WORKSPACE/build/tools build/tools
fi
fi
# and check out mozilla-central where mozharness will use it as a cache (/builds/hg-shared)

View File

@ -0,0 +1,22 @@
#!/bin/bash
set -x
: SPIDERMONKEY_VARIANT ${SPIDERMONKEY_VARIANT:-plain}
UPLOAD_DIR=$HOME/workspace/artifacts/
# cd into the correct directory
cd $HOME/workspace/
# Run the script
./build/src/js/src/devtools/automation/autospider.sh $SPIDERMONKEY_VARIANT
BUILD_STATUS=$?
# Ensure upload dir exists
mkdir -p $UPLOAD_DIR
# Move artifacts for upload by TaskCluster
mv ./build/src/obj-spider/dist/* $UPLOAD_DIR
exit $BUILD_STATUS

View File

@ -1175,6 +1175,31 @@ public:
//
// Mutation methods
//
template<class Allocator, typename ActualAlloc = Alloc>
typename ActualAlloc::ResultType Assign(
const nsTArray_Impl<E, Allocator>& aOther)
{
return ActualAlloc::ConvertBoolToResultType(
!!ReplaceElementsAt<E, ActualAlloc>(0, Length(),
aOther.Elements(), aOther.Length()));
}
template<class Allocator>
/* MOZ_WARN_UNUSED_RESULT */
bool Assign(const nsTArray_Impl<E, Allocator>& aOther,
const mozilla::fallible_t&)
{
return Assign<Allocator, FallibleAlloc>(aOther);
}
template<class Allocator>
void Assign(nsTArray_Impl<E, Allocator>&& aOther)
{
Clear();
SwapElements(aOther);
}
// This method call the destructor on each element of the array, empties it,
// but does not shrink the array's capacity.
// See also SetLengthAndRetainStorage.

View File

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsTArray.h"
#include "gtest/gtest.h"
using namespace mozilla;
namespace TestTArray {
const nsTArray<int>& DummyArray()
{
static nsTArray<int> sArray;
if (sArray.IsEmpty()) {
const int data[] = {4, 1, 2, 8};
sArray.AppendElements(data, ArrayLength(data));
}
return sArray;
}
// This returns an invalid nsTArray with a huge length in order to test that
// fallible operations actually fail.
#ifdef DEBUG
const nsTArray<int>& FakeHugeArray()
{
static nsTArray<int> sArray;
if (sArray.IsEmpty()) {
sArray.AppendElement();
((nsTArrayHeader*)sArray.DebugGetHeader())->mLength = UINT32_MAX;
}
return sArray;
}
#endif
TEST(TArray, assign)
{
nsTArray<int> array;
array.Assign(DummyArray());
ASSERT_EQ(DummyArray(), array);
ASSERT_TRUE(array.Assign(DummyArray(), fallible));
ASSERT_EQ(DummyArray(), array);
#ifdef DEBUG
ASSERT_FALSE(array.Assign(FakeHugeArray(), fallible));
#endif
nsTArray<int> array2;
array2.Assign(Move(array));
ASSERT_TRUE(array.IsEmpty());
ASSERT_EQ(DummyArray(), array2);
}
}

View File

@ -17,6 +17,7 @@ UNIFIED_SOURCES += [
'TestStrings.cpp',
'TestStringStream.cpp',
'TestSynchronization.cpp',
'TestTArray.cpp',
'TestThreadPool.cpp',
'TestThreads.cpp',
'TestTimeStamp.cpp',