forked from mirrors/gecko-dev
Merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
bdd611d2ef
28 changed files with 704 additions and 345 deletions
|
|
@ -12,11 +12,6 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsWeakPtr.h"
|
||||
|
||||
#define NS_AUDIOCHANNELAGENT_CONTRACTID "@mozilla.org/audiochannelagent;1"
|
||||
// f27688e2-3dd7-11e2-904e-10bf48d64bd4
|
||||
#define NS_AUDIOCHANNELAGENT_CID {0xf27688e2, 0x3dd7, 0x11e2, \
|
||||
{0x90, 0x4e, 0x10, 0xbf, 0x48, 0xd6, 0x4b, 0xd4}}
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
class nsPIDOMWindowOuter;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "nsILoadContext.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLObjectElementBinding.h"
|
||||
#include "AudioChannelAgent.h"
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
|
@ -1241,18 +1242,15 @@ nsNPAPIPluginInstance::CreateAudioChannelAgentIfNeeded()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
|
||||
if (NS_WARN_IF(!mAudioChannelAgent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mAudioChannelAgent = new AudioChannelAgent();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = GetDOMWindow();
|
||||
if (NS_WARN_IF(!window)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = mAudioChannelAgent->Init(window->GetCurrentInnerWindow(), this);
|
||||
nsresult rv =
|
||||
mAudioChannelAgent->Init(window->GetCurrentInnerWindow(), this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7601,9 +7601,9 @@ ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
|||
SanitizeOriginString(originSanitized);
|
||||
originScope.SetOrigin(originSanitized);
|
||||
} else if (originScope.IsPrefix()) {
|
||||
nsCString prefixSanitized(originScope.GetPrefix());
|
||||
SanitizeOriginString(prefixSanitized);
|
||||
originScope.SetPrefix(prefixSanitized);
|
||||
nsCString originNoSuffixSanitized(originScope.GetOriginNoSuffix());
|
||||
SanitizeOriginString(originNoSuffixSanitized);
|
||||
originScope.SetOriginNoSuffix(originNoSuffixSanitized);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
|
|
@ -7629,8 +7629,8 @@ ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
|||
}
|
||||
|
||||
// Skip the origin directory if it doesn't match the pattern.
|
||||
if (!originScope.MatchesOrigin(OriginScope::FromOrigin(
|
||||
NS_ConvertUTF16toUTF8(leafName)))) {
|
||||
if (!originScope.Matches(OriginScope::FromOrigin(
|
||||
NS_ConvertUTF16toUTF8(leafName)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,413 +10,473 @@
|
|||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/Variant.h"
|
||||
|
||||
BEGIN_QUOTA_NAMESPACE
|
||||
|
||||
class OriginScope
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
eOrigin,
|
||||
ePattern,
|
||||
ePrefix,
|
||||
eNull
|
||||
};
|
||||
|
||||
private:
|
||||
struct OriginAndAttributes
|
||||
class Origin
|
||||
{
|
||||
nsCString mOrigin;
|
||||
OriginAttributes mAttributes;
|
||||
nsCString mOriginNoSuffix;
|
||||
UniquePtr<OriginAttributes> mAttributes;
|
||||
|
||||
OriginAndAttributes(const OriginAndAttributes& aOther)
|
||||
: mOrigin(aOther.mOrigin)
|
||||
, mAttributes(aOther.mAttributes)
|
||||
{
|
||||
MOZ_COUNT_CTOR(OriginAndAttributes);
|
||||
}
|
||||
|
||||
explicit OriginAndAttributes(const nsACString& aOrigin)
|
||||
public:
|
||||
explicit Origin(const nsACString& aOrigin)
|
||||
: mOrigin(aOrigin)
|
||||
{
|
||||
nsCString originNoSuffix;
|
||||
MOZ_ALWAYS_TRUE(mAttributes.PopulateFromOrigin(aOrigin, originNoSuffix));
|
||||
|
||||
MOZ_COUNT_CTOR(OriginAndAttributes);
|
||||
InitMembers();
|
||||
}
|
||||
|
||||
~OriginAndAttributes()
|
||||
Origin(const Origin& aOther)
|
||||
: mOrigin(aOther.mOrigin)
|
||||
, mOriginNoSuffix(aOther.mOriginNoSuffix)
|
||||
, mAttributes(MakeUnique<OriginAttributes>(*aOther.mAttributes))
|
||||
{ }
|
||||
|
||||
Origin(Origin&& aOther) = default;
|
||||
|
||||
const nsACString&
|
||||
GetOrigin() const
|
||||
{
|
||||
MOZ_COUNT_DTOR(OriginAndAttributes);
|
||||
return mOrigin;
|
||||
}
|
||||
|
||||
void
|
||||
SetOrigin(const nsACString& aOrigin)
|
||||
{
|
||||
mOrigin = aOrigin;
|
||||
|
||||
InitMembers();
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
GetOriginNoSuffix() const
|
||||
{
|
||||
return mOriginNoSuffix;
|
||||
}
|
||||
|
||||
const OriginAttributes&
|
||||
GetAttributes() const
|
||||
{
|
||||
MOZ_ASSERT(mAttributes);
|
||||
|
||||
return *mAttributes;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
InitMembers()
|
||||
{
|
||||
mAttributes = MakeUnique<OriginAttributes>();
|
||||
|
||||
MOZ_ALWAYS_TRUE(mAttributes->PopulateFromOrigin(mOrigin,
|
||||
mOriginNoSuffix));
|
||||
}
|
||||
};
|
||||
|
||||
union {
|
||||
// eOrigin
|
||||
OriginAndAttributes* mOriginAndAttributes;
|
||||
class Prefix
|
||||
{
|
||||
nsCString mOriginNoSuffix;
|
||||
|
||||
// ePattern
|
||||
mozilla::OriginAttributesPattern* mPattern;
|
||||
public:
|
||||
explicit Prefix(const nsACString& aOriginNoSuffix)
|
||||
: mOriginNoSuffix(aOriginNoSuffix)
|
||||
{ }
|
||||
|
||||
// ePrefix
|
||||
nsCString* mPrefix;
|
||||
const nsCString&
|
||||
GetOriginNoSuffix() const
|
||||
{
|
||||
return mOriginNoSuffix;
|
||||
}
|
||||
|
||||
// eNull
|
||||
void* mDummy;
|
||||
void
|
||||
SetOriginNoSuffix(const nsACString& aOriginNoSuffix)
|
||||
{
|
||||
mOriginNoSuffix = aOriginNoSuffix;
|
||||
}
|
||||
};
|
||||
|
||||
Type mType;
|
||||
class Pattern
|
||||
{
|
||||
UniquePtr<OriginAttributesPattern> mPattern;
|
||||
|
||||
public:
|
||||
explicit Pattern(const OriginAttributesPattern& aPattern)
|
||||
: mPattern(MakeUnique<OriginAttributesPattern>(aPattern))
|
||||
{ }
|
||||
|
||||
explicit Pattern(const nsAString& aJSONPattern)
|
||||
: mPattern(MakeUnique<OriginAttributesPattern>())
|
||||
{
|
||||
MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern));
|
||||
}
|
||||
|
||||
Pattern(const Pattern& aOther)
|
||||
: mPattern(MakeUnique<OriginAttributesPattern>(*aOther.mPattern))
|
||||
{ }
|
||||
|
||||
Pattern(Pattern&& aOther) = default;
|
||||
|
||||
const OriginAttributesPattern&
|
||||
GetPattern() const
|
||||
{
|
||||
MOZ_ASSERT(mPattern);
|
||||
|
||||
return *mPattern;
|
||||
}
|
||||
|
||||
void
|
||||
SetPattern(const OriginAttributesPattern& aPattern)
|
||||
{
|
||||
mPattern = MakeUnique<OriginAttributesPattern>(aPattern);
|
||||
}
|
||||
|
||||
nsString
|
||||
GetJSONPattern() const
|
||||
{
|
||||
MOZ_ASSERT(mPattern);
|
||||
|
||||
nsString result;
|
||||
MOZ_ALWAYS_TRUE(mPattern->ToJSON(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct Null
|
||||
{ };
|
||||
|
||||
using DataType = Variant<Origin, Prefix, Pattern, Null>;
|
||||
|
||||
DataType mData;
|
||||
|
||||
public:
|
||||
OriginScope()
|
||||
: mData(Null())
|
||||
{ }
|
||||
|
||||
static OriginScope
|
||||
FromOrigin(const nsACString& aOrigin)
|
||||
{
|
||||
return OriginScope(aOrigin, true);
|
||||
}
|
||||
|
||||
static OriginScope
|
||||
FromPattern(const mozilla::OriginAttributesPattern& aPattern)
|
||||
{
|
||||
return OriginScope(aPattern);
|
||||
}
|
||||
|
||||
static OriginScope
|
||||
FromJSONPattern(const nsAString& aJSONPattern)
|
||||
{
|
||||
return OriginScope(aJSONPattern);
|
||||
return OriginScope(std::move(Origin(aOrigin)));
|
||||
}
|
||||
|
||||
static OriginScope
|
||||
FromPrefix(const nsACString& aPrefix)
|
||||
{
|
||||
return OriginScope(aPrefix, false);
|
||||
return OriginScope(std::move(Prefix(aPrefix)));
|
||||
}
|
||||
|
||||
static OriginScope
|
||||
FromPattern(const OriginAttributesPattern& aPattern)
|
||||
{
|
||||
return OriginScope(std::move(Pattern(aPattern)));
|
||||
}
|
||||
|
||||
static OriginScope
|
||||
FromJSONPattern(const nsAString& aJSONPattern)
|
||||
{
|
||||
return OriginScope(std::move(Pattern(aJSONPattern)));
|
||||
}
|
||||
|
||||
static OriginScope
|
||||
FromNull()
|
||||
{
|
||||
return OriginScope();
|
||||
}
|
||||
|
||||
OriginScope(const OriginScope& aOther)
|
||||
{
|
||||
if (aOther.IsOrigin()) {
|
||||
mOriginAndAttributes =
|
||||
new OriginAndAttributes(*aOther.mOriginAndAttributes);
|
||||
} else if (aOther.IsPattern()) {
|
||||
mPattern = new mozilla::OriginAttributesPattern(*aOther.mPattern);
|
||||
} else if (aOther.IsPrefix()) {
|
||||
mPrefix = new nsCString(*aOther.mPrefix);
|
||||
} else {
|
||||
mDummy = aOther.mDummy;
|
||||
}
|
||||
|
||||
mType = aOther.mType;
|
||||
}
|
||||
|
||||
~OriginScope()
|
||||
{
|
||||
Destroy();
|
||||
return OriginScope(std::move(Null()));
|
||||
}
|
||||
|
||||
bool
|
||||
IsOrigin() const
|
||||
{
|
||||
return mType == eOrigin;
|
||||
}
|
||||
|
||||
bool
|
||||
IsPattern() const
|
||||
{
|
||||
return mType == ePattern;
|
||||
return mData.is<Origin>();
|
||||
}
|
||||
|
||||
bool
|
||||
IsPrefix() const
|
||||
{
|
||||
return mType == ePrefix;
|
||||
return mData.is<Prefix>();
|
||||
}
|
||||
|
||||
bool
|
||||
IsPattern() const
|
||||
{
|
||||
return mData.is<Pattern>();
|
||||
}
|
||||
|
||||
bool
|
||||
IsNull() const
|
||||
{
|
||||
return mType == eNull;
|
||||
}
|
||||
|
||||
Type
|
||||
GetType() const
|
||||
{
|
||||
return mType;
|
||||
return mData.is<Null>();
|
||||
}
|
||||
|
||||
void
|
||||
SetFromOrigin(const nsACString& aOrigin)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
mOriginAndAttributes = new OriginAndAttributes(aOrigin);
|
||||
|
||||
mType = eOrigin;
|
||||
}
|
||||
|
||||
void
|
||||
SetFromPattern(const mozilla::OriginAttributesPattern& aPattern)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
mPattern = new mozilla::OriginAttributesPattern(aPattern);
|
||||
|
||||
mType = ePattern;
|
||||
}
|
||||
|
||||
void
|
||||
SetFromJSONPattern(const nsAString& aJSONPattern)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
mPattern = new mozilla::OriginAttributesPattern();
|
||||
MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern));
|
||||
|
||||
mType = ePattern;
|
||||
mData = AsVariant(Origin(aOrigin));
|
||||
}
|
||||
|
||||
void
|
||||
SetFromPrefix(const nsACString& aPrefix)
|
||||
{
|
||||
Destroy();
|
||||
mData = AsVariant(Prefix(aPrefix));
|
||||
}
|
||||
|
||||
mPrefix = new nsCString(aPrefix);
|
||||
void
|
||||
SetFromPattern(const OriginAttributesPattern& aPattern)
|
||||
{
|
||||
mData = AsVariant(Pattern(aPattern));
|
||||
}
|
||||
|
||||
mType = ePrefix;
|
||||
void
|
||||
SetFromJSONPattern(const nsAString& aJSONPattern)
|
||||
{
|
||||
mData = AsVariant(Pattern(aJSONPattern));
|
||||
}
|
||||
|
||||
void
|
||||
SetFromNull()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
mDummy = nullptr;
|
||||
|
||||
mType = eNull;
|
||||
mData = AsVariant(Null());
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
GetOrigin() const
|
||||
{
|
||||
MOZ_ASSERT(IsOrigin());
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
|
||||
return mOriginAndAttributes->mOrigin;
|
||||
return mData.as<Origin>().GetOrigin();
|
||||
}
|
||||
|
||||
void
|
||||
SetOrigin(const nsACString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(IsOrigin());
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
mOriginAndAttributes->mOrigin = aOrigin;
|
||||
}
|
||||
|
||||
const mozilla::OriginAttributes&
|
||||
GetOriginAttributes() const
|
||||
{
|
||||
MOZ_ASSERT(IsOrigin());
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
return mOriginAndAttributes->mAttributes;
|
||||
}
|
||||
|
||||
const mozilla::OriginAttributesPattern&
|
||||
GetPattern() const
|
||||
{
|
||||
MOZ_ASSERT(IsPattern());
|
||||
MOZ_ASSERT(mPattern);
|
||||
return *mPattern;
|
||||
mData.as<Origin>().SetOrigin(aOrigin);
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
GetPrefix() const
|
||||
GetOriginNoSuffix() const
|
||||
{
|
||||
MOZ_ASSERT(IsPrefix());
|
||||
MOZ_ASSERT(mPrefix);
|
||||
MOZ_ASSERT(IsOrigin() || IsPrefix());
|
||||
|
||||
return *mPrefix;
|
||||
if (IsOrigin()) {
|
||||
return mData.as<Origin>().GetOriginNoSuffix();
|
||||
}
|
||||
return mData.as<Prefix>().GetOriginNoSuffix();
|
||||
}
|
||||
|
||||
void
|
||||
SetPrefix(const nsACString& aPrefix)
|
||||
SetOriginNoSuffix(const nsACString& aOriginNoSuffix)
|
||||
{
|
||||
MOZ_ASSERT(IsPrefix());
|
||||
MOZ_ASSERT(mPrefix);
|
||||
|
||||
*mPrefix = aPrefix;
|
||||
mData.as<Prefix>().SetOriginNoSuffix(aOriginNoSuffix);
|
||||
}
|
||||
|
||||
bool MatchesOrigin(const OriginScope& aOther) const
|
||||
const OriginAttributesPattern&
|
||||
GetPattern() const
|
||||
{
|
||||
MOZ_ASSERT(aOther.IsOrigin());
|
||||
MOZ_ASSERT(aOther.mOriginAndAttributes);
|
||||
MOZ_ASSERT(IsPattern());
|
||||
|
||||
bool match;
|
||||
|
||||
if (IsOrigin()) {
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
match = mOriginAndAttributes->mOrigin.Equals(
|
||||
aOther.mOriginAndAttributes->mOrigin);
|
||||
} else if (IsPattern()) {
|
||||
MOZ_ASSERT(mPattern);
|
||||
match = mPattern->Matches(aOther.mOriginAndAttributes->mAttributes);
|
||||
} else if (IsPrefix()) {
|
||||
MOZ_ASSERT(mPrefix);
|
||||
match = StringBeginsWith(aOther.mOriginAndAttributes->mOrigin, *mPrefix);
|
||||
} else {
|
||||
match = true;
|
||||
}
|
||||
|
||||
return match;
|
||||
return mData.as<Pattern>().GetPattern();
|
||||
}
|
||||
|
||||
bool MatchesPattern(const OriginScope& aOther) const
|
||||
nsString
|
||||
GetJSONPattern() const
|
||||
{
|
||||
MOZ_ASSERT(aOther.IsPattern());
|
||||
MOZ_ASSERT(aOther.mPattern);
|
||||
MOZ_ASSERT(IsPattern());
|
||||
|
||||
bool match;
|
||||
|
||||
if (IsOrigin()) {
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
match = aOther.mPattern->Matches(mOriginAndAttributes->mAttributes);
|
||||
} else if (IsPattern()) {
|
||||
MOZ_ASSERT(mPattern);
|
||||
match = mPattern->Overlaps(*aOther.mPattern);
|
||||
} else if (IsPrefix()) {
|
||||
MOZ_ASSERT(mPrefix);
|
||||
// The match will be always true here because any origin attributes
|
||||
// pattern overlaps any origin prefix (an origin prefix targets all
|
||||
// origin attributes).
|
||||
match = true;
|
||||
} else {
|
||||
match = true;
|
||||
}
|
||||
|
||||
return match;
|
||||
return mData.as<Pattern>().GetJSONPattern();
|
||||
}
|
||||
|
||||
bool MatchesPrefix(const OriginScope& aOther) const
|
||||
void
|
||||
SetPattern(const OriginAttributesPattern& aPattern)
|
||||
{
|
||||
MOZ_ASSERT(aOther.IsPrefix());
|
||||
MOZ_ASSERT(aOther.mPrefix);
|
||||
MOZ_ASSERT(IsPattern());
|
||||
|
||||
bool match;
|
||||
|
||||
if (IsOrigin()) {
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
match = StringBeginsWith(mOriginAndAttributes->mOrigin, *aOther.mPrefix);
|
||||
} else if (IsPattern()) {
|
||||
MOZ_ASSERT(mPattern);
|
||||
// The match will be always true here because any origin attributes
|
||||
// pattern overlaps any origin prefix (an origin prefix targets all
|
||||
// origin attributes).
|
||||
match = true;
|
||||
} else if (IsPrefix()) {
|
||||
MOZ_ASSERT(mPrefix);
|
||||
match = mPrefix->Equals(*aOther.mPrefix);
|
||||
} else {
|
||||
match = true;
|
||||
}
|
||||
|
||||
return match;
|
||||
mData.as<Pattern>().SetPattern(aPattern);
|
||||
}
|
||||
|
||||
bool Matches(const OriginScope& aOther) const
|
||||
bool
|
||||
Matches(const OriginScope& aOther) const
|
||||
{
|
||||
bool match;
|
||||
struct Matcher
|
||||
{
|
||||
const OriginScope& mThis;
|
||||
|
||||
if (aOther.IsOrigin()) {
|
||||
match = MatchesOrigin(aOther);
|
||||
} else if (aOther.IsPattern()) {
|
||||
match = MatchesPattern(aOther);
|
||||
} else if (aOther.IsPrefix()) {
|
||||
match = MatchesPrefix(aOther);
|
||||
} else {
|
||||
match = true;
|
||||
}
|
||||
explicit Matcher(const OriginScope& aThis)
|
||||
: mThis(aThis)
|
||||
{ }
|
||||
|
||||
return match;
|
||||
bool
|
||||
match(const Origin& aOther) {
|
||||
return mThis.MatchesOrigin(aOther);
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Prefix& aOther) {
|
||||
return mThis.MatchesPrefix(aOther);
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Pattern& aOther) {
|
||||
return mThis.MatchesPattern(aOther);
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Null& aOther) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return aOther.mData.match(Matcher(*this));
|
||||
}
|
||||
|
||||
OriginScope
|
||||
Clone()
|
||||
{
|
||||
if (IsOrigin()) {
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
return OriginScope(*mOriginAndAttributes);
|
||||
}
|
||||
|
||||
if (IsPattern()) {
|
||||
MOZ_ASSERT(mPattern);
|
||||
return OriginScope(*mPattern);
|
||||
}
|
||||
|
||||
if (IsPrefix()) {
|
||||
MOZ_ASSERT(mPrefix);
|
||||
return OriginScope(*mPrefix, false);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsNull());
|
||||
return OriginScope();
|
||||
return OriginScope(mData);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit OriginScope(const OriginAndAttributes& aOriginAndAttributes)
|
||||
: mOriginAndAttributes(new OriginAndAttributes(aOriginAndAttributes))
|
||||
, mType(eOrigin)
|
||||
// Move constructors
|
||||
explicit OriginScope(const Origin&& aOrigin)
|
||||
: mData(aOrigin)
|
||||
{ }
|
||||
|
||||
explicit OriginScope(const nsACString& aOriginOrPrefix, bool aOrigin)
|
||||
explicit OriginScope(const Prefix&& aPrefix)
|
||||
: mData(aPrefix)
|
||||
{ }
|
||||
|
||||
explicit OriginScope(const Pattern&& aPattern)
|
||||
: mData(aPattern)
|
||||
{ }
|
||||
|
||||
explicit OriginScope(const Null&& aNull)
|
||||
: mData(aNull)
|
||||
{ }
|
||||
|
||||
// Copy constructor
|
||||
explicit OriginScope(const DataType& aOther)
|
||||
: mData(aOther)
|
||||
{ }
|
||||
|
||||
bool
|
||||
MatchesOrigin(const Origin& aOther) const
|
||||
{
|
||||
if (aOrigin) {
|
||||
mOriginAndAttributes = new OriginAndAttributes(aOriginOrPrefix);
|
||||
mType = eOrigin;
|
||||
} else {
|
||||
mPrefix = new nsCString(aOriginOrPrefix);
|
||||
mType = ePrefix;
|
||||
}
|
||||
struct OriginMatcher
|
||||
{
|
||||
const Origin& mOther;
|
||||
|
||||
explicit OriginMatcher(const Origin& aOther)
|
||||
: mOther(aOther)
|
||||
{ }
|
||||
|
||||
bool
|
||||
match(const Origin& aThis) {
|
||||
return aThis.GetOrigin().Equals(mOther.GetOrigin());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Prefix& aThis) {
|
||||
return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Pattern& aThis) {
|
||||
return aThis.GetPattern().Matches(mOther.GetAttributes());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Null& aThis) {
|
||||
// Null covers everything.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return mData.match(OriginMatcher(aOther));
|
||||
}
|
||||
|
||||
explicit OriginScope(const mozilla::OriginAttributesPattern& aPattern)
|
||||
: mPattern(new mozilla::OriginAttributesPattern(aPattern))
|
||||
, mType(ePattern)
|
||||
{ }
|
||||
|
||||
explicit OriginScope(const nsAString& aJSONPattern)
|
||||
: mPattern(new mozilla::OriginAttributesPattern())
|
||||
, mType(ePattern)
|
||||
bool
|
||||
MatchesPrefix(const Prefix& aOther) const
|
||||
{
|
||||
MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern));
|
||||
struct PrefixMatcher
|
||||
{
|
||||
const Prefix& mOther;
|
||||
|
||||
explicit PrefixMatcher(const Prefix& aOther)
|
||||
: mOther(aOther)
|
||||
{ }
|
||||
|
||||
bool
|
||||
match(const Origin& aThis) {
|
||||
return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Prefix& aThis) {
|
||||
return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Pattern& aThis) {
|
||||
// The match will be always true here because any origin attributes
|
||||
// pattern overlaps any origin prefix (an origin prefix targets all
|
||||
// origin attributes).
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Null& aThis) {
|
||||
// Null covers everything.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return mData.match(PrefixMatcher(aOther));
|
||||
}
|
||||
|
||||
OriginScope()
|
||||
: mDummy(nullptr)
|
||||
, mType(eNull)
|
||||
{ }
|
||||
|
||||
void
|
||||
Destroy()
|
||||
bool
|
||||
MatchesPattern(const Pattern& aOther) const
|
||||
{
|
||||
if (IsOrigin()) {
|
||||
MOZ_ASSERT(mOriginAndAttributes);
|
||||
delete mOriginAndAttributes;
|
||||
mOriginAndAttributes = nullptr;
|
||||
} else if (IsPattern()) {
|
||||
MOZ_ASSERT(mPattern);
|
||||
delete mPattern;
|
||||
mPattern = nullptr;
|
||||
} else if (IsPrefix()) {
|
||||
MOZ_ASSERT(mPrefix);
|
||||
delete mPrefix;
|
||||
mPrefix = nullptr;
|
||||
}
|
||||
struct PatternMatcher
|
||||
{
|
||||
const Pattern& mOther;
|
||||
|
||||
explicit PatternMatcher(const Pattern& aOther)
|
||||
: mOther(aOther)
|
||||
{ }
|
||||
|
||||
bool
|
||||
match(const Origin& aThis) {
|
||||
return mOther.GetPattern().Matches(aThis.GetAttributes());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Prefix& aThis) {
|
||||
// The match will be always true here because any origin attributes
|
||||
// pattern overlaps any origin prefix (an origin prefix targets all
|
||||
// origin attributes).
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Pattern& aThis) {
|
||||
return aThis.GetPattern().Overlaps(mOther.GetPattern());
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Null& aThis) {
|
||||
// Null covers everything.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
PatternMatcher patternMatcher(aOther);
|
||||
return mData.match(PatternMatcher(aOther));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ TEST_HARNESS_FILES.xpcshell.dom.quota.test += [
|
|||
'test/head-shared.js',
|
||||
]
|
||||
|
||||
TEST_DIRS += ['test/gtest']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIQuotaCallbacks.idl',
|
||||
'nsIQuotaManagerService.idl',
|
||||
|
|
@ -67,6 +69,7 @@ IPDL_SOURCES += [
|
|||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/caps',
|
||||
]
|
||||
|
|
|
|||
125
dom/quota/test/gtest/TestQuotaManager.cpp
Normal file
125
dom/quota/test/gtest/TestQuotaManager.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/dom/quota/OriginScope.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom::quota;
|
||||
|
||||
namespace {
|
||||
|
||||
struct OriginTest {
|
||||
const char* mOrigin;
|
||||
bool mMatch;
|
||||
};
|
||||
|
||||
void
|
||||
CheckOriginScopeMatchesOrigin(const OriginScope& aOriginScope,
|
||||
const char* aOrigin,
|
||||
bool aMatch)
|
||||
{
|
||||
bool result =
|
||||
aOriginScope.Matches(OriginScope::FromOrigin(nsDependentCString(aOrigin)));
|
||||
|
||||
EXPECT_TRUE(result == aMatch);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(QuotaManager, OriginScope)
|
||||
{
|
||||
OriginScope originScope;
|
||||
|
||||
// Sanity checks.
|
||||
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(origin, "http://www.mozilla.org");
|
||||
originScope.SetFromOrigin(origin);
|
||||
EXPECT_TRUE(originScope.IsOrigin());
|
||||
EXPECT_TRUE(originScope.GetOrigin().Equals(origin));
|
||||
EXPECT_TRUE(originScope.GetOriginNoSuffix().Equals(origin));
|
||||
}
|
||||
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(prefix, "http://www.mozilla.org");
|
||||
originScope.SetFromPrefix(prefix);
|
||||
EXPECT_TRUE(originScope.IsPrefix());
|
||||
EXPECT_TRUE(originScope.GetOriginNoSuffix().Equals(prefix));
|
||||
}
|
||||
|
||||
{
|
||||
NS_NAMED_LITERAL_STRING(pattern, "{\"appId\":1007}");
|
||||
originScope.SetFromJSONPattern(pattern);
|
||||
EXPECT_TRUE(originScope.IsPattern());
|
||||
EXPECT_TRUE(originScope.GetJSONPattern().Equals(pattern));
|
||||
}
|
||||
|
||||
{
|
||||
originScope.SetFromNull();
|
||||
EXPECT_TRUE(originScope.IsNull());
|
||||
}
|
||||
|
||||
// Test each origin scope type against particular origins.
|
||||
|
||||
{
|
||||
originScope.SetFromOrigin(NS_LITERAL_CSTRING("http://www.mozilla.org"));
|
||||
|
||||
static const OriginTest tests[] = {
|
||||
{ "http://www.mozilla.org", true },
|
||||
{ "http://www.example.org", false },
|
||||
};
|
||||
|
||||
for (const auto& test : tests) {
|
||||
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
originScope.SetFromPrefix(NS_LITERAL_CSTRING("http://www.mozilla.org"));
|
||||
|
||||
static const OriginTest tests[] = {
|
||||
{ "http://www.mozilla.org", true },
|
||||
{ "http://www.mozilla.org^userContextId=1", true },
|
||||
{ "http://www.example.org^userContextId=1", false },
|
||||
};
|
||||
|
||||
for (const auto& test : tests) {
|
||||
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
originScope.SetFromJSONPattern(NS_LITERAL_STRING("{\"appId\":1007}"));
|
||||
|
||||
static const OriginTest tests[] = {
|
||||
{ "http+++www.mozilla.org^appId=1007", true },
|
||||
{ "http+++www.example.org^appId=1007", true },
|
||||
{ "http+++www.example.org^appId=1008", false },
|
||||
};
|
||||
|
||||
for (const auto& test : tests) {
|
||||
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
originScope.SetFromNull();
|
||||
|
||||
static const OriginTest tests[] = {
|
||||
{ "http://www.mozilla.org", true },
|
||||
{ "http://www.mozilla.org^userContextId=1", true },
|
||||
{ "http://www.example.org^userContextId=1", true },
|
||||
{ "http+++www.mozilla.org^appId=1007", true },
|
||||
{ "http+++www.example.org^appId=1007", true },
|
||||
{ "http+++www.example.org^appId=1008", true },
|
||||
};
|
||||
|
||||
for (const auto& test : tests) {
|
||||
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
17
dom/quota/test/gtest/moz.build
Normal file
17
dom/quota/test/gtest/moz.build
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES = [
|
||||
'TestQuotaManager.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul-gtest'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/quota',
|
||||
]
|
||||
|
|
@ -599,6 +599,9 @@ class NodeBuilder
|
|||
MOZ_MUST_USE bool metaProperty(HandleValue meta, HandleValue property, TokenPos* pos,
|
||||
MutableHandleValue dst);
|
||||
|
||||
MOZ_MUST_USE bool callImportExpression(HandleValue ident, HandleValue arg, TokenPos* pos,
|
||||
MutableHandleValue dst);
|
||||
|
||||
MOZ_MUST_USE bool super(TokenPos* pos, MutableHandleValue dst);
|
||||
|
||||
/*
|
||||
|
|
@ -1599,6 +1602,20 @@ NodeBuilder::metaProperty(HandleValue meta, HandleValue property, TokenPos* pos,
|
|||
dst);
|
||||
}
|
||||
|
||||
bool
|
||||
NodeBuilder::callImportExpression(HandleValue ident, HandleValue arg, TokenPos* pos,
|
||||
MutableHandleValue dst)
|
||||
{
|
||||
RootedValue cb(cx, callbacks[AST_CALL_IMPORT]);
|
||||
if (!cb.isNull())
|
||||
return callback(cb, arg, pos, dst);
|
||||
|
||||
return newNode(AST_CALL_IMPORT, pos,
|
||||
"ident", ident,
|
||||
"arg", arg,
|
||||
dst);
|
||||
}
|
||||
|
||||
bool
|
||||
NodeBuilder::super(TokenPos* pos, MutableHandleValue dst)
|
||||
{
|
||||
|
|
@ -2950,6 +2967,21 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
builder.metaProperty(firstIdent, secondIdent, &pn->pn_pos, dst);
|
||||
}
|
||||
|
||||
case ParseNodeKind::CallImport:
|
||||
{
|
||||
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
|
||||
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
|
||||
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
|
||||
|
||||
RootedValue ident(cx);
|
||||
RootedValue arg(cx);
|
||||
|
||||
HandlePropertyName name = cx->names().import;
|
||||
return identifier(name, &pn->pn_left->pn_pos, &ident) &&
|
||||
expression(pn->pn_right, &arg) &&
|
||||
builder.callImportExpression(ident, arg, &pn->pn_pos, dst);
|
||||
}
|
||||
|
||||
case ParseNodeKind::SetThis:
|
||||
// SETTHIS is used to assign the result of a super() call to |this|.
|
||||
// It's not part of the original AST, so just forward to the call.
|
||||
|
|
|
|||
|
|
@ -1217,6 +1217,11 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
*answer = true;
|
||||
return true;
|
||||
|
||||
case ParseNodeKind::CallImport:
|
||||
MOZ_ASSERT(pn->isArity(PN_BINARY));
|
||||
*answer = true;
|
||||
return true;
|
||||
|
||||
// Every part of a loop might be effect-free, but looping infinitely *is*
|
||||
// an effect. (Language lawyer trivia: C++ says threads can be assumed
|
||||
// to exit or have side effects, C++14 [intro.multithread]p27, so a C++
|
||||
|
|
@ -8308,6 +8313,10 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
|||
return false;
|
||||
break;
|
||||
|
||||
case ParseNodeKind::CallImport:
|
||||
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
|
||||
return false;
|
||||
|
||||
case ParseNodeKind::SetThis:
|
||||
if (!emitSetThis(pn))
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ ContainsHoistedDeclaration(JSContext* cx, ParseNode* node, bool* result)
|
|||
case ParseNodeKind::ExportSpec:
|
||||
case ParseNodeKind::Export:
|
||||
case ParseNodeKind::ExportBatchSpec:
|
||||
case ParseNodeKind::CallImport:
|
||||
*result = false;
|
||||
return true;
|
||||
|
||||
|
|
@ -1755,6 +1756,11 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
|
|||
MOZ_ASSERT(pn->pn_right->isKind(ParseNodeKind::PosHolder));
|
||||
return true;
|
||||
|
||||
case ParseNodeKind::CallImport:
|
||||
MOZ_ASSERT(pn->isArity(PN_BINARY));
|
||||
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
|
||||
return Fold(cx, &pn->pn_right, parser);
|
||||
|
||||
case ParseNodeKind::ClassNames:
|
||||
MOZ_ASSERT(pn->isArity(PN_BINARY));
|
||||
if (ParseNode*& outerBinding = pn->pn_left) {
|
||||
|
|
|
|||
|
|
@ -562,6 +562,10 @@ class FullParseHandler
|
|||
return new_<BinaryNode>(ParseNodeKind::ImportMeta, JSOP_NOP, importHolder, metaHolder);
|
||||
}
|
||||
|
||||
ParseNode* newCallImport(ParseNode* importHolder, ParseNode* singleArg) {
|
||||
return new_<BinaryNode>(ParseNodeKind::CallImport, JSOP_NOP, importHolder, singleArg);
|
||||
}
|
||||
|
||||
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
|
||||
MOZ_ASSERT(expr->pn_pos.end <= end);
|
||||
return new_<UnaryNode>(ParseNodeKind::ExpressionStatement,
|
||||
|
|
|
|||
|
|
@ -786,6 +786,12 @@ class NameResolver
|
|||
break;
|
||||
}
|
||||
|
||||
case ParseNodeKind::CallImport:
|
||||
MOZ_ASSERT(cur->isArity(PN_BINARY));
|
||||
if (!resolve(cur->pn_right, prefix))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case ParseNodeKind::Dot:
|
||||
MOZ_ASSERT(cur->isArity(PN_BINARY));
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ class ObjectBox;
|
|||
F(SuperCall) \
|
||||
F(SetThis) \
|
||||
F(ImportMeta) \
|
||||
F(CallImport) \
|
||||
\
|
||||
/* Unary operators. */ \
|
||||
F(TypeOfName) \
|
||||
|
|
|
|||
|
|
@ -5442,7 +5442,7 @@ GeneralParser<ParseHandler, CharT>::importDeclaration()
|
|||
|
||||
template <class ParseHandler, typename CharT>
|
||||
inline typename ParseHandler::Node
|
||||
GeneralParser<ParseHandler, CharT>::importDeclarationOrImportMeta(YieldHandling yieldHandling)
|
||||
GeneralParser<ParseHandler, CharT>::importDeclarationOrImportExpr(YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
|
||||
|
||||
|
|
@ -5450,7 +5450,7 @@ GeneralParser<ParseHandler, CharT>::importDeclarationOrImportMeta(YieldHandling
|
|||
if (!tokenStream.peekToken(&tt))
|
||||
return null();
|
||||
|
||||
if (tt == TokenKind::Dot)
|
||||
if (tt == TokenKind::Dot || tt == TokenKind::LeftParen)
|
||||
return expressionStatement(yieldHandling);
|
||||
|
||||
return importDeclaration();
|
||||
|
|
@ -7811,7 +7811,7 @@ GeneralParser<ParseHandler, CharT>::statement(YieldHandling yieldHandling)
|
|||
|
||||
// ImportDeclaration (only inside modules)
|
||||
case TokenKind::Import:
|
||||
return importDeclarationOrImportMeta(yieldHandling);
|
||||
return importDeclarationOrImportExpr(yieldHandling);
|
||||
|
||||
// ExportDeclaration (only inside modules)
|
||||
case TokenKind::Export:
|
||||
|
|
@ -8004,7 +8004,7 @@ GeneralParser<ParseHandler, CharT>::statementListItem(YieldHandling yieldHandlin
|
|||
|
||||
// ImportDeclaration (only inside modules)
|
||||
case TokenKind::Import:
|
||||
return importDeclarationOrImportMeta(yieldHandling);
|
||||
return importDeclarationOrImportExpr(yieldHandling);
|
||||
|
||||
// ExportDeclaration (only inside modules)
|
||||
case TokenKind::Export:
|
||||
|
|
@ -8841,7 +8841,7 @@ GeneralParser<ParseHandler, CharT>::memberExpr(YieldHandling yieldHandling,
|
|||
if (!lhs)
|
||||
return null();
|
||||
} else if (tt == TokenKind::Import) {
|
||||
lhs = importMeta();
|
||||
lhs = importExpr(yieldHandling);
|
||||
if (!lhs)
|
||||
return null();
|
||||
} else {
|
||||
|
|
@ -10024,17 +10024,10 @@ GeneralParser<ParseHandler, CharT>::tryNewTarget(Node &newTarget)
|
|||
|
||||
template <class ParseHandler, typename CharT>
|
||||
typename ParseHandler::Node
|
||||
GeneralParser<ParseHandler, CharT>::importMeta()
|
||||
GeneralParser<ParseHandler, CharT>::importExpr(YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
|
||||
|
||||
uint32_t begin = pos().begin;
|
||||
|
||||
if (parseGoal() != ParseGoal::Module) {
|
||||
errorAt(begin, JSMSG_IMPORT_OUTSIDE_MODULE);
|
||||
return null();
|
||||
}
|
||||
|
||||
Node importHolder = handler.newPosHolder(pos());
|
||||
if (!importHolder)
|
||||
return null();
|
||||
|
|
@ -10042,23 +10035,37 @@ GeneralParser<ParseHandler, CharT>::importMeta()
|
|||
TokenKind next;
|
||||
if (!tokenStream.getToken(&next))
|
||||
return null();
|
||||
if (next != TokenKind::Dot) {
|
||||
error(JSMSG_UNEXPECTED_TOKEN, "dot", TokenKindToDesc(next));
|
||||
|
||||
if (next == TokenKind::Dot) {
|
||||
if (!tokenStream.getToken(&next))
|
||||
return null();
|
||||
if (next != TokenKind::Meta) {
|
||||
error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
|
||||
return null();
|
||||
}
|
||||
|
||||
if (parseGoal() != ParseGoal::Module) {
|
||||
errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
|
||||
return null();
|
||||
}
|
||||
|
||||
Node metaHolder = handler.newPosHolder(pos());
|
||||
if (!metaHolder)
|
||||
return null();
|
||||
|
||||
return handler.newImportMeta(importHolder, metaHolder);
|
||||
} else if (next == TokenKind::LeftParen) {
|
||||
Node arg = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!arg)
|
||||
return null();
|
||||
|
||||
MUST_MATCH_TOKEN_MOD(TokenKind::RightParen, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
|
||||
|
||||
return handler.newCallImport(importHolder, arg);
|
||||
} else {
|
||||
error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
|
||||
return null();
|
||||
}
|
||||
|
||||
if (!tokenStream.getToken(&next))
|
||||
return null();
|
||||
if (next != TokenKind::Meta) {
|
||||
error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
|
||||
return null();
|
||||
}
|
||||
|
||||
Node metaHolder = handler.newPosHolder(pos());
|
||||
if (!metaHolder)
|
||||
return null();
|
||||
|
||||
return handler.newImportMeta(importHolder, metaHolder);
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
|
|
|
|||
|
|
@ -1045,7 +1045,7 @@ class MOZ_STACK_CLASS GeneralParser
|
|||
Node lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
|
||||
|
||||
inline Node importDeclaration();
|
||||
Node importDeclarationOrImportMeta(YieldHandling yieldHandling);
|
||||
Node importDeclarationOrImportExpr(YieldHandling yieldHandling);
|
||||
|
||||
Node exportFrom(uint32_t begin, Node specList);
|
||||
Node exportBatch(uint32_t begin);
|
||||
|
|
@ -1145,7 +1145,7 @@ class MOZ_STACK_CLASS GeneralParser
|
|||
|
||||
bool tryNewTarget(Node& newTarget);
|
||||
|
||||
Node importMeta();
|
||||
Node importExpr(YieldHandling yieldHandling);
|
||||
|
||||
Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
|
||||
|
||||
|
|
|
|||
|
|
@ -302,6 +302,9 @@ class SyntaxParseHandler
|
|||
Node newImportMeta(Node importHolder, Node metaHolder) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
Node newCallImport(Node importHolder, Node singleArg) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
Node newSetThis(Node thisName, Node value) { return value; }
|
||||
|
||||
|
|
|
|||
85
js/src/jit-test/tests/modules/dynamic-import-expression.js
Normal file
85
js/src/jit-test/tests/modules/dynamic-import-expression.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
load(libdir + "match.js");
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var { Pattern, MatchError } = Match;
|
||||
|
||||
program = (elts) => Pattern({
|
||||
type: "Program",
|
||||
body: elts
|
||||
});
|
||||
expressionStatement = (expression) => Pattern({
|
||||
type: "ExpressionStatement",
|
||||
expression: expression
|
||||
});
|
||||
assignmentExpression = (left, operator, right) => Pattern({
|
||||
type: "AssignmentExpression",
|
||||
operator: operator,
|
||||
left: left,
|
||||
right: right
|
||||
});
|
||||
ident = (name) => Pattern({
|
||||
type: "Identifier",
|
||||
name: name
|
||||
});
|
||||
importCall = (ident, singleArg) => Pattern({
|
||||
type: "CallImport",
|
||||
ident: ident,
|
||||
arg: singleArg
|
||||
});
|
||||
|
||||
function parseAsClassicScript(source)
|
||||
{
|
||||
return Reflect.parse(source);
|
||||
}
|
||||
|
||||
function parseAsModuleScript(source)
|
||||
{
|
||||
return Reflect.parse(source, {target: "module"});
|
||||
}
|
||||
|
||||
for (let parse of [parseAsModuleScript, parseAsClassicScript]) {
|
||||
program([
|
||||
expressionStatement(
|
||||
importCall(
|
||||
ident("import"),
|
||||
ident("foo")
|
||||
)
|
||||
)
|
||||
]).assert(parse("import(foo);"));
|
||||
|
||||
program([
|
||||
expressionStatement(
|
||||
assignmentExpression(
|
||||
ident("x"),
|
||||
"=",
|
||||
importCall(
|
||||
ident("import"),
|
||||
ident("foo")
|
||||
)
|
||||
)
|
||||
)
|
||||
]).assert(parse("x = import(foo);"));
|
||||
}
|
||||
|
||||
function assertParseThrowsSyntaxError(source)
|
||||
{
|
||||
assertThrowsInstanceOf(() => parseAsClassicScript(source), SyntaxError);
|
||||
assertThrowsInstanceOf(() => parseAsModuleScript(source), SyntaxError);
|
||||
}
|
||||
|
||||
assertParseThrowsSyntaxError("import");
|
||||
assertParseThrowsSyntaxError("import(");
|
||||
assertParseThrowsSyntaxError("import(1,");
|
||||
assertParseThrowsSyntaxError("import(1, 2");
|
||||
assertParseThrowsSyntaxError("import(1, 2)");
|
||||
assertParseThrowsSyntaxError("x = import");
|
||||
assertParseThrowsSyntaxError("x = import(");
|
||||
assertParseThrowsSyntaxError("x = import(1,");
|
||||
assertParseThrowsSyntaxError("x = import(1, 2");
|
||||
assertParseThrowsSyntaxError("x = import(1, 2)");
|
||||
|
||||
// import() is not implemented.
|
||||
assertThrowsInstanceOf(() => eval("import('foo')"),
|
||||
SyntaxError);
|
||||
assertThrowsInstanceOf(() => parseModule("import('foo')"),
|
||||
SyntaxError);
|
||||
|
|
@ -263,7 +263,7 @@ MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage a
|
|||
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
|
||||
MSG_DEF(JSMSG_BAD_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid escape sequence")
|
||||
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
|
||||
MSG_DEF(JSMSG_IMPORT_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "the import keyword may only appear in a module")
|
||||
MSG_DEF(JSMSG_IMPORT_META_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "import.meta may only appear in a module")
|
||||
MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module")
|
||||
MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer")
|
||||
MSG_DEF(JSMSG_IN_AFTER_LEXICAL_FOR_DECL,0,JSEXN_SYNTAXERR, "a lexical declaration in the head of a for-in loop can't have an initializer")
|
||||
|
|
@ -606,6 +606,7 @@ MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 0, JSEXN_SYNTAXERR, "ambiguous import")
|
|||
MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace")
|
||||
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
|
||||
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
|
||||
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
|
||||
|
||||
// Promise
|
||||
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpres
|
|||
ASTDEF(AST_CLASS_EXPR, "ClassExpression", "classExpression")
|
||||
ASTDEF(AST_METAPROPERTY, "MetaProperty", "metaProperty")
|
||||
ASTDEF(AST_SUPER, "Super", "super")
|
||||
ASTDEF(AST_CALL_IMPORT, "CallImport", "callImport")
|
||||
|
||||
ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement")
|
||||
ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement")
|
||||
|
|
|
|||
|
|
@ -90,9 +90,6 @@ using mozilla::dom::PushNotifier;
|
|||
#define PUSHNOTIFIER_CID \
|
||||
{ 0x2fc2d3e3, 0x020f, 0x404e, { 0xb0, 0x6a, 0x6e, 0xcf, 0x3e, 0xa2, 0x33, 0x4a } }
|
||||
|
||||
#include "AudioChannelAgent.h"
|
||||
using mozilla::dom::AudioChannelAgent;
|
||||
|
||||
// Editor stuff
|
||||
#include "mozilla/EditorController.h" //CID
|
||||
|
||||
|
|
@ -140,7 +137,6 @@ static void Shutdown();
|
|||
#include "nsIMediaManager.h"
|
||||
#include "mozilla/dom/nsMixedContentBlocker.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
#include "mozilla/net/WebSocketEventService.h"
|
||||
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
|
|
@ -211,8 +207,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSynthVoiceRegistry,
|
|||
nsSynthVoiceRegistry::GetInstanceForService)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(AudioChannelAgent)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceSensors)
|
||||
|
||||
#if defined(ANDROID)
|
||||
|
|
@ -424,14 +418,9 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
|
|||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(Geolocation, Geolocation::NonWindowSingleton)
|
||||
|
||||
#define NS_AUDIOCHANNEL_SERVICE_CID \
|
||||
{ 0xf712e983, 0x048a, 0x443f, { 0x88, 0x02, 0xfc, 0xc3, 0xd9, 0x27, 0xce, 0xac }}
|
||||
|
||||
#define NS_WEBSOCKETEVENT_SERVICE_CID \
|
||||
{ 0x31689828, 0xda66, 0x49a6, { 0x87, 0x0c, 0xdf, 0x62, 0xb8, 0x3f, 0xe7, 0x89 }}
|
||||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AudioChannelService, AudioChannelService::GetOrCreate)
|
||||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WebSocketEventService, WebSocketEventService::GetOrCreate)
|
||||
|
||||
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
|
||||
|
|
@ -535,13 +524,11 @@ NS_DEFINE_NAMED_CID(STORAGEACTIVITYSERVICE_CID);
|
|||
NS_DEFINE_NAMED_CID(NOTIFICATIONTELEMETRYSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(PUSHNOTIFIER_CID);
|
||||
NS_DEFINE_NAMED_CID(WORKERDEBUGGERMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNELAGENT_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EDITORCONTROLLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EDITINGCONTROLLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EDITORCOMMANDTABLE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EDITINGCOMMANDTABLE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNEL_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_WEBSOCKETEVENT_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FOCUSMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CONTENTSECURITYMANAGER_CID);
|
||||
|
|
@ -765,13 +752,11 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
|||
{ &kNOTIFICATIONTELEMETRYSERVICE_CID, false, nullptr, NotificationTelemetryServiceConstructor },
|
||||
{ &kPUSHNOTIFIER_CID, false, nullptr, PushNotifierConstructor },
|
||||
{ &kWORKERDEBUGGERMANAGER_CID, true, nullptr, WorkerDebuggerManagerConstructor },
|
||||
{ &kNS_AUDIOCHANNELAGENT_CID, true, nullptr, AudioChannelAgentConstructor },
|
||||
{ &kNS_EDITORCONTROLLER_CID, false, nullptr, EditorControllerConstructor },
|
||||
{ &kNS_EDITINGCONTROLLER_CID, false, nullptr, nsEditingControllerConstructor },
|
||||
{ &kNS_EDITORCOMMANDTABLE_CID, false, nullptr, nsEditorCommandTableConstructor },
|
||||
{ &kNS_EDITINGCOMMANDTABLE_CID, false, nullptr, nsEditingCommandTableConstructor },
|
||||
{ &kNS_GEOLOCATION_CID, false, nullptr, GeolocationConstructor },
|
||||
{ &kNS_AUDIOCHANNEL_SERVICE_CID, false, nullptr, AudioChannelServiceConstructor },
|
||||
{ &kNS_WEBSOCKETEVENT_SERVICE_CID, false, nullptr, WebSocketEventServiceConstructor },
|
||||
{ &kNS_FOCUSMANAGER_CID, false, nullptr, CreateFocusManager },
|
||||
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
|
||||
|
|
@ -865,11 +850,9 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
|||
{ NOTIFICATIONTELEMETRYSERVICE_CONTRACTID, &kNOTIFICATIONTELEMETRYSERVICE_CID },
|
||||
{ PUSHNOTIFIER_CONTRACTID, &kPUSHNOTIFIER_CID },
|
||||
{ WORKERDEBUGGERMANAGER_CONTRACTID, &kWORKERDEBUGGERMANAGER_CID },
|
||||
{ NS_AUDIOCHANNELAGENT_CONTRACTID, &kNS_AUDIOCHANNELAGENT_CID },
|
||||
{ "@mozilla.org/editor/editorcontroller;1", &kNS_EDITORCONTROLLER_CID },
|
||||
{ "@mozilla.org/editor/editingcontroller;1", &kNS_EDITINGCONTROLLER_CID },
|
||||
{ "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_CID },
|
||||
{ "@mozilla.org/audiochannel/service;1", &kNS_AUDIOCHANNEL_SERVICE_CID },
|
||||
{ "@mozilla.org/websocketevent/service;1", &kNS_WEBSOCKETEVENT_SERVICE_CID },
|
||||
{ "@mozilla.org/focus-manager;1", &kNS_FOCUSMANAGER_CID },
|
||||
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ set -x -e -v
|
|||
|
||||
OWNER=luser
|
||||
PROJECT=rust-size
|
||||
PROJECT_REVISION=4a5d9148f50dc037dc230f10b8fc4e5ca00016aa
|
||||
PROJECT_REVISION=ab659d93b1faba95307df952aefe3fbed3583669
|
||||
|
||||
# This script is for building rust-size
|
||||
case "$(uname -s)" in
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
[dynamic-imports-fetch-error.sub.html]
|
||||
expected: ERROR
|
||||
[import(): error cases occuring during fetching]
|
||||
expected: FAIL
|
||||
|
||||
[import() must reject when there is a wrong MIME type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
[dynamic-imports-script-error.html]
|
||||
expected: ERROR
|
||||
[import(): error cases caused by the imported module script]
|
||||
expected: FAIL
|
||||
|
||||
[import() must reject when there is a parse error]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -2,3 +2,6 @@
|
|||
[Basic dynamic imports]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamic imports should resolve module.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,6 @@
|
|||
[propagate-nonce-external-classic]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,6 @@
|
|||
[propagate-nonce-external-module]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,6 @@
|
|||
[propagate-nonce-inline-classic]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,6 @@
|
|||
[propagate-nonce-inline-module]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue