Compare commits

..
Author SHA1 Message Date
Moonchild 44d17e4ee7 Replace strnlen with memchr. See code comment. 2026-08-15 10:19:41 +02:00
Moonchild 26cc7c3126 Revert "Refactor string utils in MFBT."
This reverts commit cea1b66ba5.
2026-08-15 09:49:46 +02:00
Moonchild cea1b66ba5 Refactor string utils in MFBT.
This adds an Apple carveout for strnlen for OS X < 10.7 and renames the
ToString.h header to StringUtils.h to better reflect the more generic
collection of functions in it, instead of a 1-file-1-method header.
2026-08-13 16:42:35 +02:00
86 changed files with 1007 additions and 3370 deletions

No files matched your search

+1
View File
@@ -23,6 +23,7 @@ SOURCES += [
'DocAccessibleWrap.cpp',
'EnumVariant.cpp',
'HTMLTableAccessibleWrap.cpp',
'HTMLWin32ObjectAccessible.cpp',
'HyperTextAccessibleWrap.cpp',
'ImageAccessibleWrap.cpp',
'IUnknownImpl.cpp',
-99
View File
@@ -5,19 +5,13 @@
#include "DocumentOrShadowRoot.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/CSSStyleSheetBinding.h"
#include "mozilla/dom/StyleSheetList.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsDocument.h"
#include "nsFocusManager.h"
#include "ShadowRoot.h"
#include "XULDocument.h"
#include "nsLayoutUtils.h"
#include "nsSVGUtils.h"
#include "jsapi.h"
class nsINode;
class nsIDocument;
@@ -49,99 +43,6 @@ DocumentOrShadowRoot::EnsureDOMStyleSheets()
return *mDOMStyleSheets;
}
void
DocumentOrShadowRoot::GetAdoptedStyleSheets(
JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv) const
{
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, mAdoptedStyleSheets, &value)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
MOZ_ASSERT(value.isObject());
aResult.set(&value.toObject());
}
void
DocumentOrShadowRoot::SetAdoptedStyleSheets(
JSContext* aCx,
JS::Handle<JSObject*> aSheets,
ErrorResult& aRv)
{
bool isArray = false;
if (!JS_IsArrayObject(aCx, aSheets, &isArray)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!isArray) {
aRv.ThrowTypeError<MSG_NOT_SEQUENCE>(
NS_LITERAL_STRING("DocumentOrShadowRoot.adoptedStyleSheets"));
return;
}
uint32_t length = 0;
if (!JS_GetArrayLength(aCx, aSheets, &length)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsIDocument* document = AsNode().OwnerDoc();
nsTArray<RefPtr<CSSStyleSheet>> newSheets;
if (!newSheets.SetCapacity(length, fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
JS::Rooted<JS::Value> value(aCx);
for (uint32_t i = 0; i < length; ++i) {
if (!JS_GetElement(aCx, aSheets, i, &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!value.isObject()) {
aRv.ThrowTypeError<MSG_DOES_NOT_IMPLEMENT_INTERFACE>(
NS_LITERAL_STRING("Element of DocumentOrShadowRoot.adoptedStyleSheets"),
NS_LITERAL_STRING("CSSStyleSheet"));
return;
}
RefPtr<CSSStyleSheet> sheet;
nsresult rv = UnwrapObject<prototypes::id::CSSStyleSheet,
CSSStyleSheet>(&value.toObject(), sheet);
if (NS_FAILED(rv)) {
aRv.ThrowTypeError<MSG_DOES_NOT_IMPLEMENT_INTERFACE>(
NS_LITERAL_STRING("Element of DocumentOrShadowRoot.adoptedStyleSheets"),
NS_LITERAL_STRING("CSSStyleSheet"));
return;
}
if (!sheet->IsConstructed() || sheet->ConstructorDocument() != document) {
aRv.Throw(NS_ERROR_DOM_NOT_ALLOWED_ERR);
return;
}
newSheets.AppendElement(sheet);
}
nsTArray<RefPtr<CSSStyleSheet>> oldSheets;
oldSheets.SwapElements(mAdoptedStyleSheets);
mAdoptedStyleSheets.SwapElements(newSheets);
if (mKind == Kind::Document) {
static_cast<nsDocument&>(AsNode()).AdoptedStyleSheetsChanged(oldSheets,
mAdoptedStyleSheets);
return;
}
static_cast<ShadowRoot&>(AsNode()).AdoptedStyleSheetsChanged(oldSheets,
mAdoptedStyleSheets);
}
Element*
DocumentOrShadowRoot::GetElementById(const nsAString& aElementId)
{
-16
View File
@@ -11,14 +11,11 @@
#include "nsContentListDeclarations.h"
#include "nsNameSpaceManager.h"
#include "mozilla/dom/NameSpaceConstants.h"
#include "js/RootingAPI.h"
class nsContentList;
class nsINode;
namespace mozilla {
class CSSStyleSheet;
class ErrorResult;
class StyleSheet;
namespace dom {
@@ -86,18 +83,6 @@ public:
StyleSheetList& EnsureDOMStyleSheets();
void GetAdoptedStyleSheets(JSContext* aCx,
JS::MutableHandle<JSObject*> aResult,
mozilla::ErrorResult& aRv) const;
void SetAdoptedStyleSheets(JSContext* aCx,
JS::Handle<JSObject*> aSheets,
mozilla::ErrorResult& aRv);
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& AdoptedStyleSheets() const
{
return mAdoptedStyleSheets;
}
Element* GetElementById(const nsAString& aElementId);
/**
@@ -166,7 +151,6 @@ protected:
Element* GetRetargetedFocusedElement();
nsTArray<RefPtr<mozilla::StyleSheet>> mStyleSheets;
nsTArray<RefPtr<mozilla::CSSStyleSheet>> mAdoptedStyleSheets;
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
/*
+4 -53
View File
@@ -18,7 +18,6 @@
#include "mozilla/dom/StyleSheetList.h"
#include "nsXBLPrototypeBinding.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
@@ -31,7 +30,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot,
DocumentFragment)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAdoptedStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAssociatedBinding)
for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done();
iter.Next()) {
@@ -44,10 +42,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ShadowRoot)
tmp->GetHost()->RemoveMutationObserver(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
for (CSSStyleSheet* sheet : tmp->mAdoptedStyleSheets) {
sheet->RemoveAdopter(tmp);
}
tmp->mAdoptedStyleSheets.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAssociatedBinding)
tmp->mIdentifierMap.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DocumentFragment)
@@ -96,11 +90,6 @@ ShadowRoot::~ShadowRoot()
host->RemoveMutationObserver(this);
}
for (CSSStyleSheet* sheet : mAdoptedStyleSheets) {
sheet->RemoveAdopter(this);
}
mAdoptedStyleSheets.Clear();
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// nsINode destructor expects mSubtreeRoot == this.
@@ -281,20 +270,15 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet
MOZ_DIAGNOSTIC_ASSERT(mProtoBinding->SheetCount() ==
DocumentOrShadowRoot::SheetCount() +
mAdoptedStyleSheets.Length());
MOZ_DIAGNOSTIC_ASSERT(mProtoBinding->SheetCount() == DocumentOrShadowRoot::SheetCount());
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
// FIXME(emilio, bug 1425759): For now we keep regular sheets duplicated;
// adopted sheets are stored as a suffix on the proto binding only.
// FIXME(emilio, bug 1425759): For now we keep them duplicated, the proto
// binding will disappear soon (tm).
{
size_t i = 0;
for (RefPtr<StyleSheet>& sheet : mStyleSheets) {
MOZ_DIAGNOSTIC_ASSERT(sheet.get() == mProtoBinding->StyleSheetAt(i++));
}
for (RefPtr<CSSStyleSheet>& sheet : mAdoptedStyleSheets) {
MOZ_DIAGNOSTIC_ASSERT(sheet.get() == mProtoBinding->StyleSheetAt(i++));
}
}
#endif
@@ -303,7 +287,7 @@ ShadowRoot::InsertSheet(StyleSheet* aSheet,
for (size_t i = 0; i <= SheetCount(); i++) {
if (i == SheetCount()) {
AppendStyleSheet(*aSheet);
mProtoBinding->InsertStyleSheetAt(i, aSheet);
mProtoBinding->AppendStyleSheet(aSheet);
break;
}
@@ -338,39 +322,6 @@ ShadowRoot::RemoveSheet(StyleSheet* aSheet)
}
}
void
ShadowRoot::AdoptedStyleSheetsChanged(
const nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
{
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
bool applicableChange = false;
for (size_t i = 0; i < aOldSheets.Length(); ++i) {
CSSStyleSheet* sheet = aOldSheets[i];
if (aOldSheets.IndexOf(sheet) == i) {
mProtoBinding->RemoveStyleSheet(sheet);
}
applicableChange = applicableChange || sheet->IsApplicable();
sheet->RemoveAdopter(this);
}
for (size_t i = 0; i < aNewSheets.Length(); ++i) {
CSSStyleSheet* sheet = aNewSheets[i];
sheet->AddAdopter(this);
if (aNewSheets.IndexOf(sheet) == i) {
mProtoBinding->AppendStyleSheet(sheet);
}
applicableChange = applicableChange || sheet->IsApplicable();
}
if (applicableChange) {
StyleSheetChanged();
}
OwnerDoc()->EndUpdate(UPDATE_STYLE);
}
void
ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
{
+1 -4
View File
@@ -21,7 +21,6 @@ class nsXBLPrototypeBinding;
namespace mozilla {
class CSSStyleSheet;
class EventChainPreVisitor;
namespace dom {
@@ -60,9 +59,6 @@ public:
// [deprecated] Shadow DOM v0
void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
void RemoveSheet(StyleSheet* aSheet);
void AdoptedStyleSheetsChanged(
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
StyleSheetList* StyleSheets()
{
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
@@ -177,3 +173,4 @@ protected:
} // namespace mozilla
#endif // mozilla_dom_shadowroot_h__
-60
View File
@@ -13,7 +13,6 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EffectSet.h"
#include "mozilla/IntegerRange.h"
@@ -1403,10 +1402,6 @@ nsDocument::~nsDocument()
for (StyleSheet* sheet : mStyleSheets) {
sheet->ClearAssociatedDocument();
}
for (CSSStyleSheet* sheet : mAdoptedStyleSheets) {
sheet->RemoveAdopter(this);
}
mAdoptedStyleSheets.Clear();
for (auto& sheets : mAdditionalSheets) {
for (StyleSheet* sheet : sheets) {
sheet->ClearAssociatedDocument();
@@ -1640,7 +1635,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
// Traverse all our nsCOMArrays.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAdoptedStyleSheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
@@ -1746,11 +1740,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStyleSheets)
for (CSSStyleSheet* sheet : tmp->mAdoptedStyleSheets) {
sheet->RemoveAdopter(tmp);
}
tmp->mAdoptedStyleSheets.Clear();
if (tmp->mStyleSheetSetList) {
tmp->mStyleSheetSetList->Disconnect();
tmp->mStyleSheetSetList = nullptr;
@@ -2216,12 +2205,6 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAuthorSheet],
SheetType::Doc);
for (CSSStyleSheet* sheet : mAdoptedStyleSheets) {
if (sheet->IsApplicable()) {
aStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
}
}
mStyleSetFilled = true;
}
@@ -3889,37 +3872,6 @@ nsDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet)
}
}
void
nsDocument::AdoptedStyleSheetsChanged(
const nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
{
BeginUpdate(UPDATE_STYLE);
nsCOMPtr<nsIPresShell> shell = GetShell();
nsStyleSet* styleSet = shell ? shell->StyleSet() : nullptr;
for (size_t i = 0; i < aOldSheets.Length(); ++i) {
CSSStyleSheet* sheet = aOldSheets[i];
if (styleSet && sheet->IsApplicable() &&
aOldSheets.IndexOf(sheet) == i) {
styleSet->RemoveStyleSheet(SheetType::Doc, sheet);
}
sheet->RemoveAdopter(this);
}
for (size_t i = 0; i < aNewSheets.Length(); ++i) {
CSSStyleSheet* sheet = aNewSheets[i];
sheet->AddAdopter(this);
if (styleSet && sheet->IsApplicable() &&
aNewSheets.IndexOf(sheet) == i) {
styleSet->AppendStyleSheet(SheetType::Doc, sheet);
}
}
EndUpdate(UPDATE_STYLE);
}
void
nsDocument::RemoveStyleSheet(StyleSheet* aSheet)
{
@@ -4009,18 +3961,6 @@ nsDocument::SetStyleSheetApplicableState(StyleSheet* aSheet,
} else {
RemoveStyleSheetFromStyleSets(aSheet);
}
} else if (mAdoptedStyleSheets.IndexOf(aSheet->AsConcrete()) !=
mAdoptedStyleSheets.NoIndex) {
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
if (aApplicable) {
shell->StyleSet()->AppendStyleSheet(SheetType::Doc,
aSheet->AsConcrete());
} else {
shell->StyleSet()->RemoveStyleSheet(SheetType::Doc,
aSheet->AsConcrete());
}
}
}
// We have to always notify, since this will be called for sheets
-4
View File
@@ -95,7 +95,6 @@ class nsISecurityConsoleMessage;
class nsPIBoxObject;
namespace mozilla {
class CSSStyleSheet;
class EventChainPreVisitor;
namespace dom {
class BoxObject;
@@ -472,9 +471,6 @@ public:
nsTArray<RefPtr<mozilla::StyleSheet>>& aNewSheets) override;
virtual void AddStyleSheetToStyleSets(mozilla::StyleSheet* aSheet);
virtual void RemoveStyleSheetFromStyleSets(mozilla::StyleSheet* aSheet);
void AdoptedStyleSheetsChanged(
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
virtual void InsertStyleSheetAt(mozilla::StyleSheet* aSheet,
size_t aIndex) override;
+1 -2
View File
@@ -1738,9 +1738,8 @@ nsFocusManager::Blur(nsPIDOMWindowOuter* aWindowToClear,
if (mActiveWindow)
window->UpdateCommands(NS_LITERAL_STRING("focus"), nullptr, 0);
nsCOMPtr<nsIDocument> doc = content->GetComposedDoc();
SendFocusOrBlurEvent(eBlur, presShell,
doc, content, 1,
content->GetComposedDoc(), content, 1,
false, false, aContentToFocus);
}
+3 -19
View File
@@ -6162,6 +6162,7 @@ nsGlobalWindow::CheckSecurityWidthAndHeight(int32_t* aWidth, int32_t* aHeight, b
// This one is easy. Just ensure the variable is greater than 100;
if ((aWidth && *aWidth < 100) || (aHeight && *aHeight < 100)) {
// Check security state for use in determing window dimensions
if (!nsContentUtils::IsCallerChrome()) {
//sec check failed
if (aWidth && *aWidth < 100) {
@@ -6172,21 +6173,6 @@ nsGlobalWindow::CheckSecurityWidthAndHeight(int32_t* aWidth, int32_t* aHeight, b
}
}
}
// Check for the screen dimensions and keep the size in the range of the
// screen size the window is on. We allow twice the screen size because the
// size we get for a screen is not always accurate, on Wayland in particular,
// and all we need is to keep the size in a reasonable range.
nsCOMPtr<nsIDOMScreen> screen = GetScreen();
int32_t screenWidth, screenHeight;
screen->GetAvailWidth(&screenWidth);
screen->GetAvailHeight(&screenHeight);
if (aWidth && *aWidth > 2 * screenWidth) {
*aWidth = 2 * screenWidth;
}
if (aHeight && *aHeight > 2 * screenHeight) {
*aHeight = 2 * screenHeight;
}
}
// NOTE: Arguments to this function should have values in device pixels
@@ -8105,10 +8091,8 @@ nsGlobalWindow::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height)));
// The deltas come from content and can be large enough to overflow a 32-bit
// add, so do the arithmetic in 64 bits and keep the result in range.
cssSize.width = int32_t(std::clamp<int64_t>(int64_t(cssSize.width) + aWidthDif, 0, INT32_MAX));
cssSize.height = int32_t(std::clamp<int64_t>(int64_t(cssSize.height) + aHeightDif, 0, INT32_MAX));
cssSize.width += aWidthDif;
cssSize.height += aHeightDif;
CheckSecurityWidthAndHeight(&cssSize.width, &cssSize.height, aCallerIsChrome);
-3
View File
@@ -46,9 +46,6 @@ nsIDocument::FindDocStyleSheetInsertionPoint(
break;
}
}
if (sheet->IsConstructed()) {
break;
}
if (sheet == GetFirstAdditionalAuthorSheet()) {
break;
}
-4
View File
@@ -1132,7 +1132,6 @@ void HTMLMediaElement::AbortExistingLoads()
RemoveMediaElementFromURITable();
mLoadingSrc = nullptr;
mCORSMode = CORS_NONE;
mMediaSource = nullptr;
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING ||
@@ -1371,9 +1370,6 @@ void HTMLMediaElement::SelectResource()
// If we have a 'src' attribute, use that exclusively.
nsAutoString src;
if (mSrcAttrStream) {
// Media provider objects use local mode, so a previous URL load's CORS
// mode does not apply.
mCORSMode = CORS_NONE;
SetupSrcMediaStreamPlayback(mSrcAttrStream);
} else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
nsCOMPtr<nsIURI> uri;
+5 -5
View File
@@ -117,6 +117,11 @@ public:
int32_t Index();
protected:
virtual ~HTMLOptionElement();
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
/**
* Get the select content element that contains this option, this
* intentionally does not return nsresult, all we care about is if
@@ -124,11 +129,6 @@ public:
*/
HTMLSelectElement* GetSelect();
protected:
virtual ~HTMLOptionElement();
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
bool mSelectedChanged;
bool mIsSelected;
+3 -3
View File
@@ -732,10 +732,10 @@ bool
HTMLSelectElement::MatchSelectedOptions(Element* aElement,
int32_t /* unused */,
nsIAtom* /* unused */,
void* aData)
void* /* unused*/)
{
HTMLOptionElement* option = HTMLOptionElement::FromContent(aElement);
return option && option->Selected() && option->GetSelect() == static_cast<HTMLSelectElement*>(aData);
return option && option->Selected();
}
nsIHTMLCollection*
@@ -743,7 +743,7 @@ HTMLSelectElement::SelectedOptions()
{
if (!mSelectedOptions) {
mSelectedOptions = new nsContentList(this, MatchSelectedOptions, nullptr,
this, /* deep */ true);
nullptr, /* deep */ true);
}
return mSelectedOptions;
}
-4
View File
@@ -265,10 +265,6 @@ VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
return false;
}
if (!ValidateBufferAndPicture(aBuffer, aPicture)) {
return false;
}
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
aVideoImage->SetDelayedConversion(true);
+7 -21
View File
@@ -187,7 +187,7 @@ public:
{
}
VideoInfo(int32_t aWidth, int32_t aHeight)
explicit VideoInfo(int32_t aWidth, int32_t aHeight)
: VideoInfo(nsIntSize(aWidth, aHeight))
{
}
@@ -201,6 +201,7 @@ public:
, mCodecSpecificConfig(new MediaByteBuffer)
, mExtraData(new MediaByteBuffer)
, mRotation(kDegree_0)
, mImageRect(nsIntRect(nsIntPoint(), aSize))
{
}
@@ -262,28 +263,15 @@ public:
nsIntRect ImageRect() const
{
if (!mImageRect) {
if (mImageRect.width < 0 || mImageRect.height < 0) {
return nsIntRect(0, 0, mImage.width, mImage.height);
}
return *mImageRect;
return mImageRect;
}
void SetImageRect(const nsIntRect& aRect)
{
mImageRect = Some(aRect);
}
void ResetImageRect() {
mImageRect.reset();
}
// Adopts an image size decoded from the bitstream. The picture rectangle is
// expressed relative to the image size, so a change in size invalidates it
// and it is discarded; an unchanged size keeps the existing rectangle.
void AdoptImageSize(const gfx::IntSize& aImage) {
if (mImage != aImage) {
ResetImageRect();
}
mImage = aImage;
mImageRect = aRect;
}
// Returned the crop rectangle scaled to aWidth/aHeight size relative to
@@ -344,11 +332,9 @@ public:
uint8_t mBitDepth = 8;
private:
friend struct IPC::ParamTraits<VideoInfo>;
// mImage may be cropped; currently only used with the WebM container.
// If unset, no cropping is to occur.
Maybe<nsIntRect> mImageRect;
// A negative width or height indicate that no cropping is to occur.
nsIntRect mImageRect;
// Indicates whether or not frames may contain alpha information.
bool mAlphaPresent = false;
+3 -2
View File
@@ -25,7 +25,7 @@ namespace IPC {
WriteParam(aMsg, aParam.mDisplay);
WriteParam(aMsg, aParam.mStereoMode);
WriteParam(aMsg, aParam.mImage);
WriteParam(aMsg, aParam.mImageRect);
WriteParam(aMsg, aParam.ImageRect());
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
@@ -35,7 +35,8 @@ namespace IPC {
ReadParam(aMsg, aIter, &aResult->mDisplay) &&
ReadParam(aMsg, aIter, &aResult->mStereoMode) &&
ReadParam(aMsg, aIter, &aResult->mImage) &&
ReadParam(aMsg, aIter, &aResult->mImageRect)) {
ReadParam(aMsg, aIter, &imageRect)) {
aResult->SetImageRect(imageRect);
return true;
}
return false;
@@ -847,15 +847,12 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
RefPtr<layers::PlanarYCbCrImage> image =
new IMFYCbCrImage(buffer, twoDBuffer);
if (!VideoData::SetVideoDataToImage(image,
mVideoInfo,
b,
pictureRegion,
false)) {
LOG("CreateBasicVideoFrame: failed to set video data to image (shmem path)");
return E_FAIL;
}
VideoData::SetVideoDataToImage(image,
mVideoInfo,
b,
pictureRegion,
false);
RefPtr<VideoData> v =
VideoData::CreateFromImage(mVideoInfo,
aStreamOffset,
@@ -307,7 +307,8 @@ H264Converter::UpdateConfigFromExtraData(MediaByteBuffer* aExtraData)
if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtraData, spsdata) &&
spsdata.pic_width > 0 && spsdata.pic_height > 0) {
mp4_demuxer::H264::EnsureSPSIsSane(spsdata);
mCurrentConfig.AdoptImageSize(gfx::IntSize(spsdata.pic_width, spsdata.pic_height));
mCurrentConfig.mImage.width = spsdata.pic_width;
mCurrentConfig.mImage.height = spsdata.pic_height;
mCurrentConfig.mDisplay.width = spsdata.display_width;
mCurrentConfig.mDisplay.height = spsdata.display_height;
}
-2
View File
@@ -18,8 +18,6 @@ interface mixin DocumentOrShadowRoot {
readonly attribute Element? activeElement;
readonly attribute StyleSheetList styleSheets;
[Throws]
attribute object adoptedStyleSheets;
readonly attribute Element? pointerLockElement;
[LenientSetter, Func="nsDocument::IsUnprefixedFullscreenEnabled"]
+2 -8
View File
@@ -294,12 +294,12 @@ nsXMLContentSink::DidBuildModel(bool aTerminated)
}
}
mDocumentChildren.Clear();
mXSLTProcessor->SetSourceContentModel(mDocument, mDocumentChildren);
// Since the processor now holds a reference to us we drop our reference
// to it to avoid owning cycles
mXSLTProcessor = nullptr;
} else {
}
else {
// Kick off layout for non-XSLT transformed documents.
// Check if we want to prettyprint
@@ -881,9 +881,6 @@ nsXMLContentSink::SetDocElement(int32_t aNameSpaceID,
if (!mDocumentChildren.IsEmpty()) {
for (nsIContent* child : mDocumentChildren) {
if (MOZ_UNLIKELY(child->GetParentNode())) {
child->Remove();
}
mDocument->AppendChildTo(child, false);
}
mDocumentChildren.Clear();
@@ -994,9 +991,6 @@ nsXMLContentSink::HandleStartElement(const char16_t *aName,
if (!SetDocElement(nameSpaceID, localName, content) && appendContent) {
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
if (MOZ_UNLIKELY(content->GetParentNode())) {
content->Remove();
}
parent->AppendChildTo(content, false);
}
}
+1 -1
View File
@@ -5159,7 +5159,7 @@ HTMLEditor::IsAcceptableInputEvent(WidgetGUIEvent* aGUIEvent)
// If the event is a mouse event, we need to check if the target content is
// the focused editing host or its descendant.
if (aGUIEvent->AsMouseEventBase()) {
RefPtr<nsIContent> editingHost = GetActiveEditingHost();
nsIContent* editingHost = GetActiveEditingHost();
// If there is no active editing host, we cannot handle the mouse event
// correctly.
if (!editingHost) {
File diff suppressed because it is too large. Load diff
+3 -7
View File
@@ -632,13 +632,9 @@ NVImage::GetAsSourceSurface()
// Convert the current NV12 or NV21 data to YUV420P so that we can follow the
// logics in PlanarYCbCrImage::GetAsSourceSurface().
auto bufferLength = CheckedInt<uint32_t>(mData.mYSize.height) * mData.mYStride +
CheckedInt<uint32_t>(mData.mCbCrSize.height) * mData.mCbCrSize.width * 2;
if (!bufferLength.isValid()) {
NS_ERROR("Image buffer length exceeds integer limits.");
return nullptr;
}
uint8_t* buffer = new uint8_t[bufferLength.value()];
const int bufferLength = mData.mYSize.height * mData.mYStride +
mData.mCbCrSize.height * mData.mCbCrSize.width * 2;
uint8_t* buffer = new uint8_t[bufferLength];
Data aData = mData;
aData.mCbCrStride = aData.mCbCrSize.width;
@@ -40,7 +40,7 @@ static void SK_BLITBWMASK_NAME(const SkPixmap& dst, const SkMask& srcMask,
const uint8_t* bits = srcMask.getAddr1(cx, cy);
SK_BLITBWMASK_DEVTYPE* device = dst.SK_BLITBWMASK_GETADDR(cx, cy);
if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight && (clip.width() & 7) == 0)
if (cx == maskLeft && clip.fRight == srcMask.fBounds.fRight)
{
do {
SK_BLITBWMASK_DEVTYPE* dst = device;
+6 -5
View File
@@ -702,16 +702,17 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
case FT_GLYPH_FORMAT_BITMAP:
if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
glyph->fMaskFormat = SkMask::kARGB32_Format;
} else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY ||
isLCD(fRec)) {
glyph->fMaskFormat = SkMask::kA8_Format;
}
if (isLCD(fRec)) {
fRec.fMaskFormat = SkMask::kA8_Format;
}
if (fHaveShape) {
// Ensure filtering is preserved when the bitmap is transformed.
// Otherwise, the result will look horrifically aliased.
if (glyph->fMaskFormat == SkMask::kBW_Format) {
glyph->fMaskFormat = SkMask::kA8_Format;
if (fRec.fMaskFormat == SkMask::kBW_Format) {
fRec.fMaskFormat = SkMask::kA8_Format;
}
// Apply the shape matrix to the glyph's bounding box.
+2 -3
View File
@@ -587,9 +587,8 @@ gfxFontUtils::MapCharToGlyphFormat4(const uint8_t* aBuf, uint32_t aLength,
const AutoSwap_PRUint16* idDelta = &startCodes[segCount];
const AutoSwap_PRUint16* idRangeOffset = &idDelta[segCount];
// Sanity-check that the fixed-size arrays don't exceed the buffer or the
// current subtable.
const uint8_t* const limit = aBuf + std::min(aLength, uint32_t(cmap4->length));
// Sanity-check that the fixed-size arrays don't exceed the buffer.
const uint8_t* const limit = aBuf + aLength;
if ((const uint8_t*)(&idRangeOffset[segCount]) > limit) {
return 0; // broken font, just bail out safely
}
+1 -1
View File
@@ -2761,7 +2761,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
ufe->Load();
ff.CheckState(mSkipDrawing);
}
RefPtr<gfxFontEntry> pfe = ufe->GetPlatformFontEntry();
gfxFontEntry* pfe = ufe->GetPlatformFontEntry();
if (pfe && pfe->HasCharacter(aCh)) {
font = GetFontAt(i, aCh);
if (font) {
+1 -3
View File
@@ -44,8 +44,7 @@ class ExpandingMemoryStream : public ots::OTSStream {
public:
ExpandingMemoryStream(size_t initial, size_t limit)
: mLength(initial), mLimit(limit), mOff(0) {
mPtr = moz_xmalloc(initial);
std::memset(mPtr, 0, initial);
mPtr = moz_xmalloc(mLength);
}
~ExpandingMemoryStream() {
@@ -75,7 +74,6 @@ public:
newLength = mLimit;
}
mPtr = moz_xrealloc(mPtr, newLength);
std::memset(static_cast<char*>(mPtr) + mLength, 0, newLength - mLength);
mLength = newLength;
return WriteRaw(data, length);
}
+9 -9
View File
@@ -94,6 +94,8 @@ RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
//******************************************************************************
RasterImage::~RasterImage()
{
mIsBeingDestroyed = true;
// Make sure our SourceBuffer is marked as complete. This will ensure that any
// outstanding decoders terminate.
if (!mSourceBuffer->IsComplete()) {
@@ -429,17 +431,15 @@ RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey)
{
MOZ_ASSERT(mProgressTracker);
if (mIsBeingDestroyed) {
return;
}
bool animatedFramesDiscarded = aSurfaceKey.Playback() == PlaybackType::eAnimated;
RefPtr<ProgressTracker> progressTracker = mProgressTracker;
NS_DispatchToMainThread(NS_NewRunnableFunction(
[progressTracker, animatedFramesDiscarded]() -> void {
RefPtr<Image> image = progressTracker->GetImage();
if (!image) {
return;
}
static_cast<RasterImage*>(image.get())
->OnSurfaceDiscardedInternal(animatedFramesDiscarded);
RefPtr<RasterImage> image = this;
NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void {
image->OnSurfaceDiscardedInternal(animatedFramesDiscarded);
}));
}
+3
View File
@@ -17,6 +17,7 @@
#ifndef mozilla_image_RasterImage_h
#define mozilla_image_RasterImage_h
#include "mozilla/Atomics.h"
#include "Image.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
@@ -402,6 +403,8 @@ private: // data
// This is currently only used for statistics
int32_t mDecodeCount;
Atomic<bool> mIsBeingDestroyed{false};
// A weak pointer to our ImageContainer, which stays alive only as long as
// the layer system needs it.
WeakPtr<layers::ImageContainer> mImageContainer;
+7 -16
View File
@@ -238,21 +238,16 @@ static inline JS::Value PoisonedObjectValue(JSObject* obj);
namespace detail {
constexpr int CanonicalizedNaNSignBit = 0;
constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL;
// A legacy MIPS ABI can run on hardware whose native NaN encoding does not
// match the encoding selected by the compiler. Determine the canonical NaN
// from an actual floating-point operation during JS initialization.
#if defined(__mips__) && !defined(__mips_nan2008) && \
!defined(__mips_nan_2008)
# define JS_RUNTIME_CANONICAL_NAN
extern JS_PUBLIC_DATA(uint64_t) CanonicalizedNaNBits;
#if defined(__mips__) && !defined(__mips_nan2008)
constexpr uint64_t CanonicalizedNaNSignificand = 0x7FFFFFFFFFFFFULL;
#else
constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000ULL;
#endif
constexpr uint64_t CanonicalizedNaNBits =
mozilla::SpecificNaNBits<double,
detail::CanonicalizedNaNSignBit,
detail::CanonicalizedNaNSignificand>::value;
#endif
} // namespace detail
@@ -265,7 +260,8 @@ constexpr uint64_t CanonicalizedNaNBits =
static MOZ_ALWAYS_INLINE double
GenericNaN()
{
return mozilla::BitwiseCast<double>(detail::CanonicalizedNaNBits);
return mozilla::SpecificNaN<double>(detail::CanonicalizedNaNSignBit,
detail::CanonicalizedNaNSignificand);
}
/* MSVC with PGO miscompiles this function. */
@@ -359,11 +355,6 @@ class MOZ_NON_PARAM alignas(8) Value
}
void setDouble(double d) {
#if defined(JS_RUNTIME_CANONICAL_NAN) && defined(JS_PUNBOX64)
// A non-canonical NaN can overlap the punbox64 tag space. Normalize
// it before storing it so it cannot be mistaken for a GC pointer.
d = CanonicalizeNaN(d);
#endif
// Don't assign to data.asDouble to fix a miscompilation with
// GCC 5.2.1 and 5.3.1. See bug 1312488.
data = layout(d);
+4 -4
View File
@@ -902,8 +902,8 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void rotateLeft(Imm32 count, Register input, Register dest) PER_SHARED_ARCH;
inline void rotateLeft(Register count, Register input, Register dest) PER_SHARED_ARCH;
inline void rotateLeft64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
inline void rotateLeft64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
inline void rotateLeft64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
inline void rotateLeft64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
inline void rotateLeft64(Imm32 count, Register64 input, Register64 dest, Register temp)
DEFINED_ON(x86, x64, arm, mips32, mips64, loongarch64);
inline void rotateLeft64(Register count, Register64 input, Register64 dest, Register temp)
@@ -911,8 +911,8 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void rotateRight(Imm32 count, Register input, Register dest) PER_SHARED_ARCH;
inline void rotateRight(Register count, Register input, Register dest) PER_SHARED_ARCH;
inline void rotateRight64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
inline void rotateRight64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, mips64, loongarch64);
inline void rotateRight64(Imm32 count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
inline void rotateRight64(Register count, Register64 input, Register64 dest) DEFINED_ON(x64, loongarch64);
inline void rotateRight64(Imm32 count, Register64 input, Register64 dest, Register temp)
DEFINED_ON(x86, x64, arm, mips32, mips64, loongarch64);
inline void rotateRight64(Register count, Register64 input, Register64 dest, Register temp)
@@ -16,11 +16,6 @@
namespace js {
namespace jit {
static uint32_t CountPhysBits(FloatRegisters::SetType bits) {
MOZ_ASSERT((bits & ~FloatRegisters::AllPhysMask) == 0);
return mozilla::CountPopulation32(uint32_t(bits));
}
Registers::Code Registers::FromName(const char* name) {
for (size_t i = 0; i < TotalPhys; i++) {
if (strcmp(GetName(i), name) == 0) {
@@ -42,47 +37,43 @@ FloatRegisters::Code FloatRegisters::FromName(const char* name) {
}
FloatRegisterSet FloatRegister::ReduceSetForPush(const FloatRegisterSet& s) {
SetType bits = s.bits();
#ifdef ENABLE_WASM_SIMD
# error "Needs more careful logic if SIMD is enabled"
#endif
// Exclude registers already represented by a wider alias. Higher alias banks
// are wider, so preserve only the widest live view of each physical register.
bits &= ~(bits >> (1 * FloatRegisters::TotalPhys));
bits &= ~(bits >> (2 * FloatRegisters::TotalPhys));
return FloatRegisterSet(bits);
LiveFloatRegisterSet ret;
for (FloatRegisterIterator iter(s); iter.more(); ++iter) {
ret.addUnchecked(FromCode((*iter).encoding()));
}
return ret.set();
}
uint32_t FloatRegister::GetSizeInBytes(const FloatRegisterSet& s) {
return s.size() * sizeof(FloatRegisters::RegisterContent);
#ifdef ENABLE_WASM_SIMD
# error "Needs more careful logic if SIMD is enabled"
#endif
return s.size() * sizeof(double);
}
uint32_t FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s) {
SetType all = s.bits();
SetType set128b =
(all >> (uint32_t(FloatRegisters::Simd128) * FloatRegisters::TotalPhys)) &
FloatRegisters::AllPhysMask;
SetType doubleSet =
(all >> (uint32_t(FloatRegisters::Double) * FloatRegisters::TotalPhys)) &
FloatRegisters::AllPhysMask;
SetType singleSet =
(all >> (uint32_t(FloatRegisters::Single) * FloatRegisters::TotalPhys)) &
FloatRegisters::AllPhysMask;
#ifdef ENABLE_WASM_SIMD
# error "Needs more careful logic if SIMD is enabled"
#endif
SetType set64b = doubleSet & ~set128b;
SetType set32b = singleSet & ~set64b & ~set128b;
return CountPhysBits(set128b) * (4 * sizeof(int32_t)) +
CountPhysBits(set64b) * sizeof(double) +
CountPhysBits(set32b) * sizeof(float);
return s.size() * sizeof(double);
}
uint32_t FloatRegister::getRegisterDumpOffsetInBytes() {
return encoding() * sizeof(FloatRegisters::RegisterContent);
#ifdef ENABLE_WASM_SIMD
# error "Needs more careful logic if SIMD is enabled"
#endif
return encoding() * sizeof(double);
}
bool CPUFlagsHaveBeenComputed() {
// The LoongArch64 backend does not currently gate code generation on
// optional CPU features.
// TODO(loongarch64): Add CPU flags support.
return true;
}
@@ -249,9 +249,9 @@ class FloatRegisters {
// Eight bits: (invalid << 7) | (kind << 5) | encoding
typedef uint8_t Code;
typedef FPRegisterID Encoding;
typedef unsigned __int128 SetType;
typedef uint64_t SetType;
enum Kind : uint8_t { Double, Single, Simd128, NumTypes };
enum Kind : uint8_t { Double, Single, NumTypes };
static constexpr Code Invalid = 0x80;
@@ -285,11 +285,7 @@ class FloatRegisters {
<< (uint32_t(Single) * TotalPhys);
static const SetType SpreadDouble = SetType(1)
<< (uint32_t(Double) * TotalPhys);
static const SetType SpreadSimd128 = SetType(1)
<< (uint32_t(Simd128) * TotalPhys);
static const SetType SpreadScalar = SpreadSingle | SpreadDouble;
static const SetType SpreadVector = SpreadSimd128;
static const SetType Spread = SpreadScalar | SpreadVector;
static const SetType Spread = SpreadSingle | SpreadDouble;
static const SetType AllPhysMask = ((SetType(1) << TotalPhys) - 1);
static const SetType AllMask = AllPhysMask * Spread;
@@ -297,16 +293,13 @@ class FloatRegisters {
static const SetType AllDoubleMask = AllPhysMask * SpreadDouble;
static const SetType NoneMask = SetType(0);
// LoongArch64 callee-saved floating-point registers are f24-f31.
// TODO(loongarch64): Much less than ARM64 here.
static const SetType NonVolatileMask =
((SetType(1) << FloatRegisters::f24) |
(SetType(1) << FloatRegisters::f25) |
(SetType(1) << FloatRegisters::f26) |
(SetType(1) << FloatRegisters::f27) |
(SetType(1) << FloatRegisters::f28) |
(SetType(1) << FloatRegisters::f29) |
(SetType(1) << FloatRegisters::f30) |
(SetType(1) << FloatRegisters::f31)) * Spread;
SetType((1 << FloatRegisters::f24) | (1 << FloatRegisters::f25) |
(1 << FloatRegisters::f26) | (1 << FloatRegisters::f27) |
(1 << FloatRegisters::f28) | (1 << FloatRegisters::f29) |
(1 << FloatRegisters::f30) | (1 << FloatRegisters::f31)) *
Spread;
static const SetType VolatileMask = AllMask & ~NonVolatileMask;
@@ -324,8 +317,6 @@ class FloatRegisters {
union RegisterContent {
float s;
double d;
int32_t i4[4];
float s4[4];
};
static constexpr Encoding encoding(Code c) {
@@ -368,35 +359,26 @@ struct FloatRegister {
typedef Codes::SetType SetType;
static uint32_t SetSize(SetType x) {
static_assert(sizeof(SetType) == 16, "SetType must be 128 bits");
static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
x |= x >> FloatRegisters::TotalPhys;
x |= x >> (2 * FloatRegisters::TotalPhys);
x &= FloatRegisters::AllPhysMask;
return mozilla::CountPopulation32(x);
}
static uint32_t FirstBit(SetType x) {
MOZ_ASSERT(x != 0);
uint64_t low = uint64_t(x);
if (low) {
return mozilla::CountTrailingZeroes64(low);
}
return 64 + mozilla::CountTrailingZeroes64(uint64_t(x >> 64));
static_assert(sizeof(SetType) == 8, "SetType");
return mozilla::CountTrailingZeroes64(x);
}
static uint32_t LastBit(SetType x) {
MOZ_ASSERT(x != 0);
uint64_t high = uint64_t(x >> 64);
if (high) {
return 127 - mozilla::CountLeadingZeroes64(high);
}
return 63 - mozilla::CountLeadingZeroes64(uint64_t(x));
static_assert(sizeof(SetType) == 8, "SetType");
return 63 - mozilla::CountLeadingZeroes64(x);
}
private:
// These fields only hold valid values: an invalid register is always
// represented as a valid encoding and kind with the invalid_ bit set.
uint8_t encoding_; // 32 encodings
uint8_t kind_; // Double, Single, Simd128
uint8_t kind_; // Double, Single; more later
bool invalid_;
typedef Codes::Kind Kind;
@@ -405,8 +387,6 @@ struct FloatRegister {
union RegisterContent {
float s;
double d;
int32_t i4[4];
float s4[4];
};
constexpr FloatRegister(Encoding encoding, Kind kind)
@@ -437,7 +417,7 @@ struct FloatRegister {
}
bool isSimd128() const {
MOZ_ASSERT(!invalid_);
return kind_ == FloatRegisters::Simd128;
return false;
}
bool isInvalid() const { return invalid_; }
@@ -450,19 +430,13 @@ struct FloatRegister {
return FloatRegister(Encoding(encoding_), FloatRegisters::Double);
}
FloatRegister doubleOverlay() const { return asDouble(); }
FloatRegister asSimd128() const {
MOZ_ASSERT(!invalid_);
return FloatRegister(Encoding(encoding_), FloatRegisters::Simd128);
}
FloatRegister asSimd128() const { MOZ_CRASH(); }
constexpr uint32_t size() const {
MOZ_ASSERT(!invalid_);
if (kind_ == FloatRegisters::Double) {
return sizeof(double);
}
if (kind_ == FloatRegisters::Simd128) {
return 4 * sizeof(int32_t);
}
MOZ_ASSERT(kind_ == FloatRegisters::Single);
return sizeof(float);
}
+17 -598
View File
@@ -49,6 +49,11 @@ void js::jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
// Note this is used for inter-wasm calls and may pass arguments and results
// in floating point registers even if the system ABI does not.
// TODO(loongarch64): Inconsistent with LoongArch's calling convention.
// LoongArch floating-point parameters calling convention:
// The first eight floating-point parameters should be passed in f0-f7, and
// the other floating point parameters will be passed like integer parameters.
// But we just pass the other floating-point parameters on stack here.
ABIArg ABIArgGenerator::next(MIRType type) {
switch (type) {
case MIRType::Int32:
@@ -65,40 +70,16 @@ ABIArg ABIArgGenerator::next(MIRType type) {
}
case MIRType::Float32:
case MIRType::Double: {
if (floatRegIndex_ < NumFloatArgRegs) {
current_ = ABIArg(FloatRegister(
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
type == MIRType::Double ? FloatRegisters::Double
: FloatRegisters::Single));
floatRegIndex_++;
break;
}
if (intRegIndex_ == NumIntArgRegs) {
if (floatRegIndex_ == NumFloatArgRegs) {
current_ = ABIArg(stackOffset_);
stackOffset_ += sizeof(double);
break;
}
current_ = ABIArg(Register::FromCode(intRegIndex_ + a0.encoding()));
intRegIndex_++;
break;
}
case MIRType::Int8x16:
case MIRType::Int16x8:
case MIRType::Int32x4:
case MIRType::Float32x4:
case MIRType::Bool8x16:
case MIRType::Bool16x8:
case MIRType::Bool32x4: {
if (floatRegIndex_ < NumFloatArgRegs) {
current_ = ABIArg(FloatRegister(
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
FloatRegisters::Simd128));
floatRegIndex_++;
break;
}
stackOffset_ = AlignBytes(stackOffset_, SimdMemoryAlignment);
current_ = ABIArg(stackOffset_);
stackOffset_ += Simd128DataSize;
current_ = ABIArg(FloatRegister(
FloatRegisters::Encoding(floatRegIndex_ + f0.encoding()),
type == MIRType::Double ? FloatRegisters::Double
: FloatRegisters::Single));
floatRegIndex_++;
break;
}
default:
@@ -353,19 +334,8 @@ void AssemblerLOONGARCH64::WriteInstStatic(uint32_t x, uint32_t* dest) {
}
BufferOffset AssemblerLOONGARCH64::haltingAlign(int alignment) {
BufferOffset ret;
MOZ_ASSERT(m_buffer.isAligned(4));
MOZ_ASSERT((alignment & (alignment - 1)) == 0);
while (size() & (alignment - 1)) {
BufferOffset tmp(size());
as_break(WASM_TRAP);
if (!ret.assigned()) {
ret = tmp;
}
}
return ret;
// TODO(loongarch64): Implement a proper halting align.
return nopAlign(alignment);
}
BufferOffset AssemblerLOONGARCH64::nopAlign(int alignment) {
@@ -466,30 +436,10 @@ InstImm AssemblerLOONGARCH64::getBranchCode(JumpOrCall jumpOrCall) {
}
InstImm AssemblerLOONGARCH64::getBranchCode(Register rj, Register rd, Condition c) {
switch (c) {
case AssemblerLOONGARCH64::Equal:
return InstImm(op_beq, BOffImm16(0), rj, rd);
case AssemblerLOONGARCH64::NotEqual:
return InstImm(op_bne, BOffImm16(0), rj, rd);
case AssemblerLOONGARCH64::Above:
return InstImm(op_bltu, BOffImm16(0), rd, rj);
case AssemblerLOONGARCH64::AboveOrEqual:
return InstImm(op_bgeu, BOffImm16(0), rj, rd);
case AssemblerLOONGARCH64::Below:
return InstImm(op_bltu, BOffImm16(0), rj, rd);
case AssemblerLOONGARCH64::BelowOrEqual:
return InstImm(op_bgeu, BOffImm16(0), rd, rj);
case AssemblerLOONGARCH64::GreaterThan:
return InstImm(op_blt, BOffImm16(0), rd, rj);
case AssemblerLOONGARCH64::GreaterThanOrEqual:
return InstImm(op_bge, BOffImm16(0), rj, rd);
case AssemblerLOONGARCH64::LessThan:
return InstImm(op_blt, BOffImm16(0), rj, rd);
case AssemblerLOONGARCH64::LessThanOrEqual:
return InstImm(op_bge, BOffImm16(0), rd, rj);
default:
MOZ_CRASH("Condition not supported.");
}
// beq, bne
MOZ_ASSERT(c == AssemblerLOONGARCH64::Equal || c == AssemblerLOONGARCH64::NotEqual);
return InstImm(c == AssemblerLOONGARCH64::Equal ? op_beq : op_bne, BOffImm16(0),
rj, rd);
}
InstImm AssemblerLOONGARCH64::getBranchCode(Register rj, Condition c) {
@@ -1060,118 +1010,6 @@ BufferOffset AssemblerLOONGARCH64::as_st_d(Register rd, Register rj, int32_t si1
return writeInst(InstImm(op_st_d, si12, rj, rd, 12).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vld(FloatRegister vd, Register rj,
int32_t si12) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(is_intN(si12, 12));
spew("vld %3s,%3s,0x%x", vd.name(), rj.name(), si12);
return writeInst(InstImm(op_vld, si12, rj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vst(FloatRegister vd, Register rj,
int32_t si12) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(is_intN(si12, 12));
spew("vst %3s,%3s,0x%x", vd.name(), rj.name(), si12);
return writeInst(InstImm(op_vst, si12, rj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_clt_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.clt.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_clt_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_ceq_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.ceq.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_ceq_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cle_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.cle.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_cle_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cun_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.cun.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_cun_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cult_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.cult.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_cult_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cule_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.cule.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_cule_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfcmp_cune_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfcmp.cune.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfcmp_cune_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vbitsel_v(FloatRegister vd,
FloatRegister vj,
FloatRegister vk,
FloatRegister va) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
MOZ_ASSERT(va.isSimd128());
spew("vbitsel.v %3s,%3s,%3s,%3s", vd.name(), vj.name(), vk.name(),
va.name());
return writeInst(InstReg(op_vbitsel_v, va, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vshuf_b(FloatRegister vd,
FloatRegister vj,
FloatRegister vk,
FloatRegister va) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
MOZ_ASSERT(va.isSimd128());
spew("vshuf.b %3s,%3s,%3s,%3s", vd.name(), vj.name(), vk.name(),
va.name());
return writeInst(InstReg(op_vshuf_b, va, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_ldx_b(Register rd, Register rj, Register rk) {
spew("ldx_b %3s,%3s,%3s", rd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_ldx_b, rk, rj, rd).encode());
@@ -1230,425 +1068,6 @@ BufferOffset AssemblerLOONGARCH64::as_stx_d(Register rd, Register rj, Register r
return writeInst(InstReg(op_stx_d, rk, rj, rd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vldx(FloatRegister vd, Register rj,
Register rk) {
MOZ_ASSERT(vd.isSimd128());
spew("vldx %3s,%3s,%3s", vd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_vldx, rk, rj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vstx(FloatRegister vd, Register rj,
Register rk) {
MOZ_ASSERT(vd.isSimd128());
spew("vstx %3s,%3s,%3s", vd.name(), rj.name(), rk.name());
return writeInst(InstReg(op_vstx, rk, rj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vseq_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vseq.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vseq_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vsle_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vsle.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vsle_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vsle_wu(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vsle.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vsle_wu, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vslt_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vslt.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vslt_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vslt_wu(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vslt.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vslt_wu, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vadd_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vadd.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vadd_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vsub_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vsub.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vsub_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vmax_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vmax.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vmax_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vmin_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vmin.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vmin_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vmax_wu(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vmax.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vmax_wu, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vmin_wu(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vmin.wu %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vmin_wu, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vmul_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vmul.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vmul_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vsll_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vsll.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vsll_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vsrl_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vsrl.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vsrl_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vsra_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vsra.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vsra_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vilvl_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vilvl.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vilvl_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vilvh_w(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vilvh.w %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vilvh_w, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vand_v(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vand.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vand_v, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vor_v(FloatRegister vd, FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vor.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vor_v, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vxor_v(FloatRegister vd, FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vxor.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vxor_v, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vnor_v(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vnor.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vnor_v, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vandn_v(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vandn.v %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vandn_v, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfadd_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfadd.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfadd_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfsub_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfsub.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfsub_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfmul_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfmul.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfmul_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfmax_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfmax.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfmax_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vfmin_s(FloatRegister vd,
FloatRegister vj,
FloatRegister vk) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(vk.isSimd128());
spew("vfmin.s %3s,%3s,%3s", vd.name(), vj.name(), vk.name());
return writeInst(InstReg(op_vfmin_s, vk, vj, vd).encode());
}
BufferOffset AssemblerLOONGARCH64::as_vneg_w(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vneg.w %3s,%3s", vd.name(), vj.name());
return writeInst(op_vneg_w | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vfsqrt_s(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vfsqrt.s %3s,%3s", vd.name(), vj.name());
return writeInst(op_vfsqrt_s | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vfrecip_s(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vfrecip.s %3s,%3s", vd.name(), vj.name());
return writeInst(op_vfrecip_s | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vfrsqrt_s(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vfrsqrt.s %3s,%3s", vd.name(), vj.name());
return writeInst(op_vfrsqrt_s | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vfrint_s(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vfrint.s %3s,%3s", vd.name(), vj.name());
return writeInst(op_vfrint_s | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vffint_s_w(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vffint.s.w %3s,%3s", vd.name(), vj.name());
return writeInst(op_vffint_s_w | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vftint_w_s(FloatRegister vd,
FloatRegister vj) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
spew("vftint.w.s %3s,%3s", vd.name(), vj.name());
return writeInst(op_vftint_w_s | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vreplgr2vr_w(FloatRegister vd,
Register rj) {
MOZ_ASSERT(vd.isSimd128());
spew("vreplgr2vr.w %3s,%3s", vd.name(), rj.name());
return writeInst(op_vreplgr2vr_w | RJ(rj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vreplvei_w(FloatRegister vd,
FloatRegister vj,
uint32_t lane) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(lane < 4);
spew("vreplvei.w %3s,%3s,%u", vd.name(), vj.name(), lane);
return writeInst(op_vreplvei_w | (lane << RKShift) | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vinsgr2vr_w(FloatRegister vd,
Register rj,
uint32_t lane) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(lane < 4);
spew("vinsgr2vr.w %3s,%3s,%u", vd.name(), rj.name(), lane);
return writeInst(op_vinsgr2vr_w | (lane << RKShift) | RJ(rj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vpickve2gr_w(Register rd,
FloatRegister vj,
uint32_t lane) {
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(lane < 4);
spew("vpickve2gr.w %3s,%3s,%u", rd.name(), vj.name(), lane);
return writeInst(op_vpickve2gr_w | (lane << RKShift) | FJ(vj) | RD(rd));
}
BufferOffset AssemblerLOONGARCH64::as_vpickve2gr_wu(Register rd,
FloatRegister vj,
uint32_t lane) {
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(lane < 4);
spew("vpickve2gr.wu %3s,%3s,%u", rd.name(), vj.name(), lane);
return writeInst(op_vpickve2gr_wu | (lane << RKShift) | FJ(vj) | RD(rd));
}
BufferOffset AssemblerLOONGARCH64::as_vslli_w(FloatRegister vd,
FloatRegister vj,
uint32_t imm) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(imm < 32);
spew("vslli.w %3s,%3s,%u", vd.name(), vj.name(), imm);
return writeInst(op_vslli_w | (imm << RKShift) | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vsrli_w(FloatRegister vd,
FloatRegister vj,
uint32_t imm) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(imm < 32);
spew("vsrli.w %3s,%3s,%u", vd.name(), vj.name(), imm);
return writeInst(op_vsrli_w | (imm << RKShift) | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vsrai_w(FloatRegister vd,
FloatRegister vj,
uint32_t imm) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(vj.isSimd128());
MOZ_ASSERT(imm < 32);
spew("vsrai.w %3s,%3s,%u", vd.name(), vj.name(), imm);
return writeInst(op_vsrai_w | (imm << RKShift) | FJ(vj) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_vldi(FloatRegister vd, int32_t imm) {
MOZ_ASSERT(vd.isSimd128());
MOZ_ASSERT(is_intN(imm, 13));
spew("vldi %3s,%d", vd.name(), imm);
return writeInst(op_vldi | ((imm & Imm13Mask) << Imm13Shift) | FD(vd));
}
BufferOffset AssemblerLOONGARCH64::as_ldptr_w(Register rd, Register rj,
int32_t si14) {
MOZ_ASSERT(is_intN(si14, 16) && ((si14 & 0x3) == 0));
+12 -147
View File
@@ -101,8 +101,7 @@ static constexpr Register64 ReturnReg64(ReturnReg);
static constexpr FloatRegister ReturnFloat32Reg{FloatRegisters::f0,
FloatRegisters::Single};
static constexpr FloatRegister ReturnDoubleReg = f0;
static constexpr FloatRegister ReturnSimd128Reg{FloatRegisters::f0,
FloatRegisters::Simd128};
static constexpr FloatRegister ReturnSimd128Reg = InvalidFloatReg;
static constexpr Register ScratchRegister = t7;
static constexpr Register SecondScratchReg = t8;
@@ -122,8 +121,7 @@ struct SecondScratchRegisterScope : public AutoRegisterScope {
static constexpr FloatRegister ScratchFloat32Reg{FloatRegisters::f23,
FloatRegisters::Single};
static constexpr FloatRegister ScratchDoubleReg = f23;
static constexpr FloatRegister ScratchSimd128Reg{FloatRegisters::f23,
FloatRegisters::Simd128};
static constexpr FloatRegister ScratchSimd128Reg = InvalidFloatReg;
struct ScratchFloat32Scope : public AutoFloatRegisterScope {
explicit ScratchFloat32Scope(MacroAssembler& masm)
@@ -228,20 +226,11 @@ static constexpr Register WasmJitEntryReturnScratch = t1;
static constexpr uint32_t ABIStackAlignment = 16;
static constexpr uint32_t CodeAlignment = 16;
// Does this architecture support SIMD conversions between Uint32x4 and
// Float32x4?
static constexpr bool SupportsUint32x4FloatConversions = false;
// Does this architecture support comparisons of unsigned integer vectors?
static constexpr bool SupportsUint8x16Compares = false;
static constexpr bool SupportsUint16x8Compares = false;
static constexpr bool SupportsUint32x4Compares = false;
// This boolean indicates whether we support SIMD instructions flavoured for
// this architecture or not. Rather than a method in the LIRGenerator, it is
// here such that it is accessible from the entire codebase. Once full support
// for SIMD is reached on all tier-1 platforms, this constant can be deleted.
static constexpr bool SupportsSimd = true;
static constexpr bool SupportsSimd = false;
static constexpr uint32_t JitStackAlignment = 16;
static constexpr uint32_t JitStackValueAlignment =
@@ -250,8 +239,8 @@ static_assert(JitStackAlignment % sizeof(Value) == 0 &&
JitStackValueAlignment >= 1,
"Stack alignment should be a non-zero multiple of sizeof(Value)");
// LoongArch LSX SIMD vectors are 128 bits wide, so use 16-byte alignment for
// SIMD constants and wasm stack alignment even while SIMD codegen is disabled.
// TODO(loongarch64): this is just a filler to prevent a build failure. The
// LoongArch SIMD alignment requirements still need to be explored.
static constexpr uint32_t SimdMemoryAlignment = 16;
static_assert(CodeAlignment % SimdMemoryAlignment == 0,
@@ -271,8 +260,9 @@ static constexpr uint32_t WasmCheckedTailEntryOffset = 16u;
static constexpr Scale ScalePointer = TimesEight;
// LoongArch instruction encoding constants. The assembler models the encodings
// used by this backend as register, immediate, and jump instruction records.
// TODO(loongarch64): Add LoongArch instruction types description.
// LoongArch instruction encoding constants.
static const uint32_t RJShift = 5;
static const uint32_t RJBits = 5;
static const uint32_t RKShift = 10;
@@ -313,8 +303,6 @@ static const uint32_t Imm6Shift = 10;
static const uint32_t Imm6Bits = 6;
static const uint32_t Imm12Shift = 10;
static const uint32_t Imm12Bits = 12;
static const uint32_t Imm13Shift = 5;
static const uint32_t Imm13Bits = 13;
static const uint32_t Imm14Shift = 10;
static const uint32_t Imm14Bits = 14;
static const uint32_t Imm15Shift = 0;
@@ -345,7 +333,6 @@ static const uint32_t CODEMask = (1 << CODEBits) - 1;
static const uint32_t Imm5Mask = (1 << Imm5Bits) - 1;
static const uint32_t Imm6Mask = (1 << Imm6Bits) - 1;
static const uint32_t Imm12Mask = (1 << Imm12Bits) - 1;
static const uint32_t Imm13Mask = (1 << Imm13Bits) - 1;
static const uint32_t Imm14Mask = (1 << Imm14Bits) - 1;
static const uint32_t Imm15Mask = (1 << Imm15Bits) - 1;
static const uint32_t Imm16Mask = (1 << Imm16Bits) - 1;
@@ -357,11 +344,11 @@ static const uint32_t BOffImm21Mask = ((1 << Imm21Bits) - 1) << Imm21Shift;
static const uint32_t BOffImm26Mask = ((1 << Imm26Bits) - 1) << Imm26Shift;
static const uint32_t RegMask = Registers::Total - 1;
// TODO(loongarch64) Change to syscall?
static const uint32_t MAX_BREAK_CODE = 1024 - 1;
// Use LoongArch BRK for wasm traps and debug breakpoints. Signal handling code
// decodes the BRK immediate to recover the wasm trap kind.
static const uint32_t WASM_TRAP = 6; // BRK_OVERFLOW
// TODO(loongarch64) Change to LoongArch instruction type.
class Instruction;
class InstReg;
class InstImm;
@@ -441,17 +428,6 @@ enum OpcodeField {
op_fst_s = 0xadU << 22,
op_fld_d = 0xaeU << 22,
op_fst_d = 0xafU << 22,
op_vld = 0x2c000000,
op_vst = 0x2c400000,
op_vfcmp_clt_s = 0x0c510000,
op_vfcmp_ceq_s = 0x0c520000,
op_vfcmp_cle_s = 0x0c530000,
op_vfcmp_cun_s = 0x0c540000,
op_vfcmp_cult_s = 0x0c550000,
op_vfcmp_cule_s = 0x0c570000,
op_vfcmp_cune_s = 0x0c5c0000,
op_vbitsel_v = 0x0d100000,
op_vshuf_b = 0x0d500000,
op_bstr_w = 0x3U << 21, // BSTRINS_W & BSTRPICK_W
op_fmadd_s = 0x81U << 20,
op_fmadd_d = 0x82U << 20,
@@ -554,51 +530,6 @@ enum OpcodeField {
op_fldx_d = 0x7068U << 15,
op_fstx_s = 0x7070U << 15,
op_fstx_d = 0x7078U << 15,
op_vldx = 0x38400000,
op_vstx = 0x38440000,
op_vseq_w = 0x70010000,
op_vsle_w = 0x70030000,
op_vsle_wu = 0x70050000,
op_vslt_w = 0x70070000,
op_vslt_wu = 0x70090000,
op_vadd_w = 0x700b0000,
op_vsub_w = 0x700d0000,
op_vmax_w = 0x70710000,
op_vmin_w = 0x70730000,
op_vmax_wu = 0x70750000,
op_vmin_wu = 0x70770000,
op_vmul_w = 0x70850000,
op_vsll_w = 0x70e90000,
op_vsrl_w = 0x70eb0000,
op_vsra_w = 0x70ed0000,
op_vilvl_w = 0x711b0000,
op_vilvh_w = 0x711d0000,
op_vand_v = 0x71260000,
op_vor_v = 0x71268000,
op_vxor_v = 0x71270000,
op_vnor_v = 0x71278000,
op_vandn_v = 0x71280000,
op_vfadd_s = 0x71308000,
op_vfsub_s = 0x71328000,
op_vfmul_s = 0x71388000,
op_vfmax_s = 0x713c8000,
op_vfmin_s = 0x713e8000,
op_vneg_w = 0x729c3800,
op_vfsqrt_s = 0x729ce400,
op_vfrecip_s = 0x729cf400,
op_vfrsqrt_s = 0x729d0400,
op_vfrint_s = 0x729d3400,
op_vffint_s_w = 0x729e0000,
op_vftint_w_s = 0x729e3000,
op_vreplgr2vr_w = 0x729f0800,
op_vreplvei_w = 0x72f7e000,
op_vinsgr2vr_w = 0x72ebe000,
op_vpickve2gr_w = 0x72efe000,
op_vpickve2gr_wu = 0x72f3e000,
op_vslli_w = 0x732c8000,
op_vsrli_w = 0x73308000,
op_vsrai_w = 0x73348000,
op_vldi = 0x73e00000,
op_amswap_w = 0x70c0U << 15,
op_amswap_d = 0x70c1U << 15,
op_amadd_w = 0x70c2U << 15,
@@ -935,8 +866,7 @@ class LOONGBufferWithExecutableCopy : public LOONGBuffer {
class AssemblerLOONGARCH64 : public AssemblerShared {
public:
// Keep the shared condition vocabulary so shared MacroAssembler and
// CodeGenerator code can lower comparisons without per-use remapping.
// TODO(loongarch64): Should we remove these conditions here?
enum Condition {
Equal,
NotEqual,
@@ -1321,26 +1251,6 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
BufferOffset as_st_h(Register rd, Register rj, int32_t si12);
BufferOffset as_st_w(Register rd, Register rj, int32_t si12);
BufferOffset as_st_d(Register rd, Register rj, int32_t si12);
BufferOffset as_vld(FloatRegister vd, Register rj, int32_t si12);
BufferOffset as_vst(FloatRegister vd, Register rj, int32_t si12);
BufferOffset as_vfcmp_clt_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vfcmp_ceq_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vfcmp_cle_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vfcmp_cun_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vfcmp_cult_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vfcmp_cule_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vfcmp_cune_s(FloatRegister vd, FloatRegister vj,
FloatRegister vk);
BufferOffset as_vbitsel_v(FloatRegister vd, FloatRegister vj,
FloatRegister vk, FloatRegister va);
BufferOffset as_vshuf_b(FloatRegister vd, FloatRegister vj, FloatRegister vk,
FloatRegister va);
BufferOffset as_ldx_b(Register rd, Register rj, Register rk);
BufferOffset as_ldx_h(Register rd, Register rj, Register rk);
@@ -1353,51 +1263,6 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
BufferOffset as_stx_h(Register rd, Register rj, Register rk);
BufferOffset as_stx_w(Register rd, Register rj, Register rk);
BufferOffset as_stx_d(Register rd, Register rj, Register rk);
BufferOffset as_vldx(FloatRegister vd, Register rj, Register rk);
BufferOffset as_vstx(FloatRegister vd, Register rj, Register rk);
BufferOffset as_vseq_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vsle_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vsle_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vslt_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vslt_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vadd_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vsub_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vmax_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vmin_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vmax_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vmin_wu(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vmul_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vsll_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vsrl_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vsra_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vilvl_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vilvh_w(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vand_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vor_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vxor_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vnor_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vandn_v(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vfadd_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vfsub_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vfmul_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vfmax_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vfmin_s(FloatRegister vd, FloatRegister vj, FloatRegister vk);
BufferOffset as_vneg_w(FloatRegister vd, FloatRegister vj);
BufferOffset as_vfsqrt_s(FloatRegister vd, FloatRegister vj);
BufferOffset as_vfrecip_s(FloatRegister vd, FloatRegister vj);
BufferOffset as_vfrsqrt_s(FloatRegister vd, FloatRegister vj);
BufferOffset as_vfrint_s(FloatRegister vd, FloatRegister vj);
BufferOffset as_vffint_s_w(FloatRegister vd, FloatRegister vj);
BufferOffset as_vftint_w_s(FloatRegister vd, FloatRegister vj);
BufferOffset as_vreplgr2vr_w(FloatRegister vd, Register rj);
BufferOffset as_vreplvei_w(FloatRegister vd, FloatRegister vj, uint32_t lane);
BufferOffset as_vinsgr2vr_w(FloatRegister vd, Register rj, uint32_t lane);
BufferOffset as_vpickve2gr_w(Register rd, FloatRegister vj, uint32_t lane);
BufferOffset as_vpickve2gr_wu(Register rd, FloatRegister vj, uint32_t lane);
BufferOffset as_vslli_w(FloatRegister vd, FloatRegister vj, uint32_t imm);
BufferOffset as_vsrli_w(FloatRegister vd, FloatRegister vj, uint32_t imm);
BufferOffset as_vsrai_w(FloatRegister vd, FloatRegister vj, uint32_t imm);
BufferOffset as_vldi(FloatRegister vd, int32_t imm);
BufferOffset as_ldptr_w(Register rd, Register rj, int32_t si14);
BufferOffset as_ldptr_d(Register rd, Register rj, int32_t si14);
@@ -1614,7 +1479,7 @@ class AssemblerLOONGARCH64 : public AssemblerShared {
return false;
#endif
}
static bool SupportsSimd() { return true; }
static bool SupportsSimd() { return false; }
static bool SupportsUnalignedAccesses() { return true; }
static bool SupportsFastUnalignedFPAccesses() { return true; }
@@ -833,14 +833,7 @@ CodeGeneratorLoongArch64::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir)
else
masm.ma_sll(output, ToRegister(input), Imm32(0));
} else {
if (input->isMemory())
masm.load32(Address(ToAddress(input).base,
ToAddress(input).offset + sizeof(int32_t)),
output);
else {
masm.ma_dsrl(output, ToRegister(input), Imm32(32));
masm.ma_sll(output, output, Imm32(0));
}
MOZ_CRASH("Not implemented.");
}
}
@@ -1017,37 +1010,15 @@ CodeGeneratorLoongArch64::visitTestI64AndBranch(LTestI64AndBranch* lir)
emitBranch(input.reg, Imm32(0), Assembler::NonZero, ifTrue, ifFalse);
}
void
CodeGeneratorLoongArch64::visitWasmStackArg(LWasmStackArg* ins)
{
MIRType type = ins->mir()->input()->type();
if (IsSimdType(type)) {
MOZ_ASSERT(ins->arg()->isFloatReg());
Address dst(StackPointer, ins->mir()->spOffset());
FloatRegister src = ToFloatRegister(ins->arg()).asSimd128();
if (type == MIRType::Float32x4)
masm.storeAlignedSimd128Float(src, dst);
else
masm.storeAlignedSimd128Int(src, dst);
return;
}
CodeGeneratorMIPSShared::visitWasmStackArg(ins);
}
void
CodeGeneratorLoongArch64::setReturnDoubleRegs(LiveRegisterSet* regs)
{
MOZ_ASSERT(ReturnFloat32Reg.encoding() == FloatRegisters::f0);
MOZ_ASSERT(ReturnDoubleReg.encoding() == FloatRegisters::f0);
MOZ_ASSERT(ReturnSimd128Reg.encoding() == FloatRegisters::f0);
FloatRegister f1 = { FloatRegisters::f1, FloatRegisters::Single };
regs->add(ReturnFloat32Reg);
regs->add(f1);
regs->add(ReturnDoubleReg);
regs->add(ReturnSimd128Reg);
}
void
@@ -65,7 +65,6 @@ class CodeGeneratorLoongArch64 : public CodeGeneratorMIPSShared
void visitWasmUnalignedLoadI64(LWasmUnalignedLoadI64* lir);
void visitWasmStoreI64(LWasmStoreI64* ins);
void visitWasmUnalignedStoreI64(LWasmUnalignedStoreI64* ins);
void visitWasmStackArg(LWasmStackArg* ins);
void visitWasmLoadGlobalVarI64(LWasmLoadGlobalVarI64* ins);
void visitWasmStoreGlobalVarI64(LWasmStoreGlobalVarI64* ins);
void visitWasmSelectI64(LWasmSelectI64* ins);
@@ -6,8 +6,6 @@
#include "jit/loongarch64/MacroAssembler-loongarch64.h"
#include <cstring>
#include "jsmath.h"
#include "jit/Bailouts.h"
@@ -957,13 +955,8 @@ void MacroAssemblerLOONGARCH64::ma_subPtrTestOverflow(Register rd, Register rj,
void MacroAssemblerLOONGARCH64::ma_subPtrTestOverflow(Register rd, Register rj,
Imm32 imm, Label* overflow) {
if (imm.value == INT32_MIN) {
SecondScratchRegisterScope scratch2(asMasm());
ma_li(scratch2, imm);
ma_subPtrTestOverflow(rd, rj, scratch2, overflow);
return;
}
// TODO(loongarch64): Check subPtrTestOverflow
MOZ_ASSERT(imm.value != INT32_MIN);
ma_addPtrTestOverflow(rd, rj, Imm32(-imm.value), overflow);
}
@@ -1301,20 +1294,10 @@ void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Register rj, ImmPtr imm,
void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Address address, Imm32 imm,
Condition c) {
// TODO(loongarch64): 32-bit ma_cmp_set?
SecondScratchRegisterScope scratch2(asMasm());
switch (c) {
case Above:
case AboveOrEqual:
case Below:
case BelowOrEqual:
ma_ld_wu(scratch2, address);
ma_cmp_set(rd, Register(scratch2), ImmWord(uint32_t(imm.value)), c);
break;
default:
ma_ld_w(scratch2, address);
ma_cmp_set(rd, Register(scratch2), imm, c);
break;
}
ma_ld_w(scratch2, address);
ma_cmp_set(rd, Register(scratch2), imm, c);
}
void MacroAssemblerLOONGARCH64::ma_cmp_set(Register rd, Address address,
@@ -1401,36 +1384,6 @@ void MacroAssemblerLOONGARCH64::ma_fst_d(FloatRegister src, Address address) {
}
}
void MacroAssemblerLOONGARCH64::ma_vld(FloatRegister dest, Address address) {
MOZ_ASSERT(dest.isSimd128());
int32_t offset = address.offset;
Register base = address.base;
if (is_intN(offset, 12)) {
as_vld(dest, base, offset);
} else {
ScratchRegisterScope scratch(asMasm());
MOZ_ASSERT(base != scratch);
ma_li(scratch, Imm32(offset));
as_vldx(dest, base, scratch);
}
}
void MacroAssemblerLOONGARCH64::ma_vst(FloatRegister src, Address address) {
MOZ_ASSERT(src.isSimd128());
int32_t offset = address.offset;
Register base = address.base;
if (is_intN(offset, 12)) {
as_vst(src, base, offset);
} else {
ScratchRegisterScope scratch(asMasm());
MOZ_ASSERT(base != scratch);
ma_li(scratch, Imm32(offset));
as_vstx(src, base, scratch);
}
}
void MacroAssemblerLOONGARCH64::ma_pop(FloatRegister f) {
if (f.isDouble()) {
as_fld_d(f, StackPointer, 0);
@@ -1894,19 +1847,12 @@ void MacroAssemblerLOONGARCH64::storeUnalignedFloat32(
}
// Branches when done from within loongarch-specific code.
// TODO(loongarch64) Optimize ma_b
void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
Condition c, JumpKind jumpKind) {
switch (c) {
case Equal:
case NotEqual:
case Above:
case AboveOrEqual:
case Below:
case BelowOrEqual:
case GreaterThan:
case GreaterThanOrEqual:
case LessThan:
case LessThanOrEqual:
asMasm().branchWithCode(getBranchCode(lhs, rhs, c), label, jumpKind);
break;
case Always:
@@ -1919,8 +1865,12 @@ void MacroAssemblerLOONGARCH64::ma_b(Register lhs, Register rhs, Label* label,
MOZ_ASSERT(lhs == rhs);
asMasm().branchWithCode(getBranchCode(lhs, c), label, jumpKind);
break;
default:
MOZ_CRASH("Invalid condition.");
default: {
Condition cond = ma_cmp(ScratchRegister, lhs, rhs, c);
asMasm().branchWithCode(getBranchCode(ScratchRegister, cond), label,
jumpKind);
break;
}
}
}
@@ -2096,12 +2046,6 @@ void MacroAssemblerLOONGARCH64::ma_fst_s(FloatRegister ft, BaseIndex address) {
asMasm().ma_fst_s(ft, Address(scratch2, address.offset));
}
void MacroAssemblerLOONGARCH64::ma_vst(FloatRegister ft, BaseIndex address) {
SecondScratchRegisterScope scratch2(asMasm());
asMasm().computeScaledAddress(address, scratch2);
asMasm().ma_vst(ft, Address(scratch2, address.offset));
}
void MacroAssemblerLOONGARCH64::ma_fld_d(FloatRegister ft, const BaseIndex& src) {
SecondScratchRegisterScope scratch2(asMasm());
asMasm().computeScaledAddress(src, scratch2);
@@ -2114,12 +2058,6 @@ void MacroAssemblerLOONGARCH64::ma_fld_s(FloatRegister ft, const BaseIndex& src)
asMasm().ma_fld_s(ft, Address(scratch2, src.offset));
}
void MacroAssemblerLOONGARCH64::ma_vld(FloatRegister ft, const BaseIndex& src) {
SecondScratchRegisterScope scratch2(asMasm());
asMasm().computeScaledAddress(src, scratch2);
asMasm().ma_vld(ft, Address(scratch2, src.offset));
}
void MacroAssemblerLOONGARCH64::ma_bc_s(FloatRegister lhs, FloatRegister rhs,
Label* label, DoubleCondition c,
JumpKind jumpKind, FPConditionBit fcc) {
@@ -2452,390 +2390,6 @@ void MacroAssemblerLOONGARCH64::loadFloat32(const BaseIndex& src,
asMasm().ma_fld_s(dest, src);
}
void MacroAssemblerLOONGARCH64::loadUnalignedSimd128Float(const Address& src,
FloatRegister dest) {
asMasm().ma_vld(dest.asSimd128(), src);
}
void MacroAssemblerLOONGARCH64::loadUnalignedSimd128Float(const BaseIndex& src,
FloatRegister dest) {
asMasm().ma_vld(dest.asSimd128(), src);
}
void MacroAssemblerLOONGARCH64::storeUnalignedSimd128Float(FloatRegister src,
const Address& dest) {
asMasm().ma_vst(src.asSimd128(), dest);
}
void MacroAssemblerLOONGARCH64::storeUnalignedSimd128Float(FloatRegister src,
const BaseIndex& dest) {
asMasm().ma_vst(src.asSimd128(), dest);
}
void MacroAssemblerLOONGARCH64::loadConstantSimd128Int(const SimdConstant& v,
FloatRegister dest) {
uint64_t words[2];
memcpy(words, v.bytes(), sizeof(words));
ma_add_d(StackPointer, StackPointer, Imm32(-Simd128DataSize));
{
ScratchRegisterScope scratch(asMasm());
ma_li(scratch, ImmWord(words[0]));
ma_st_d(scratch, Address(StackPointer, 0));
ma_li(scratch, ImmWord(words[1]));
ma_st_d(scratch, Address(StackPointer, sizeof(uint64_t)));
}
loadAlignedSimd128Int(Address(StackPointer, 0), dest);
ma_add_d(StackPointer, StackPointer, Imm32(Simd128DataSize));
}
void MacroAssemblerLOONGARCH64::loadConstantSimd128Float(const SimdConstant& v,
FloatRegister dest) {
loadConstantSimd128Int(v, dest);
}
void MacroAssemblerLOONGARCH64::moveSimd128Float(FloatRegister src,
FloatRegister dest) {
src = src.asSimd128();
dest = dest.asSimd128();
if (src == dest) {
return;
}
as_vor_v(dest, src, src);
}
void MacroAssemblerLOONGARCH64::zeroSimd128Float(FloatRegister dest) {
dest = dest.asSimd128();
as_vxor_v(dest, dest, dest);
}
void MacroAssemblerLOONGARCH64::createInt32x4(Register lane0, Register lane1,
Register lane2, Register lane3,
FloatRegister dest) {
dest = dest.asSimd128();
as_vreplgr2vr_w(dest, lane0);
as_vinsgr2vr_w(dest, lane1, 1);
as_vinsgr2vr_w(dest, lane2, 2);
as_vinsgr2vr_w(dest, lane3, 3);
}
void MacroAssemblerLOONGARCH64::splatX4(Register input, FloatRegister output) {
as_vreplgr2vr_w(output.asSimd128(), input);
}
void MacroAssemblerLOONGARCH64::splatX4(FloatRegister input,
FloatRegister output) {
as_vreplvei_w(output.asSimd128(), input.asSimd128(), 0);
}
void MacroAssemblerLOONGARCH64::extractLaneInt32x4(FloatRegister input,
Register output,
unsigned lane) {
as_vpickve2gr_w(output, input.asSimd128(), lane);
}
void MacroAssemblerLOONGARCH64::extractLaneFloat32x4(FloatRegister input,
FloatRegister output,
unsigned lane,
bool canonicalize) {
ScratchRegisterScope scratch(asMasm());
as_vpickve2gr_w(scratch, input.asSimd128(), lane);
moveToFloat32(scratch, output);
if (canonicalize) {
asMasm().canonicalizeFloat(output);
}
}
void MacroAssemblerLOONGARCH64::insertLaneSimdInt(FloatRegister input,
Register value,
FloatRegister output,
unsigned lane,
unsigned numLanes) {
MOZ_ASSERT(numLanes == 4);
if (input != output) {
moveSimd128Int(input, output);
}
as_vinsgr2vr_w(output.asSimd128(), value, lane);
}
void MacroAssemblerLOONGARCH64::insertLaneFloat32x4(FloatRegister input,
FloatRegister value,
FloatRegister output,
unsigned lane) {
if (input != output) {
moveSimd128Float(input, output);
}
ScratchRegisterScope scratch(asMasm());
moveFromFloat32(value, scratch);
as_vinsgr2vr_w(output.asSimd128(), scratch, lane);
}
void MacroAssemblerLOONGARCH64::addInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vadd_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::subInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vsub_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::mulInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vmul_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::minInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vmin_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::maxInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vmax_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::minUint32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vmin_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::maxUint32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vmax_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::negInt32x4(FloatRegister input,
FloatRegister dest) {
as_vneg_w(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::shiftLeftInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vsll_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::shiftRightInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vsra_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::unsignedShiftRightInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vsrl_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::shiftLeftInt32x4(FloatRegister lhs, Imm32 rhs,
FloatRegister dest) {
as_vslli_w(dest.asSimd128(), lhs.asSimd128(), rhs.value & 31);
}
void MacroAssemblerLOONGARCH64::shiftRightInt32x4(FloatRegister lhs, Imm32 rhs,
FloatRegister dest) {
as_vsrai_w(dest.asSimd128(), lhs.asSimd128(), rhs.value & 31);
}
void MacroAssemblerLOONGARCH64::unsignedShiftRightInt32x4(FloatRegister lhs,
Imm32 rhs,
FloatRegister dest) {
as_vsrli_w(dest.asSimd128(), lhs.asSimd128(), rhs.value & 31);
}
void MacroAssemblerLOONGARCH64::compareInt32x4Equal(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vseq_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareInt32x4LessThan(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vslt_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareInt32x4LessThanOrEqual(
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
as_vsle_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareUint32x4LessThan(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vslt_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareUint32x4LessThanOrEqual(
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
as_vsle_wu(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::addFloat32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfadd_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::subFloat32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfsub_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::mulFloat32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfmul_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::minFloat32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfmin_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::maxFloat32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfmax_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::sqrtFloat32x4(FloatRegister input,
FloatRegister dest) {
as_vfsqrt_s(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::reciprocalApproximationFloat32x4(
FloatRegister input, FloatRegister dest) {
as_vfrecip_s(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::reciprocalSqrtApproximationFloat32x4(
FloatRegister input, FloatRegister dest) {
as_vfrsqrt_s(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::roundFloat32x4(FloatRegister input,
FloatRegister dest) {
as_vfrint_s(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::convertInt32x4ToFloat32x4(FloatRegister input,
FloatRegister dest) {
as_vffint_s_w(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::convertFloat32x4ToInt32x4(FloatRegister input,
FloatRegister dest) {
as_vftint_w_s(dest.asSimd128(), input.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4Equal(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfcmp_ceq_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4NotEqual(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfcmp_cune_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4LessThan(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfcmp_clt_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4LessThanOrEqual(
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
as_vfcmp_cle_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4Unordered(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vfcmp_cun_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4UnorderedLessThan(
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
as_vfcmp_cult_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::compareFloat32x4UnorderedLessThanOrEqual(
FloatRegister lhs, FloatRegister rhs, FloatRegister dest) {
as_vfcmp_cule_s(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::interleaveLowInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vilvl_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::interleaveHighInt32x4(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vilvh_w(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::bitselectSimd128(FloatRegister mask,
FloatRegister onTrue,
FloatRegister onFalse,
FloatRegister dest) {
as_vbitsel_v(dest.asSimd128(), onFalse.asSimd128(), onTrue.asSimd128(),
mask.asSimd128());
}
void MacroAssemblerLOONGARCH64::shuffleBytesSimd128(FloatRegister lhs,
FloatRegister rhs,
FloatRegister control,
FloatRegister dest) {
as_vshuf_b(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128(),
control.asSimd128());
}
void MacroAssemblerLOONGARCH64::bitwiseAndSimd128(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vand_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::bitwiseOrSimd128(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vor_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::bitwiseXorSimd128(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vxor_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::bitwiseNorSimd128(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vnor_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::bitwiseAndNotSimd128(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest) {
as_vandn_v(dest.asSimd128(), lhs.asSimd128(), rhs.asSimd128());
}
void MacroAssemblerLOONGARCH64::wasmLoadImpl(const wasm::MemoryAccessDesc& access,
Register memoryBase, Register ptr,
Register ptrScratch,
@@ -2962,8 +2516,7 @@ void MacroAssemblerLOONGARCH64Compat::wasmLoadI64Impl(
as_ldx_w(output.reg, memoryBase, ptr);
break;
case Scalar::Uint32:
// Uint32 loads must clear the upper 32 bits before the value is consumed
// by 64-bit wasm operations.
// TODO(loongarch64): Why need zero-extension here?
as_ldx_wu(output.reg, memoryBase, ptr);
break;
case Scalar::Int64:
@@ -3064,18 +2617,14 @@ void MacroAssembler::PushRegsInMask(LiveRegisterSet set) {
storePtr(*iter, Address(StackPointer, diff));
}
#ifdef ENABLE_WASM_SIMD
# error "Needs more careful logic if SIMD is enabled"
#endif
for (FloatRegisterBackwardIterator iter(set.fpus().reduceSetForPush());
iter.more(); ++iter) {
FloatRegister reg = *iter;
diff -= reg.size();
if (reg.isSingle()) {
storeFloat32(reg, Address(StackPointer, diff));
} else if (reg.isSimd128()) {
storeUnalignedSimd128Float(reg, Address(StackPointer, diff));
} else {
MOZ_ASSERT(reg.isDouble());
storeDouble(reg, Address(StackPointer, diff));
}
diff -= sizeof(double);
storeDouble(*iter, Address(StackPointer, diff));
}
MOZ_ASSERT(diff == 0);
}
@@ -3093,19 +2642,15 @@ void MacroAssembler::PopRegsInMaskIgnore(LiveRegisterSet set,
}
}
#ifdef ENABLE_WASM_SIMD
# error "Needs more careful logic if SIMD is enabled"
#endif
for (FloatRegisterBackwardIterator iter(set.fpus().reduceSetForPush());
iter.more(); ++iter) {
FloatRegister reg = *iter;
diff -= reg.size();
diff -= sizeof(double);
if (!ignore.has(*iter)) {
if (reg.isSingle()) {
loadFloat32(Address(StackPointer, diff), reg);
} else if (reg.isSimd128()) {
loadUnalignedSimd128Float(Address(StackPointer, diff), reg);
} else {
MOZ_ASSERT(reg.isDouble());
loadDouble(Address(StackPointer, diff), reg);
}
loadDouble(Address(StackPointer, diff), *iter);
}
}
MOZ_ASSERT(diff == 0);
@@ -199,8 +199,6 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
void ma_fld_d(FloatRegister ft, Address address);
void ma_fst_d(FloatRegister ft, Address address);
void ma_fst_s(FloatRegister ft, Address address);
void ma_vld(FloatRegister vt, Address address);
void ma_vst(FloatRegister vt, Address address);
void ma_pop(FloatRegister f);
void ma_push(FloatRegister f);
@@ -453,11 +451,9 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
void ma_fst_d(FloatRegister src, BaseIndex address);
void ma_fst_s(FloatRegister src, BaseIndex address);
void ma_vst(FloatRegister src, BaseIndex address);
void ma_fld_d(FloatRegister dest, const BaseIndex& src);
void ma_fld_s(FloatRegister dest, const BaseIndex& src);
void ma_vld(FloatRegister dest, const BaseIndex& src);
// FP branches
void ma_bc_s(FloatRegister lhs, FloatRegister rhs, Label* label,
@@ -635,139 +631,6 @@ class MacroAssemblerLOONGARCH64 : public Assembler {
void loadFloat32(const Address& addr, FloatRegister dest);
void loadFloat32(const BaseIndex& src, FloatRegister dest);
void loadUnalignedSimd128Float(const Address& src, FloatRegister dest);
void loadUnalignedSimd128Float(const BaseIndex& src, FloatRegister dest);
void storeUnalignedSimd128Float(FloatRegister src, const Address& dest);
void storeUnalignedSimd128Float(FloatRegister src, const BaseIndex& dest);
void loadAlignedSimd128Float(const Address& src, FloatRegister dest) {
loadUnalignedSimd128Float(src, dest);
}
void loadAlignedSimd128Float(const BaseIndex& src, FloatRegister dest) {
loadUnalignedSimd128Float(src, dest);
}
void storeAlignedSimd128Float(FloatRegister src, const Address& dest) {
storeUnalignedSimd128Float(src, dest);
}
void storeAlignedSimd128Float(FloatRegister src, const BaseIndex& dest) {
storeUnalignedSimd128Float(src, dest);
}
void loadConstantSimd128Float(const SimdConstant& v, FloatRegister dest);
void loadConstantSimd128Int(const SimdConstant& v, FloatRegister dest);
void moveSimd128Float(FloatRegister src, FloatRegister dest);
void moveSimd128Int(FloatRegister src, FloatRegister dest) {
moveSimd128Float(src, dest);
}
void zeroSimd128Float(FloatRegister dest);
void zeroSimd128Int(FloatRegister dest) { zeroSimd128Float(dest); }
void createInt32x4(Register lane0, Register lane1, Register lane2,
Register lane3, FloatRegister dest);
void splatX4(Register input, FloatRegister output);
void splatX4(FloatRegister input, FloatRegister output);
void extractLaneInt32x4(FloatRegister input, Register output, unsigned lane);
void extractLaneFloat32x4(FloatRegister input, FloatRegister output,
unsigned lane, bool canonicalize);
void insertLaneSimdInt(FloatRegister input, Register value,
FloatRegister output, unsigned lane,
unsigned numLanes);
void insertLaneFloat32x4(FloatRegister input, FloatRegister value,
FloatRegister output, unsigned lane);
void addInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void subInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void mulInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void minInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void maxInt32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void minUint32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void maxUint32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void negInt32x4(FloatRegister input, FloatRegister dest);
void shiftLeftInt32x4(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void shiftRightInt32x4(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void unsignedShiftRightInt32x4(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void shiftLeftInt32x4(FloatRegister lhs, Imm32 rhs, FloatRegister dest);
void shiftRightInt32x4(FloatRegister lhs, Imm32 rhs, FloatRegister dest);
void unsignedShiftRightInt32x4(FloatRegister lhs, Imm32 rhs,
FloatRegister dest);
void compareInt32x4Equal(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareInt32x4LessThan(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareInt32x4LessThanOrEqual(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareUint32x4LessThan(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareUint32x4LessThanOrEqual(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void addFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void subFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void mulFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void minFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void maxFloat32x4(FloatRegister lhs, FloatRegister rhs, FloatRegister dest);
void sqrtFloat32x4(FloatRegister input, FloatRegister dest);
void reciprocalApproximationFloat32x4(FloatRegister input, FloatRegister dest);
void reciprocalSqrtApproximationFloat32x4(FloatRegister input,
FloatRegister dest);
void roundFloat32x4(FloatRegister input, FloatRegister dest);
void convertInt32x4ToFloat32x4(FloatRegister input, FloatRegister dest);
void convertFloat32x4ToInt32x4(FloatRegister input, FloatRegister dest);
void compareFloat32x4Equal(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareFloat32x4NotEqual(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareFloat32x4LessThan(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareFloat32x4LessThanOrEqual(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareFloat32x4Unordered(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareFloat32x4UnorderedLessThan(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void compareFloat32x4UnorderedLessThanOrEqual(FloatRegister lhs,
FloatRegister rhs,
FloatRegister dest);
void interleaveLowInt32x4(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void interleaveHighInt32x4(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void bitselectSimd128(FloatRegister mask, FloatRegister onTrue,
FloatRegister onFalse, FloatRegister dest);
void shuffleBytesSimd128(FloatRegister lhs, FloatRegister rhs,
FloatRegister control, FloatRegister dest);
void bitwiseAndSimd128(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void bitwiseOrSimd128(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void bitwiseXorSimd128(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void bitwiseNorSimd128(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void bitwiseAndNotSimd128(FloatRegister lhs, FloatRegister rhs,
FloatRegister dest);
void loadUnalignedSimd128Int(const Address& src, FloatRegister dest) {
loadUnalignedSimd128Float(src, dest);
}
void loadUnalignedSimd128Int(const BaseIndex& src, FloatRegister dest) {
loadUnalignedSimd128Float(src, dest);
}
void loadAlignedSimd128Int(const Address& src, FloatRegister dest) {
loadUnalignedSimd128Float(src, dest);
}
void loadAlignedSimd128Int(const BaseIndex& src, FloatRegister dest) {
loadUnalignedSimd128Float(src, dest);
}
void storeUnalignedSimd128Int(FloatRegister src, const Address& dest) {
storeUnalignedSimd128Float(src, dest);
}
void storeUnalignedSimd128Int(FloatRegister src, const BaseIndex& dest) {
storeUnalignedSimd128Float(src, dest);
}
void storeAlignedSimd128Int(FloatRegister src, const Address& dest) {
storeUnalignedSimd128Float(src, dest);
}
void storeAlignedSimd128Int(FloatRegister src, const BaseIndex& dest) {
storeUnalignedSimd128Float(src, dest);
}
protected:
void wasmLoadImpl(const wasm::MemoryAccessDesc& access, Register memoryBase,
@@ -10,75 +10,6 @@
using namespace js;
using namespace js::jit;
Address
MoveEmitterLoongArch64::cycleSlot(uint32_t slot, uint32_t subslot) const
{
int32_t offset = masm.framePushed() - pushedAtCycle_;
MOZ_ASSERT(Imm16::IsInSignedRange(offset));
return Address(StackPointer, offset + slot * Simd128DataSize + subslot);
}
void
MoveEmitterLoongArch64::emit(const MoveResolver& moves)
{
if (moves.numCycles()) {
masm.reserveStack(moves.numCycles() * Simd128DataSize);
pushedAtCycle_ = masm.framePushed();
}
for (size_t i = 0; i < moves.numMoves(); i++)
emit(moves.getMove(i));
}
void
MoveEmitterLoongArch64::emit(const MoveOp& move)
{
const MoveOperand& from = move.from();
const MoveOperand& to = move.to();
if (move.isCycleEnd() && move.isCycleBegin()) {
breakCycle(from, to, move.endCycleType(), move.cycleBeginSlot());
completeCycle(from, to, move.type(), move.cycleEndSlot());
return;
}
if (move.isCycleEnd()) {
MOZ_ASSERT(inCycle_);
completeCycle(from, to, move.type(), move.cycleEndSlot());
MOZ_ASSERT(inCycle_ > 0);
inCycle_--;
return;
}
if (move.isCycleBegin()) {
breakCycle(from, to, move.endCycleType(), move.cycleBeginSlot());
inCycle_++;
}
switch (move.type()) {
case MoveOp::FLOAT32:
emitFloat32Move(from, to);
break;
case MoveOp::DOUBLE:
emitDoubleMove(from, to);
break;
case MoveOp::INT32:
emitInt32Move(from, to);
break;
case MoveOp::GENERAL:
emitMove(from, to);
break;
case MoveOp::SIMD128INT:
emitSimd128IntMove(from, to);
break;
case MoveOp::SIMD128FLOAT:
emitSimd128FloatMove(from, to);
break;
default:
MOZ_CRASH("Unexpected move type");
}
}
void
MoveEmitterLoongArch64::breakCycle(const MoveOperand& from, const MoveOperand& to,
MoveOp::Type type, uint32_t slotId)
@@ -102,24 +33,6 @@ MoveEmitterLoongArch64::breakCycle(const MoveOperand& from, const MoveOperand& t
masm.storeDouble(to.floatReg(), cycleSlot(slotId));
}
break;
case MoveOp::SIMD128INT:
if (to.isMemory()) {
FloatRegister temp = ScratchSimd128Reg;
masm.loadAlignedSimd128Int(getAdjustedAddress(to), temp);
masm.storeAlignedSimd128Int(temp, cycleSlot(slotId));
} else {
masm.storeAlignedSimd128Int(to.floatReg(), cycleSlot(slotId));
}
break;
case MoveOp::SIMD128FLOAT:
if (to.isMemory()) {
FloatRegister temp = ScratchSimd128Reg;
masm.loadAlignedSimd128Float(getAdjustedAddress(to), temp);
masm.storeAlignedSimd128Float(temp, cycleSlot(slotId));
} else {
masm.storeAlignedSimd128Float(to.floatReg(), cycleSlot(slotId));
}
break;
case MoveOp::INT32:
if (to.isMemory()) {
Register temp = tempReg();
@@ -168,24 +81,6 @@ MoveEmitterLoongArch64::completeCycle(const MoveOperand& from, const MoveOperand
masm.loadDouble(cycleSlot(slotId), to.floatReg());
}
break;
case MoveOp::SIMD128INT:
if (to.isMemory()) {
FloatRegister temp = ScratchSimd128Reg;
masm.loadAlignedSimd128Int(cycleSlot(slotId), temp);
masm.storeAlignedSimd128Int(temp, getAdjustedAddress(to));
} else {
masm.loadAlignedSimd128Int(cycleSlot(slotId), to.floatReg());
}
break;
case MoveOp::SIMD128FLOAT:
if (to.isMemory()) {
FloatRegister temp = ScratchSimd128Reg;
masm.loadAlignedSimd128Float(cycleSlot(slotId), temp);
masm.storeAlignedSimd128Float(temp, getAdjustedAddress(to));
} else {
masm.loadAlignedSimd128Float(cycleSlot(slotId), to.floatReg());
}
break;
case MoveOp::INT32:
MOZ_ASSERT(slotId == 0);
if (to.isMemory()) {
@@ -213,56 +108,6 @@ MoveEmitterLoongArch64::completeCycle(const MoveOperand& from, const MoveOperand
}
}
void
MoveEmitterLoongArch64::emitSimd128IntMove(const MoveOperand& from, const MoveOperand& to)
{
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isSimd128());
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isSimd128());
if (from.isFloatReg()) {
if (to.isFloatReg()) {
masm.moveSimd128Int(from.floatReg(), to.floatReg());
} else {
MOZ_ASSERT(to.isMemory());
masm.storeAlignedSimd128Int(from.floatReg(), getAdjustedAddress(to));
}
} else if (to.isFloatReg()) {
MOZ_ASSERT(from.isMemory());
masm.loadAlignedSimd128Int(getAdjustedAddress(from), to.floatReg());
} else {
MOZ_ASSERT(from.isMemory());
MOZ_ASSERT(to.isMemory());
FloatRegister temp = ScratchSimd128Reg;
masm.loadAlignedSimd128Int(getAdjustedAddress(from), temp);
masm.storeAlignedSimd128Int(temp, getAdjustedAddress(to));
}
}
void
MoveEmitterLoongArch64::emitSimd128FloatMove(const MoveOperand& from, const MoveOperand& to)
{
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isSimd128());
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isSimd128());
if (from.isFloatReg()) {
if (to.isFloatReg()) {
masm.moveSimd128Float(from.floatReg(), to.floatReg());
} else {
MOZ_ASSERT(to.isMemory());
masm.storeAlignedSimd128Float(from.floatReg(), getAdjustedAddress(to));
}
} else if (to.isFloatReg()) {
MOZ_ASSERT(from.isMemory());
masm.loadAlignedSimd128Float(getAdjustedAddress(from), to.floatReg());
} else {
MOZ_ASSERT(from.isMemory());
MOZ_ASSERT(to.isMemory());
FloatRegister temp = ScratchSimd128Reg;
masm.loadAlignedSimd128Float(getAdjustedAddress(from), temp);
masm.storeAlignedSimd128Float(temp, getAdjustedAddress(to));
}
}
void
MoveEmitterLoongArch64::emitDoubleMove(const MoveOperand& from, const MoveOperand& to)
{
@@ -13,13 +13,7 @@ namespace jit {
class MoveEmitterLoongArch64 : public MoveEmitterMIPSShared
{
Address cycleSlot(uint32_t slot, uint32_t subslot = 0) const;
void emitDoubleMove(const MoveOperand& from, const MoveOperand& to);
void emitSimd128IntMove(const MoveOperand& from, const MoveOperand& to);
void emitSimd128FloatMove(const MoveOperand& from, const MoveOperand& to);
void emit(const MoveOp& move);
void breakCycle(const MoveOperand& from, const MoveOperand& to,
MoveOp::Type type, uint32_t slot);
void completeCycle(const MoveOperand& from, const MoveOperand& to,
@@ -29,8 +23,6 @@ class MoveEmitterLoongArch64 : public MoveEmitterMIPSShared
MoveEmitterLoongArch64(MacroAssembler& masm)
: MoveEmitterMIPSShared(masm)
{ }
void emit(const MoveResolver& moves);
};
typedef MoveEmitterLoongArch64 MoveEmitter;
@@ -874,13 +874,6 @@ MacroAssembler::branchTestSymbol(Condition cond, Register tag, Label* label)
ma_b(tag, ImmTag(JSVAL_TAG_SYMBOL), label, cond);
}
void
MacroAssembler::branchTestBigInt(Condition cond, Register tag, Label* label)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ma_b(tag, ImmTag(JSVAL_TAG_BIGINT), label, cond);
}
void
MacroAssembler::branchTestSymbol(Condition cond, const BaseIndex& address, Label* label)
{
@@ -614,25 +614,6 @@ CodeGeneratorMIPS64::visitExtendInt32ToInt64(LExtendInt32ToInt64* lir)
masm.ma_sll(output, ToRegister(input), Imm32(0));
}
void
CodeGeneratorMIPS64::visitSignExtendInt64(LSignExtendInt64* lir)
{
Register64 input = ToRegister64(lir->getInt64Operand(0));
Register64 output = ToOutRegister64(lir);
switch (lir->mode()) {
case MSignExtendInt64::Byte:
masm.move8SignExtend(input.reg, output.reg);
break;
case MSignExtendInt64::Half:
masm.move16SignExtend(input.reg, output.reg);
break;
case MSignExtendInt64::Word:
masm.ma_sll(output.reg, input.reg, Imm32(0));
break;
}
}
void
CodeGeneratorMIPS64::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir)
{
-1
View File
@@ -62,7 +62,6 @@ class CodeGeneratorMIPS64 : public CodeGeneratorMIPSShared
void visitWasmReinterpretFromI64(LWasmReinterpretFromI64* lir);
void visitWasmReinterpretToI64(LWasmReinterpretToI64* lir);
void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir);
void visitSignExtendInt64(LSignExtendInt64* lir);
void visitWrapInt64ToInt32(LWrapInt64ToInt32* lir);
void visitClzI64(LClzI64* lir);
void visitCtzI64(LCtzI64* lir);
-6
View File
@@ -184,9 +184,3 @@ LIRGeneratorMIPS64::visitRandom(MRandom* ins)
temp());
defineFixed(lir, ins, LFloatReg(ReturnDoubleReg));
}
void
LIRGeneratorMIPS64::visitSignExtendInt64(MSignExtendInt64* ins)
{
defineInt64(new(alloc()) LSignExtendInt64(useInt64RegisterAtStart(ins->input())), ins);
}
-1
View File
@@ -46,7 +46,6 @@ class LIRGeneratorMIPS64 : public LIRGeneratorMIPSShared
void visitUnbox(MUnbox* unbox);
void visitReturn(MReturn* ret);
void visitRandom(MRandom* ins);
void visitSignExtendInt64(MSignExtendInt64* ins);
};
typedef LIRGeneratorMIPS64 LIRGeneratorSpecific;
@@ -364,18 +364,6 @@ MacroAssembler::rshift64Arithmetic(Register shift, Register64 dest)
// ===============================================================
// Rotation functions
void
MacroAssembler::rotateLeft64(Imm32 count, Register64 src, Register64 dest)
{
rotateLeft64(count, src, dest, InvalidReg);
}
void
MacroAssembler::rotateLeft64(Register count, Register64 src, Register64 dest)
{
rotateLeft64(count, src, dest, InvalidReg);
}
void
MacroAssembler::rotateLeft64(Imm32 count, Register64 src, Register64 dest, Register temp)
{
@@ -394,18 +382,6 @@ MacroAssembler::rotateLeft64(Register count, Register64 src, Register64 dest, Re
ma_drol(dest.reg, src.reg, count);
}
void
MacroAssembler::rotateRight64(Imm32 count, Register64 src, Register64 dest)
{
rotateRight64(count, src, dest, InvalidReg);
}
void
MacroAssembler::rotateRight64(Register count, Register64 src, Register64 dest)
{
rotateRight64(count, src, dest, InvalidReg);
}
void
MacroAssembler::rotateRight64(Imm32 count, Register64 src, Register64 dest, Register temp)
{
+3 -8
View File
@@ -1497,17 +1497,17 @@ MacroAssemblerMIPS64Compat::unboxSymbol(Register src, Register dest)
void MacroAssemblerMIPS64Compat::unboxBigInt(const ValueOperand& operand, Register dest)
{
unboxNonDouble(operand, dest);
unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
}
void MacroAssemblerMIPS64Compat::unboxBigInt(Register src, Register dest)
{
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
void MacroAssemblerMIPS64Compat::unboxBigInt(const Address& src, Register dest)
{
unboxNonDouble(src, dest);
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
void
@@ -1559,11 +1559,6 @@ MacroAssemblerMIPS64Compat::unboxPrivate(const ValueOperand& src, Register dest)
void
MacroAssemblerMIPS64Compat::boxDouble(FloatRegister src, const ValueOperand& dest)
{
#if defined(JS_RUNTIME_CANONICAL_NAN)
// Legacy-ABI MIPS hardware can produce NaN payloads that overlap the
// punbox64 tag space. Normalize them before creating a JS::Value.
asMasm().canonicalizeDouble(src);
#endif
as_dmfc1(dest.valueReg(), src);
}
-12
View File
@@ -173,18 +173,6 @@ ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
masm.neg32(ExtractTemp0);
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
break;
case JSOP_INC: {
masm.unboxInt32(R0, ExtractTemp0);
masm.ma_addTestOverflow(ExtractTemp0, ExtractTemp0, Imm32(1), &failure);
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
break;
}
case JSOP_DEC: {
masm.unboxInt32(R0, ExtractTemp0);
masm.ma_subTestOverflow(ExtractTemp0, ExtractTemp0, Imm32(1), &failure);
masm.tagValue(JSVAL_TYPE_INT32, ExtractTemp0, R0);
break;
}
default:
MOZ_CRASH("Unexpected op");
return false;
+2 -3
View File
@@ -85,9 +85,8 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator* gen, LIRGraph* graph, Mac
MOZ_ASSERT(graph->argumentSlotCount() == 0);
frameDepth_ += gen->wasmMaxStackArgBytes();
if (SupportsSimd) {
frameDepth_ = AlignBytes(frameDepth_, SimdMemoryAlignment);
}
static_assert(!SupportsSimd, "we need padding so that local slots are SIMD-aligned and "
"the stack must be kept SIMD-aligned too.");
if (gen->performsCall()) {
// An MWasmCall does not align the stack pointer at calls sites but
+1 -8
View File
@@ -940,14 +940,7 @@ GlobalHelperThreadState::maxParseThreads() const
if (IsHelperThreadSimulatingOOM(js::oom::THREAD_TYPE_PARSE))
return 1;
// Use the number of logical processors in a system.
if (cpuCount < 4)
return 2;
//return cpuCount - 2;
// XXX Issue #3172 XXX
// For the time being, return a hard-coded value of 2 on all targets and CPUs.
// It's unclear where the contention happens, but it has shown to be detrimental
// especially on *nixes and older hardware.
return 2;
return cpuCount;
}
size_t
-33
View File
@@ -8,8 +8,6 @@
#include "js/Initialization.h"
#include "mozilla/Assertions.h"
#include "mozilla/Casting.h"
#include "mozilla/FloatingPoint.h"
#include <ctype.h>
@@ -21,7 +19,6 @@
#include "jit/ExecutableAllocator.h"
#include "jit/Ion.h"
#include "js/Utility.h"
#include "js/Value.h"
#include "unicode/uclean.h"
#include "unicode/utypes.h"
#include "vm/DateTime.h"
@@ -37,31 +34,6 @@ using js::FutexRuntime;
InitState JS::detail::libraryInitState;
// MIPS-specific
#if defined(JS_RUNTIME_CANONICAL_NAN)
namespace JS {
namespace detail {
JS_PUBLIC_DATA(uint64_t) CanonicalizedNaNBits;
} // namespace detail
} // namespace JS
// MIPS-specific
static void
SetupCanonicalNaN()
{
// Use a real hardware operation. A legacy MIPS ABI can run on hardware
// whose NaN behavior does not match the compiler's predefined NAN value.
volatile double infinity = mozilla::PositiveInfinity<double>();
volatile double hardwareNaN = infinity - infinity;
uint64_t hardwareNaNBits = mozilla::BitwiseCast<uint64_t>(hardwareNaN);
hardwareNaNBits &= ~mozilla::FloatingPoint<double>::kSignBit;
// The selected NaN must remain a double in the JS::Value representation.
MOZ_RELEASE_ASSERT(JS::Value::fromRawBits(hardwareNaNBits).isDouble());
JS::detail::CanonicalizedNaNBits = hardwareNaNBits;
}
#endif
#ifdef DEBUG
static unsigned
MessageParameterCount(const char* format)
@@ -104,11 +76,6 @@ JS::detail::InitWithFailureDiagnostic(bool isDebugBuild)
MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
"how do we have live runtimes before JS_Init?");
// MIPS-specific
#if defined(JS_RUNTIME_CANONICAL_NAN)
SetupCanonicalNaN();
#endif
PRMJ_NowInit();
// The first invocation of `ProcessCreation` creates a temporary thread
+1
View File
@@ -1059,6 +1059,7 @@ wasm::GenerateInterruptExit(MacroAssembler& masm, Label* throwLabel)
// jump scratch to resume execution.
masm.subFromStackPtr(Imm32(sizeof(intptr_t)));
masm.setFramePushed(0);
static_assert(!SupportsSimd, "high lanes of SIMD registers need to be saved too.");
masm.PushRegsInMask(AllRegsExceptSP);
// Save the unaligned stack pointer in a non-volatile register, then align
+1 -5
View File
@@ -8938,11 +8938,7 @@ PresShell::DidDoReflow(bool aInterruptible)
{
mFrameConstructor->EndUpdate();
if (!mHandlingCallbacks) {
mHandlingCallbacks = true; // Prevent recursion
HandlePostedReflowCallbacks(aInterruptible);
mHandlingCallbacks = false;
}
HandlePostedReflowCallbacks(aInterruptible);
nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
if (docShell) {
-2
View File
@@ -926,8 +926,6 @@ protected:
bool mAsyncResizeTimerIsActive : 1;
bool mInResize : 1;
bool mHandlingCallbacks : 1;
bool mApproximateFrameVisibilityVisited : 1;
+2 -2
View File
@@ -164,9 +164,9 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
// We should be able to interact with the element by doing drag and drop.
mContent->AddSystemEventListener(NS_LITERAL_STRING("drop"),
mMouseListener, false, false);
mMouseListener, false);
mContent->AddSystemEventListener(NS_LITERAL_STRING("dragover"),
mMouseListener, false, false);
mMouseListener, false);
SyncDisabledState();
+8 -7
View File
@@ -235,17 +235,18 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
WritingMode wm = GetWritingMode();
LogicalSize availSize = aButtonReflowInput.ComputedSize(wm);
// The anonymous button-content frame cannot have a continuation. Give it
// unconstrained available block-size so flex/grid layout does not treat a
// definite button block-size as a fragmentainer constraint. Its computed
// block-size is overridden separately below when it needs to be definite.
availSize.BSize(wm) = NS_INTRINSICSIZE;
// Identify if the inner anonymous block is actually functioning as a flex or grid container.
nsIAtom* kidType = aFirstKid->GetType();
bool isFlexOrGrid = (kidType == nsGkAtoms::flexContainerFrame ||
kidType == nsGkAtoms::gridContainerFrame);
// Preserve the button's definite BSize ONLY for flex/grid children so they
// see a definite containing block main size. For standard buttons, clobber
// to intrinsic so standard vertical centering (extraSpace) calculations work.
if (!isFlexOrGrid || aButtonReflowInput.ComputedBSize() == NS_INTRINSICSIZE) {
availSize.BSize(wm) = NS_INTRINSICSIZE;
}
// shorthand for a value we need to use in a bunch of places
const LogicalMargin& clbp = aButtonReflowInput.ComputedLogicalBorderPadding();
@@ -259,7 +260,7 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
availSize);
// Apply the definite BSize directly on the inner reflow input ONLY if it's
// a flex or grid container, without constraining its available BSize.
// a flex or grid container, allowing it to be used as-is.
if (isFlexOrGrid && aButtonReflowInput.ComputedBSize() != NS_INTRINSICSIZE) {
contentsReflowInput.SetComputedBSize(aButtonReflowInput.ComputedBSize());
}
+1 -9
View File
@@ -1781,7 +1781,6 @@ CSSStyleSheet::DidDirty()
MOZ_ASSERT(!mInner->mComplete || mDirty,
"caller must have called WillDirty()");
ClearRuleCascades();
NotifyAdopterRuleChanged();
}
void
@@ -1871,20 +1870,13 @@ CSSStyleSheet::InsertRuleInternal(const nsAString& aRule,
RefPtr<css::Rule> rule;
aRv = css.ParseRule(aRule, mInner->mSheetURI, mInner->mBaseURI,
mInner->mPrincipal, getter_AddRefs(rule));
// A syntax error from web content is an expected insertRule() outcome. The
// binding reports it to script; do not flood debug stderr as well.
if (aRv.Failed()) {
if (NS_WARN_IF(aRv.Failed())) {
return 0;
}
// Hierarchy checking.
int32_t newType = rule->GetType();
if (IsConstructed() && newType == css::Rule::IMPORT_RULE) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return 0;
}
// check that we're not inserting before a charset rule
css::Rule* nextRule = mInner->mOrderedRules.SafeObjectAt(aIndex);
if (nextRule) {
+2 -6
View File
@@ -639,12 +639,8 @@ Declaration::GetPropertyValueInternal(
}
if (revertCount == totalCount) {
// Simplify serialization below by serializing revert up-front.
// eCSSUnit_Revert carries the cascade origin, so it cannot use the
// nsCSSValue constructor reserved for valueless units.
nsCSSValue revert;
revert.SetRevertValue(SheetType::Unknown);
revert.AppendToString(eCSSProperty_UNKNOWN, aValue,
nsCSSValue::eNormalized);
nsCSSValue(eCSSUnit_Revert).AppendToString(eCSSProperty_UNKNOWN, aValue,
nsCSSValue::eNormalized);
return;
}
if (revertLayerCount == totalCount) {
+1 -62
View File
@@ -28,7 +28,6 @@ StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode)
, mDisabled(false)
, mConstructed(false)
, mDisallowModification(false)
, mAdoptionCount(0)
, mDocumentAssociationMode(NotOwnedByDocument)
{
}
@@ -43,7 +42,6 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
, mDisabled(aCopy.mDisabled)
, mConstructed(aCopy.mConstructed)
, mDisallowModification(false)
, mAdoptionCount(0)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
, mDocumentAssociationMode(NotOwnedByDocument)
@@ -60,7 +58,7 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(StyleSheet)
NS_IMPL_CYCLE_COLLECTING_RELEASE(StyleSheet)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(StyleSheet, mConstructorDocument)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(StyleSheet)
mozilla::dom::CSSStyleSheetParsingMode
StyleSheet::ParsingModeDOM()
@@ -261,69 +259,10 @@ StyleSheet::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
sheet->SetPrincipal(principal);
sheet->SetComplete();
sheet->SetConstructed();
sheet->SetConstructorDocument(document);
return sheet.forget();
}
void
StyleSheet::AddAdopter(nsIDocument* aDocument)
{
MOZ_ASSERT(IsConstructed());
MOZ_ASSERT(aDocument);
MOZ_ASSERT(ConstructorDocument() == aDocument);
if (mAdoptionCount++ == 0) {
SetAssociatedDocument(aDocument, NotOwnedByDocument);
}
}
void
StyleSheet::AddAdopter(dom::ShadowRoot* aShadowRoot)
{
MOZ_ASSERT(aShadowRoot);
mAdopterShadowRoots.AppendElement(aShadowRoot);
AddAdopter(aShadowRoot->OwnerDoc());
}
void
StyleSheet::RemoveAdopter(nsIDocument* aDocument)
{
MOZ_ASSERT(IsConstructed());
MOZ_ASSERT(aDocument);
MOZ_ASSERT(ConstructorDocument() == aDocument);
MOZ_ASSERT(mAdoptionCount > 0);
if (mAdoptionCount == 0) {
return;
}
if (--mAdoptionCount == 0 && !IsOwnedByDocument()) {
ClearAssociatedDocument();
}
}
void
StyleSheet::RemoveAdopter(dom::ShadowRoot* aShadowRoot)
{
MOZ_ASSERT(aShadowRoot);
mAdopterShadowRoots.RemoveElement(aShadowRoot);
RemoveAdopter(aShadowRoot->OwnerDoc());
}
void
StyleSheet::NotifyAdopterRuleChanged()
{
for (size_t i = 0; i < mAdopterShadowRoots.Length(); ++i) {
dom::ShadowRoot* shadowRoot = mAdopterShadowRoots[i];
if (mAdopterShadowRoots.IndexOf(shadowRoot) == i) {
shadowRoot->StyleSheetChanged();
}
}
}
dom::CSSRuleList*
StyleSheet::GetCssRules(nsIPrincipal& aSubjectPrincipal,
ErrorResult& aRv)
+1 -18
View File
@@ -12,7 +12,6 @@
#include "mozilla/CORSMode.h"
#include "nsIDOMCSSStyleSheet.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
class nsIDocument;
@@ -27,7 +26,6 @@ struct StyleSheetInfo;
namespace dom {
class CSSRuleList;
class ShadowRoot;
class SRIMetadata;
} // namespace dom
@@ -195,13 +193,6 @@ public:
inline void DidDirty();
inline void AssertHasUniqueInner();
bool IsConstructed() const { return mConstructed; }
nsIDocument* ConstructorDocument() const { return mConstructorDocument; }
void AddAdopter(nsIDocument* aDocument);
void RemoveAdopter(nsIDocument* aDocument);
void AddAdopter(dom::ShadowRoot* aShadowRoot);
void RemoveAdopter(dom::ShadowRoot* aShadowRoot);
private:
// Get a handle to the various stylesheet bits which live on the 'inner' for
// gecko stylesheets.
@@ -215,12 +206,8 @@ private:
bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal,
ErrorResult& aRv);
bool IsConstructed() const { return mConstructed; }
void SetConstructed() { mConstructed = true; }
void SetConstructorDocument(nsIDocument* aDocument)
{
MOZ_ASSERT(IsConstructed());
mConstructorDocument = aDocument;
}
bool IsModificationDisallowed() const { return mDisallowModification; }
protected:
@@ -230,13 +217,10 @@ protected:
// it will set the principal of the inner to the subject principal.
void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
ErrorResult& aRv);
void NotifyAdopterRuleChanged();
nsString mTitle;
nsIDocument* mDocument; // weak ref; parents maintain this for their children
RefPtr<nsIDocument> mConstructorDocument;
nsINode* mOwningNode; // weak ref
nsTArray<dom::ShadowRoot*> mAdopterShadowRoots; // weak; roots unadopt on unlink/destruction
// mParsingMode controls access to nonstandard style constructs that
// are not safe for use on the public Web but necessary in UA sheets
@@ -246,7 +230,6 @@ protected:
bool mDisabled;
bool mConstructed;
bool mDisallowModification;
uint32_t mAdoptionCount;
// mDocumentAssociationMode determines whether mDocument directly owns us (in
// the sense that if it's known-live then we're known-live). Always
+6 -4
View File
@@ -13454,16 +13454,18 @@ bool
CSSParserImpl::ParseAspectRatioRatio(nsCSSValue& aValue)
{
nsCSSValue width;
if (ParseNonNegativeVariant(width, VARIANT_NUMBER | VARIANT_CALC,
nullptr) != CSSParseResult::Ok) {
if (!ParseSingleTokenNonNegativeVariant(width,
VARIANT_NUMBER | VARIANT_CALC,
nullptr)) {
return false;
}
nsCSSValue height;
height.SetFloatValue(1.0f, eCSSUnit_Number);
if (ExpectSymbol('/', true)) {
if (ParseNonNegativeVariant(height, VARIANT_NUMBER | VARIANT_CALC,
nullptr) != CSSParseResult::Ok) {
if (!ParseSingleTokenNonNegativeVariant(height,
VARIANT_NUMBER | VARIANT_CALC,
nullptr)) {
return false;
}
}
@@ -8,13 +8,9 @@
</head>
<body>
<pre id="test"></pre>
<div id="adopted-target"></div>
<div id="shadow-host"></div>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
let sheet;
try {
@@ -62,105 +58,7 @@ if (sheet) {
is(e.name, "NotAllowedError",
"replaceSync should reject non-constructed sheets with NotAllowedError");
}
try {
sheet.insertRule("@import url('neverending_stylesheet_load.sjs');", 0);
ok(false, "insertRule should reject @import rules for constructed sheets");
} catch (e) {
is(e.name, "SyntaxError",
"insertRule should reject constructed-sheet @import rules with SyntaxError");
}
}
function colorFor(node) {
return getComputedStyle(node).color;
}
function runAdoptionTests() {
let target = document.getElementById("adopted-target");
let adopted = new CSSStyleSheet();
adopted.replaceSync("#adopted-target { color: rgb(12, 34, 56); }");
document.adoptedStyleSheets = [adopted];
is(document.adoptedStyleSheets.length, 1,
"document.adoptedStyleSheets should expose assigned sheets");
is(document.adoptedStyleSheets[0], adopted,
"document.adoptedStyleSheets should expose the same CSSStyleSheet object");
is(document.styleSheets.length, 1,
"document.styleSheets should not include adopted sheets");
is(colorFor(target), "rgb(12, 34, 56)",
"adopted document sheets should apply");
adopted.replaceSync("#adopted-target { color: rgb(20, 30, 40); }");
is(colorFor(target), "rgb(20, 30, 40)",
"mutating an adopted sheet should update document style");
let laterStyle = document.createElement("style");
laterStyle.textContent = "#adopted-target { color: rgb(1, 2, 3); }";
document.head.appendChild(laterStyle);
is(colorFor(target), "rgb(20, 30, 40)",
"adopted document sheets should cascade after ordinary document sheets");
try {
document.adoptedStyleSheets = [document.styleSheets[0]];
ok(false, "adopting a non-constructed sheet should throw");
} catch (e) {
is(e.name, "NotAllowedError",
"adopting a non-constructed sheet should throw NotAllowedError");
}
let iframe = document.createElement("iframe");
iframe.onload = function() {
let foreignSheet = new iframe.contentWindow.CSSStyleSheet();
try {
document.adoptedStyleSheets = [foreignSheet];
ok(false, "adopting a sheet from another document should throw");
} catch (e) {
is(e.name, "NotAllowedError",
"adopting a sheet from another document should throw NotAllowedError");
}
iframe.remove();
if ("attachShadow" in document.getElementById("shadow-host")) {
runShadowAdoptionTests();
} else {
finishAdoptionTests();
}
};
document.body.appendChild(iframe);
}
function runShadowAdoptionTests() {
let host = document.getElementById("shadow-host");
let root = host.attachShadow({ mode: "open" });
root.innerHTML = "<style>span { color: rgb(1, 2, 3); }</style><span>shadow</span>";
let shadowSheet = new CSSStyleSheet();
shadowSheet.replaceSync("span { color: rgb(45, 67, 89); }");
root.adoptedStyleSheets = [shadowSheet];
let span = root.querySelector("span");
is(root.adoptedStyleSheets.length, 1,
"shadowRoot.adoptedStyleSheets should expose assigned sheets");
is(root.styleSheets.length, 1,
"shadowRoot.styleSheets should not include adopted sheets");
is(colorFor(span), "rgb(45, 67, 89)",
"adopted shadow sheets should apply after ordinary shadow sheets");
shadowSheet.replaceSync("span { color: rgb(90, 80, 70); }");
is(colorFor(span), "rgb(90, 80, 70)",
"mutating an adopted shadow sheet should update shadow style");
finishAdoptionTests();
}
function finishAdoptionTests() {
document.adoptedStyleSheets = [];
SimpleTest.finish();
}
runAdoptionTests();
</script>
</body>
</html>
-7
View File
@@ -49,13 +49,6 @@
#include "config_unix_ppc.h"
#elif defined(__sparcv9) || defined(__sparcv9__)
#include "config_unix_sparc64.h"
#elif defined(__mips__)
// This is needed to avoid enabling x86 assembly on 64-bit MIPS.
#include "config_unix32.h"
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#undef HAVE_BIGENDIAN
#define HAVE_BIGENDIAN 1
#endif
#elif defined(__loongarch64)
#include "config_unix_loongarch64.h"
#else
-4
View File
@@ -6,9 +6,5 @@
#else
#define AV_HAVE_BIGENDIAN 0
#endif
#if defined(__mips__)
#define AV_HAVE_FAST_UNALIGNED 0
#else
#define AV_HAVE_FAST_UNALIGNED 1
#endif
#endif /* AVUTIL_AVCONFIG_H */
@@ -16,30 +16,6 @@
#if HAVE_MMI
/*
* Clang's integrated assembler uses the prefixed spellings below, while
* GNU as names the same Loongson MMI instructions xor/and/or/dsrl/srl.
* Define GNU as aliases so the inline assembly works with either toolchain.
*/
#if defined(__GNUC__) && !defined(__clang__)
__asm__(
".macro pxor dst, src1, src2\n\t"
"xor \\dst, \\src1, \\src2\n\t"
".endm\n\t"
".macro pand dst, src1, src2\n\t"
"and \\dst, \\src1, \\src2\n\t"
".endm\n\t"
".macro por dst, src1, src2\n\t"
"or \\dst, \\src1, \\src2\n\t"
".endm\n\t"
".macro ssrld dst, src1, src2\n\t"
"dsrl \\dst, \\src1, \\src2\n\t"
".endm\n\t"
".macro ssrlw dst, src1, src2\n\t"
"srl \\dst, \\src1, \\src2\n\t"
".endm\n\t");
#endif
#if HAVE_MIPS64
#define mips_reg int64_t
#define MMI_ADDU(reg1, reg2, reg3) \
+7 -11
View File
@@ -110,27 +110,22 @@ nsHttpChunkedDecoder::ParseChunkRemaining(char *buf,
count = mLineBuf.Length();
}
// NUL is illegal in a chunk-size or trailer field line (RFC 9110 section
// 5.5).
if (memchr(buf, '\0', count)) {
LOG(("chunked line contains embedded NUL; rejecting\n"));
return NS_ERROR_UNEXPECTED;
}
if (mWaitEOF) {
if (count) {
if (*buf) {
LOG(("got trailer: %s\n", buf));
// allocate a header array for the trailers on demand
if (!mTrailers) {
mTrailers = new nsHttpHeaderArray();
}
mTrailers->ParseHeaderLine(nsDependentCSubstring(buf, count));
} else {
}
else {
mWaitEOF = false;
mReachedEOF = true;
LOG(("reached end of chunked-body\n"));
}
} else if (count) {
}
else if (*buf) {
char *endptr;
unsigned long parsedval; // could be 64 bit, could be 32
@@ -156,7 +151,8 @@ nsHttpChunkedDecoder::ParseChunkRemaining(char *buf,
// ensure that the line buffer is clear
mLineBuf.Truncate();
} else {
}
else {
// save the partial line; wait for more data
*bytesConsumed = count;
// ignore a trailing CR
-24
View File
@@ -1,24 +0,0 @@
diff --git a/lib/xmltok.c b/lib/xmltok.c
--- a/lib/xmltok.c
+++ b/lib/xmltok.c
@@ -700,17 +700,19 @@ unicode_byte_type(char hi, char lo) {
static enum XML_Convert_Result PTRCALL E##toUtf16( \
const ENCODING *enc, const char **fromP, const char *fromLim, \
unsigned short **toP, const unsigned short *toLim) { \
enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
UNUSED_P(enc); \
fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
/* Avoid copying first half only of surrogate */ \
if (fromLim - *fromP > ((toLim - *toP) << 1) \
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
+/* BEGIN MCP CHANGE (Only high surrogate mask) */ \
+ && (GET_HI(fromLim - 2) & 0xFC) == 0xD8) { \
+/* END MCP CHANGE */ \
fromLim -= 2; \
res = XML_CONVERT_INPUT_INCOMPLETE; \
} \
for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
*(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
if ((*toP == toLim) && (*fromP < fromLim)) \
return XML_CONVERT_OUTPUT_EXHAUSTED; \
else \
+1 -3
View File
@@ -705,9 +705,7 @@ unicode_byte_type(char hi, char lo) {
fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
/* Avoid copying first half only of surrogate */ \
if (fromLim - *fromP > ((toLim - *toP) << 1) \
/* BEGIN MCP CHANGE (Only high surrogate mask) */ \
&& (GET_HI(fromLim - 2) & 0xFC) == 0xD8) { \
/* END MCP CHANGE */ \
&& (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
fromLim -= 2; \
res = XML_CONVERT_INPUT_INCOMPLETE; \
} \
+1 -1
View File
@@ -9,4 +9,4 @@
* depend builds. See comments in rules.mk.
*/
#error "Do not include this header file."
#error "Do not include this header file."
@@ -7,16 +7,9 @@
#include "gtest/gtest.h"
#include "cert.h"
#include "certdb.h"
#include "certt.h"
#include "nss_scoped_ptrs.h"
#include "prerror.h"
#include "secerr.h"
extern "C" SECStatus __CERT_AddTempCertToPerm(CERTCertificate* cert,
char* nickname,
CERTCertTrust* trust);
class DecodeCertsTest : public ::testing::Test {};
TEST_F(DecodeCertsTest, EmptyCertPackage) {
@@ -46,113 +39,3 @@ TEST_F(DecodeCertsTest, EmptySignedData) {
sizeof(emptySignedData)));
EXPECT_EQ(SEC_ERROR_BAD_DER, PR_GetError());
}
// Generated with pycert, but the details are unimportant. This can just be any
// unique certificate. In this case, the specification used was:
// issuer:test temp to perm cert
// subject:test temp to perm cert
// issuerKey:secp256r1
// subjectKey:secp256r1
// serialNumber:1
uint8_t kTestTempToPermCertDER[] = {
0x30, 0x82, 0x01, 0x37, 0x30, 0x81, 0xdc, 0xa0, 0x03, 0x02, 0x01, 0x02,
0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x20,
0x74, 0x65, 0x6d, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x6d,
0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x32,
0x34, 0x31, 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
0x18, 0x0f, 0x32, 0x30, 0x32, 0x37, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x21, 0x31, 0x1f, 0x30, 0x1d, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x74, 0x65, 0x73, 0x74, 0x20, 0x74,
0x65, 0x6d, 0x70, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x20,
0x63, 0x65, 0x72, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61,
0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec,
0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79,
0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11,
0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99,
0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x5c, 0x75, 0x51,
0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06,
0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb,
0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x20, 0x43, 0xee, 0xef, 0x45, 0x3d,
0xbb, 0xf3, 0x3c, 0x61, 0x9a, 0xbb, 0x95, 0x89, 0xb4, 0x23, 0x3c, 0xc7,
0x1e, 0x39, 0x01, 0x74, 0x9e, 0xef, 0x04, 0x44, 0x86, 0x8c, 0xc9, 0x0f,
0x8b, 0x2d, 0x0d};
TEST_F(DecodeCertsTest, AddTempCertToPerm) {
SECItem certDER = {siBuffer, kTestTempToPermCertDER,
sizeof(kTestTempToPermCertDER)};
ScopedCERTCertificate cert1(CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
EXPECT_NE(cert1.get(), nullptr);
CERTCertTrust trust = {0};
char nickname1[] = "test temp to perm cert 1";
SECStatus rv = __CERT_AddTempCertToPerm(cert1.get(), nickname1, &trust);
EXPECT_EQ(rv, SECSuccess);
ScopedCERTCertificate cert2(CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
EXPECT_NE(cert2.get(), cert1.get());
char nickname2[] = "test temp to perm cert 2";
rv = __CERT_AddTempCertToPerm(cert2.get(), nickname2, &trust);
EXPECT_EQ(rv, SECSuccess);
}
// Generated with pycert, but the details are unimportant. This can just be any
// unique certificate. In this case, the specification used was:
// issuer:test import cert
// subject:test import cert
// issuerKey:secp256r1
// subjectKey:secp256r1
// serialNumber:1
uint8_t kTestImportCertDER[] = {
0x30, 0x82, 0x01, 0x2c, 0x30, 0x81, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02,
0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x74, 0x65, 0x73, 0x74, 0x20,
0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30,
0x22, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x31, 0x31, 0x32, 0x37, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x37,
0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10,
0x74, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20,
0x63, 0x65, 0x72, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61,
0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec,
0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79,
0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11,
0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99,
0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51,
0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06,
0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb,
0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0xe9, 0x58, 0x16, 0x07,
0xbf, 0x0b, 0xdc, 0x64, 0x35, 0x7a, 0x92, 0x51, 0xb2, 0xee, 0x77, 0x22,
0xd4, 0xec, 0x98, 0xb6, 0x35, 0x96, 0xa6, 0x5b, 0x96, 0xbe, 0x73, 0x1a,
0xa3, 0xa4, 0xfe, 0x5c};
TEST_F(DecodeCertsTest, ImportCert) {
SECItem certDER = {siBuffer, kTestImportCertDER, sizeof(kTestImportCertDER)};
ScopedCERTCertificate cert1(CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
EXPECT_NE(cert1.get(), nullptr);
char nickname1[] = "test import cert 1";
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
SECStatus rv = PK11_ImportCert(slot.get(), cert1.get(), CK_INVALID_HANDLE,
nickname1, PR_TRUE);
EXPECT_EQ(rv, SECSuccess);
ScopedCERTCertificate cert2(CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &certDER, nullptr, PR_TRUE, PR_TRUE));
EXPECT_NE(cert2.get(), cert1.get());
char nickname2[] = "test import cert 2";
rv = PK11_ImportCert(slot.get(), cert2.get(), CK_INVALID_HANDLE, nickname2,
PR_TRUE);
EXPECT_EQ(rv, SECSuccess);
}
+14 -16
View File
@@ -255,6 +255,8 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
NSSCertificate *c = STAN_GetNSSCertificate(cert);
nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
SECStatus rv;
PRStatus ret;
if (c == NULL) {
CERT_MapStanError();
@@ -316,19 +318,12 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
return SECFailure;
}
nssPKIObject_AddInstance(&c->object, permInstance);
// nssTrustDomain_AddCertToCache takes ownership of 'c' and returns an
// owned reference to an NSSCertificate that may be a different object from
// 'c'. Because 'cert' is backed by 'c', and because it must not go away as
// a result of calling this function, increment the refcount on 'c' for the
// duration of the call.
nssCertificate_AddRef(c);
NSSCertificate *cInCache = nssTrustDomain_AddCertToCache(STAN_GetDefaultTrustDomain(), c);
if (!cInCache) {
CERT_MapStanError();
return SECFailure;
}
c = cInCache;
cert = STAN_GetCERTCertificateOrRelease(c);
nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
/* reset the CERTCertificate fields */
CERT_LockCertTempPerm(cert);
cert->nssCertificate = NULL;
CERT_UnlockCertTempPerm(cert);
cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
if (!cert) {
CERT_MapStanError();
return SECFailure;
@@ -337,12 +332,15 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
cert->istemp = PR_FALSE;
cert->isperm = PR_TRUE;
CERT_UnlockCertTempPerm(cert);
SECStatus rv = SECSuccess;
if (trust && STAN_ChangeCertTrust(cert, trust) != PR_SUCCESS) {
if (!trust) {
return SECSuccess;
}
ret = STAN_ChangeCertTrust(cert, trust);
rv = SECSuccess;
if (ret != PR_SUCCESS) {
rv = SECFailure;
CERT_MapStanError();
}
nssCertificate_Destroy(c);
return rv;
}
+2 -2
View File
@@ -22,10 +22,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define NSS_VERSION "3.90.14.0 (UXP)" _NSS_CUSTOMIZED
#define NSS_VERSION "3.90.13.0 (UXP)" _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
#define NSS_VMINOR 90
#define NSS_VPATCH 14
#define NSS_VPATCH 13
#define NSS_VBUILD 0
#define NSS_BETA PR_FALSE
+24 -43
View File
@@ -93,19 +93,17 @@ pk11_buildNickname(PK11SlotInfo *slot, CK_ATTRIBUTE *cert_label,
suffixLen = key_label->ulValueLen;
suffix = (char *)key_label->pValue;
} else if (cert_id && cert_id->ulValueLen > 0) {
int i, first = cert_id->ulValueLen - MAX_CERT_ID;
int offset = sizeof(DEFAULT_STRING);
char *idValue = (char *)cert_id->pValue;
/* Hex-encode the last min(MAX_CERT_ID, ulValueLen) bytes of cert_id. */
CK_ULONG idLen = (cert_id->ulValueLen > MAX_CERT_ID)
? MAX_CERT_ID
: cert_id->ulValueLen;
CK_ULONG first = cert_id->ulValueLen - idLen;
CK_ULONG i;
PORT_Memcpy(buildNew, DEFAULT_STRING, sizeof(DEFAULT_STRING) - 1);
next = buildNew + sizeof(DEFAULT_STRING) - 1;
for (i = 0; i < idLen; i++) {
*next++ = toHex((idValue[first + i] >> 4) & 0xf);
*next++ = toHex(idValue[first + i] & 0xf);
next = buildNew + offset;
if (first < 0)
first = 0;
for (i = first; i < (int)cert_id->ulValueLen; i++) {
*next++ = toHex((idValue[i] >> 4) & 0xf);
*next++ = toHex(idValue[i] & 0xf);
}
*next++ = 0;
suffix = buildNew;
@@ -274,7 +272,7 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
}
/* Build and output a nickname, if desired.
* This must be done before calling nssTrustDomain_AddCertToCache
* This must be done before calling nssTrustDomain_AddCertsToCache
* because that function may destroy c, pkio and co!
*/
if ((nickptr) && (co->label)) {
@@ -291,15 +289,12 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
*nickptr = pk11_buildNickname(slot, &label, privateLabel, &id);
}
// nssTrustDomain_AddCertToCache takes ownership of 'c' and returns an
// owned reference to an NSSCertificate that may be a different object from
// 'c'. Presumably, the nickname which we just output above remains valid
// (the memory is valid because pk11_buildNickname allocates memory for it
// on the heap).
c = nssTrustDomain_AddCertToCache(td, c);
if (!c) {
return NULL;
}
/* This function may destroy the cert in "c" and all its subordinate
* structures, and replace the value in "c" with the address of a
* different NSSCertificate that it found in the cache.
* Presumably, the nickname which we just output above remains valid. :)
*/
(void)nssTrustDomain_AddCertsToCache(td, &c, 1);
return STAN_GetCERTCertificateOrRelease(c);
}
@@ -1249,21 +1244,13 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
* CERTCertificate, and finish
*/
nssPKIObject_AddInstance(&c->object, certobj);
// nssTrustDomain_AddCertToCache takes ownership of 'c' and returns an
// owned reference to an NSSCertificate that may be a different object from
// 'c'. Because 'cert' is backed by 'c', and because it must not go away as
// a result of calling this function, increment the refcount on 'c' for the
// duration of the call.
/* nssTrustDomain_AddCertsToCache may release a reference to 'c' and
* replace 'c' with a different value. So we add a reference to 'c' to
* prevent 'c' from being destroyed. */
nssCertificate_AddRef(c);
NSSCertificate *cInCache = nssTrustDomain_AddCertToCache(STAN_GetDefaultTrustDomain(), c);
if (cInCache) {
(void)STAN_ForceCERTCertificateUpdate(cInCache);
// Release the reference returned by nssTrustDomain_AddCertToCache.
nssCertificate_Destroy(cInCache);
} else {
(void)STAN_ForceCERTCertificateUpdate(c);
// nssTrustDomain_AddCertToCache already called nssCertificate_Destroy(c).
}
nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
(void)STAN_ForceCERTCertificateUpdate(c);
nssCertificate_Destroy(c);
SECITEM_FreeItem(keyID, PR_TRUE);
(void)nssToken_Destroy(token);
return SECSuccess;
@@ -1566,13 +1553,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
goto loser;
}
object = NULL; /* adopted by the previous call */
// nssTrustDomain_AddCertToCache takes ownership of 'cert' and returns an
// owned reference to an NSSCertificate that may be a different object from
// 'cert'.
cert = nssTrustDomain_AddCertToCache(td, cert);
if (!cert) {
goto loser;
}
nssTrustDomain_AddCertsToCache(td, &cert, 1);
/* on failure, cert is freed below */
rvCert = STAN_GetCERTCertificate(cert);
if (!rvCert) {
@@ -2031,9 +2012,9 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
}
/* Check to see if the cert's token is still there */
} while (rvCert->slot && !PK11_IsPresent(rvCert->slot));
} while (!PK11_IsPresent(rvCert->slot));
if (rvCert && rvCert->slot && slotPtr)
if (rvCert && slotPtr)
*slotPtr = PK11_ReferenceSlot(rvCert->slot);
SECITEM_FreeItem(derSerial, PR_TRUE);
+1 -8
View File
@@ -2611,16 +2611,9 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
templateCount--;
}
if (key_size != 0 && (CK_ULONG)key_size > inKey->len) {
PORT_SetError(PK11_MapError(CKR_UNWRAPPING_KEY_SIZE_RANGE));
if (crvp)
*crvp = CKR_UNWRAPPING_KEY_SIZE_RANGE;
return NULL;
}
/* keys are almost always aligned, but if we get this far,
* we've gone above and beyond anyway... */
outKey.data = (unsigned char *)PORT_ZAlloc(inKey->len);
outKey.data = (unsigned char *)PORT_Alloc(inKey->len);
if (outKey.data == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
if (crvp)
+13 -14
View File
@@ -1009,20 +1009,19 @@ cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
static nssPKIObject *
cert_createObject(nssPKIObject *o)
{
NSSCertificate *cert = nssCertificate_Create(o);
if (!cert) {
return NULL;
}
NSSTrustDomain *td = o->trustDomain;
/* nssTrustDomain_AddCertToCache takes ownership of the reference to cert,
* so first increase the refcount so it doesn't go away. */
nssCertificate_AddRef(cert);
NSSCertificate *certInCache = nssTrustDomain_AddCertToCache(td, cert);
if (certInCache) {
// This code should probably use the certificate returned from the cache,
// but currently the merge tests rely on not doing so. Discard it
// instead.
nssCertificate_Destroy(certInCache);
NSSCertificate *cert;
cert = nssCertificate_Create(o);
/* if (STAN_GetCERTCertificate(cert) == NULL) {
nssCertificate_Destroy(cert);
return (nssPKIObject *)NULL;
} */
/* In 3.4, have to maintain uniqueness of cert pointers by caching all
* certs. Cache the cert here, before returning. If it is already
* cached, take the cached entry.
*/
{
NSSTrustDomain *td = o->trustDomain;
nssTrustDomain_AddCertsToCache(td, &cert, 1);
}
return (nssPKIObject *)cert;
}
+4 -7
View File
@@ -445,14 +445,11 @@ nssTrustDomain_InitializeCache(
NSSTrustDomain *td,
PRUint32 cacheSize);
// Takes an owned reference to cert and either moves it to the cache (on
// success) or drops it (on failure).
// Returns a strong reference to the cache-owned cert (NB: which may be
// different from the given cert!) or NULL.
NSS_EXTERN NSSCertificate *
nssTrustDomain_AddCertToCache(
NSS_EXTERN PRStatus
nssTrustDomain_AddCertsToCache(
NSSTrustDomain *td,
NSSCertificate *cert);
NSSCertificate **certs,
PRUint32 numCerts);
NSS_EXTERN void
nssTrustDomain_RemoveCertFromCacheLOCKED(
+43 -6
View File
@@ -705,8 +705,8 @@ merge_object_instances(
return rv;
}
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_AddCertToCache(
static NSSCertificate *
add_cert_to_cache(
NSSTrustDomain *td,
NSSCertificate *cert)
{
@@ -745,11 +745,10 @@ nssTrustDomain_AddCertToCache(
/* merge the instances of the cert */
if (merge_object_instances(&rvCert->object, &cert->object) != SECSuccess) {
nssCertificate_Destroy(rvCert);
nssCertificate_Destroy(cert); // consume the owned reference to cert
return NULL;
}
STAN_ForceCERTCertificateUpdate(rvCert);
nssCertificate_Destroy(cert); // consume the owned reference to cert
nssCertificate_Destroy(cert);
return rvCert;
}
/* create a new cache entry for this cert within the cert's arena*/
@@ -772,12 +771,18 @@ nssTrustDomain_AddCertToCache(
added++;
/* If a new subject entry was created, also need nickname and/or email */
if (subjectList != NULL) {
#ifdef nodef
PRBool handle = PR_FALSE;
#endif
if (certNickname) {
nssrv = add_nickname_entry(arena, td->cache,
certNickname, subjectList);
if (nssrv != PR_SUCCESS) {
goto loser;
}
#ifdef nodef
handle = PR_TRUE;
#endif
added++;
}
if (cert->email) {
@@ -785,13 +790,27 @@ nssTrustDomain_AddCertToCache(
if (nssrv != PR_SUCCESS) {
goto loser;
}
#ifdef nodef
handle = PR_TRUE;
#endif
added += 2;
}
#ifdef nodef
/* I think either a nickname or email address must be associated
* with the cert. However, certs are passed to NewTemp without
* either. This worked in the old code, so it must work now.
*/
if (!handle) {
/* Require either nickname or email handle */
nssrv = PR_FAILURE;
goto loser;
}
#endif
} else {
/* A new subject entry was not created. arena is unused. */
nssArena_Destroy(arena);
}
rvCert = cert; // rvCert is now the owned reference to cert
rvCert = cert;
PZ_Unlock(td->cache->lock);
nss_ZFreeIf(certNickname);
return rvCert;
@@ -821,10 +840,28 @@ loser:
nssArena_Destroy(arena);
}
PZ_Unlock(td->cache->lock);
nssCertificate_Destroy(cert); // consume the owned reference to cert
return NULL;
}
NSS_IMPLEMENT PRStatus
nssTrustDomain_AddCertsToCache(
NSSTrustDomain *td,
NSSCertificate **certs,
PRUint32 numCerts)
{
PRUint32 i;
NSSCertificate *c;
for (i = 0; i < numCerts && certs[i]; i++) {
c = add_cert_to_cache(td, certs[i]);
if (c == NULL) {
return PR_FAILURE;
} else {
certs[i] = c;
}
}
return PR_SUCCESS;
}
static NSSCertificate **
collect_subject_certs(
nssList *subjectList,
+4 -23
View File
@@ -1209,13 +1209,7 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
DESContext *ctxt;
unsigned int pad;
/* freebl's DES_CreateContext has no IV/key length parameters and reads
* fixed-size buffers, so reject undersized SECItems here before they can
* cause an out-of-bounds read. */
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
(key->data == NULL) ||
(key->len < (unsigned int)(triple_des ? 24 : DES_KEY_LENGTH)) ||
(iv->data == NULL) || (iv->len < DES_BLOCK_SIZE)) {
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
@@ -1291,11 +1285,7 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
AESContext *ctxt;
unsigned int pad;
/* AES_CreateContext reads AES_BLOCK_SIZE bytes of IV with no length
* parameter; reject undersized SECItems to prevent OOB reads. */
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
(key->data == NULL) || (iv->data == NULL) ||
(iv->len < AES_BLOCK_SIZE)) {
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
@@ -1370,12 +1360,7 @@ sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_de
AESKeyWrapContext *ctxt;
unsigned int pad;
/* AESKeyWrap_CreateContext reads AES_KEY_WRAP_BLOCK_SIZE bytes of IV when
* non-NULL; reject undersized SECItems to prevent OOB reads. A NULL
* iv->data is allowed and selects the default key-wrap IV. */
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
(key->data == NULL) ||
(iv->data != NULL && iv->len < AES_KEY_WRAP_BLOCK_SIZE)) {
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
@@ -1449,11 +1434,7 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
SECStatus rv = SECFailure;
int pad;
/* RC2_CreateContext reads 8 bytes of IV in CBC mode with no length
* parameter; reject undersized SECItems to prevent OOB reads. */
if ((src == NULL) || (key == NULL) || (iv == NULL) ||
(key->data == NULL) || (iv->data == NULL) ||
(iv->len < 8 /* RC2_BLOCK_SIZE */)) {
if ((src == NULL) || (key == NULL) || (iv == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
+2 -2
View File
@@ -17,10 +17,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define SOFTOKEN_VERSION "3.90.14.0 (UXP)" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VERSION "3.90.13.0 (UXP)" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 90
#define SOFTOKEN_VPATCH 14
#define SOFTOKEN_VPATCH 13
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE
+2 -2
View File
@@ -19,10 +19,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
#define NSSUTIL_VERSION "3.90.14.0 (UXP)"
#define NSSUTIL_VERSION "3.90.13.0 (UXP)"
#define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 90
#define NSSUTIL_VPATCH 14
#define NSSUTIL_VPATCH 13
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE
+4 -12
View File
@@ -175,9 +175,7 @@ MatchComponentType(const SEC_ASN1Template* templateEntry,
/* optional component. This is the hard case. Now we need to
look at the subtemplate to get the expected kind */
const SEC_ASN1Template* subTemplate =
SEC_ASN1GetSubtemplate(templateEntry,
(char*)dest + templateEntry->offset,
PR_FALSE);
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
if (!subTemplate) {
PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
return SECFailure;
@@ -403,9 +401,7 @@ DecodeInline(void* dest,
SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
const SEC_ASN1Template* inlineTemplate =
SEC_ASN1GetSubtemplate(templateEntry,
(char*)dest + templateEntry->offset,
PR_FALSE);
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
return DecodeItem((void*)((char*)dest + templateEntry->offset),
inlineTemplate, src, arena, checkTag);
}
@@ -416,9 +412,7 @@ DecodePointer(void* dest,
SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
const SEC_ASN1Template* ptrTemplate =
SEC_ASN1GetSubtemplate(templateEntry,
(char*)dest + templateEntry->offset,
PR_FALSE);
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
if (!ptrTemplate) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -504,9 +498,7 @@ DecodeGroup(void* dest,
void** entries = NULL;
const SEC_ASN1Template* subTemplate =
SEC_ASN1GetSubtemplate(templateEntry,
(char*)dest + templateEntry->offset,
PR_FALSE);
SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
source = *src;
+4
View File
@@ -32,6 +32,10 @@
#430544
**/PR_CallOnce/InitializeArenas/PR_NewLock/**
#458905
**/cert_createObject/nssTrustDomain_AddCertsToCache/add_cert_to_cache/**
**/cert_createObject/nssTrustDomain_AddCertsToCache/nssArena_Create/**
#459237
**/PR_FormatTime/strftime/**
**/PR_FormatTime/__strftime_std/**
+1 -1
View File
@@ -466,7 +466,7 @@ nsFilePicker::Open(nsIFilePickerShownCallback *aCallback)
}
if (GTK_IS_DIALOG(file_chooser)) {
gtk_dialog_set_default_response(GTK_DIALOG(file_chooser), GTK_RESPONSE_CANCEL);
gtk_dialog_set_default_response(GTK_DIALOG(file_chooser), GTK_RESPONSE_ACCEPT);
}
int32_t count = mFilters.Length();
+16 -20
View File
@@ -223,27 +223,23 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
// results
// If the user chose a Win7+ Library, resolve to the library's filesystem
// objects, like the user's Documents library (but not .library-ms files).
SFGAOF attrs = 0;
if (SUCCEEDED(item->GetAttributes(SFGAO_FILESYSTEM, &attrs)) &&
!(attrs & SFGAO_FILESYSTEM)) {
RefPtr<IShellItem> folderPath;
RefPtr<IShellLibrary> shellLib;
if (FAILED(CoCreateInstance(CLSID_ShellLibrary,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IShellLibrary,
getter_AddRefs(shellLib)))) {
return false;
}
// If the user chose a Win7 Library, resolve to the library's
// default save folder.
RefPtr<IShellItem> folderPath;
RefPtr<IShellLibrary> shellLib;
if (FAILED(CoCreateInstance(CLSID_ShellLibrary,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IShellLibrary,
getter_AddRefs(shellLib)))) {
return false;
}
if (shellLib &&
SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) &&
SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
getter_AddRefs(folderPath)))) {
item.swap(folderPath);
}
if (shellLib &&
SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) &&
SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
getter_AddRefs(folderPath)))) {
item.swap(folderPath);
}
// get the folder's file system path