Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2017-02-15 12:59:23 +01:00
commit dacc230ad3
323 changed files with 3060 additions and 7105 deletions

View File

@ -2,13 +2,15 @@
# 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/.
GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
GARBAGE += $(MIDL_GENERATED_FILES) done_gen
MIDL_GENERATED_FILES = \
IGeckoCustom.h \
IGeckoCustom_p.c \
IGeckoCustom_i.c \
$(NULL)
dlldata.c \
IGeckoCustom.h \
IGeckoCustom_p.c \
IGeckoCustom_i.c \
IGeckoCustom.tlb \
$(NULL)
$(MIDL_GENERATED_FILES): done_gen

View File

@ -11,7 +11,11 @@ SOURCES += [
]
GENERATED_FILES += [
'dlldata.c',
'IGeckoCustom.h',
'IGeckoCustom.tlb',
'IGeckoCustom_i.c',
'IGeckoCustom_p.c',
]
FINAL_LIBRARY = 'xul'

View File

@ -6,6 +6,8 @@ IA2DIR = $(topsrcdir)/other-licenses/ia2
GARBAGE += $(MIDL_GENERATED_FILES) \
$(MIDL_UNUSED_GENERATED_FILES) \
midl_done \
typelib_done \
$(NULL)
# Please keep this list in sync with the moz.build file until the rest of this
@ -53,10 +55,11 @@ CSRCS = \
MIDL_GENERATED_FILES = \
dlldata.c \
$(MIDL_ENUMS:%.idl=%.h) \
$(MIDL_INTERFACES:%.idl=%_p.c) \
$(MIDL_INTERFACES:%.idl=%_i.c) \
$(MIDL_INTERFACES:%.idl=%.h) \
$(MIDL_ENUMS:%.idl=%.h) \
$(MIDL_LIBRARIES:%.idl=%.tlb) \
$(NULL)
# We want to generate a .tlb from MIDL_LIBRARIES, but midl also generates
@ -80,8 +83,8 @@ export:: midl
include $(topsrcdir)/config/rules.mk
# generate list of to-be-generated files that are missing
# but ignore special file dlldata.c
missing:=$(strip $(foreach onefile,$(strip $(subst dlldata.c,,$(MIDL_GENERATED_FILES))),$(if $(wildcard $(onefile)),,$(onefile))))
# but ignore special file dlldata.c and .tlb files
missing:=$(strip $(foreach onefile,$(strip $(patsubst %.tlb,,$(subst dlldata.c,,$(MIDL_GENERATED_FILES)))),$(if $(wildcard $(onefile)),,$(onefile))))
missing_base:=$(sort $(basename $(subst _p.c,,$(subst _i.c,,$(missing)))))
@ -99,9 +102,9 @@ midl_done : $(addprefix $(IA2DIR)/,$(MIDL_INTERFACES) $(MIDL_ENUMS))
# The intent of this rule is to generate the .tlb file that is referenced in the
# .rc file for IA2Marshal.dll
typelib_done : $(MIDL_LIBRARIES)
typelib_done : $(addprefix $(srcdir)/,$(MIDL_LIBRARIES))
for idl in $?; do \
$(MIDL) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -D _MIDL_DECLARE_WIREM_HANDLE -dlldata `basename $$idl .idl`.c -Oicf $$idl; \
$(MIDL) $(MIDL_FLAGS) -app_config -I $(IA2DIR) -D _MIDL_DECLARE_WIREM_HANDLE -dlldata `basename $$idl .idl`.c -Oicf $$idl; \
done
touch $@

View File

@ -19,6 +19,68 @@ OS_LIBS += [
]
GENERATED_FILES += [
'Accessible2.h',
'Accessible2_2.h',
'Accessible2_2_i.c',
'Accessible2_2_p.c',
'Accessible2_3.h',
'Accessible2_3_i.c',
'Accessible2_3_p.c',
'Accessible2_i.c',
'Accessible2_p.c',
'AccessibleAction.h',
'AccessibleAction_i.c',
'AccessibleAction_p.c',
'AccessibleApplication.h',
'AccessibleApplication_i.c',
'AccessibleApplication_p.c',
'AccessibleComponent.h',
'AccessibleComponent_i.c',
'AccessibleComponent_p.c',
'AccessibleDocument.h',
'AccessibleDocument_i.c',
'AccessibleDocument_p.c',
'AccessibleEditableText.h',
'AccessibleEditableText_i.c',
'AccessibleEditableText_p.c',
'AccessibleEventId.h',
'AccessibleHyperlink.h',
'AccessibleHyperlink_i.c',
'AccessibleHyperlink_p.c',
'AccessibleHypertext.h',
'AccessibleHypertext2.h',
'AccessibleHypertext2_i.c',
'AccessibleHypertext2_p.c',
'AccessibleHypertext_i.c',
'AccessibleHypertext_p.c',
'AccessibleImage.h',
'AccessibleImage_i.c',
'AccessibleImage_p.c',
'AccessibleRelation.h',
'AccessibleRelation_i.c',
'AccessibleRelation_p.c',
'AccessibleRole.h',
'AccessibleStates.h',
'AccessibleTable.h',
'AccessibleTable2.h',
'AccessibleTable2_i.c',
'AccessibleTable2_p.c',
'AccessibleTable_i.c',
'AccessibleTable_p.c',
'AccessibleTableCell.h',
'AccessibleTableCell_i.c',
'AccessibleTableCell_p.c',
'AccessibleText.h',
'AccessibleText2.h',
'AccessibleText2_i.c',
'AccessibleText2_p.c',
'AccessibleText_i.c',
'AccessibleText_p.c',
'AccessibleValue.h',
'AccessibleValue_i.c',
'AccessibleValue_p.c',
'dlldata.c',
'IA2CommonTypes.h',
'IA2Typelib.tlb',
]

View File

@ -2,19 +2,21 @@
# 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/.
GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
GARBAGE += $(MIDL_GENERATED_FILES) done_gen
MIDL_GENERATED_FILES = \
ISimpleDOMNode.h \
ISimpleDOMNode_p.c \
ISimpleDOMNode_i.c \
ISimpleDOMDocument.h \
ISimpleDOMDocument_p.c \
ISimpleDOMDocument_i.c \
ISimpleDOMText.h \
ISimpleDOMText_p.c \
ISimpleDOMText_i.c \
$(NULL)
dlldata.c \
ISimpleDOMNode.h \
ISimpleDOMNode_p.c \
ISimpleDOMNode_i.c \
ISimpleDOMNode.tlb \
ISimpleDOMDocument.h \
ISimpleDOMDocument_p.c \
ISimpleDOMDocument_i.c \
ISimpleDOMText.h \
ISimpleDOMText_p.c \
ISimpleDOMText_i.c \
$(NULL)
$(MIDL_GENERATED_FILES): done_gen

View File

@ -27,7 +27,17 @@ OS_LIBS += [
]
GENERATED_FILES += [
'dlldata.c',
'ISimpleDOMDocument.h',
'ISimpleDOMDocument_i.c',
'ISimpleDOMDocument_p.c',
'ISimpleDOMNode.h',
'ISimpleDOMNode.tlb',
'ISimpleDOMNode_i.c',
'ISimpleDOMNode_p.c',
'ISimpleDOMText.h',
'ISimpleDOMText_i.c',
'ISimpleDOMText_p.c',
]
RCINCLUDE = 'AccessibleMarshal.rc'

View File

@ -427,8 +427,8 @@ DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
aChildDoc->SetParent(outerDoc);
outerDoc->SetChildDoc(aChildDoc);
mChildDocs.AppendElement(aChildDoc);
aChildDoc->mParentDoc = this;
mChildDocs.AppendElement(aChildDoc->IProtocol::Id());
aChildDoc->mParentDoc = IProtocol::Id();
if (aCreating) {
ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT);
@ -471,7 +471,7 @@ DocAccessibleParent::Destroy()
}
for (uint32_t i = childDocCount - 1; i < childDocCount; i--)
mChildDocs[i]->Destroy();
ChildDocAt(i)->Destroy();
for (auto iter = mAccessibles.Iter(); !iter.Done(); iter.Next()) {
MOZ_ASSERT(iter.Get()->mProxy != this);
@ -486,21 +486,32 @@ DocAccessibleParent::Destroy()
DocManager::NotifyOfRemoteDocShutdown(this);
ProxyDestroyed(this);
if (mParentDoc)
mParentDoc->RemoveChildDoc(this);
if (DocAccessibleParent* parentDoc = ParentDoc())
parentDoc->RemoveChildDoc(this);
else if (IsTopLevel())
GetAccService()->RemoteDocShutdown(this);
}
DocAccessibleParent*
DocAccessibleParent::ParentDoc() const
{
if (mParentDoc == kNoParentDoc) {
return nullptr;
}
return LiveDocs().Get(mParentDoc);
}
bool
DocAccessibleParent::CheckDocTree() const
{
size_t childDocs = mChildDocs.Length();
for (size_t i = 0; i < childDocs; i++) {
if (!mChildDocs[i] || mChildDocs[i]->mParentDoc != this)
const DocAccessibleParent* childDoc = ChildDocAt(i);
if (!childDoc || childDoc->ParentDoc() != this)
return false;
if (!mChildDocs[i]->CheckDocTree()) {
if (!childDoc->CheckDocTree()) {
return false;
}
}

View File

@ -28,7 +28,7 @@ class DocAccessibleParent : public ProxyAccessible,
{
public:
DocAccessibleParent() :
ProxyAccessible(this), mParentDoc(nullptr),
ProxyAccessible(this), mParentDoc(kNoParentDoc),
mTopLevel(false), mShutdown(false)
#if defined(XP_WIN)
, mEmulatedWindowHandle(nullptr)
@ -36,6 +36,7 @@ public:
{ MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
~DocAccessibleParent()
{
LiveDocs().Remove(IProtocol::Id());
MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
MOZ_ASSERT(mChildDocs.Length() == 0);
MOZ_ASSERT(!ParentDoc());
@ -58,6 +59,11 @@ public:
mShutdown = true;
}
/**
* Add this document to the set of tracked documents.
*/
void AddToMap() { LiveDocs().Put(IProtocol::Id(), this); }
/*
* Called when a message from a document in a child process notifies the main
* process it is firing an event.
@ -111,7 +117,8 @@ public:
* Return the main processes representation of the parent document (if any)
* of the document this object represents.
*/
DocAccessibleParent* ParentDoc() const { return mParentDoc; }
DocAccessibleParent* ParentDoc() const;
static const int32_t kNoParentDoc = INT32_MIN;
/*
* Called when a document in a content process notifies the main process of a
@ -131,8 +138,8 @@ public:
if (parent) {
aChildDoc->Parent()->ClearChildDoc(aChildDoc);
}
DebugOnly<bool> result = mChildDocs.RemoveElement(aChildDoc);
aChildDoc->mParentDoc = nullptr;
DebugOnly<bool> result = mChildDocs.RemoveElement(aChildDoc->IProtocol::Id());
aChildDoc->mParentDoc = kNoParentDoc;
MOZ_ASSERT(result);
MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0);
}
@ -160,7 +167,9 @@ public:
size_t ChildDocCount() const { return mChildDocs.Length(); }
const DocAccessibleParent* ChildDocAt(size_t aIdx) const
{ return mChildDocs[aIdx]; }
{ return const_cast<DocAccessibleParent*>(this)->ChildDocAt(aIdx); }
DocAccessibleParent* ChildDocAt(size_t aIdx)
{ return LiveDocs().Get(mChildDocs[aIdx]); }
#if defined(XP_WIN)
void SetCOMProxy(const RefPtr<IAccessible>& aCOMProxy);
@ -207,8 +216,8 @@ private:
MOZ_MUST_USE bool CheckDocTree() const;
xpcAccessibleGeneric* GetXPCAccessible(ProxyAccessible* aProxy);
nsTArray<DocAccessibleParent*> mChildDocs;
DocAccessibleParent* mParentDoc;
nsTArray<int32_t> mChildDocs;
int32_t mParentDoc;
#if defined(XP_WIN)
// The handle associated with the emulated window that contains this document
@ -222,6 +231,13 @@ private:
nsTHashtable<ProxyEntry> mAccessibles;
bool mTopLevel;
bool mShutdown;
static nsDataHashtable<nsUint64HashKey, DocAccessibleParent*>&
LiveDocs()
{
static nsDataHashtable<nsUint64HashKey, DocAccessibleParent*> sLiveDocs;
return sLiveDocs;
}
};
}

View File

@ -3,6 +3,9 @@
/certutil
/firefox-bin
/gtest/***
#if defined(MOZ_ASAN) || defined(MOZ_TSAN)
/llvm-symbolizer
#endif
/pingsender
/pk12util
/ssltunnel

View File

@ -1377,6 +1377,12 @@ pref("media.eme.enabled", false);
pref("media.eme.enabled", true);
#endif
#ifdef NIGHTLY_BUILD
pref("media.eme.vp9-in-mp4.enabled", true);
#else
pref("media.eme.vp9-in-mp4.enabled", false);
#endif
// Whether we should run a test-pattern through EME GMPs before assuming they'll
// decode H.264.
pref("media.gmp.trial-create.enabled", true);

View File

@ -34,7 +34,7 @@ struct RedirEntry {
required before adding new map entries without
URI_SAFE_FOR_UNTRUSTED_CONTENT.
*/
static RedirEntry kRedirMap[] = {
static const RedirEntry kRedirMap[] = {
{ "blocked", "chrome://browser/content/blockedSite.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |

View File

@ -1,20 +1,24 @@
. $topsrcdir/build/unix/mozconfig.asan
# Use at least -O1 for optimization to avoid stack space
# exhaustions caused by Clang function inlining.
ac_add_options --enable-application=browser
ac_add_options --enable-debug
ac_add_options --enable-optimize="-O1"
. $topsrcdir/build/unix/mozconfig.asan
# Enable Telemetry
export MOZ_TELEMETRY_REPORTING=1
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
ac_add_options --with-macbundlename-prefix=Firefox
fi
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1
# Need this to prevent name conflicts with the normal nightly build packages
# Before mozconfig.common so we can test for asan builds there
export MOZ_PKG_SPECIAL=asan
. "$topsrcdir/build/macosx/mozconfig.common"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -0,0 +1,23 @@
ac_add_options --enable-application=browser
# We still need to build with debug symbols
ac_add_options --disable-debug
ac_add_options --enable-optimize="-O2"
. $topsrcdir/build/unix/mozconfig.asan
# Enable Telemetry
export MOZ_TELEMETRY_REPORTING=1
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
ac_add_options --with-macbundlename-prefix=Firefox
fi
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1
# Need this to prevent name conflicts with the normal nightly build packages
# Before mozconfig.common so we can test for asan builds there
export MOZ_PKG_SPECIAL=asan
. "$topsrcdir/build/macosx/mozconfig.common"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -41,11 +41,7 @@ html|*.pointerlockfswarning-domain {
margin: 0;
}
html|*.pointerlockfswarning-exit-button {
padding: 5px 30px;
font: message-box;
font-size: 14px;
font-weight: lighter;
html|*#fullscreen-exit-button {
margin: 0;
box-sizing: content-box;
}
}

View File

@ -82,6 +82,7 @@ AC_CHECK_PROGS(LIPO, "${TOOLCHAIN_PREFIX}lipo", :)
AC_CHECK_PROGS(STRIP, "${TOOLCHAIN_PREFIX}strip", :)
AC_CHECK_PROGS(WINDRES, "${TOOLCHAIN_PREFIX}windres", :)
AC_CHECK_PROGS(OTOOL, "${TOOLCHAIN_PREFIX}otool", :)
AC_CHECK_PROGS(INSTALL_NAME_TOOL, "${TOOLCHAIN_PREFIX}install_name_tool", :)
AC_CHECK_PROGS(OBJCOPY, "${TOOLCHAIN_PREFIX}objcopy", :)
PATH=$_SAVE_PATH
])

View File

@ -45,8 +45,11 @@ export HOST_LDFLAGS="-g"
ac_add_options --target=x86_64-apple-darwin
ac_add_options --with-macos-private-frameworks=$CROSS_PRIVATE_FRAMEWORKS
# Enable static analysis checks by default on OSX cross builds.
ac_add_options --enable-clang-plugin
if [ "x$MOZ_PKG_SPECIAL" != "xasan" ]; then
# Enable static analysis checks by default on OSX cross builds.
# Exception is ASan, where this breaks.
ac_add_options --enable-clang-plugin
fi
. "$topsrcdir/build/mozconfig.cache"

View File

@ -2,6 +2,7 @@
# 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/.
import re
import sys
import os
import subprocess
@ -17,6 +18,35 @@ reference it with absolute paths but with @executable_path instead.
# This is the dylib we're looking for
DYLIB_NAME='libclang_rt.asan_osx_dynamic.dylib'
def resolve_rpath(filename):
otoolOut = subprocess.check_output([substs['OTOOL'], '-l', filename])
currentCmd = None
# The lines we need to find look like this:
# ...
# Load command 22
# cmd LC_RPATH
# cmdsize 80
# path /home/build/src/clang/bin/../lib/clang/3.8.0/lib/darwin (offset 12)
# Load command 23
# ...
# Other load command types have a varying number of fields.
for line in otoolOut.splitlines():
cmdMatch = re.match(r'^\s+cmd ([A-Z_]+)', line)
if cmdMatch is not None:
currentCmd = cmdMatch.group(1)
continue
if currentCmd == 'LC_RPATH':
pathMatch = re.match(r'^\s+path (.*) \(offset \d+\)', line)
if pathMatch is not None:
path = pathMatch.group(1)
if os.path.isdir(path):
return path
sys.stderr.write('@rpath could not be resolved from %s\n' % filename)
exit(1)
def scan_directory(path):
dylibCopied = False
@ -43,16 +73,22 @@ def scan_directory(path):
continue
if not dylibCopied:
if absDylibPath.find('@rpath/') == 0:
rpath = resolve_rpath(filename)
copyDylibPath = absDylibPath.replace('@rpath', rpath)
else:
copyDylibPath = absDylibPath
# Copy the runtime once to the main directory, which is passed
# as the argument to this function.
shutil.copy(absDylibPath, path)
shutil.copy(copyDylibPath, path)
# Now rewrite the library itself
subprocess.check_call(['install_name_tool', '-id', '@executable_path/' + DYLIB_NAME, os.path.join(path, DYLIB_NAME)])
subprocess.check_call([substs['INSTALL_NAME_TOOL'], '-id', '@executable_path/' + DYLIB_NAME, os.path.join(path, DYLIB_NAME)])
dylibCopied = True
# Now use install_name_tool to rewrite the path in our binary
subprocess.check_call(['install_name_tool', '-change', absDylibPath, '@executable_path/' + DYLIB_NAME, filename])
subprocess.check_call([substs['INSTALL_NAME_TOOL'], '-change', absDylibPath, '@executable_path/' + DYLIB_NAME, filename])
break
if __name__ == '__main__':

View File

@ -147,12 +147,12 @@ networkMenu.sortedDesc=Sorted descending
# in the network table footer when there are no requests available.
networkMenu.empty=No requests
# LOCALIZATION NOTE (networkMenu.summary): Semi-colon list of plural forms.
# LOCALIZATION NOTE (networkMenu.summary2): Semi-colon list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# This label is displayed in the network table footer providing concise
# information about all requests. Parameters: #1 is the number of requests,
# #2 is the size, #3 is the number of seconds.
networkMenu.summary=One request, #2 KB, #3 s;#1 requests, #2 KB, #3 s
# #2 is the size, #3 is the transferred size, #4 is the number of seconds.
networkMenu.summary2=One request, #2 KB (transferred: #3 KB), #4 s;#1 requests, #2 KB (transferred: #3 KB), #4 s
# LOCALIZATION NOTE (networkMenu.sizeB): This is the label displayed
# in the network menu specifying the size of a request (in bytes).
@ -225,10 +225,22 @@ tableChart.unavailable=No data available
# in pie or table charts specifying the size of a request (in kilobytes).
charts.sizeKB=%S KB
# LOCALIZATION NOTE (charts.transferredSizeKB): This is the label displayed
# in pie or table charts specifying the size of a transferred request (in kilobytes).
charts.transferredSizeKB=%S KB
# LOCALIZATION NOTE (charts.totalS): This is the label displayed
# in pie or table charts specifying the time for a request to finish (in seconds).
charts.totalS=%S s
# LOCALIZATION NOTE (charts.totalS): This is the label displayed
# in the performance analysis view for total requests size, in kilobytes.
charts.totalSize=Size: %S KB
# LOCALIZATION NOTE (charts.totalTranferredSize): This is the label displayed
# in the performance analysis view for total transferred size, in kilobytes.
charts.totalTransferredSize=Transferred Size: %S KB
# LOCALIZATION NOTE (charts.cacheEnabled): This is the label displayed
# in the performance analysis view for "cache enabled" charts.
charts.cacheEnabled=Primed cache
@ -255,6 +267,23 @@ charts.totalCached=Cached responses: %S
# in the performance analysis view for total requests.
charts.totalCount=Total requests: %S
# LOCALIZATION NOTE (charts.totalCount): This is the label displayed
# in the header column in the performance analysis view for size of the request.
charts.size=Size
# LOCALIZATION NOTE (charts.totalCount): This is the label displayed
# in the header column in the performance analysis view for type of request.
charts.type=Type
# LOCALIZATION NOTE (charts.totalCount): This is the label displayed
# in the header column in the performance analysis view for transferred
# size of the request.
charts.transferred=Transferred
# LOCALIZATION NOTE (charts.totalCount): This is the label displayed
# in the header column in the performance analysis view for time of request.
charts.time=Time
# LOCALIZATION NOTE (netRequest.headers): A label used for Headers tab
# This tab displays list of HTTP headers
netRequest.headers=Headers
@ -753,3 +782,6 @@ netmonitor.backButton=Back
# LOCALIZATION NOTE (netmonitor.headers.learnMore): This is the label displayed
# next to a header list item, with a link to external documentation
netmonitor.headers.learnMore=Learn More

View File

@ -89,7 +89,6 @@ const RequestList = createClass({
},
componentWillUnmount() {
Prefs.filters = this.props.activeFilters;
this.splitter.removeEventListener("mouseup", this.resize);
window.removeEventListener("resize", this.resize);
},

View File

@ -53,13 +53,13 @@ const StatisticsPanel = createClass({
this.createChart({
id: "primedCacheChart",
title: CHARTS_CACHE_ENABLED,
data: ready ? this.sanitizeChartDataSource(requests, false) : null,
data: ready ? this.sanitizeChartDataSource(requests, false) : null
});
this.createChart({
id: "emptyCacheChart",
title: CHARTS_CACHE_DISABLED,
data: ready ? this.sanitizeChartDataSource(requests, true) : null,
data: ready ? this.sanitizeChartDataSource(requests, true) : null
});
},
@ -68,18 +68,32 @@ const StatisticsPanel = createClass({
let chart = Chart.PieTable(document, {
diameter: NETWORK_ANALYSIS_PIE_CHART_DIAMETER,
title,
header: {
cached: "",
count: "",
label: L10N.getStr("charts.type"),
size: L10N.getStr("charts.size"),
transferredSize: L10N.getStr("charts.transferred"),
time: L10N.getStr("charts.time")
},
data,
strings: {
size: (value) =>
L10N.getFormatStr("charts.sizeKB", getSizeWithDecimals(value / 1024)),
transferredSize: (value) =>
L10N.getFormatStr("charts.transferredSizeKB",
getSizeWithDecimals(value / 1024)),
time: (value) =>
L10N.getFormatStr("charts.totalS", getTimeWithDecimals(value / 1000)),
L10N.getFormatStr("charts.totalS", getTimeWithDecimals(value / 1000))
},
totals: {
cached: (total) => L10N.getFormatStr("charts.totalCached", total),
count: (total) => L10N.getFormatStr("charts.totalCount", total),
size: (total) =>
L10N.getFormatStr("charts.totalSize", getSizeWithDecimals(total / 1024)),
transferredSize: total =>
L10N.getFormatStr("charts.totalTransferredSize",
getSizeWithDecimals(total / 1024)),
time: (total) => {
let seconds = total / 1000;
let string = getTimeWithDecimals(seconds);
@ -107,9 +121,16 @@ const StatisticsPanel = createClass({
},
sanitizeChartDataSource(requests, emptyCache) {
let data = [
const data = [
"html", "css", "js", "xhr", "fonts", "images", "media", "flash", "ws", "other"
].map((type) => ({ cached: 0, count: 0, label: type, size: 0, time: 0 }));
].map((type) => ({
cached: 0,
count: 0,
label: type,
size: 0,
transferredSize: 0,
time: 0
}));
for (let request of requests) {
let type;
@ -150,6 +171,7 @@ const StatisticsPanel = createClass({
if (emptyCache || !this.responseIsFresh(request)) {
data[type].time += request.totalTime || 0;
data[type].size += request.contentSize || 0;
data[type].transferredSize += request.transferredSize || 0;
} else {
data[type].cached++;
}

View File

@ -57,12 +57,13 @@ function Toolbar({
toggleButtonClassName.push("pane-collapsed");
}
let { count, bytes, millis } = summary;
let { count, contentSize, transferredSize, millis } = summary;
const text = (count === 0) ? L10N.getStr("networkMenu.empty") :
PluralForm.get(count, L10N.getStr("networkMenu.summary"))
PluralForm.get(count, L10N.getStr("networkMenu.summary2"))
.replace("#1", count)
.replace("#2", getSizeWithDecimals(bytes / 1024))
.replace("#3", getTimeWithDecimals(millis / 1000));
.replace("#2", getSizeWithDecimals(contentSize / 1024))
.replace("#3", getSizeWithDecimals(transferredSize / 1024))
.replace("#4", getTimeWithDecimals(millis / 1000));
const buttons = requestFilterTypes.entrySeq().map(([type, checked]) => {
let classList = ["devtools-button"];

View File

@ -4,4 +4,5 @@
DevToolsModules(
'batching.js',
'prefs.js',
)

View File

@ -0,0 +1,29 @@
/* 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/. */
"use strict";
const {
ENABLE_REQUEST_FILTER_TYPE_ONLY,
TOGGLE_REQUEST_FILTER_TYPE,
} = require("../constants");
const { Prefs } = require("../prefs");
const { getActiveFilters } = require("../selectors/index");
/**
* Whenever the User clicks on a filter in the network monitor, save the new
* filters for future tabs
*/
function prefsMiddleware(store) {
return next => action => {
const res = next(action);
if (action.type === ENABLE_REQUEST_FILTER_TYPE_ONLY ||
action.type === TOGGLE_REQUEST_FILTER_TYPE) {
Prefs.filters = getActiveFilters(store.getState());
}
return res;
};
}
module.exports = prefsMiddleware;

View File

@ -77,16 +77,22 @@ const getDisplayedRequestsSummary = createSelector(
return { count: 0, bytes: 0, millis: 0 };
}
const totalBytes = requests.reduce((total, item) => {
const totalBytes = requests.reduce((totals, item) => {
if (typeof item.contentSize == "number") {
total += item.contentSize;
totals.contentSize += item.contentSize;
}
return total;
}, 0);
if (typeof item.transferredSize == "number") {
totals.transferredSize += item.transferredSize;
}
return totals;
}, { contentSize: 0, transferredSize: 0 });
return {
count: requests.size,
bytes: totalBytes,
contentSize: totalBytes.contentSize,
transferredSize: totalBytes.transferredSize,
millis: totalMillis,
};
}

View File

@ -7,6 +7,7 @@
const { createStore, applyMiddleware } = require("devtools/client/shared/vendor/redux");
const { thunk } = require("devtools/client/shared/redux/middleware/thunk");
const batching = require("./middleware/batching");
const prefs = require("./middleware/prefs");
const rootReducer = require("./reducers/index");
function configureStore() {
@ -14,6 +15,7 @@ function configureStore() {
rootReducer,
applyMiddleware(
thunk,
prefs,
batching
)
);

View File

@ -34,6 +34,10 @@ add_task(function* () {
totals: {
label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
label2: value => "World " + L10N.numberWithDecimals(value, 2)
},
header: {
label1: "label1header",
label2: "label2header",
}
});
@ -52,39 +56,49 @@ add_task(function* () {
is(title.textContent, "Table title",
"The title node displays the correct text.");
is(rows.length, 3, "There should be 3 table chart rows created.");
is(rows.length, 4, "There should be 3 table chart rows and a header created.");
ok(rows[0].querySelector(".table-chart-row-box.chart-colored-blob"),
"A colored blob exists for the firt row.");
is(rows[0].querySelectorAll("span")[0].getAttribute("name"), "label1",
"The first column of the first row exists.");
"The first column of the header exists.");
is(rows[0].querySelectorAll("span")[1].getAttribute("name"), "label2",
"The second column of the first row exists.");
is(rows[0].querySelectorAll("span")[0].textContent, "1",
"The first column of the first row displays the correct text.");
is(rows[0].querySelectorAll("span")[1].textContent, "11.1foo",
"The second column of the first row displays the correct text.");
"The second column of the header exists.");
is(rows[0].querySelectorAll("span")[0].textContent, "label1header",
"The first column of the header displays the correct text.");
is(rows[0].querySelectorAll("span")[1].textContent, "label2header",
"The second column of the header displays the correct text.");
ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"),
"A colored blob exists for the second row.");
"A colored blob exists for the firt row.");
is(rows[1].querySelectorAll("span")[0].getAttribute("name"), "label1",
"The first column of the second row exists.");
"The first column of the first row exists.");
is(rows[1].querySelectorAll("span")[1].getAttribute("name"), "label2",
"The second column of the second row exists.");
is(rows[1].querySelectorAll("span")[0].textContent, "2",
"The first column of the second row displays the correct text.");
is(rows[1].querySelectorAll("span")[1].textContent, "12.2bar",
"The second column of the first row exists.");
is(rows[1].querySelectorAll("span")[0].textContent, "1",
"The first column of the first row displays the correct text.");
is(rows[1].querySelectorAll("span")[1].textContent, "11.1foo",
"The second column of the first row displays the correct text.");
ok(rows[2].querySelector(".table-chart-row-box.chart-colored-blob"),
"A colored blob exists for the third row.");
"A colored blob exists for the second row.");
is(rows[2].querySelectorAll("span")[0].getAttribute("name"), "label1",
"The first column of the third row exists.");
"The first column of the second row exists.");
is(rows[2].querySelectorAll("span")[1].getAttribute("name"), "label2",
"The second column of the second row exists.");
is(rows[2].querySelectorAll("span")[0].textContent, "2",
"The first column of the second row displays the correct text.");
is(rows[2].querySelectorAll("span")[1].textContent, "12.2bar",
"The second column of the first row displays the correct text.");
ok(rows[3].querySelector(".table-chart-row-box.chart-colored-blob"),
"A colored blob exists for the third row.");
is(rows[3].querySelectorAll("span")[0].getAttribute("name"), "label1",
"The first column of the third row exists.");
is(rows[3].querySelectorAll("span")[1].getAttribute("name"), "label2",
"The second column of the third row exists.");
is(rows[2].querySelectorAll("span")[0].textContent, "3",
is(rows[3].querySelectorAll("span")[0].textContent, "3",
"The first column of the third row displays the correct text.");
is(rows[2].querySelectorAll("span")[1].textContent, "13.3baz",
is(rows[3].querySelectorAll("span")[1].textContent, "13.3baz",
"The second column of the third row displays the correct text.");
is(sums.length, 2, "There should be 2 total summaries created.");

View File

@ -23,6 +23,10 @@ add_task(function* () {
totals: {
label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
label2: value => "World " + L10N.numberWithDecimals(value, 2)
},
header: {
label1: "",
label2: ""
}
});
@ -41,17 +45,17 @@ add_task(function* () {
is(title.textContent, "Table title",
"The title node displays the correct text.");
is(rows.length, 1, "There should be 1 table chart row created.");
is(rows.length, 2, "There should be 1 table chart row and a 1 header created.");
ok(rows[0].querySelector(".table-chart-row-box.chart-colored-blob"),
ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"),
"A colored blob exists for the firt row.");
is(rows[0].querySelectorAll("span")[0].getAttribute("name"), "size",
is(rows[1].querySelectorAll("span")[0].getAttribute("name"), "size",
"The first column of the first row exists.");
is(rows[0].querySelectorAll("span")[1].getAttribute("name"), "label",
is(rows[1].querySelectorAll("span")[1].getAttribute("name"), "label",
"The second column of the first row exists.");
is(rows[0].querySelectorAll("span")[0].textContent, "",
is(rows[1].querySelectorAll("span")[0].textContent, "",
"The first column of the first row displays the correct text.");
is(rows[0].querySelectorAll("span")[1].textContent,
is(rows[1].querySelectorAll("span")[1].textContent,
L10N.getStr("tableChart.loading"),
"The second column of the first row displays the correct text.");

View File

@ -34,6 +34,10 @@ add_task(function* () {
totals: {
size: value => "Hello " + L10N.numberWithDecimals(value, 2),
label: value => "World " + L10N.numberWithDecimals(value, 2)
},
header: {
label1: "",
label2: ""
}
});
@ -54,9 +58,9 @@ add_task(function* () {
ok(node.querySelector(".table-chart-container"),
"A table chart was created successfully.");
is(rows.length, 3, "There should be 3 pie chart slices created.");
is(rows.length, 3, "There should be 3 table chart rows created.");
is(sums.length, 2, "There should be 2 total summaries created.");
is(rows.length, 4, "There should be 3 pie chart slices and 1 header created.");
is(rows.length, 4, "There should be 3 table chart rows and 1 header created.");
is(sums.length, 2, "There should be 2 total summaries and 1 header created.");
yield teardown(monitor);
});

View File

@ -21,6 +21,10 @@ add_task(function* () {
totals: {
label1: value => "Hello " + L10N.numberWithDecimals(value, 2),
label2: value => "World " + L10N.numberWithDecimals(value, 2)
},
header: {
label1: "",
label2: ""
}
});
@ -30,17 +34,17 @@ add_task(function* () {
let rows = grid.querySelectorAll(".table-chart-row");
let sums = node.querySelectorAll(".table-chart-summary-label");
is(rows.length, 1, "There should be 1 table chart row created.");
is(rows.length, 2, "There should be 1 table chart row and 1 header created.");
ok(rows[0].querySelector(".table-chart-row-box.chart-colored-blob"),
ok(rows[1].querySelector(".table-chart-row-box.chart-colored-blob"),
"A colored blob exists for the firt row.");
is(rows[0].querySelectorAll("span")[0].getAttribute("name"), "size",
is(rows[1].querySelectorAll("span")[0].getAttribute("name"), "size",
"The first column of the first row exists.");
is(rows[0].querySelectorAll("span")[1].getAttribute("name"), "label",
is(rows[1].querySelectorAll("span")[1].getAttribute("name"), "label",
"The second column of the first row exists.");
is(rows[0].querySelectorAll("span")[0].textContent, "",
is(rows[1].querySelectorAll("span")[0].textContent, "",
"The first column of the first row displays the correct text.");
is(rows[0].querySelectorAll("span")[1].textContent,
is(rows[1].querySelectorAll("span")[1].textContent,
L10N.getStr("tableChart.unavailable"),
"The second column of the first row displays the correct text.");

View File

@ -30,7 +30,7 @@ const REQUESTS_WITH_MEDIA_AND_FLASH_AND_WS = REQUESTS_WITH_MEDIA_AND_FLASH.conca
]);
add_task(function* () {
Services.prefs.setCharPref("devtools.netmonitor.filters", '["js", "bogus"]');
Services.prefs.setCharPref("devtools.netmonitor.filters", '["bogus", "js", "alsobogus"]');
let { monitor } = yield initNetMonitor(FILTERING_URL);
info("Starting test... ");
@ -41,12 +41,10 @@ add_task(function* () {
gStore.dispatch(Actions.batchEnable(false));
is(Prefs.filters.length, 2,
"All filter types were loaded as an array from the preferences.");
is(Prefs.filters.length, 1,
"Only the valid filter types should be loaded, the others should be ignored");
is(Prefs.filters[0], "js",
"The first filter type is correct.");
is(Prefs.filters[1], "bogus",
"The second filter type is invalid, but loaded anyway.");
"The only filter type is correct.");
let wait = waitForNetworkEvents(monitor, 9);
loadCommonFrameScript();

View File

@ -61,10 +61,11 @@ add_task(function* () {
info(`Computed total bytes: ${requestsSummary.bytes}`);
info(`Computed total millis: ${requestsSummary.millis}`);
is(value, PluralForm.get(requestsSummary.count, L10N.getStr("networkMenu.summary"))
is(value, PluralForm.get(requestsSummary.count, L10N.getStr("networkMenu.summary2"))
.replace("#1", requestsSummary.count)
.replace("#2", L10N.numberWithDecimals(requestsSummary.bytes / 1024, 2))
.replace("#3", L10N.numberWithDecimals(requestsSummary.millis / 1000, 2))
.replace("#2", L10N.numberWithDecimals(requestsSummary.contentSize / 1024, 2))
.replace("#3", L10N.numberWithDecimals(requestsSummary.transferredSize / 1024, 2))
.replace("#4", L10N.numberWithDecimals(requestsSummary.millis / 1000, 2))
, "The current summary text is correct.");
}
});

View File

@ -94,7 +94,7 @@ function PieTableChart(node, pie, table) {
* - "click", when the mouse enters a slice or a row
*/
function createPieTableChart(document,
{ title, diameter, data, strings, totals, sorted }) {
{ title, diameter, data, strings, totals, sorted, header }) {
if (data && sorted) {
data = data.slice().sort((a, b) => +(a.size < b.size));
}
@ -108,7 +108,8 @@ function createPieTableChart(document,
title: title,
data: data,
strings: strings,
totals: totals
totals: totals,
header: header,
});
let container = document.createElement("div");
@ -327,7 +328,7 @@ function createPieChart(document, { data, width, height, centerX, centerY, radiu
* - "mouseout", when the mouse leaves a row
* - "click", when the mouse clicks a row
*/
function createTableChart(document, { title, data, strings, totals }) {
function createTableChart(document, { title, data, strings, totals, header }) {
strings = strings || {};
totals = totals || {};
let isPlaceholder = false;
@ -362,6 +363,24 @@ function createTableChart(document, { title, data, strings, totals }) {
tableNode.setAttribute("style", "-moz-box-orient: vertical");
container.appendChild(tableNode);
const headerNode = document.createElement("div");
headerNode.className = "table-chart-row";
const headerBoxNode = document.createElement("div");
headerBoxNode.className = "table-chart-row-box";
headerNode.appendChild(headerBoxNode);
for (let [key, value] of Object.entries(header)) {
let headerLabelNode = document.createElement("span");
headerLabelNode.className = "plain table-chart-row-label";
headerLabelNode.setAttribute("name", key);
headerLabelNode.textContent = value;
headerNode.appendChild(headerLabelNode);
}
tableNode.appendChild(headerNode);
for (let rowInfo of data) {
let rowNode = document.createElement("div");
rowNode.className = "table-chart-row";

View File

@ -78,7 +78,7 @@ struct DeserializedNode {
const char16_t* typeName,
uint64_t size,
EdgeVector&& edges,
Maybe<StackFrameId> allocationStack,
const Maybe<StackFrameId>& allocationStack,
const char* className,
const char* filename,
HeapSnapshot& owner)

View File

@ -29,7 +29,7 @@ struct RedirEntry
URI_SAFE_FOR_UNTRUSTED_CONTENT will allow random web sites to link to that
URI. Perhaps we should separate the two concepts out...
*/
static RedirEntry kRedirMap[] = {
static const RedirEntry kRedirMap[] = {
{
"", "chrome://global/content/about.xhtml",
nsIAboutModule::ALLOW_SCRIPT

View File

@ -146,9 +146,6 @@ DOM4_MSG_DEF(NetworkError, "Push service unreachable.", NS_ERROR_DOM_PUSH_SERVIC
DOM4_MSG_DEF(InvalidAccessError, "Invalid raw ECDSA P-256 public key.", NS_ERROR_DOM_PUSH_INVALID_KEY_ERR)
DOM4_MSG_DEF(InvalidStateError, "A subscription with a different application server key already exists.", NS_ERROR_DOM_PUSH_MISMATCHED_KEY_ERR)
DOM_MSG_DEF(NS_ERROR_DOM_JS_EXCEPTION, "A callback threw an exception")
DOM_MSG_DEF(NS_ERROR_DOM_DOMEXCEPTION, "A DOMException was thrown")
/* Media errors */
DOM4_MSG_DEF(AbortError, "The fetching process for the media resource was aborted by the user agent at the user's request.", NS_ERROR_DOM_MEDIA_ABORT_ERR)
DOM4_MSG_DEF(NotAllowedError, "The play method is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.", NS_ERROR_DOM_MEDIA_NOT_ALLOWED_ERR)

View File

@ -289,12 +289,12 @@ TErrorResult<CleanupPolicy>::ThrowJSException(JSContext* cx, JS::Handle<JS::Valu
// root.
mJSException.setUndefined();
if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) {
// Don't use NS_ERROR_DOM_JS_EXCEPTION, because that indicates we have
// in fact rooted mJSException.
// Don't use NS_ERROR_INTERNAL_ERRORRESULT_JS_EXCEPTION, because that
// indicates we have in fact rooted mJSException.
mResult = NS_ERROR_OUT_OF_MEMORY;
} else {
mJSException = exn;
mResult = NS_ERROR_DOM_JS_EXCEPTION;
mResult = NS_ERROR_INTERNAL_ERRORRESULT_JS_EXCEPTION;
#ifdef DEBUG
mUnionState = HasJSException;
#endif // DEBUG
@ -379,7 +379,7 @@ TErrorResult<CleanupPolicy>::ThrowDOMException(nsresult rv,
AssertInOwningThread();
ClearUnionData();
mResult = NS_ERROR_DOM_DOMEXCEPTION;
mResult = NS_ERROR_INTERNAL_ERRORRESULT_DOMEXCEPTION;
mDOMExceptionInfo = new DOMExceptionInfo(rv, message);
#ifdef DEBUG
mUnionState = HasDOMExceptionInfo;
@ -600,7 +600,7 @@ TErrorResult<CleanupPolicy>::NoteJSContextException(JSContext* aCx)
{
AssertInOwningThread();
if (JS_IsExceptionPending(aCx)) {
mResult = NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT;
mResult = NS_ERROR_INTERNAL_ERRORRESULT_EXCEPTION_ON_JSCONTEXT;
} else {
mResult = NS_ERROR_UNCATCHABLE_EXCEPTION;
}
@ -1211,14 +1211,6 @@ GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
}
}
bool
UnforgeableValueOf(JSContext* cx, unsigned argc, JS::Value* vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
args.rval().set(args.thisv());
return true;
}
bool
ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
@ -2590,7 +2582,7 @@ NonVoidByteStringToJsval(JSContext *cx, const nsACString &str,
template<typename T> static void
NormalizeUSVStringInternal(JSContext* aCx, T& aString)
NormalizeUSVStringInternal(T& aString)
{
char16_t* start = aString.BeginWriting();
// Must use const here because we can't pass char** to UTF16CharEnumerator as
@ -2607,15 +2599,15 @@ NormalizeUSVStringInternal(JSContext* aCx, T& aString)
}
void
NormalizeUSVString(JSContext* aCx, nsAString& aString)
NormalizeUSVString(nsAString& aString)
{
NormalizeUSVStringInternal(aCx, aString);
NormalizeUSVStringInternal(aString);
}
void
NormalizeUSVString(JSContext* aCx, binding_detail::FakeString& aString)
NormalizeUSVString(binding_detail::FakeString& aString)
{
NormalizeUSVStringInternal(aCx, aString);
NormalizeUSVStringInternal(aString);
}
bool

View File

@ -50,7 +50,7 @@ namespace mozilla {
enum UseCounter : int16_t;
namespace dom {
template<typename DataType> class MozMap;
template<typename KeyType, typename ValueType> class Record;
nsresult
UnwrapArgImpl(JSContext* cx, JS::Handle<JSObject*> src, const nsIID& iid,
@ -1828,9 +1828,6 @@ GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID,
GetInterfaceImpl(aCx, aThis, aThis, aIID, aRetval, aError);
}
bool
UnforgeableValueOf(JSContext* cx, unsigned argc, JS::Value* vp);
bool
ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
@ -1901,11 +1898,30 @@ ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v,
return AssignJSString(cx, result, s);
}
void
NormalizeUSVString(JSContext* aCx, nsAString& aString);
template<typename T>
static inline bool
ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v, T& result)
{
return ConvertJSValueToString(cx, v, eStringify, eStringify, result);
}
void
NormalizeUSVString(JSContext* aCx, binding_detail::FakeString& aString);
NormalizeUSVString(nsAString& aString);
void
NormalizeUSVString(binding_detail::FakeString& aString);
template<typename T>
static inline bool
ConvertJSValueToUSVString(JSContext* cx, JS::Handle<JS::Value> v, T& result)
{
if (!ConvertJSValueToString(cx, v, eStringify, eStringify, result)) {
return false;
}
NormalizeUSVString(result);
return true;
}
template<typename T>
inline bool
@ -1932,6 +1948,13 @@ bool
ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
bool nullable, nsACString& result);
inline bool
ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
nsACString& result)
{
return ConvertJSValueToByteString(cx, v, false, result);
}
template<typename T>
void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
template<typename T>
@ -2067,31 +2090,26 @@ public:
}
};
template<typename T>
static void
TraceMozMapValue(T* aValue, void* aClosure)
template<typename K, typename V>
void TraceRecord(JSTracer* trc, Record<K, V>& record)
{
JSTracer* trc = static_cast<JSTracer*>(aClosure);
// Act like it's a one-element sequence to leverage all that infrastructure.
SequenceTracer<T>::TraceSequence(trc, aValue, aValue + 1);
for (auto& entry : record.Entries()) {
// Act like it's a one-element sequence to leverage all that infrastructure.
SequenceTracer<V>::TraceSequence(trc, &entry.mValue, &entry.mValue + 1);
}
}
template<typename T>
void TraceMozMap(JSTracer* trc, MozMap<T>& map)
{
map.EnumerateValues(TraceMozMapValue<T>, trc);
}
// sequence<MozMap>
template<typename T>
class SequenceTracer<MozMap<T>, false, false, false>
// sequence<record>
template<typename K, typename V>
class SequenceTracer<Record<K, V>, false, false, false>
{
explicit SequenceTracer() = delete; // Should never be instantiated
public:
static void TraceSequence(JSTracer* trc, MozMap<T>* seqp, MozMap<T>* end) {
static void TraceSequence(JSTracer* trc, Record<K, V>* seqp,
Record<K, V>* end) {
for (; seqp != end; ++seqp) {
seqp->EnumerateValues(TraceMozMapValue<T>, trc);
TraceRecord(trc, *seqp);
}
}
};
@ -2169,51 +2187,51 @@ public:
SequenceType mSequenceType;
};
// Rooter class for MozMap; this is what we mostly use in the codegen.
template<typename T>
class MOZ_RAII MozMapRooter final : private JS::CustomAutoRooter
// Rooter class for Record; this is what we mostly use in the codegen.
template<typename K, typename V>
class MOZ_RAII RecordRooter final : private JS::CustomAutoRooter
{
public:
MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap
RecordRooter(JSContext *aCx, Record<K, V>* aRecord
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
mMozMap(aMozMap),
mMozMapType(eMozMap)
mRecord(aRecord),
mRecordType(eRecord)
{
}
MozMapRooter(JSContext *aCx, Nullable<MozMap<T>>* aMozMap
RecordRooter(JSContext *aCx, Nullable<Record<K, V>>* aRecord
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
mNullableMozMap(aMozMap),
mMozMapType(eNullableMozMap)
mNullableRecord(aRecord),
mRecordType(eNullableRecord)
{
}
private:
enum MozMapType {
eMozMap,
eNullableMozMap
enum RecordType {
eRecord,
eNullableRecord
};
virtual void trace(JSTracer *trc) override
{
if (mMozMapType == eMozMap) {
TraceMozMap(trc, *mMozMap);
if (mRecordType == eRecord) {
TraceRecord(trc, *mRecord);
} else {
MOZ_ASSERT(mMozMapType == eNullableMozMap);
if (!mNullableMozMap->IsNull()) {
TraceMozMap(trc, mNullableMozMap->Value());
MOZ_ASSERT(mRecordType == eNullableRecord);
if (!mNullableRecord->IsNull()) {
TraceRecord(trc, mNullableRecord->Value());
}
}
}
union {
MozMap<T>* mMozMap;
Nullable<MozMap<T>>* mNullableMozMap;
Record<K, V>* mRecord;
Nullable<Record<K, V>>* mNullableRecord;
};
MozMapType mMozMapType;
RecordType mRecordType;
};
template<typename T>

View File

@ -84,7 +84,7 @@ def idlTypeNeedsCycleCollection(type):
return True
elif type.isUnion():
return any(idlTypeNeedsCycleCollection(t) for t in type.flatMemberTypes)
elif type.isMozMap():
elif type.isRecord():
if idlTypeNeedsCycleCollection(type.inner):
raise TypeError("Cycle collection for type %s is not supported" % type)
return False
@ -996,6 +996,8 @@ class CGElseChain(CGThing):
class CGTemplatedType(CGWrapper):
def __init__(self, templateName, child, isConst=False, isReference=False):
if isinstance(child, list):
child = CGList(child, ", ")
const = "const " if isConst else ""
pre = "%s%s<" % (const, templateName)
ref = "&" if isReference else ""
@ -1163,12 +1165,12 @@ class CGHeaders(CGWrapper):
declareIncludes.add(filename)
elif unrolled.isPrimitive():
bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
elif unrolled.isMozMap():
elif unrolled.isRecord():
if dictionary or jsImplementedDescriptors:
declareIncludes.add("mozilla/dom/MozMap.h")
declareIncludes.add("mozilla/dom/Record.h")
else:
bindingHeaders.add("mozilla/dom/MozMap.h")
# Also add headers for the type the MozMap is
bindingHeaders.add("mozilla/dom/Record.h")
# Also add headers for the type the record is
# parametrized over, if needed.
addHeadersForType((t.inner, dictionary))
@ -1390,8 +1392,8 @@ def UnionTypes(unionTypes, config):
# the right header to be able to Release() in our inlined
# code.
headers.add(CGHeaders.getDeclarationFilename(f.callback))
elif f.isMozMap():
headers.add("mozilla/dom/MozMap.h")
elif f.isRecord():
headers.add("mozilla/dom/Record.h")
# And add headers for the type we're parametrized over
addHeadersForType(f.inner)
@ -1458,9 +1460,9 @@ def UnionConversions(unionTypes, config):
headers.add("mozilla/dom/PrimitiveConversions.h")
elif f.isPrimitive():
headers.add("mozilla/dom/PrimitiveConversions.h")
elif f.isMozMap():
headers.add("mozilla/dom/MozMap.h")
# And the internal type of the MozMap
elif f.isRecord():
headers.add("mozilla/dom/Record.h")
# And the internal type of the record
addHeadersForType(f.inner)
# We plan to include UnionTypes.h no matter what, so it's
@ -2486,11 +2488,10 @@ class MethodDefiner(PropertyDefiner):
# Synthesize our valueOf method
self.regular.append({
"name": 'valueOf',
"nativeName": "UnforgeableValueOf",
"selfHostedName": "Object_valueOf",
"methodInfo": False,
"length": 0,
"flags": "JSPROP_ENUMERATE", # readonly/permanent added
# automatically.
"flags": "0", # readonly/permanent added automatically.
"condition": MemberCondition()
})
@ -3561,19 +3562,15 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties, failureCode,
"nsContentUtils::ThreadsafeIsSystemCaller(aCx)"))
if descriptor.interface.getExtendedAttribute("Unforgeable"):
# We do our undefined toJSON and toPrimitive here, not as a regular
# property because we don't have a concept of value props anywhere in
# IDL.
# We do our undefined toPrimitive here, not as a regular property
# because we don't have a concept of value props anywhere in IDL.
unforgeables.append(CGGeneric(fill(
"""
JS::RootedId toPrimitive(aCx,
SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::toPrimitive)));
if (!JS_DefinePropertyById(aCx, ${holderName}, toPrimitive,
JS::UndefinedHandleValue,
JSPROP_READONLY | JSPROP_PERMANENT) ||
!JS_DefineProperty(aCx, ${holderName}, "toJSON",
JS::UndefinedHandleValue,
JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
JSPROP_READONLY | JSPROP_PERMANENT)) {
$*{failureCode}
}
""",
@ -4391,6 +4388,9 @@ class JSToNativeConversionInfo():
for whether we have a JS::Value. Only used when
defaultValue is not None or when True is passed for
checkForValue to instantiateJSToNativeConversion.
This expression may not be already-parenthesized, so if
you use it with && or || make sure to put parens
around it.
${passedToJSImpl} replaced by an expression that evaluates to a boolean
for whether this value is being passed to a JS-
implemented interface.
@ -4468,6 +4468,17 @@ def handleDefaultStringValue(defaultValue, method):
}
def recordKeyType(recordType):
assert recordType.keyType.isString()
if recordType.keyType.isByteString():
return "nsCString"
return "nsString"
def recordKeyDeclType(recordType):
return CGGeneric(recordKeyType(recordType))
# If this function is modified, modify CGNativeMember.getArg and
# CGNativeMember.getRetvalInfo accordingly. The latter cares about the decltype
# and holdertype we end up using, because it needs to be able to return the code
@ -4662,7 +4673,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
declArgs = "cx"
else:
assert (isMember in
("Sequence", "Variadic", "Dictionary", "OwningUnion", "MozMap"))
("Sequence", "Variadic", "Dictionary", "OwningUnion", "Record"))
# We'll get traced by the sequence or dictionary or union tracer
declType = CGGeneric("JSObject*")
declArgs = None
@ -4827,39 +4838,41 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
dealWithOptional=isOptional,
holderArgs=holderArgs)
if type.isMozMap():
if type.isRecord():
assert not isEnforceRange and not isClamp
if failureCode is None:
notMozMap = ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
notRecord = ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
"%s" % (firstCap(sourceDescription), exceptionCode))
else:
notMozMap = failureCode
notRecord = failureCode
nullable = type.nullable()
# Be very careful not to change "type": we need it later
if nullable:
valueType = type.inner.inner
recordType = type.inner
else:
valueType = type.inner
recordType = type
valueType = recordType.inner
valueInfo = getJSToNativeConversionInfo(
valueType, descriptorProvider, isMember="MozMap",
valueType, descriptorProvider, isMember="Record",
exceptionCode=exceptionCode, lenientFloatCode=lenientFloatCode,
isCallbackReturnValue=isCallbackReturnValue,
sourceDescription="value in %s" % sourceDescription,
nestingLevel=incrementNestingLevel())
if valueInfo.dealWithOptional:
raise TypeError("Shouldn't have optional things in MozMap")
raise TypeError("Shouldn't have optional things in record")
if valueInfo.holderType is not None:
raise TypeError("Shouldn't need holders for MozMap")
raise TypeError("Shouldn't need holders for record")
typeName = CGTemplatedType("MozMap", valueInfo.declType)
mozMapType = typeName.define()
declType = CGTemplatedType("Record", [recordKeyDeclType(recordType),
valueInfo.declType])
typeName = declType.define()
if nullable:
typeName = CGTemplatedType("Nullable", typeName)
mozMapRef = "${declName}.SetValue()"
declType = CGTemplatedType("Nullable", declType)
recordRef = "${declName}.SetValue()"
else:
mozMapRef = "${declName}"
recordRef = "${declName}"
valueConversion = string.Template(valueInfo.template).substitute({
"val": "temp",
@ -4871,68 +4884,124 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
"passedToJSImpl": "${passedToJSImpl}"
})
keyType = recordKeyType(recordType)
if recordType.keyType.isByteString():
keyConversionFunction = "ConvertJSValueToByteString"
hashKeyType = "nsCStringHashKey"
else:
hashKeyType = "nsStringHashKey"
if recordType.keyType.isDOMString():
keyConversionFunction = "ConvertJSValueToString"
else:
assert recordType.keyType.isUSVString()
keyConversionFunction = "ConvertJSValueToUSVString"
templateBody = fill(
"""
${mozMapType} &mozMap = ${mozMapRef};
auto& recordEntries = ${recordRef}.Entries();
JS::Rooted<JSObject*> mozMapObj(cx, &$${val}.toObject());
JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx));
if (!JS_Enumerate(cx, mozMapObj, &ids)) {
JS::Rooted<JSObject*> recordObj(cx, &$${val}.toObject());
JS::AutoIdVector ids(cx);
// Keep skipping symbols until
// https://github.com/heycam/webidl/issues/294 is sorted out.
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN, &ids)) {
$*{exceptionCode}
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
$*{exceptionCode}
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<${hashKeyType}> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
// Make sure we get the value before converting the name, since
// getting the value can trigger GC but our name is a dependent
// string.
curId = ids[i];
binding_detail::FakeString propName;
bool isSymbol;
if (!ConvertIdToString(cx, curId, propName, isSymbol) ||
(!isSymbol && !JS_GetPropertyById(cx, mozMapObj, curId, &temp))) {
MOZ_ASSERT(!JSID_IS_SYMBOL(curId), "No symbols, we said!");
JS::Rooted<JS::PropertyDescriptor> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
$*{exceptionCode}
}
if (isSymbol) {
if (!desc.object() /* == undefined in spec terms */ ||
!desc.enumerable()) {
continue;
}
${valueType}* slotPtr = mozMap.AddEntry(propName);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
idVal = js::IdToValue(curId);
${keyType} propName;
if (!${keyConversionFunction}(cx, idVal, propName)) {
$*{exceptionCode}
}
${valueType}& slot = *slotPtr;
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
$*{exceptionCode}
}
${typeName}::EntryType* entry;
if (idsSeen.Contains(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
idsSeen.PutEntry(propName);
}
entry->mKey = propName;
${valueType}& slot = entry->mValue;
$*{valueConversion}
}
""",
exceptionCode=exceptionCode,
mozMapType=mozMapType,
mozMapRef=mozMapRef,
recordRef=recordRef,
hashKeyType=hashKeyType,
keyType=keyType,
keyConversionFunction=keyConversionFunction,
typeName=typeName,
valueType=valueInfo.declType.define(),
valueConversion=valueConversion)
templateBody = wrapObjectTemplate(templateBody, type,
"${declName}.SetNull();\n",
notMozMap)
notRecord)
declType = typeName
declArgs = None
holderType = None
holderArgs = None
# MozMap arguments that might contain traceable things need
# record arguments that might contain traceable things need
# to get traced
if not isMember and isCallbackReturnValue:
# Go ahead and just convert directly into our actual return value
declType = CGWrapper(declType, post="&")
declArgs = "aRetVal"
elif not isMember and typeNeedsRooting(valueType):
holderType = CGTemplatedType("MozMapRooter", valueInfo.declType)
# If our MozMap is nullable, this will set the Nullable to be
holderType = CGTemplatedType("RecordRooter",
[recordKeyDeclType(recordType),
valueInfo.declType])
# If our record is nullable, this will set the Nullable to be
# not-null, but that's ok because we make an explicit SetNull() call
# on it as needed if our JS value is actually null.
holderArgs = "cx, &%s" % mozMapRef
holderArgs = "cx, &%s" % recordRef
return JSToNativeConversionInfo(templateBody, declType=declType,
declArgs=declArgs,
@ -5015,16 +5084,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
else:
setDictionary = None
mozMapMemberTypes = filter(lambda t: t.isMozMap(), memberTypes)
if len(mozMapMemberTypes) > 0:
assert len(mozMapMemberTypes) == 1
name = getUnionMemberName(mozMapMemberTypes[0])
mozMapObject = CGGeneric(
recordMemberTypes = filter(lambda t: t.isRecord(), memberTypes)
if len(recordMemberTypes) > 0:
assert len(recordMemberTypes) == 1
name = getUnionMemberName(recordMemberTypes[0])
recordObject = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
else:
mozMapObject = None
recordObject = None
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
if len(objectMemberTypes) > 0:
@ -5040,10 +5109,10 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
else:
object = None
hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or mozMapObject
hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or recordObject
if hasObjectTypes:
# "object" is not distinguishable from other types
assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or mozMapObject)
assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or recordObject)
if sequenceObject or dateObject or callbackObject:
# An object can be both an sequence object and a callback or
# dictionary, but we shouldn't have both in the union's members
@ -5063,9 +5132,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if dateObject:
templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
if mozMapObject:
if recordObject:
templateBody = CGList([templateBody,
CGIfWrapper(mozMapObject, "!done")])
CGIfWrapper(recordObject, "!done")])
templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
else:
@ -5245,7 +5314,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if isinstance(defaultValue, IDLNullValue):
extraConditionForNull = "!(${haveValue}) || "
else:
extraConditionForNull = "${haveValue} && "
extraConditionForNull = "(${haveValue}) && "
else:
extraConditionForNull = ""
templateBody = handleNull(templateBody, declLoc,
@ -5606,7 +5675,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
def getConversionCode(varName):
normalizeCode = ""
if type.isUSVString():
normalizeCode = "NormalizeUSVString(cx, %s);\n" % varName
normalizeCode = "NormalizeUSVString(%s);\n" % varName
conversionCode = fill("""
if (!ConvertJSValueToString(cx, $${val}, ${nullBehavior}, ${undefinedBehavior}, ${varName})) {
@ -5769,7 +5838,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
haveCallable = "${val}.isObject() && " + haveCallable
if defaultValue is not None:
assert(isinstance(defaultValue, IDLNullValue))
haveCallable = "${haveValue} && " + haveCallable
haveCallable = "(${haveValue}) && " + haveCallable
template = (
("if (%s) {\n" % haveCallable) +
conversion +
@ -5781,7 +5850,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
haveObject = "${val}.isObject()"
if defaultValue is not None:
assert(isinstance(defaultValue, IDLNullValue))
haveObject = "${haveValue} && " + haveObject
haveObject = "(${haveValue}) && " + haveObject
template = CGIfElseWrapper(haveObject,
CGGeneric(conversion),
CGGeneric("${declName} = nullptr;\n")).define()
@ -5805,7 +5874,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert not isEnforceRange and not isClamp
declArgs = None
if isMember in ("Variadic", "Sequence", "Dictionary", "MozMap"):
if isMember in ("Variadic", "Sequence", "Dictionary", "Record"):
# Rooting is handled by the sequence and dictionary tracers.
declType = "JS::Value"
else:
@ -5849,8 +5918,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
if type.isDictionary():
# There are no nullable dictionaries
assert not type.nullable() or isCallbackReturnValue
# There are no nullable dictionary arguments or dictionary members
assert(not type.nullable() or isCallbackReturnValue or
(isMember and isMember != "Dictionary"))
# All optional dictionaries always have default values, so we
# should be able to assume not isOptional here.
assert not isOptional
@ -6325,7 +6395,7 @@ def getMaybeWrapValueFuncForType(type):
sequenceWrapLevel = 0
mozMapWrapLevel = 0
recordWrapLevel = 0
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
@ -6430,7 +6500,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
if type is None or type.isVoid():
return (setUndefined(), True)
if (type.isSequence() or type.isMozMap()) and type.nullable():
if (type.isSequence() or type.isRecord()) and type.nullable():
# These are both wrapped in Nullable<>
recTemplate, recInfall = getWrapTemplateForType(type.inner, descriptorProvider,
"%s.Value()" % result, successCode,
@ -6503,14 +6573,14 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
return (code, False)
if type.isMozMap():
# Now do non-nullable MozMap. Our success code is just to break to
if type.isRecord():
# Now do non-nullable record. Our success code is just to break to
# where we define the property on the object. Note that we bump the
# mozMapWrapLevel around this call so that nested MozMap conversions
# recordWrapLevel around this call so that nested record conversions
# will use different temp value names.
global mozMapWrapLevel
valueName = "mozMapValue%d" % mozMapWrapLevel
mozMapWrapLevel += 1
global recordWrapLevel
valueName = "recordValue%d" % recordWrapLevel
recordWrapLevel += 1
innerTemplate = wrapForType(
type.inner, descriptorProvider,
{
@ -6523,12 +6593,22 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
'obj': "returnObj",
'typedArraysAreStructs': typedArraysAreStructs
})
mozMapWrapLevel -= 1
recordWrapLevel -= 1
if type.keyType.isByteString():
# There is no length-taking JS_DefineProperty. So to keep
# things sane with embedded nulls, we want to byte-inflate
# to an nsAString. The only byte-inflation function we
# have around is AppendASCIItoUTF16, which luckily doesn't
# assert anything about the input being ASCII.
expandedKeyDecl = "NS_ConvertASCIItoUTF16 expandedKey(entry.mKey);\n"
keyName = "expandedKey"
else:
expandedKeyDecl = ""
keyName = "entry.mKey"
code = fill(
"""
nsTArray<nsString> keys;
${result}.GetKeys(keys);
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
$*{exceptionCode}
@ -6536,15 +6616,17 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (size_t idx = 0; idx < keys.Length(); ++idx) {
auto& ${valueName} = ${result}.Get(keys[idx]);
for (auto& entry : ${result}.Entries()) {
auto& ${valueName} = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
$*{innerTemplate}
} while (0);
if (!JS_DefineUCProperty(cx, returnObj, keys[idx].get(),
keys[idx].Length(), tmp,
$*{expandedKeyDecl}
if (!JS_DefineUCProperty(cx, returnObj,
${keyName}.BeginReading(),
${keyName}.Length(), tmp,
JSPROP_ENUMERATE)) {
$*{exceptionCode}
}
@ -6556,6 +6638,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
exceptionCode=exceptionCode,
valueName=valueName,
innerTemplate=innerTemplate,
expandedKeyDecl=expandedKeyDecl,
keyName=keyName,
set=setObject("*returnObj"))
return (code, False)
@ -6844,7 +6928,7 @@ def typeMatchesLambda(type, func):
return False
if type.nullable():
return typeMatchesLambda(type.inner, func)
if type.isSequence() or type.isMozMap():
if type.isSequence() or type.isRecord():
return typeMatchesLambda(type.inner, func)
if type.isUnion():
return any(typeMatchesLambda(t, func) for t in
@ -6943,20 +7027,21 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if nullable:
result = CGTemplatedType("Nullable", result)
return result, "ref", rooter, None, None
if returnType.isMozMap():
if returnType.isRecord():
nullable = returnType.nullable()
if nullable:
returnType = returnType.inner
result, _, _, _, _ = getRetvalDeclarationForType(returnType.inner,
descriptorProvider,
isMember="MozMap")
isMember="Record")
# While we have our inner type, set up our rooter, if needed
if not isMember and typeNeedsRooting(returnType):
rooter = CGGeneric("MozMapRooter<%s> resultRooter(cx, &result);\n" %
result.define())
rooter = CGGeneric("RecordRooter<%s> resultRooter(cx, &result);\n" %
("nsString, " + result.define()))
else:
rooter = None
result = CGTemplatedType("MozMap", result)
result = CGTemplatedType("Record", [recordKeyDeclType(returnType),
result])
if nullable:
result = CGTemplatedType("Nullable", result)
return result, "ref", rooter, None, None
@ -7061,7 +7146,7 @@ class CGCallGenerator(CGThing):
return True
if a.type.isSequence():
return True
if a.type.isMozMap():
if a.type.isRecord():
return True
# isObject() types are always a JS::Rooted, whether
# nullable or not, and it turns out a const JS::Rooted
@ -7218,7 +7303,7 @@ class MethodNotNewObjectError(Exception):
# nested sequences we don't use the same variable name to iterate over
# different sequences.
sequenceWrapLevel = 0
mapWrapLevel = 0
recordWrapLevel = 0
def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
@ -7279,29 +7364,27 @@ def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % origValue)
return wrapCode
if type.isMozMap():
origValue = value
if type.isRecord():
origType = type
if type.nullable():
type = type.inner
value = "%s.Value()" % value
global mapWrapLevel
key = "mapName%d" % mapWrapLevel
mapWrapLevel += 1
recordRef = "%s.Value()" % value
else:
recordRef = value
global recordWrapLevel
entryRef = "mapEntry%d" % recordWrapLevel
recordWrapLevel += 1
wrapElement = wrapTypeIntoCurrentCompartment(type.inner,
"%s.Get(%sKeys[%sIndex])" % (value, key, key))
mapWrapLevel -= 1
"%s.mValue" % entryRef)
recordWrapLevel -= 1
if not wrapElement:
return None
wrapCode = CGWrapper(CGIndenter(wrapElement),
pre=("""
nsTArray<nsString> %sKeys;
%s.GetKeys(%sKeys);
for (uint32_t %sIndex = 0; %sIndex < %sKeys.Length(); ++%sIndex) {
""" % (key, value, key, key, key, key, key)),
pre=("for (auto& %s : %s.Entries()) {\n" %
(entryRef, recordRef)),
post="}\n")
if origType.nullable():
wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % origValue)
wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % value)
return wrapCode
if type.isDictionary():
@ -8139,11 +8222,11 @@ class CGMethodCall(CGThing):
if distinguishingType(s).isSequence())
# Now append all the overloads that take a dictionary or callback
# interface or MozMap. There should be only one of these!
# interface or record. There should be only one of these!
genericObjectSigs = [
s for s in possibleSignatures
if (distinguishingType(s).isDictionary() or
distinguishingType(s).isMozMap() or
distinguishingType(s).isRecord() or
distinguishingType(s).isCallbackInterface())]
assert len(genericObjectSigs) <= 1
objectSigs.extend(genericObjectSigs)
@ -9538,7 +9621,7 @@ class CGMemberJITInfo(CGThing):
return "JSVAL_TYPE_UNDEFINED"
if t.isSequence():
return "JSVAL_TYPE_OBJECT"
if t.isMozMap():
if t.isRecord():
return "JSVAL_TYPE_OBJECT"
if t.isPromise():
return "JSVAL_TYPE_OBJECT"
@ -9817,17 +9900,22 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
# distinguishable from anything.
assert not type.isPromise()
if type.isSequence() or type.isMozMap():
if type.isSequence() or type.isRecord():
if type.isSequence():
wrapperType = "Sequence"
else:
wrapperType = "MozMap"
wrapperType = "Record"
# We don't use the returned template here, so it's OK to just pass no
# sourceDescription.
elementInfo = getJSToNativeConversionInfo(type.inner,
descriptorProvider,
isMember=wrapperType)
return CGTemplatedType(wrapperType, elementInfo.declType,
if wrapperType == "Sequence":
innerType = elementInfo.declType
else:
innerType = [recordKeyDeclType(type), elementInfo.declType]
return CGTemplatedType(wrapperType, innerType,
isConst=True, isReference=True)
# Nested unions are unwrapped automatically into our flatMemberTypes.
@ -10182,10 +10270,10 @@ class CGUnionStruct(CGThing):
CGCase("e" + vars["name"],
CGGeneric("DoTraceSequence(trc, mValue.m%s.Value());\n" %
vars["name"])))
elif t.isMozMap():
elif t.isRecord():
traceCases.append(
CGCase("e" + vars["name"],
CGGeneric("TraceMozMap(trc, mValue.m%s.Value());\n" %
CGGeneric("TraceRecord(trc, mValue.m%s.Value());\n" %
vars["name"])))
else:
assert t.isSpiderMonkeyInterface()
@ -13336,8 +13424,8 @@ class CGDictionary(CGThing):
trace = CGGeneric('%s.TraceSelf(trc);\n' % memberData)
if type.nullable():
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
elif type.isMozMap():
# If you implement this, add a MozMap<object> to
elif type.isRecord():
# If you implement this, add a record<DOMString, object> to
# TestInterfaceJSDictionary and test it in test_bug1036214.html
# to make sure we end up with the correct security properties.
assert False
@ -13749,7 +13837,7 @@ class ForwardDeclarationBuilder:
# since we don't know which one we might want
self.addInMozillaDom(CGUnionStruct.unionTypeName(t, False))
self.addInMozillaDom(CGUnionStruct.unionTypeName(t, True))
elif t.isMozMap():
elif t.isRecord():
self.forwardDeclareForType(t.inner, config)
# Don't need to do anything for void, primitive, string, any or object.
# There may be some other cases we are missing.
@ -14258,9 +14346,9 @@ class CGNativeMember(ClassMethod):
else:
returnCode = "aRetVal.SwapElements(${declName});\n"
return "void", "", returnCode
if type.isMozMap():
# If we want to handle MozMap-of-MozMap return values, we're
# going to need to fix example codegen to not produce MozMap<void>
if type.isRecord():
# If we want to handle record-of-record return values, we're
# going to need to fix example codegen to not produce record<void>
# for the relevant argument...
assert not isMember
# In this case we convert directly into our outparam to start with
@ -14308,13 +14396,14 @@ class CGNativeMember(ClassMethod):
if nullable:
type = CGTemplatedType("Nullable", type)
args.append(Argument("%s&" % type.define(), "aRetVal"))
elif returnType.isMozMap():
elif returnType.isRecord():
nullable = returnType.nullable()
if nullable:
returnType = returnType.inner
# And now the actual underlying type
elementDecl = self.getReturnType(returnType.inner, True)
type = CGTemplatedType("MozMap", CGGeneric(elementDecl))
type = CGTemplatedType("Record", [recordKeyDeclType(returnType),
CGGeneric(elementDecl)])
if nullable:
type = CGTemplatedType("Nullable", type)
args.append(Argument("%s&" % type.define(), "aRetVal"))
@ -14378,7 +14467,7 @@ class CGNativeMember(ClassMethod):
Nullable as needed.
isMember can be false or one of the strings "Sequence", "Variadic",
"MozMap"
"Record"
"""
if type.isSequence():
nullable = type.nullable()
@ -14389,13 +14478,13 @@ class CGNativeMember(ClassMethod):
decl = CGTemplatedType("Sequence", argType)
return decl.define(), True, True
if type.isMozMap():
if type.isRecord():
nullable = type.nullable()
if nullable:
type = type.inner
elementType = type.inner
argType = self.getArgType(elementType, False, "MozMap")[0]
decl = CGTemplatedType("MozMap", argType)
argType = self.getArgType(elementType, False, "Record")[0]
decl = CGTemplatedType("Record", [recordKeyDeclType(type), argType])
return decl.define(), True, True
if type.isUnion():

View File

@ -143,7 +143,7 @@ class Configuration(DescriptorProvider):
for (t, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
while True:
if t.isMozMap():
if t.isRecord():
t = t.inner
elif t.unroll() != t:
t = t.unroll()

View File

@ -187,12 +187,10 @@ public:
nsresult rv = ErrorCode();
SuppressException();
// Don't propagate out our internal error codes that have special meaning.
if (rv == NS_ERROR_TYPE_ERR ||
rv == NS_ERROR_RANGE_ERR ||
rv == NS_ERROR_DOM_JS_EXCEPTION ||
rv == NS_ERROR_DOM_DOMEXCEPTION) {
// What about NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT? I guess that can be
// legitimately passed on through....
if (rv == NS_ERROR_INTERNAL_ERRORRESULT_TYPEERROR ||
rv == NS_ERROR_INTERNAL_ERRORRESULT_RANGEERROR ||
rv == NS_ERROR_INTERNAL_ERRORRESULT_JS_EXCEPTION ||
rv == NS_ERROR_INTERNAL_ERRORRESULT_DOMEXCEPTION) {
// What to pick here?
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
@ -253,18 +251,22 @@ public:
template<dom::ErrNum errorNumber, typename... Ts>
void ThrowTypeError(Ts&&... messageArgs)
{
ThrowErrorWithMessage<errorNumber>(NS_ERROR_TYPE_ERR,
ThrowErrorWithMessage<errorNumber>(NS_ERROR_INTERNAL_ERRORRESULT_TYPEERROR,
Forward<Ts>(messageArgs)...);
}
template<dom::ErrNum errorNumber, typename... Ts>
void ThrowRangeError(Ts&&... messageArgs)
{
ThrowErrorWithMessage<errorNumber>(NS_ERROR_RANGE_ERR,
ThrowErrorWithMessage<errorNumber>(NS_ERROR_INTERNAL_ERRORRESULT_RANGEERROR,
Forward<Ts>(messageArgs)...);
}
bool IsErrorWithMessage() const { return ErrorCode() == NS_ERROR_TYPE_ERR || ErrorCode() == NS_ERROR_RANGE_ERR; }
bool IsErrorWithMessage() const
{
return ErrorCode() == NS_ERROR_INTERNAL_ERRORRESULT_TYPEERROR ||
ErrorCode() == NS_ERROR_INTERNAL_ERRORRESULT_RANGEERROR;
}
// Facilities for throwing a preexisting JS exception value via this
// TErrorResult. The contract is that any code which might end up calling
@ -277,7 +279,10 @@ public:
// not have to be in the compartment of cx. If someone later uses it, they
// will wrap it into whatever compartment they're working in, as needed.
void ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn);
bool IsJSException() const { return ErrorCode() == NS_ERROR_DOM_JS_EXCEPTION; }
bool IsJSException() const
{
return ErrorCode() == NS_ERROR_INTERNAL_ERRORRESULT_JS_EXCEPTION;
}
// Facilities for throwing a DOMException. If an empty message string is
// passed to ThrowDOMException, the default message string for the given
@ -285,7 +290,10 @@ public:
// passed in must be one we create DOMExceptions for; otherwise you may get an
// XPConnect Exception.
void ThrowDOMException(nsresult rv, const nsACString& message = EmptyCString());
bool IsDOMException() const { return ErrorCode() == NS_ERROR_DOM_DOMEXCEPTION; }
bool IsDOMException() const
{
return ErrorCode() == NS_ERROR_INTERNAL_ERRORRESULT_DOMEXCEPTION;
}
// Flag on the TErrorResult that whatever needs throwing has been
// thrown on the JSContext already and we should not mess with it.
@ -295,7 +303,7 @@ public:
// Check whether the TErrorResult says to just throw whatever is on
// the JSContext already.
bool IsJSContextException() {
return ErrorCode() == NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT;
return ErrorCode() == NS_ERROR_INTERNAL_ERRORRESULT_EXCEPTION_ON_JSCONTEXT;
}
// Support for uncatchable exceptions.
@ -396,25 +404,21 @@ private:
}
void AssignErrorCode(nsresult aRv) {
MOZ_ASSERT(aRv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
MOZ_ASSERT(aRv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_TYPEERROR,
"Use ThrowTypeError()");
MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_RANGEERROR,
"Use ThrowRangeError()");
MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
MOZ_ASSERT(aRv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_JS_EXCEPTION,
"Use ThrowJSException()");
MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
MOZ_ASSERT(aRv != NS_ERROR_DOM_DOMEXCEPTION, "Use ThrowDOMException()");
MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_DOMEXCEPTION,
"Use ThrowDOMException()");
MOZ_ASSERT(!IsDOMException(), "Don't overwrite DOM exceptions");
MOZ_ASSERT(aRv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "May need to bring back ThrowNotEnoughArgsError");
MOZ_ASSERT(aRv != NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT,
MOZ_ASSERT(aRv != NS_ERROR_INTERNAL_ERRORRESULT_EXCEPTION_ON_JSCONTEXT,
"Use NoteJSContextException");
// Don't trust people anyway, though.
if (aRv == NS_ERROR_TYPE_ERR ||
aRv == NS_ERROR_RANGE_ERR ||
aRv == NS_ERROR_DOM_JS_EXCEPTION ||
aRv == NS_ERROR_DOM_DOMEXCEPTION) {
mResult = NS_ERROR_UNEXPECTED;
} else {
mResult = aRv;
}
mResult = aRv;
}
void ClearMessage();
@ -446,11 +450,13 @@ private:
}
// Special values of mResult:
// NS_ERROR_TYPE_ERR -- ThrowTypeError() called on us.
// NS_ERROR_RANGE_ERR -- ThrowRangeError() called on us.
// NS_ERROR_DOM_JS_EXCEPTION -- ThrowJSException() called on us.
// NS_ERROR_INTERNAL_ERRORRESULT_TYPEERROR -- ThrowTypeError() called on us.
// NS_ERROR_INTERNAL_ERRORRESULT_RANGEERROR -- ThrowRangeError() called on us.
// NS_ERROR_INTERNAL_ERRORRESULT_JS_EXCEPTION -- ThrowJSException() called
// on us.
// NS_ERROR_UNCATCHABLE_EXCEPTION -- ThrowUncatchableException called on us.
// NS_ERROR_DOM_DOMEXCEPTION -- ThrowDOMException() called on us.
// NS_ERROR_INTERNAL_ERRORRESULT_DOMEXCEPTION -- ThrowDOMException() called
// on us.
nsresult mResult;
struct Message;

View File

@ -1,121 +0,0 @@
/* -*- 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/. */
/**
* Class for representing MozMap arguments. This is an nsTHashtable
* under the hood, but we don't want to leak that implementation
* detail.
*/
#ifndef mozilla_dom_MozMap_h
#define mozilla_dom_MozMap_h
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "nsStringGlue.h"
#include "nsTArray.h"
#include "mozilla/Attributes.h"
#include "mozilla/Move.h"
namespace mozilla {
namespace dom {
namespace binding_detail {
template<typename DataType>
class MozMapEntry : public nsStringHashKey
{
public:
explicit MozMapEntry(const nsAString* aKeyTypePointer)
: nsStringHashKey(aKeyTypePointer)
{
}
// Move constructor so we can do MozMaps of MozMaps.
MozMapEntry(MozMapEntry<DataType>&& aOther)
: nsStringHashKey(aOther),
mData(Move(aOther.mData))
{
}
DataType mData;
};
} // namespace binding_detail
template<typename DataType>
class MozMap : protected nsTHashtable<binding_detail::MozMapEntry<DataType>>
{
public:
typedef typename binding_detail::MozMapEntry<DataType> EntryType;
typedef nsTHashtable<EntryType> Base;
typedef MozMap<DataType> SelfType;
MozMap()
{
}
// Move constructor so we can do MozMap of MozMap.
MozMap(SelfType&& aOther) :
Base(Move(aOther))
{
}
// The return value is only safe to use until an AddEntry call.
const DataType& Get(const nsAString& aKey) const
{
const EntryType* ent = this->GetEntry(aKey);
MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?");
return ent->mData;
}
DataType& Get(const nsAString& aKey)
{
EntryType* ent = this->GetEntry(aKey);
MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?");
return ent->mData;
}
// The return value is only safe to use until an AddEntry call.
const DataType* GetIfExists(const nsAString& aKey) const
{
const EntryType* ent = this->GetEntry(aKey);
if (!ent) {
return nullptr;
}
return &ent->mData;
}
void GetKeys(nsTArray<nsString>& aKeys) const {
for (auto iter = this->ConstIter(); !iter.Done(); iter.Next()) {
aKeys.AppendElement(iter.Get()->GetKey());
}
}
// XXXbz we expose this generic enumerator for tracing. Otherwise we'd end up
// with a dependency on BindingUtils.h here for the SequenceTracer bits.
typedef void (* Enumerator)(DataType* aValue, void* aClosure);
void EnumerateValues(Enumerator aEnumerator, void *aClosure)
{
for (auto iter = this->Iter(); !iter.Done(); iter.Next()) {
aEnumerator(&iter.Get()->mData, aClosure);
}
}
MOZ_MUST_USE
DataType* AddEntry(const nsAString& aKey)
{
EntryType* ent = this->PutEntry(aKey, fallible);
if (!ent) {
return nullptr;
}
return &ent->mData;
}
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MozMap_h

91
dom/bindings/Record.h Normal file
View File

@ -0,0 +1,91 @@
/* -*- 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/. */
/**
* Class for representing record arguments. Basically an array under the hood.
*/
#ifndef mozilla_dom_Record_h
#define mozilla_dom_Record_h
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "nsStringGlue.h"
#include "nsTArray.h"
#include "mozilla/Attributes.h"
#include "mozilla/Move.h"
namespace mozilla {
namespace dom {
namespace binding_detail {
template<typename KeyType, typename ValueType>
class RecordEntry
{
public:
RecordEntry()
{
}
// Move constructor so we can do Records of Records.
RecordEntry(RecordEntry<KeyType, ValueType>&& aOther)
: mKey(Move(aOther.mKey)),
mValue(Move(aOther.mValue))
{
}
KeyType mKey;
ValueType mValue;
};
} // namespace binding_detail
template<typename KeyType, typename ValueType>
class Record
{
public:
typedef typename binding_detail::RecordEntry<KeyType, ValueType> EntryType;
typedef Record<KeyType, ValueType> SelfType;
Record()
{
}
// Move constructor so we can do Record of Record.
Record(SelfType&& aOther) :
mEntries(Move(aOther.mEntries))
{
}
const nsTArray<EntryType>& Entries() const
{
return mEntries;
}
nsTArray<EntryType>& Entries()
{
return mEntries;
}
private:
nsTArray<EntryType> mEntries;
};
} // namespace dom
} // namespace mozilla
template<typename K, typename V>
class nsDefaultComparator<mozilla::dom::binding_detail::RecordEntry<K, V>, K>
{
public:
bool Equals(const mozilla::dom::binding_detail::RecordEntry<K, V>& aEntry,
const K& aKey) const
{
return aEntry.mKey == aKey;
}
};
#endif // mozilla_dom_Record_h

View File

@ -41,10 +41,10 @@ EXPORTS.mozilla.dom += [
'FakeString.h',
'IterableIterator.h',
'JSSlots.h',
'MozMap.h',
'NonRefcountedDOMObject.h',
'Nullable.h',
'PrimitiveConversions.h',
'Record.h',
'RootedDictionary.h',
'SimpleGlobalObject.h',
'StructuredClone.h',

View File

@ -1886,7 +1886,7 @@ class IDLDictionary(IDLObjectWithScope):
if (memberType.nullable() or
memberType.isSequence() or
memberType.isMozMap()):
memberType.isRecord()):
return typeContainsDictionary(memberType.inner, dictionary)
if memberType.isDictionary():
@ -2007,7 +2007,7 @@ class IDLType(IDLObject):
'callback',
'union',
'sequence',
'mozmap',
'record',
'promise',
)
@ -2058,7 +2058,7 @@ class IDLType(IDLObject):
def isSequence(self):
return False
def isMozMap(self):
def isRecord(self):
return False
def isArrayBuffer(self):
@ -2279,8 +2279,8 @@ class IDLNullableType(IDLParametrizedType):
def isSequence(self):
return self.inner.isSequence()
def isMozMap(self):
return self.inner.isMozMap()
def isRecord(self):
return self.inner.isRecord()
def isArrayBuffer(self):
return self.inner.isArrayBuffer()
@ -2339,8 +2339,10 @@ class IDLNullableType(IDLParametrizedType):
return self
def isDistinguishableFrom(self, other):
if (other.nullable() or (other.isUnion() and other.hasNullableType) or
other.isDictionary()):
if (other.nullable() or
other.isDictionary() or
(other.isUnion() and
(other.hasNullableType or other.hasDictionaryType()))):
# Can't tell which type null should become
return False
return self.inner.isDistinguishableFrom(other)
@ -2415,34 +2417,38 @@ class IDLSequenceType(IDLParametrizedType):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isDate() or other.isInterface() or
other.isDictionary() or
other.isCallback() or other.isMozMap())
other.isCallback() or other.isRecord())
class IDLMozMapType(IDLParametrizedType):
def __init__(self, location, parameterType):
assert not parameterType.isVoid()
class IDLRecordType(IDLParametrizedType):
def __init__(self, location, keyType, valueType):
assert keyType.isString()
assert keyType.isComplete()
assert not valueType.isVoid()
IDLParametrizedType.__init__(self, location, valueType.name, valueType)
self.keyType = keyType
IDLParametrizedType.__init__(self, location, parameterType.name, parameterType)
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "MozMap"
self.name = self.keyType.name + self.inner.name + "Record"
def __eq__(self, other):
return isinstance(other, IDLMozMapType) and self.inner == other.inner
return isinstance(other, IDLRecordType) and self.inner == other.inner
def __str__(self):
return self.inner.__str__() + "MozMap"
return self.keyType.__str__() + self.inner.__str__() + "Record"
def isMozMap(self):
def isRecord(self):
return True
def tag(self):
return IDLType.Tags.mozmap
return IDLType.Tags.record
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name + "MozMap"
self.name = self.keyType.name + self.inner.name + "Record"
return self
def unroll(self):
@ -2632,8 +2638,8 @@ class IDLTypedefType(IDLType):
def isSequence(self):
return self.inner.isSequence()
def isMozMap(self):
return self.inner.isMozMap()
def isRecord(self):
return self.inner.isRecord()
def isDictionary(self):
return self.inner.isDictionary()
@ -2804,7 +2810,7 @@ class IDLWrapperType(IDLType):
if self.isEnum():
return (other.isPrimitive() or other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
other.isSequence() or other.isMozMap() or other.isDate())
other.isSequence() or other.isRecord() or other.isDate())
if self.isDictionary() and other.nullable():
return False
if (other.isPrimitive() or other.isString() or other.isEnum() or
@ -2826,7 +2832,7 @@ class IDLWrapperType(IDLType):
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
other.isMozMap()):
other.isRecord()):
return self.isNonCallbackInterface()
# Not much else |other| can be
@ -3071,17 +3077,17 @@ class IDLBuiltinType(IDLType):
return (other.isNumeric() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
other.isSequence() or other.isMozMap() or other.isDate())
other.isSequence() or other.isRecord() or other.isDate())
if self.isNumeric():
return (other.isBoolean() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
other.isSequence() or other.isMozMap() or other.isDate())
other.isSequence() or other.isRecord() or other.isDate())
if self.isString():
return (other.isPrimitive() or other.isInterface() or
other.isObject() or
other.isCallback() or other.isDictionary() or
other.isSequence() or other.isMozMap() or other.isDate())
other.isSequence() or other.isRecord() or other.isDate())
if self.isAny():
# Can't tell "any" apart from anything
return False
@ -3091,7 +3097,7 @@ class IDLBuiltinType(IDLType):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isInterface() or other.isCallback() or
other.isDictionary() or other.isSequence() or
other.isMozMap())
other.isRecord())
if self.isVoid():
return not other.isVoid()
# Not much else we could be!
@ -3099,7 +3105,7 @@ class IDLBuiltinType(IDLType):
# Like interfaces, but we know we're not a callback
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isCallback() or other.isDictionary() or
other.isSequence() or other.isMozMap() or other.isDate() or
other.isSequence() or other.isRecord() or other.isDate() or
(other.isInterface() and (
# ArrayBuffer is distinguishable from everything
# that's not an ArrayBuffer or a callback interface
@ -3884,6 +3890,9 @@ class IDLConst(IDLInterfaceMember):
if type.isDictionary():
raise WebIDLError("A constant cannot be of a dictionary type",
[self.location])
if type.isRecord():
raise WebIDLError("A constant cannot be of a record type",
[self.location])
self.type = type
self.value = value
@ -3995,8 +4004,8 @@ class IDLAttribute(IDLInterfaceMember):
if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
raise WebIDLError("A non-cached attribute cannot be of a sequence "
"type", [self.location])
if self.type.isMozMap() and not self.getExtendedAttribute("Cached"):
raise WebIDLError("A non-cached attribute cannot be of a MozMap "
if self.type.isRecord() and not self.getExtendedAttribute("Cached"):
raise WebIDLError("A non-cached attribute cannot be of a record "
"type", [self.location])
if self.type.isUnion():
for f in self.type.unroll().flatMemberTypes:
@ -4012,11 +4021,11 @@ class IDLAttribute(IDLInterfaceMember):
"one of its member types's member "
"types, and so on) is a sequence "
"type", [self.location, f.location])
if f.isMozMap():
if f.isRecord():
raise WebIDLError("An attribute cannot be of a union "
"type if one of its member types (or "
"one of its member types's member "
"types, and so on) is a MozMap "
"types, and so on) is a record "
"type", [self.location, f.location])
if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
raise WebIDLError("An attribute with [PutForwards] must have an "
@ -4035,7 +4044,7 @@ class IDLAttribute(IDLInterfaceMember):
def typeContainsChromeOnlyDictionaryMember(type):
if (type.nullable() or
type.isSequence() or
type.isMozMap()):
type.isRecord()):
return typeContainsChromeOnlyDictionaryMember(type.inner)
if type.isUnion():
@ -4081,10 +4090,10 @@ class IDLAttribute(IDLInterfaceMember):
[self.location, location])
if self.getExtendedAttribute("Frozen"):
if (not self.type.isSequence() and not self.type.isDictionary() and
not self.type.isMozMap()):
not self.type.isRecord()):
raise WebIDLError("[Frozen] is only allowed on "
"sequence-valued, dictionary-valued, and "
"MozMap-valued attributes",
"record-valued attributes",
[self.location])
if not self.type.unroll().isExposedInAllOf(self.exposureSet):
raise WebIDLError("Attribute returns a type that is not exposed "
@ -5221,7 +5230,7 @@ class Tokenizer(object):
"Promise": "PROMISE",
"required": "REQUIRED",
"sequence": "SEQUENCE",
"MozMap": "MOZMAP",
"record": "RECORD",
"short": "SHORT",
"unsigned": "UNSIGNED",
"void": "VOID",
@ -6350,7 +6359,7 @@ class Parser(Tokenizer):
| OCTET
| OPTIONAL
| SEQUENCE
| MOZMAP
| RECORD
| SETTER
| SHORT
| STATIC
@ -6429,7 +6438,7 @@ class Parser(Tokenizer):
def p_NonAnyType(self, p):
"""
NonAnyType : PrimitiveOrStringType Null
NonAnyType : PrimitiveType Null
| ARRAYBUFFER Null
| SHAREDARRAYBUFFER Null
| OBJECT Null
@ -6445,6 +6454,12 @@ class Parser(Tokenizer):
p[0] = self.handleNullable(type, p[2])
def p_NonAnyTypeStringType(self, p):
"""
NonAnyType : StringType Null
"""
p[0] = self.handleNullable(p[1], p[2])
def p_NonAnyTypeSequenceType(self, p):
"""
NonAnyType : SEQUENCE LT Type GT Null
@ -6461,13 +6476,14 @@ class Parser(Tokenizer):
"""
p[0] = IDLPromiseType(self.getLocation(p, 1), p[3])
def p_NonAnyTypeMozMapType(self, p):
def p_NonAnyTypeRecordType(self, p):
"""
NonAnyType : MOZMAP LT Type GT Null
NonAnyType : RECORD LT StringType COMMA Type GT Null
"""
innerType = p[3]
type = IDLMozMapType(self.getLocation(p, 1), innerType)
p[0] = self.handleNullable(type, p[5])
keyType = p[3]
valueType = p[5]
type = IDLRecordType(self.getLocation(p, 1), keyType, valueType)
p[0] = self.handleNullable(type, p[7])
def p_NonAnyTypeScopedName(self, p):
"""
@ -6510,7 +6526,7 @@ class Parser(Tokenizer):
def p_ConstType(self, p):
"""
ConstType : PrimitiveOrStringType Null
ConstType : PrimitiveType Null
"""
type = BuiltinTypes[p[1]]
p[0] = self.handleNullable(type, p[2])
@ -6524,69 +6540,75 @@ class Parser(Tokenizer):
type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
p[0] = self.handleNullable(type, p[2])
def p_PrimitiveOrStringTypeUint(self, p):
def p_PrimitiveTypeUint(self, p):
"""
PrimitiveOrStringType : UnsignedIntegerType
PrimitiveType : UnsignedIntegerType
"""
p[0] = p[1]
def p_PrimitiveOrStringTypeBoolean(self, p):
def p_PrimitiveTypeBoolean(self, p):
"""
PrimitiveOrStringType : BOOLEAN
PrimitiveType : BOOLEAN
"""
p[0] = IDLBuiltinType.Types.boolean
def p_PrimitiveOrStringTypeByte(self, p):
def p_PrimitiveTypeByte(self, p):
"""
PrimitiveOrStringType : BYTE
PrimitiveType : BYTE
"""
p[0] = IDLBuiltinType.Types.byte
def p_PrimitiveOrStringTypeOctet(self, p):
def p_PrimitiveTypeOctet(self, p):
"""
PrimitiveOrStringType : OCTET
PrimitiveType : OCTET
"""
p[0] = IDLBuiltinType.Types.octet
def p_PrimitiveOrStringTypeFloat(self, p):
def p_PrimitiveTypeFloat(self, p):
"""
PrimitiveOrStringType : FLOAT
PrimitiveType : FLOAT
"""
p[0] = IDLBuiltinType.Types.float
def p_PrimitiveOrStringTypeUnrestictedFloat(self, p):
def p_PrimitiveTypeUnrestictedFloat(self, p):
"""
PrimitiveOrStringType : UNRESTRICTED FLOAT
PrimitiveType : UNRESTRICTED FLOAT
"""
p[0] = IDLBuiltinType.Types.unrestricted_float
def p_PrimitiveOrStringTypeDouble(self, p):
def p_PrimitiveTypeDouble(self, p):
"""
PrimitiveOrStringType : DOUBLE
PrimitiveType : DOUBLE
"""
p[0] = IDLBuiltinType.Types.double
def p_PrimitiveOrStringTypeUnrestictedDouble(self, p):
def p_PrimitiveTypeUnrestictedDouble(self, p):
"""
PrimitiveOrStringType : UNRESTRICTED DOUBLE
PrimitiveType : UNRESTRICTED DOUBLE
"""
p[0] = IDLBuiltinType.Types.unrestricted_double
def p_PrimitiveOrStringTypeDOMString(self, p):
def p_StringType(self, p):
"""
PrimitiveOrStringType : DOMSTRING
StringType : BuiltinStringType
"""
p[0] = BuiltinTypes[p[1]]
def p_BuiltinStringTypeDOMString(self, p):
"""
BuiltinStringType : DOMSTRING
"""
p[0] = IDLBuiltinType.Types.domstring
def p_PrimitiveOrStringTypeBytestring(self, p):
def p_BuiltinStringTypeBytestring(self, p):
"""
PrimitiveOrStringType : BYTESTRING
BuiltinStringType : BYTESTRING
"""
p[0] = IDLBuiltinType.Types.bytestring
def p_PrimitiveOrStringTypeUSVString(self, p):
def p_BuiltinStringTypeUSVString(self, p):
"""
PrimitiveOrStringType : USVSTRING
BuiltinStringType : USVSTRING
"""
p[0] = IDLBuiltinType.Types.usvstring

View File

@ -158,11 +158,15 @@ def WebIDLTest(parser, harness):
"CallbackInterface?", "CallbackInterface2",
"object", "Callback", "Callback2", "optional Dict",
"optional Dict2", "sequence<long>", "sequence<short>",
"MozMap<object>", "MozMap<Dict>", "MozMap<long>",
"record<DOMString, object>",
"record<USVString, Dict>",
"record<ByteString, long>",
"Date", "Date?", "any",
"Promise<any>", "Promise<any>?",
"USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
"Uint8Array", "Uint16Array" ]
"Uint8Array", "Uint16Array",
"(long or Callback)", "optional (long or Dict)",
]
# When we can parse Date, we need to add it here.
# XXXbz we can, and should really do that...
@ -170,10 +174,11 @@ def WebIDLTest(parser, harness):
def allBut(list1, list2):
return [a for a in list1 if a not in list2 and
(a != "any" and a != "Promise<any>" and a != "Promise<any>?")]
unions = [ "(long or Callback)", "optional (long or Dict)" ]
numerics = [ "long", "short", "long?", "short?" ]
booleans = [ "boolean", "boolean?" ]
primitives = numerics + booleans
nonNumerics = allBut(argTypes, numerics)
nonNumerics = allBut(argTypes, numerics + unions)
nonBooleans = allBut(argTypes, booleans)
strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString" ]
nonStrings = allBut(argTypes, strings)
@ -183,16 +188,18 @@ def WebIDLTest(parser, harness):
sharedBufferSourceTypes = ["SharedArrayBuffer"]
interfaces = [ "Interface", "Interface?", "AncestorInterface",
"UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
nullables = ["long?", "short?", "boolean?", "Interface?",
"CallbackInterface?", "optional Dict", "optional Dict2",
"Date?", "any", "Promise<any>?"]
nullables = (["long?", "short?", "boolean?", "Interface?",
"CallbackInterface?", "optional Dict", "optional Dict2",
"Date?", "any", "Promise<any>?"] +
allBut(unions, [ "(long or Callback)" ]))
dates = [ "Date", "Date?" ]
sequences = [ "sequence<long>", "sequence<short>" ]
nonUserObjects = nonObjects + interfaces + dates + sequences
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
records = [ "record<DOMString, object>", "record<USVString, Dict>",
"record<ByteString, long>" ]
# Build a representation of the distinguishability table as a dict
# of dicts, holding True values where needed, holes elsewhere.
@ -232,9 +239,9 @@ def WebIDLTest(parser, harness):
allBut(argTypes, sequences + ["object"]))
setDistinguishable("sequence<short>",
allBut(argTypes, sequences + ["object"]))
setDistinguishable("MozMap<object>", nonUserObjects)
setDistinguishable("MozMap<Dict>", nonUserObjects)
setDistinguishable("MozMap<long>", nonUserObjects)
setDistinguishable("record<DOMString, object>", nonUserObjects)
setDistinguishable("record<USVString, Dict>", nonUserObjects)
setDistinguishable("record<ByteString, long>", nonUserObjects)
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
setDistinguishable("any", [])
@ -245,6 +252,10 @@ def WebIDLTest(parser, harness):
setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]))
setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
setDistinguishable("(long or Callback)",
allBut(nonUserObjects, numerics))
setDistinguishable("optional (long or Dict)",
allBut(nonUserObjects, numerics + nullables))
def areDistinguishable(type1, type2):
return data[type1].get(type2, False)

View File

@ -3,8 +3,8 @@ import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict {};
interface MozMapArg {
void foo(MozMap<Dict> arg);
interface RecordArg {
void foo(record<DOMString, Dict> arg);
};
""")
@ -19,7 +19,7 @@ def WebIDLTest(parser, harness):
signature = members[0].signatures()[0]
args = signature[1]
harness.check(len(args), 1, "Should have one arg")
harness.ok(args[0].type.isMozMap(), "Should have a MozMap type here")
harness.ok(args[0].type.isRecord(), "Should have a record type here")
harness.ok(args[0].type.inner.isDictionary(),
"Should have a dictionary inner type")
@ -27,13 +27,27 @@ def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface MozMapVoidArg {
void foo(MozMap<void> arg);
interface RecordVoidArg {
void foo(record<DOMString, void> arg);
};
""")
results = parser.finish()
except Exception,x:
threw = True
harness.ok(threw, "Should have thrown because record can't have void as value type.")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary Dict {
record<DOMString, Dict> val;
};
""")
harness.ok(threw, "Should have thrown.")
results = parser.finish()
except Exception,x:
threw = True
harness.ok(threw,
"Should have thrown on dictionary containing itself via record.")

View File

@ -10,7 +10,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Date.h"
#include "mozilla/dom/MozMap.h"
#include "mozilla/dom/Record.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/ErrorResult.h"
#include "nsCOMPtr.h"
@ -170,7 +170,22 @@ public:
static
already_AddRefed<TestInterface> Test3(const GlobalObject&,
const LongOrAnyMozMap&,
const LongOrStringAnyRecord&,
ErrorResult&);
static
already_AddRefed<TestInterface> Test4(const GlobalObject&,
const Record<nsString, Record<nsString, JS::Value>>&,
ErrorResult&);
static
already_AddRefed<TestInterface> Test5(const GlobalObject&,
const Record<nsString, Sequence<Record<nsString, Record<nsString, Sequence<Sequence<JS::Value>>>>>>&,
ErrorResult&);
static
already_AddRefed<TestInterface> Test6(const GlobalObject&,
const Sequence<Record<nsCString, Sequence<Sequence<Record<nsCString, Record<nsString, JS::Value>>>>>>&,
ErrorResult&);
// Integer types
@ -266,27 +281,27 @@ public:
float WritableUnrestrictedFloat() const;
void SetWritableUnrestrictedFloat(float);
Nullable<float> GetWritableNullableFloat() const;
void SetWritableNullableFloat(Nullable<float>);
void SetWritableNullableFloat(const Nullable<float>&);
Nullable<float> GetWritableNullableUnrestrictedFloat() const;
void SetWritableNullableUnrestrictedFloat(Nullable<float>);
void SetWritableNullableUnrestrictedFloat(const Nullable<float>&);
double WritableDouble() const;
void SetWritableDouble(double);
double WritableUnrestrictedDouble() const;
void SetWritableUnrestrictedDouble(double);
Nullable<double> GetWritableNullableDouble() const;
void SetWritableNullableDouble(Nullable<double>);
void SetWritableNullableDouble(const Nullable<double>&);
Nullable<double> GetWritableNullableUnrestrictedDouble() const;
void SetWritableNullableUnrestrictedDouble(Nullable<double>);
void PassFloat(float, float, Nullable<float>, Nullable<float>,
double, double, Nullable<double>, Nullable<double>,
void SetWritableNullableUnrestrictedDouble(const Nullable<double>&);
void PassFloat(float, float, const Nullable<float>&, const Nullable<float>&,
double, double, const Nullable<double>&, const Nullable<double>&,
const Sequence<float>&, const Sequence<float>&,
const Sequence<Nullable<float> >&,
const Sequence<Nullable<float> >&,
const Sequence<double>&, const Sequence<double>&,
const Sequence<Nullable<double> >&,
const Sequence<Nullable<double> >&);
void PassLenientFloat(float, float, Nullable<float>, Nullable<float>,
double, double, Nullable<double>, Nullable<double>,
void PassLenientFloat(float, float, const Nullable<float>&, const Nullable<float>&,
double, double, const Nullable<double>&, const Nullable<double>&,
const Sequence<float>&, const Sequence<float>&,
const Sequence<Nullable<float> >&,
const Sequence<Nullable<float> >&,
@ -431,31 +446,31 @@ public:
void ReceiveSequenceOfSequences(nsTArray< nsTArray<int32_t> >&);
void ReceiveSequenceOfSequencesOfSequences(nsTArray<nsTArray<nsTArray<int32_t>>>&);
// MozMap types
void PassMozMap(const MozMap<int32_t> &);
void PassNullableMozMap(const Nullable< MozMap<int32_t> >&);
void PassMozMapOfNullableInts(const MozMap<Nullable<int32_t> >&);
void PassOptionalMozMapOfNullableInts(const Optional<MozMap<Nullable<int32_t> > > &);
void PassOptionalNullableMozMapOfNullableInts(const Optional<Nullable<MozMap<Nullable<int32_t> > > > &);
void PassCastableObjectMozMap(const MozMap< OwningNonNull<TestInterface> >&);
void PassNullableCastableObjectMozMap(const MozMap< RefPtr<TestInterface> > &);
void PassCastableObjectNullableMozMap(const Nullable< MozMap< OwningNonNull<TestInterface> > >&);
void PassNullableCastableObjectNullableMozMap(const Nullable< MozMap< RefPtr<TestInterface> > >&);
void PassOptionalMozMap(const Optional<MozMap<int32_t> >&);
void PassOptionalNullableMozMap(const Optional<Nullable<MozMap<int32_t> > >&);
void PassOptionalNullableMozMapWithDefaultValue(const Nullable< MozMap<int32_t> >&);
void PassOptionalObjectMozMap(const Optional<MozMap<OwningNonNull<TestInterface> > >&);
void PassExternalInterfaceMozMap(const MozMap<RefPtr<TestExternalInterface> >&);
void PassNullableExternalInterfaceMozMap(const MozMap<RefPtr<TestExternalInterface> >&);
void PassStringMozMap(const MozMap<nsString>&);
void PassByteStringMozMap(const MozMap<nsCString>&);
void PassMozMapOfMozMaps(const MozMap< MozMap<int32_t> >&);
void ReceiveMozMap(MozMap<int32_t>&);
void ReceiveNullableMozMap(Nullable<MozMap<int32_t>>&);
void ReceiveMozMapOfNullableInts(MozMap<Nullable<int32_t>>&);
void ReceiveNullableMozMapOfNullableInts(Nullable<MozMap<Nullable<int32_t>>>&);
void ReceiveMozMapOfMozMaps(MozMap<MozMap<int32_t>>&);
void ReceiveAnyMozMap(JSContext*, MozMap<JS::Value>&);
// Record types
void PassRecord(const Record<nsString, int32_t> &);
void PassNullableRecord(const Nullable< Record<nsString, int32_t> >&);
void PassRecordOfNullableInts(const Record<nsString, Nullable<int32_t> >&);
void PassOptionalRecordOfNullableInts(const Optional<Record<nsString, Nullable<int32_t> > > &);
void PassOptionalNullableRecordOfNullableInts(const Optional<Nullable<Record<nsString, Nullable<int32_t> > > > &);
void PassCastableObjectRecord(const Record<nsString, OwningNonNull<TestInterface> >&);
void PassNullableCastableObjectRecord(const Record<nsString, RefPtr<TestInterface> > &);
void PassCastableObjectNullableRecord(const Nullable< Record<nsString, OwningNonNull<TestInterface> > >&);
void PassNullableCastableObjectNullableRecord(const Nullable< Record<nsString, RefPtr<TestInterface> > >&);
void PassOptionalRecord(const Optional<Record<nsString, int32_t> >&);
void PassOptionalNullableRecord(const Optional<Nullable<Record<nsString, int32_t> > >&);
void PassOptionalNullableRecordWithDefaultValue(const Nullable< Record<nsString, int32_t> >&);
void PassOptionalObjectRecord(const Optional<Record<nsString, OwningNonNull<TestInterface> > >&);
void PassExternalInterfaceRecord(const Record<nsString, RefPtr<TestExternalInterface> >&);
void PassNullableExternalInterfaceRecord(const Record<nsString, RefPtr<TestExternalInterface> >&);
void PassStringRecord(const Record<nsString, nsString>&);
void PassByteStringRecord(const Record<nsString, nsCString>&);
void PassRecordOfRecords(const Record<nsString, Record<nsString, int32_t> >&);
void ReceiveRecord(Record<nsString, int32_t>&);
void ReceiveNullableRecord(Nullable<Record<nsString, int32_t>>&);
void ReceiveRecordOfNullableInts(Record<nsString, Nullable<int32_t>>&);
void ReceiveNullableRecordOfNullableInts(Nullable<Record<nsString, Nullable<int32_t>>>&);
void ReceiveRecordOfRecords(Record<nsString, Record<nsString, int32_t>>&);
void ReceiveAnyRecord(JSContext*, Record<nsString, JS::Value>&);
// Typed array types
void PassArrayBuffer(const ArrayBuffer&);
@ -475,8 +490,8 @@ public:
void PassFloat64Array(const Float64Array&);
void PassSequenceOfArrayBuffers(const Sequence<ArrayBuffer>&);
void PassSequenceOfNullableArrayBuffers(const Sequence<Nullable<ArrayBuffer> >&);
void PassMozMapOfArrayBuffers(const MozMap<ArrayBuffer>&);
void PassMozMapOfNullableArrayBuffers(const MozMap<Nullable<ArrayBuffer> >&);
void PassRecordOfArrayBuffers(const Record<nsString, ArrayBuffer>&);
void PassRecordOfNullableArrayBuffers(const Record<nsString, Nullable<ArrayBuffer> >&);
void PassVariadicTypedArray(const Sequence<Float32Array>&);
void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array> >&);
void ReceiveUint8Array(JSContext*, JS::MutableHandle<JSObject*>);
@ -584,17 +599,17 @@ public:
void PassSequenceOfNullableSequenceOfAny(JSContext*, const Sequence<Nullable<Sequence<JS::Value> > >&);
void PassNullableSequenceOfNullableSequenceOfAny(JSContext*, const Nullable<Sequence<Nullable<Sequence<JS::Value> > > >&);
void PassOptionalNullableSequenceOfNullableSequenceOfAny(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JS::Value> > > > >&);
void PassMozMapOfAny(JSContext*, const MozMap<JS::Value>&);
void PassNullableMozMapOfAny(JSContext*, const Nullable<MozMap<JS::Value> >&);
void PassOptionalMozMapOfAny(JSContext*, const Optional<MozMap<JS::Value> >&);
void PassOptionalNullableMozMapOfAny(JSContext*, const Optional<Nullable<MozMap<JS::Value> > >&);
void PassOptionalMozMapOfAnyWithDefaultValue(JSContext*, const Nullable<MozMap<JS::Value> >&);
void PassMozMapOfMozMapOfAny(JSContext*, const MozMap<MozMap<JS::Value> >&);
void PassMozMapOfNullableMozMapOfAny(JSContext*, const MozMap<Nullable<MozMap<JS::Value> > >&);
void PassNullableMozMapOfNullableMozMapOfAny(JSContext*, const Nullable<MozMap<Nullable<MozMap<JS::Value> > > >&);
void PassOptionalNullableMozMapOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<MozMap<JS::Value>>>>>&);
void PassOptionalNullableMozMapOfNullableSequenceOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<Sequence<JS::Value>>>>>&);
void PassOptionalNullableSequenceOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<Sequence<Nullable<MozMap<JS::Value>>>>>&);
void PassRecordOfAny(JSContext*, const Record<nsString, JS::Value>&);
void PassNullableRecordOfAny(JSContext*, const Nullable<Record<nsString, JS::Value> >&);
void PassOptionalRecordOfAny(JSContext*, const Optional<Record<nsString, JS::Value> >&);
void PassOptionalNullableRecordOfAny(JSContext*, const Optional<Nullable<Record<nsString, JS::Value> > >&);
void PassOptionalRecordOfAnyWithDefaultValue(JSContext*, const Nullable<Record<nsString, JS::Value> >&);
void PassRecordOfRecordOfAny(JSContext*, const Record<nsString, Record<nsString, JS::Value> >&);
void PassRecordOfNullableRecordOfAny(JSContext*, const Record<nsString, Nullable<Record<nsString, JS::Value> > >&);
void PassNullableRecordOfNullableRecordOfAny(JSContext*, const Nullable<Record<nsString, Nullable<Record<nsString, JS::Value> > > >&);
void PassOptionalNullableRecordOfNullableRecordOfAny(JSContext*, const Optional<Nullable<Record<nsString, Nullable<Record<nsString, JS::Value>>>>>&);
void PassOptionalNullableRecordOfNullableSequenceOfAny(JSContext*, const Optional<Nullable<Record<nsString, Nullable<Sequence<JS::Value>>>>>&);
void PassOptionalNullableSequenceOfNullableRecordOfAny(JSContext*, const Optional<Nullable<Sequence<Nullable<Record<nsString, JS::Value>>>>>&);
void ReceiveAny(JSContext*, JS::MutableHandle<JS::Value>);
// object types
@ -610,7 +625,7 @@ public:
void PassNullableSequenceOfObject(JSContext*, const Nullable<Sequence<JSObject*> >&);
void PassOptionalNullableSequenceOfNullableSequenceOfObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
void PassMozMapOfObject(JSContext*, const MozMap<JSObject*>&);
void PassRecordOfObject(JSContext*, const Record<nsString, JSObject*>&);
void ReceiveObject(JSContext*, JS::MutableHandle<JSObject*>);
void ReceiveNullableObject(JSContext*, JS::MutableHandle<JSObject*>);
@ -650,8 +665,8 @@ public:
void PassUnion18(JSContext*, const ObjectSequenceOrLong&);
void PassUnion19(JSContext*, const Optional<ObjectSequenceOrLong>&);
void PassUnion20(JSContext*, const ObjectSequenceOrLong&);
void PassUnion21(const LongMozMapOrLong&);
void PassUnion22(JSContext*, const ObjectMozMapOrLong&);
void PassUnion21(const StringLongRecordOrLong&);
void PassUnion22(JSContext*, const StringObjectRecordOrLong&);
void PassUnion23(const ImageDataSequenceOrLong&);
void PassUnion24(const ImageDataOrNullSequenceOrLong&);
void PassUnion25(const ImageDataSequenceSequenceOrLong&);
@ -660,9 +675,9 @@ public:
void PassUnion28(const EventInitOrStringSequence&);
void PassUnionWithCallback(const EventHandlerNonNullOrNullOrLong& arg);
void PassUnionWithByteString(const ByteStringOrLong&);
void PassUnionWithMozMap(const StringMozMapOrString&);
void PassUnionWithMozMapAndSequence(const StringMozMapOrStringSequence&);
void PassUnionWithSequenceAndMozMap(const StringSequenceOrStringMozMap&);
void PassUnionWithRecord(const StringStringRecordOrString&);
void PassUnionWithRecordAndSequence(const StringStringRecordOrStringSequence&);
void PassUnionWithSequenceAndRecord(const StringSequenceOrStringStringRecord&);
void PassUnionWithUSVS(const USVStringOrLong&);
#endif
void PassNullableUnion(JSContext*, const Nullable<ObjectOrLong>&);
@ -731,8 +746,8 @@ public:
void PassSequenceOfNullableUnions(const Sequence<Nullable<OwningCanvasPatternOrCanvasGradient>>&);
void PassVariadicNullableUnion(const Sequence<Nullable<OwningCanvasPatternOrCanvasGradient>>&);
void PassMozMapOfUnions(const MozMap<OwningCanvasPatternOrCanvasGradient>&);
void PassMozMapOfUnions2(JSContext*, const MozMap<OwningObjectOrLong>&);
void PassRecordOfUnions(const Record<nsString, OwningCanvasPatternOrCanvasGradient>&);
void PassRecordOfUnions2(JSContext*, const Record<nsString, OwningObjectOrLong>&);
void ReceiveUnion(OwningCanvasPatternOrCanvasGradient&);
void ReceiveUnion2(JSContext*, OwningObjectOrLong&);
@ -753,7 +768,7 @@ public:
void PassOptionalNullableDate(const Optional<Nullable<Date> >&);
void PassOptionalNullableDateWithDefaultValue(const Nullable<Date>&);
void PassDateSequence(const Sequence<Date>&);
void PassDateMozMap(const MozMap<Date>&);
void PassDateRecord(const Record<nsString, Date>&);
void PassNullableDateSequence(const Sequence<Nullable<Date> >&);
Date ReceiveDate();
Nullable<Date> ReceiveNullableDate();
@ -762,7 +777,7 @@ public:
void PassPromise(Promise&);
void PassOptionalPromise(const Optional<OwningNonNull<Promise>>&);
void PassPromiseSequence(const Sequence<OwningNonNull<Promise>>&);
void PassPromiseMozMap(const MozMap<RefPtr<Promise>>&);
void PassPromiseRecord(const Record<nsString, RefPtr<Promise>>&);
Promise* ReceivePromise();
already_AddRefed<Promise> ReceiveAddrefedPromise();
@ -791,7 +806,7 @@ public:
void ReceiveNullableDictionary(JSContext*, Nullable<Dict>&);
void PassOtherDictionary(const GrandparentDict&);
void PassSequenceOfDictionaries(JSContext*, const Sequence<Dict>&);
void PassMozMapOfDictionaries(const MozMap<GrandparentDict>&);
void PassRecordOfDictionaries(const Record<nsString, GrandparentDict>&);
void PassDictionaryOrLong(JSContext*, const Dict&);
void PassDictionaryOrLong(int32_t);
void PassDictContainingDict(JSContext*, const DictContainingDict&);
@ -863,8 +878,8 @@ public:
void Overload16(int32_t);
void Overload16(const Optional<TestInterface*>&);
void Overload17(const Sequence<int32_t>&);
void Overload17(const MozMap<int32_t>&);
void Overload18(const MozMap<nsString>&);
void Overload17(const Record<nsString, int32_t>&);
void Overload18(const Record<nsString, nsString>&);
void Overload18(const Sequence<nsString>&);
void Overload19(const Sequence<int32_t>&);
void Overload19(JSContext*, const Dict&);

View File

@ -22,7 +22,7 @@ callback interface TestCallbackInterface {
long doSomethingElse(DOMString arg, TestInterface otherArg);
void doSequenceLongArg(sequence<long> arg);
void doSequenceStringArg(sequence<DOMString> arg);
void doMozMapLongArg(MozMap<long> arg);
void doRecordLongArg(record<DOMString, long> arg);
sequence<long> getSequenceOfLong();
sequence<TestInterface> getSequenceOfInterfaces();
sequence<TestInterface>? getNullableSequenceOfInterfaces();
@ -32,7 +32,7 @@ callback interface TestCallbackInterface {
sequence<TestCallbackInterface>? getNullableSequenceOfCallbackInterfaces();
sequence<TestCallbackInterface?> getSequenceOfNullableCallbackInterfaces();
sequence<TestCallbackInterface?>? getNullableSequenceOfNullableCallbackInterfaces();
MozMap<long> getMozMapOfLong();
record<DOMString, long> getRecordOfLong();
Dict? getDictionary();
void passArrayBuffer(ArrayBuffer arg);
void passNullableArrayBuffer(ArrayBuffer? arg);
@ -140,7 +140,10 @@ interface OnlyForUseInConstructor {
NamedConstructor=Test2(DictForConstructor dict, any any1, object obj1,
object? obj2, sequence<Dict> seq, optional any any2,
optional object obj3, optional object? obj4),
NamedConstructor=Test3((long or MozMap<any>) arg1)
NamedConstructor=Test3((long or record<DOMString, any>) arg1),
NamedConstructor=Test4(record<DOMString, record<DOMString, any>> arg1),
NamedConstructor=Test5(record<DOMString, sequence<record<DOMString, record<DOMString, sequence<sequence<any>>>>>> arg1),
NamedConstructor=Test6(sequence<record<ByteString, sequence<sequence<record<ByteString, record<USVString, any>>>>>> arg1),
]
interface TestInterface {
// Integer types
@ -415,31 +418,31 @@ interface TestInterface {
sequence<sequence<long>> receiveSequenceOfSequences();
sequence<sequence<sequence<long>>> receiveSequenceOfSequencesOfSequences();
// MozMap types
void passMozMap(MozMap<long> arg);
void passNullableMozMap(MozMap<long>? arg);
void passMozMapOfNullableInts(MozMap<long?> arg);
void passOptionalMozMapOfNullableInts(optional MozMap<long?> arg);
void passOptionalNullableMozMapOfNullableInts(optional MozMap<long?>? arg);
void passCastableObjectMozMap(MozMap<TestInterface> arg);
void passNullableCastableObjectMozMap(MozMap<TestInterface?> arg);
void passCastableObjectNullableMozMap(MozMap<TestInterface>? arg);
void passNullableCastableObjectNullableMozMap(MozMap<TestInterface?>? arg);
void passOptionalMozMap(optional MozMap<long> arg);
void passOptionalNullableMozMap(optional MozMap<long>? arg);
void passOptionalNullableMozMapWithDefaultValue(optional MozMap<long>? arg = null);
void passOptionalObjectMozMap(optional MozMap<TestInterface> arg);
void passExternalInterfaceMozMap(MozMap<TestExternalInterface> arg);
void passNullableExternalInterfaceMozMap(MozMap<TestExternalInterface?> arg);
void passStringMozMap(MozMap<DOMString> arg);
void passByteStringMozMap(MozMap<ByteString> arg);
void passMozMapOfMozMaps(MozMap<MozMap<long>> arg);
MozMap<long> receiveMozMap();
MozMap<long>? receiveNullableMozMap();
MozMap<long?> receiveMozMapOfNullableInts();
MozMap<long?>? receiveNullableMozMapOfNullableInts();
MozMap<MozMap<long>> receiveMozMapOfMozMaps();
MozMap<any> receiveAnyMozMap();
// record types
void passRecord(record<DOMString, long> arg);
void passNullableRecord(record<DOMString, long>? arg);
void passRecordOfNullableInts(record<DOMString, long?> arg);
void passOptionalRecordOfNullableInts(optional record<DOMString, long?> arg);
void passOptionalNullableRecordOfNullableInts(optional record<DOMString, long?>? arg);
void passCastableObjectRecord(record<DOMString, TestInterface> arg);
void passNullableCastableObjectRecord(record<DOMString, TestInterface?> arg);
void passCastableObjectNullableRecord(record<DOMString, TestInterface>? arg);
void passNullableCastableObjectNullableRecord(record<DOMString, TestInterface?>? arg);
void passOptionalRecord(optional record<DOMString, long> arg);
void passOptionalNullableRecord(optional record<DOMString, long>? arg);
void passOptionalNullableRecordWithDefaultValue(optional record<DOMString, long>? arg = null);
void passOptionalObjectRecord(optional record<DOMString, TestInterface> arg);
void passExternalInterfaceRecord(record<DOMString, TestExternalInterface> arg);
void passNullableExternalInterfaceRecord(record<DOMString, TestExternalInterface?> arg);
void passStringRecord(record<DOMString, DOMString> arg);
void passByteStringRecord(record<DOMString, ByteString> arg);
void passRecordOfRecords(record<DOMString, record<DOMString, long>> arg);
record<DOMString, long> receiveRecord();
record<DOMString, long>? receiveNullableRecord();
record<DOMString, long?> receiveRecordOfNullableInts();
record<DOMString, long?>? receiveNullableRecordOfNullableInts();
record<DOMString, record<DOMString, long>> receiveRecordOfRecords();
record<DOMString, any> receiveAnyRecord();
// Typed array types
void passArrayBuffer(ArrayBuffer arg);
@ -459,8 +462,8 @@ interface TestInterface {
void passFloat64Array(Float64Array arg);
void passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
void passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
void passMozMapOfArrayBuffers(MozMap<ArrayBuffer> arg);
void passMozMapOfNullableArrayBuffers(MozMap<ArrayBuffer?> arg);
void passRecordOfArrayBuffers(record<DOMString, ArrayBuffer> arg);
void passRecordOfNullableArrayBuffers(record<DOMString, ArrayBuffer?> arg);
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
@ -565,17 +568,17 @@ interface TestInterface {
void passSequenceOfNullableSequenceOfAny(sequence<sequence<any>?> arg);
void passNullableSequenceOfNullableSequenceOfAny(sequence<sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfAny(optional sequence<sequence<any>?>? arg);
void passMozMapOfAny(MozMap<any> arg);
void passNullableMozMapOfAny(MozMap<any>? arg);
void passOptionalMozMapOfAny(optional MozMap<any> arg);
void passOptionalNullableMozMapOfAny(optional MozMap<any>? arg);
void passOptionalMozMapOfAnyWithDefaultValue(optional MozMap<any>? arg = null);
void passMozMapOfMozMapOfAny(MozMap<MozMap<any>> arg);
void passMozMapOfNullableMozMapOfAny(MozMap<MozMap<any>?> arg);
void passNullableMozMapOfNullableMozMapOfAny(MozMap<MozMap<any>?>? arg);
void passOptionalNullableMozMapOfNullableMozMapOfAny(optional MozMap<MozMap<any>?>? arg);
void passOptionalNullableMozMapOfNullableSequenceOfAny(optional MozMap<sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableMozMapOfAny(optional sequence<MozMap<any>?>? arg);
void passRecordOfAny(record<DOMString, any> arg);
void passNullableRecordOfAny(record<DOMString, any>? arg);
void passOptionalRecordOfAny(optional record<DOMString, any> arg);
void passOptionalNullableRecordOfAny(optional record<DOMString, any>? arg);
void passOptionalRecordOfAnyWithDefaultValue(optional record<DOMString, any>? arg = null);
void passRecordOfRecordOfAny(record<DOMString, record<DOMString, any>> arg);
void passRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?> arg);
void passNullableRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?>? arg);
void passOptionalNullableRecordOfNullableRecordOfAny(optional record<DOMString, record<DOMString, any>?>? arg);
void passOptionalNullableRecordOfNullableSequenceOfAny(optional record<DOMString, sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableRecordOfAny(optional sequence<record<DOMString, any>?>? arg);
any receiveAny();
// object types
@ -591,7 +594,7 @@ interface TestInterface {
void passNullableSequenceOfObject(sequence<object>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
void passMozMapOfObject(MozMap<object> arg);
void passRecordOfObject(record<DOMString, object> arg);
object receiveObject();
object? receiveNullableObject();
@ -619,8 +622,8 @@ interface TestInterface {
void passUnion18((sequence<object> or long) arg);
void passUnion19(optional (sequence<object> or long) arg);
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion21((record<DOMString, long> or long) arg);
void passUnion22((record<DOMString, object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
@ -629,9 +632,9 @@ interface TestInterface {
void passUnion28(optional (EventInit or sequence<DOMString>) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);
void passUnionWithMozMapAndSequence((MozMap<DOMString> or sequence<DOMString>) arg);
void passUnionWithSequenceAndMozMap((sequence<DOMString> or MozMap<DOMString>) arg);
void passUnionWithRecord((record<DOMString, DOMString> or DOMString) arg);
void passUnionWithRecordAndSequence((record<DOMString, DOMString> or sequence<DOMString>) arg);
void passUnionWithSequenceAndRecord((sequence<DOMString> or record<DOMString, DOMString>) arg);
void passUnionWithUSVS((USVString or long) arg);
#endif
void passUnionWithNullable((object? or long) arg);
@ -710,9 +713,9 @@ interface TestInterface {
void passSequenceOfNullableUnions(sequence<(CanvasPattern or CanvasGradient)?> arg);
void passVariadicNullableUnion((CanvasPattern or CanvasGradient)?... arg);
void passMozMapOfUnions(MozMap<(CanvasPattern or CanvasGradient)> arg);
void passRecordOfUnions(record<DOMString, (CanvasPattern or CanvasGradient)> arg);
// XXXbz no move constructor on some unions
// void passMozMapOfUnions2(MozMap<(object or long)> arg);
// void passRecordOfUnions2(record<DOMString, (object or long)> arg);
(CanvasPattern or CanvasGradient) receiveUnion();
(object or long) receiveUnion2();
@ -732,7 +735,7 @@ interface TestInterface {
void passOptionalNullableDateWithDefaultValue(optional Date? arg = null);
void passDateSequence(sequence<Date> arg);
void passNullableDateSequence(sequence<Date?> arg);
void passDateMozMap(MozMap<Date> arg);
void passDateRecord(record<DOMString, Date> arg);
Date receiveDate();
Date? receiveNullableDate();
@ -771,7 +774,7 @@ interface TestInterface {
Dict? receiveNullableDictionary();
void passOtherDictionary(optional GrandparentDict x);
void passSequenceOfDictionaries(sequence<Dict> x);
void passMozMapOfDictionaries(MozMap<GrandparentDict> x);
void passRecordOfDictionaries(record<DOMString, GrandparentDict> x);
// No support for nullable dictionaries inside a sequence (nor should there be)
// void passSequenceOfNullableDictionaries(sequence<Dict?> x);
void passDictionaryOrLong(optional Dict x);
@ -860,8 +863,8 @@ interface TestInterface {
void overload16(long arg);
void overload16(optional TestInterface? arg);
void overload17(sequence<long> arg);
void overload17(MozMap<long> arg);
void overload18(MozMap<DOMString> arg);
void overload17(record<DOMString, long> arg);
void overload18(record<DOMString, DOMString> arg);
void overload18(sequence<DOMString> arg);
void overload19(sequence<long> arg);
void overload19(optional Dict arg);
@ -1116,6 +1119,17 @@ dictionary Dict : ParentDict {
Promise<void> promise;
sequence<Promise<void>> promiseSequence;
record<DOMString, long> recordMember;
record<DOMString, long>? nullableRecord;
record<DOMString, DOMString>? nullableRecordWithDefault = null;
record<USVString, long> usvStringRecord;
record<USVString, long>? nullableUSVStringRecordWithDefault = null;
record<ByteString, long> byteStringRecord;
record<ByteString, long>? nullableByteStringRecordWithDefault = null;
required record<DOMString, TestInterface> requiredRecord;
required record<USVString, TestInterface> requiredUSVRecord;
required record<ByteString, TestInterface> requiredByteRecord;
};
dictionary ParentDict : GrandparentDict {

View File

@ -17,7 +17,7 @@
NamedConstructor=Example2(DictForConstructor dict, any any1, object obj1,
object? obj2, sequence<Dict> seq, optional any any2,
optional object obj3, optional object? obj4),
NamedConstructor=Example2((long or MozMap<any>) arg1)
NamedConstructor=Example2((long or record<DOMString, any>) arg1)
]
interface TestExampleInterface {
// Integer types
@ -278,32 +278,32 @@ interface TestExampleInterface {
//XXXbz No support for sequence of sequence return values yet.
//sequence<sequence<long>> receiveSequenceOfSequences();
// MozMap types
void passMozMap(MozMap<long> arg);
void passNullableMozMap(MozMap<long>? arg);
void passMozMapOfNullableInts(MozMap<long?> arg);
void passOptionalMozMapOfNullableInts(optional MozMap<long?> arg);
void passOptionalNullableMozMapOfNullableInts(optional MozMap<long?>? arg);
void passCastableObjectMozMap(MozMap<TestInterface> arg);
void passNullableCastableObjectMozMap(MozMap<TestInterface?> arg);
void passCastableObjectNullableMozMap(MozMap<TestInterface>? arg);
void passNullableCastableObjectNullableMozMap(MozMap<TestInterface?>? arg);
void passOptionalMozMap(optional MozMap<long> arg);
void passOptionalNullableMozMap(optional MozMap<long>? arg);
void passOptionalNullableMozMapWithDefaultValue(optional MozMap<long>? arg = null);
void passOptionalObjectMozMap(optional MozMap<TestInterface> arg);
void passExternalInterfaceMozMap(MozMap<TestExternalInterface> arg);
void passNullableExternalInterfaceMozMap(MozMap<TestExternalInterface?> arg);
void passStringMozMap(MozMap<DOMString> arg);
void passByteStringMozMap(MozMap<ByteString> arg);
void passMozMapOfMozMaps(MozMap<MozMap<long>> arg);
MozMap<long> receiveMozMap();
MozMap<long>? receiveNullableMozMap();
MozMap<long?> receiveMozMapOfNullableInts();
MozMap<long?>? receiveNullableMozMapOfNullableInts();
//XXXbz No support for MozMap of MozMaps return values yet.
//MozMap<MozMap<long>> receiveMozMapOfMozMaps();
MozMap<any> receiveAnyMozMap();
// record types
void passRecord(record<DOMString, long> arg);
void passNullableRecord(record<DOMString, long>? arg);
void passRecordOfNullableInts(record<DOMString, long?> arg);
void passOptionalRecordOfNullableInts(optional record<DOMString, long?> arg);
void passOptionalNullableRecordOfNullableInts(optional record<DOMString, long?>? arg);
void passCastableObjectRecord(record<DOMString, TestInterface> arg);
void passNullableCastableObjectRecord(record<DOMString, TestInterface?> arg);
void passCastableObjectNullableRecord(record<DOMString, TestInterface>? arg);
void passNullableCastableObjectNullableRecord(record<DOMString, TestInterface?>? arg);
void passOptionalRecord(optional record<DOMString, long> arg);
void passOptionalNullableRecord(optional record<DOMString, long>? arg);
void passOptionalNullableRecordWithDefaultValue(optional record<DOMString, long>? arg = null);
void passOptionalObjectRecord(optional record<DOMString, TestInterface> arg);
void passExternalInterfaceRecord(record<DOMString, TestExternalInterface> arg);
void passNullableExternalInterfaceRecord(record<DOMString, TestExternalInterface?> arg);
void passStringRecord(record<DOMString, DOMString> arg);
void passByteStringRecord(record<DOMString, ByteString> arg);
void passRecordOfRecords(record<DOMString, record<DOMString, long>> arg);
record<DOMString, long> receiveRecord();
record<DOMString, long>? receiveNullableRecord();
record<DOMString, long?> receiveRecordOfNullableInts();
record<DOMString, long?>? receiveNullableRecordOfNullableInts();
//XXXbz No support for record of records return values yet.
//record<DOMString, record<DOMString, long>> receiveRecordOfRecords();
record<DOMString, any> receiveAnyRecord();
// Typed array types
void passArrayBuffer(ArrayBuffer arg);
@ -323,8 +323,8 @@ interface TestExampleInterface {
void passFloat64Array(Float64Array arg);
void passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
void passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
void passMozMapOfArrayBuffers(MozMap<ArrayBuffer> arg);
void passMozMapOfNullableArrayBuffers(MozMap<ArrayBuffer?> arg);
void passRecordOfArrayBuffers(record<DOMString, ArrayBuffer> arg);
void passRecordOfNullableArrayBuffers(record<DOMString, ArrayBuffer?> arg);
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
@ -400,17 +400,17 @@ interface TestExampleInterface {
void passSequenceOfNullableSequenceOfAny(sequence<sequence<any>?> arg);
void passNullableSequenceOfNullableSequenceOfAny(sequence<sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfAny(optional sequence<sequence<any>?>? arg);
void passMozMapOfAny(MozMap<any> arg);
void passNullableMozMapOfAny(MozMap<any>? arg);
void passOptionalMozMapOfAny(optional MozMap<any> arg);
void passOptionalNullableMozMapOfAny(optional MozMap<any>? arg);
void passOptionalMozMapOfAnyWithDefaultValue(optional MozMap<any>? arg = null);
void passMozMapOfMozMapOfAny(MozMap<MozMap<any>> arg);
void passMozMapOfNullableMozMapOfAny(MozMap<MozMap<any>?> arg);
void passNullableMozMapOfNullableMozMapOfAny(MozMap<MozMap<any>?>? arg);
void passOptionalNullableMozMapOfNullableMozMapOfAny(optional MozMap<MozMap<any>?>? arg);
void passOptionalNullableMozMapOfNullableSequenceOfAny(optional MozMap<sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableMozMapOfAny(optional sequence<MozMap<any>?>? arg);
void passRecordOfAny(record<DOMString, any> arg);
void passNullableRecordOfAny(record<DOMString, any>? arg);
void passOptionalRecordOfAny(optional record<DOMString, any> arg);
void passOptionalNullableRecordOfAny(optional record<DOMString, any>? arg);
void passOptionalRecordOfAnyWithDefaultValue(optional record<DOMString, any>? arg = null);
void passRecordOfRecordOfAny(record<DOMString, record<DOMString, any>> arg);
void passRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?> arg);
void passNullableRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?>? arg);
void passOptionalNullableRecordOfNullableRecordOfAny(optional record<DOMString, record<DOMString, any>?>? arg);
void passOptionalNullableRecordOfNullableSequenceOfAny(optional record<DOMString, sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableRecordOfAny(optional sequence<record<DOMString, any>?>? arg);
any receiveAny();
// object types
@ -426,7 +426,7 @@ interface TestExampleInterface {
void passNullableSequenceOfObject(sequence<object>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
void passMozMapOfObject(MozMap<object> arg);
void passRecordOfObject(record<DOMString, object> arg);
object receiveObject();
object? receiveNullableObject();
@ -455,8 +455,8 @@ interface TestExampleInterface {
void passUnion18((sequence<object> or long) arg);
void passUnion19(optional (sequence<object> or long) arg);
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion21((record<DOMString, long> or long) arg);
void passUnion22((record<DOMString, object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
@ -465,9 +465,9 @@ interface TestExampleInterface {
void passUnion28(optional (EventInit or sequence<DOMString>) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);
void passUnionWithMozMapAndSequence((MozMap<DOMString> or sequence<DOMString>) arg);
void passUnionWithSequenceAndMozMap((sequence<DOMString> or MozMap<DOMString>) arg);
void passUnionWithRecord((record<DOMString, DOMString> or DOMString) arg);
void passUnionWithRecordAndSequence((record<DOMString, DOMString> or sequence<DOMString>) arg);
void passUnionWithSequenceAndRecord((sequence<DOMString> or record<DOMString, DOMString>) arg);
void passUnionWithSVS((USVString or long) arg);
#endif
void passUnionWithNullable((object? or long) arg);
@ -546,9 +546,9 @@ interface TestExampleInterface {
void passSequenceOfNullableUnions(sequence<(CanvasPattern or CanvasGradient)?> arg);
void passVariadicNullableUnion((CanvasPattern or CanvasGradient)?... arg);
void passMozMapOfUnions(MozMap<(CanvasPattern or CanvasGradient)> arg);
void passRecordOfUnions(record<DOMString, (CanvasPattern or CanvasGradient)> arg);
// XXXbz no move constructor on some unions
// void passMozMapOfUnions2(MozMap<(object or long)> arg);
// void passRecordOfUnions2(record<DOMString, (object or long)> arg);
(CanvasPattern or CanvasGradient) receiveUnion();
(object or long) receiveUnion2();
@ -568,7 +568,7 @@ interface TestExampleInterface {
void passOptionalNullableDateWithDefaultValue(optional Date? arg = null);
void passDateSequence(sequence<Date> arg);
void passNullableDateSequence(sequence<Date?> arg);
void passDateMozMap(MozMap<Date> arg);
void passDateRecord(record<DOMString, Date> arg);
Date receiveDate();
Date? receiveNullableDate();
@ -607,7 +607,7 @@ interface TestExampleInterface {
Dict? receiveNullableDictionary();
void passOtherDictionary(optional GrandparentDict x);
void passSequenceOfDictionaries(sequence<Dict> x);
void passMozMapOfDictionaries(MozMap<GrandparentDict> x);
void passRecordOfDictionaries(record<DOMString, GrandparentDict> x);
// No support for nullable dictionaries inside a sequence (nor should there be)
// void passSequenceOfNullableDictionaries(sequence<Dict?> x);
void passDictionaryOrLong(optional Dict x);
@ -693,8 +693,8 @@ interface TestExampleInterface {
void overload16(long arg);
void overload16(optional TestInterface? arg);
void overload17(sequence<long> arg);
void overload17(MozMap<long> arg);
void overload18(MozMap<DOMString> arg);
void overload17(record<DOMString, long> arg);
void overload18(record<DOMString, DOMString> arg);
void overload18(sequence<DOMString> arg);
void overload19(sequence<long> arg);
void overload19(optional Dict arg);

View File

@ -289,32 +289,32 @@ interface TestJSImplInterface {
//XXXbz No support for sequence of sequence return values yet.
//sequence<sequence<long>> receiveSequenceOfSequences();
// MozMap types
void passMozMap(MozMap<long> arg);
void passNullableMozMap(MozMap<long>? arg);
void passMozMapOfNullableInts(MozMap<long?> arg);
void passOptionalMozMapOfNullableInts(optional MozMap<long?> arg);
void passOptionalNullableMozMapOfNullableInts(optional MozMap<long?>? arg);
void passCastableObjectMozMap(MozMap<TestJSImplInterface> arg);
void passNullableCastableObjectMozMap(MozMap<TestJSImplInterface?> arg);
void passCastableObjectNullableMozMap(MozMap<TestJSImplInterface>? arg);
void passNullableCastableObjectNullableMozMap(MozMap<TestJSImplInterface?>? arg);
void passOptionalMozMap(optional MozMap<long> arg);
void passOptionalNullableMozMap(optional MozMap<long>? arg);
void passOptionalNullableMozMapWithDefaultValue(optional MozMap<long>? arg = null);
void passOptionalObjectMozMap(optional MozMap<TestJSImplInterface> arg);
void passExternalInterfaceMozMap(MozMap<TestExternalInterface> arg);
void passNullableExternalInterfaceMozMap(MozMap<TestExternalInterface?> arg);
void passStringMozMap(MozMap<DOMString> arg);
void passByteStringMozMap(MozMap<ByteString> arg);
void passMozMapOfMozMaps(MozMap<MozMap<long>> arg);
MozMap<long> receiveMozMap();
MozMap<long>? receiveNullableMozMap();
MozMap<long?> receiveMozMapOfNullableInts();
MozMap<long?>? receiveNullableMozMapOfNullableInts();
//XXXbz No support for MozMap of MozMaps return values yet.
//MozMap<MozMap<long>> receiveMozMapOfMozMaps();
MozMap<any> receiveAnyMozMap();
// record types
void passRecord(record<DOMString, long> arg);
void passNullableRecord(record<DOMString, long>? arg);
void passRecordOfNullableInts(record<DOMString, long?> arg);
void passOptionalRecordOfNullableInts(optional record<DOMString, long?> arg);
void passOptionalNullableRecordOfNullableInts(optional record<DOMString, long?>? arg);
void passCastableObjectRecord(record<DOMString, TestInterface> arg);
void passNullableCastableObjectRecord(record<DOMString, TestInterface?> arg);
void passCastableObjectNullableRecord(record<DOMString, TestInterface>? arg);
void passNullableCastableObjectNullableRecord(record<DOMString, TestInterface?>? arg);
void passOptionalRecord(optional record<DOMString, long> arg);
void passOptionalNullableRecord(optional record<DOMString, long>? arg);
void passOptionalNullableRecordWithDefaultValue(optional record<DOMString, long>? arg = null);
void passOptionalObjectRecord(optional record<DOMString, TestInterface> arg);
void passExternalInterfaceRecord(record<DOMString, TestExternalInterface> arg);
void passNullableExternalInterfaceRecord(record<DOMString, TestExternalInterface?> arg);
void passStringRecord(record<DOMString, DOMString> arg);
void passByteStringRecord(record<DOMString, ByteString> arg);
void passRecordOfRecords(record<DOMString, record<DOMString, long>> arg);
record<DOMString, long> receiveRecord();
record<DOMString, long>? receiveNullableRecord();
record<DOMString, long?> receiveRecordOfNullableInts();
record<DOMString, long?>? receiveNullableRecordOfNullableInts();
//XXXbz No support for record of records return values yet.
//record<DOMString, record<DOMString, long>> receiveRecordOfRecords();
record<DOMString, any> receiveAnyRecord();
// Typed array types
void passArrayBuffer(ArrayBuffer arg);
@ -334,8 +334,8 @@ interface TestJSImplInterface {
void passFloat64Array(Float64Array arg);
void passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
void passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
void passMozMapOfArrayBuffers(MozMap<ArrayBuffer> arg);
void passMozMapOfNullableArrayBuffers(MozMap<ArrayBuffer?> arg);
void passRecordOfArrayBuffers(record<DOMString, ArrayBuffer> arg);
void passRecordOfNullableArrayBuffers(record<DOMString, ArrayBuffer?> arg);
void passVariadicTypedArray(Float32Array... arg);
void passVariadicNullableTypedArray(Float32Array?... arg);
Uint8Array receiveUint8Array();
@ -412,17 +412,17 @@ interface TestJSImplInterface {
void passSequenceOfNullableSequenceOfAny(sequence<sequence<any>?> arg);
void passNullableSequenceOfNullableSequenceOfAny(sequence<sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfAny(optional sequence<sequence<any>?>? arg);
void passMozMapOfAny(MozMap<any> arg);
void passNullableMozMapOfAny(MozMap<any>? arg);
void passOptionalMozMapOfAny(optional MozMap<any> arg);
void passOptionalNullableMozMapOfAny(optional MozMap<any>? arg);
void passOptionalMozMapOfAnyWithDefaultValue(optional MozMap<any>? arg = null);
void passMozMapOfMozMapOfAny(MozMap<MozMap<any>> arg);
void passMozMapOfNullableMozMapOfAny(MozMap<MozMap<any>?> arg);
void passNullableMozMapOfNullableMozMapOfAny(MozMap<MozMap<any>?>? arg);
void passOptionalNullableMozMapOfNullableMozMapOfAny(optional MozMap<MozMap<any>?>? arg);
void passOptionalNullableMozMapOfNullableSequenceOfAny(optional MozMap<sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableMozMapOfAny(optional sequence<MozMap<any>?>? arg);
void passRecordOfAny(record<DOMString, any> arg);
void passNullableRecordOfAny(record<DOMString, any>? arg);
void passOptionalRecordOfAny(optional record<DOMString, any> arg);
void passOptionalNullableRecordOfAny(optional record<DOMString, any>? arg);
void passOptionalRecordOfAnyWithDefaultValue(optional record<DOMString, any>? arg = null);
void passRecordOfRecordOfAny(record<DOMString, record<DOMString, any>> arg);
void passRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?> arg);
void passNullableRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?>? arg);
void passOptionalNullableRecordOfNullableRecordOfAny(optional record<DOMString, record<DOMString, any>?>? arg);
void passOptionalNullableRecordOfNullableSequenceOfAny(optional record<DOMString, sequence<any>?>? arg);
void passOptionalNullableSequenceOfNullableRecordOfAny(optional sequence<record<DOMString, any>?>? arg);
any receiveAny();
// object types
@ -438,7 +438,7 @@ interface TestJSImplInterface {
void passNullableSequenceOfObject(sequence<object>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
void passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
void passMozMapOfObject(MozMap<object> arg);
void passRecordOfObject(record<DOMString, object> arg);
object receiveObject();
object? receiveNullableObject();
@ -466,8 +466,8 @@ interface TestJSImplInterface {
void passUnion18((sequence<object> or long) arg);
void passUnion19(optional (sequence<object> or long) arg);
void passUnion20(optional (sequence<object> or long) arg = []);
void passUnion21((MozMap<long> or long) arg);
void passUnion22((MozMap<object> or long) arg);
void passUnion21((record<DOMString, long> or long) arg);
void passUnion22((record<DOMString, object> or long) arg);
void passUnion23((sequence<ImageData> or long) arg);
void passUnion24((sequence<ImageData?> or long) arg);
void passUnion25((sequence<sequence<ImageData>> or long) arg);
@ -476,9 +476,9 @@ interface TestJSImplInterface {
void passUnion28(optional (EventInit or sequence<DOMString>) arg);
void passUnionWithCallback((EventHandler or long) arg);
void passUnionWithByteString((ByteString or long) arg);
void passUnionWithMozMap((MozMap<DOMString> or DOMString) arg);
void passUnionWithMozMapAndSequence((MozMap<DOMString> or sequence<DOMString>) arg);
void passUnionWithSequenceAndMozMap((sequence<DOMString> or MozMap<DOMString>) arg);
void passUnionWithRecord((record<DOMString, DOMString> or DOMString) arg);
void passUnionWithRecordAndSequence((record<DOMString, DOMString> or sequence<DOMString>) arg);
void passUnionWithSequenceAndRecord((sequence<DOMString> or record<DOMString, DOMString>) arg);
void passUnionWithSVS((USVString or long) arg);
#endif
void passUnionWithNullable((object? or long) arg);
@ -557,9 +557,9 @@ interface TestJSImplInterface {
void passSequenceOfNullableUnions(sequence<(CanvasPattern or CanvasGradient)?> arg);
void passVariadicNullableUnion((CanvasPattern or CanvasGradient)?... arg);
void passMozMapOfUnions(MozMap<(CanvasPattern or CanvasGradient)> arg);
void passRecordOfUnions(record<DOMString, (CanvasPattern or CanvasGradient)> arg);
// XXXbz no move constructor on some unions
// void passMozMapOfUnions2(MozMap<(object or long)> arg);
// void passRecordOfUnions2(record<DOMString, (object or long)> arg);
(CanvasPattern or CanvasGradient) receiveUnion();
(object or long) receiveUnion2();
@ -579,7 +579,7 @@ interface TestJSImplInterface {
void passOptionalNullableDateWithDefaultValue(optional Date? arg = null);
void passDateSequence(sequence<Date> arg);
void passNullableDateSequence(sequence<Date?> arg);
void passDateMozMap(MozMap<Date> arg);
void passDateRecord(record<DOMString, Date> arg);
Date receiveDate();
Date? receiveNullableDate();
@ -618,7 +618,7 @@ interface TestJSImplInterface {
Dict? receiveNullableDictionary();
void passOtherDictionary(optional GrandparentDict x);
void passSequenceOfDictionaries(sequence<Dict> x);
void passMozMapOfDictionaries(MozMap<GrandparentDict> x);
void passRecordOfDictionaries(record<DOMString, GrandparentDict> x);
// No support for nullable dictionaries inside a sequence (nor should there be)
// void passSequenceOfNullableDictionaries(sequence<Dict?> x);
void passDictionaryOrLong(optional Dict x);
@ -707,8 +707,8 @@ interface TestJSImplInterface {
void overload16(long arg);
void overload16(optional TestInterface? arg);
void overload17(sequence<long> arg);
void overload17(MozMap<long> arg);
void overload18(MozMap<DOMString> arg);
void overload17(record<DOMString, long> arg);
void overload18(record<DOMString, DOMString> arg);
void overload18(sequence<DOMString> arg);
void overload19(sequence<long> arg);
void overload19(optional Dict arg);

View File

@ -69,7 +69,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
is(t.pingPongDictionary(myDict).innerDictionary.innerObject.answer, "rabbithole", "ping pong works with layered dicts");
is(t.pingPongDictionaryOrLong({anyMember: 42}), 42, "ping pong (dict or long) works with dict");
is(t.pingPongDictionaryOrLong(42), 42, "ping pong (dict or long) works with long");
ok(/canary/.test(t.pingPongMap({ someVal: 42, someOtherVal: "canary" })), "ping pong works with mozmap");
ok(/canary/.test(t.pingPongMap({ someVal: 42, someOtherVal: "canary" })), "ping pong works with record");
is(t.objectSequenceLength([{}, {}, {}]), 3, "ping pong works with object sequence");
is(t.anySequenceLength([42, 'string', {}, undefined]), 4, "ping pong works with any sequence");
@ -99,7 +99,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
checkThrows(() => t.pingPongDictionary({ objectOrStringMember: xoObj }), "dictionary pingpong objectorstring");
checkThrows(() => t.pingPongDictionaryOrLong({ objectMember: xoObj }), "unionable dictionary");
checkThrows(() => t.pingPongDictionaryOrLong({ anyMember: xoObj }), "unionable dictionary");
checkThrows(() => t.pingPongMap({ someMember: 42, someOtherMember: {}, crossOriginMember: xoObj }), "mozmap");
checkThrows(() => t.pingPongMap({ someMember: 42, someOtherMember: {}, crossOriginMember: xoObj }), "record");
checkThrows(() => t.objectSequenceLength([{}, {}, xoObj, {}]), "object sequence");
checkThrows(() => t.anySequenceLength([42, 'someString', xoObj, {}]), "any sequence");
});

View File

@ -33,7 +33,7 @@ DeviceMotionEvent::InitDeviceMotionEvent(
const DeviceAccelerationInit& aAcceleration,
const DeviceAccelerationInit& aAccelIncludingGravity,
const DeviceRotationRateInit& aRotationRate,
Nullable<double> aInterval)
const Nullable<double>& aInterval)
{
InitDeviceMotionEvent(aType, aCanBubble, aCancelable, aAcceleration,
aAccelIncludingGravity, aRotationRate, aInterval,
@ -48,8 +48,8 @@ DeviceMotionEvent::InitDeviceMotionEvent(
const DeviceAccelerationInit& aAcceleration,
const DeviceAccelerationInit& aAccelIncludingGravity,
const DeviceRotationRateInit& aRotationRate,
Nullable<double> aInterval,
Nullable<uint64_t> aTimeStamp)
const Nullable<double>& aInterval,
const Nullable<uint64_t>& aTimeStamp)
{
NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);
@ -115,9 +115,9 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DeviceAcceleration, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DeviceAcceleration, Release)
DeviceAcceleration::DeviceAcceleration(DeviceMotionEvent* aOwner,
Nullable<double> aX,
Nullable<double> aY,
Nullable<double> aZ)
const Nullable<double>& aX,
const Nullable<double>& aY,
const Nullable<double>& aZ)
: mOwner(aOwner)
, mX(aX)
, mY(aY)
@ -139,9 +139,9 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DeviceRotationRate, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DeviceRotationRate, Release)
DeviceRotationRate::DeviceRotationRate(DeviceMotionEvent* aOwner,
Nullable<double> aAlpha,
Nullable<double> aBeta,
Nullable<double> aGamma)
const Nullable<double>& aAlpha,
const Nullable<double>& aBeta,
const Nullable<double>& aGamma)
: mOwner(aOwner)
, mAlpha(aAlpha)
, mBeta(aBeta)

View File

@ -21,8 +21,9 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DeviceRotationRate)
DeviceRotationRate(DeviceMotionEvent* aOwner,
Nullable<double> aAlpha, Nullable<double> aBeta,
Nullable<double> aGamma);
const Nullable<double>& aAlpha,
const Nullable<double>& aBeta,
const Nullable<double>& aGamma);
DeviceMotionEvent* GetParentObject() const
{
@ -53,8 +54,9 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DeviceAcceleration)
DeviceAcceleration(DeviceMotionEvent* aOwner,
Nullable<double> aX, Nullable<double> aY,
Nullable<double> aZ);
const Nullable<double>& aX,
const Nullable<double>& aY,
const Nullable<double>& aZ);
DeviceMotionEvent* GetParentObject() const
{
@ -128,7 +130,7 @@ public:
const DeviceAccelerationInit& aAcceleration,
const DeviceAccelerationInit& aAccelerationIncludingGravity,
const DeviceRotationRateInit& aRotationRate,
Nullable<double> aInterval);
const Nullable<double>& aInterval);
void InitDeviceMotionEvent(
const nsAString& aType,
@ -137,8 +139,8 @@ public:
const DeviceAccelerationInit& aAcceleration,
const DeviceAccelerationInit& aAccelerationIncludingGravity,
const DeviceRotationRateInit& aRotationRate,
Nullable<double> aInterval,
Nullable<uint64_t> aTimeStamp);
const Nullable<double>& aInterval,
const Nullable<uint64_t>& aTimeStamp);
static already_AddRefed<DeviceMotionEvent>
Constructor(const GlobalObject& aGlobal,

View File

@ -25,7 +25,7 @@ NS_INTERFACE_MAP_END
// static
already_AddRefed<Headers>
Headers::Constructor(const GlobalObject& aGlobal,
const Optional<HeadersOrByteStringSequenceSequenceOrByteStringMozMap>& aInit,
const Optional<HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord>& aInit,
ErrorResult& aRv)
{
RefPtr<InternalHeaders> ih = new InternalHeaders();
@ -39,8 +39,8 @@ Headers::Constructor(const GlobalObject& aGlobal,
ih->Fill(*aInit.Value().GetAsHeaders().mInternalHeaders, aRv);
} else if (aInit.Value().IsByteStringSequenceSequence()) {
ih->Fill(aInit.Value().GetAsByteStringSequenceSequence(), aRv);
} else if (aInit.Value().IsByteStringMozMap()) {
ih->Fill(aInit.Value().GetAsByteStringMozMap(), aRv);
} else if (aInit.Value().IsByteStringByteStringRecord()) {
ih->Fill(aInit.Value().GetAsByteStringByteStringRecord(), aRv);
}
if (aRv.Failed()) {
@ -53,7 +53,7 @@ Headers::Constructor(const GlobalObject& aGlobal,
// static
already_AddRefed<Headers>
Headers::Constructor(const GlobalObject& aGlobal,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
@ -62,7 +62,7 @@ Headers::Constructor(const GlobalObject& aGlobal,
/* static */ already_AddRefed<Headers>
Headers::Create(nsIGlobalObject* aGlobal,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv)
{
RefPtr<InternalHeaders> ih = new InternalHeaders();
@ -72,8 +72,8 @@ Headers::Create(nsIGlobalObject* aGlobal,
ih->Fill(*(aInit.GetAsHeaders().get()->mInternalHeaders), aRv);
} else if (aInit.IsByteStringSequenceSequence()) {
ih->Fill(aInit.GetAsByteStringSequenceSequence(), aRv);
} else if (aInit.IsByteStringMozMap()) {
ih->Fill(aInit.GetAsByteStringMozMap(), aRv);
} else if (aInit.IsByteStringByteStringRecord()) {
ih->Fill(aInit.GetAsByteStringByteStringRecord(), aRv);
}
if (NS_WARN_IF(aRv.Failed())) {

View File

@ -20,9 +20,9 @@ class ErrorResult;
namespace dom {
template<typename T> class MozMap;
class HeadersOrByteStringSequenceSequenceOrByteStringMozMap;
class OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap;
template<typename K, typename V> class Record;
class HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
class OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
/**
* This Headers class is only used to represent the content facing Headers
@ -57,17 +57,17 @@ public:
static already_AddRefed<Headers>
Constructor(const GlobalObject& aGlobal,
const Optional<HeadersOrByteStringSequenceSequenceOrByteStringMozMap>& aInit,
const Optional<HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord>& aInit,
ErrorResult& aRv);
static already_AddRefed<Headers>
Constructor(const GlobalObject& aGlobal,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv);
static already_AddRefed<Headers>
Create(nsIGlobalObject* aGlobalObject,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv);
void Append(const nsACString& aName, const nsACString& aValue,

View File

@ -306,12 +306,13 @@ InternalHeaders::Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& a
}
void
InternalHeaders::Fill(const MozMap<nsCString>& aInit, ErrorResult& aRv)
InternalHeaders::Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv)
{
nsTArray<nsString> keys;
aInit.GetKeys(keys);
for (uint32_t i = 0; i < keys.Length() && !aRv.Failed(); ++i) {
Append(NS_ConvertUTF16toUTF8(keys[i]), aInit.Get(keys[i]), aRv);
for (auto& entry : aInit.Entries()) {
Append(entry.mKey, entry.mValue, aRv);
if (aRv.Failed()) {
return;
}
}
}

View File

@ -20,7 +20,7 @@ class ErrorResult;
namespace dom {
template<typename T> class MozMap;
template<typename K, typename V> class Record;
class HeadersEntry;
class InternalHeaders final
@ -101,7 +101,7 @@ public:
void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
void Fill(const MozMap<nsCString>& aInit, ErrorResult& aRv);
void Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv);
void FillResponseHeaders(nsIRequest* aRequest);
bool HasOnlySimpleHeaders() const;

View File

@ -2332,7 +2332,7 @@ HTMLInputElement::GetValueAsDate(ErrorResult& aRv)
}
void
HTMLInputElement::SetValueAsDate(Nullable<Date> aDate, ErrorResult& aRv)
HTMLInputElement::SetValueAsDate(const Nullable<Date>& aDate, ErrorResult& aRv)
{
if (!IsDateTimeInputType(mType)) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);

View File

@ -669,7 +669,7 @@ public:
Nullable<Date> GetValueAsDate(ErrorResult& aRv);
void SetValueAsDate(Nullable<Date>, ErrorResult& aRv);
void SetValueAsDate(const Nullable<Date>& aDate, ErrorResult& aRv);
double ValueAsNumber() const
{

View File

@ -4513,6 +4513,15 @@ void HTMLMediaElement::UnbindFromTree(bool aDeep,
RunInStableState(task);
}
static bool
IsVP9InMP4(const MediaContainerType& aContainerType)
{
const MediaContainerType mimeType(aContainerType.Type());
return DecoderTraits::IsMP4SupportedType(mimeType,
/* DecoderDoctorDiagnostics* */ nullptr)
&& IsVP9CodecString(aContainerType.ExtendedType().Codecs().AsString());
}
/* static */
CanPlayStatus
HTMLMediaElement::GetCanPlay(const nsAString& aType,
@ -4522,7 +4531,16 @@ HTMLMediaElement::GetCanPlay(const nsAString& aType,
if (!containerType) {
return CANPLAY_NO;
}
return DecoderTraits::CanHandleContainerType(*containerType, aDiagnostics);
CanPlayStatus status = DecoderTraits::CanHandleContainerType(*containerType, aDiagnostics);
if (status == CANPLAY_YES && IsVP9InMP4(*containerType)) {
// We don't have a demuxer that can handle VP9 in non-fragmented MP4.
// So special-case VP9 in MP4 here, as we assume canPlayType() implies
// non-fragmented MP4 anyway. Note we report that we can play VP9
// in MP4 in MediaSource.isTypeSupported(), as the fragmented MP4
// demuxer can handle VP9 in fragmented MP4.
return CANPLAY_NO;
}
return status;
}
NS_IMETHODIMP

View File

@ -52,7 +52,7 @@ already_AddRefed<IDBVersionChangeEvent>
IDBVersionChangeEvent::CreateInternal(EventTarget* aOwner,
const nsAString& aType,
uint64_t aOldVersion,
Nullable<uint64_t> aNewVersion)
const Nullable<uint64_t>& aNewVersion)
{
RefPtr<IDBVersionChangeEvent> event =
new IDBVersionChangeEvent(aOwner, aOldVersion);

View File

@ -123,7 +123,7 @@ private:
CreateInternal(EventTarget* aOwner,
const nsAString& aName,
uint64_t aOldVersion,
Nullable<uint64_t> aNewVersion);
const Nullable<uint64_t>& aNewVersion);
};
NS_DEFINE_STATIC_IID_ACCESSOR(IDBVersionChangeEvent, IDBVERSIONCHANGEEVENT_IID)

View File

@ -917,6 +917,7 @@ TabParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
{
#ifdef ACCESSIBILITY
auto doc = static_cast<a11y::DocAccessibleParent*>(aDoc);
doc->AddToMap();
// If this tab is already shutting down just mark the new actor as shutdown
// and ignore it. When the tab actor is destroyed it will be too.

View File

@ -287,6 +287,9 @@ GetSupportedKeySystems()
clearkey.mMP4.SetCanDecrypt(EME_CODEC_AAC);
clearkey.mMP4.SetCanDecrypt(EME_CODEC_H264);
#endif
if (Preferences::GetBool("media.eme.vp9-in-mp4.enabled", false)) {
clearkey.mMP4.SetCanDecrypt(EME_CODEC_VP9);
}
clearkey.mWebM.SetCanDecrypt(EME_CODEC_VORBIS);
clearkey.mWebM.SetCanDecrypt(EME_CODEC_OPUS);
clearkey.mWebM.SetCanDecrypt(EME_CODEC_VP8);
@ -336,6 +339,7 @@ GetSupportedKeySystems()
DataForValidation validationList[] = {
{ nsCString("video/mp4"), EME_CODEC_H264, MediaDrmProxy::AVC, &widevine.mMP4 },
{ nsCString("video/mp4"), EME_CODEC_VP9, MediaDrmProxy::AVC, &widevine.mMP4 },
{ nsCString("audio/mp4"), EME_CODEC_AAC, MediaDrmProxy::AAC, &widevine.mMP4 },
{ nsCString("video/webm"), EME_CODEC_VP8, MediaDrmProxy::VP8, &widevine.mWebM },
{ nsCString("video/webm"), EME_CODEC_VP9, MediaDrmProxy::VP9, &widevine.mWebM},
@ -355,6 +359,9 @@ GetSupportedKeySystems()
}
#else
widevine.mMP4.SetCanDecryptAndDecode(EME_CODEC_H264);
if (Preferences::GetBool("media.eme.vp9-in-mp4.enabled", false)) {
widevine.mMP4.SetCanDecryptAndDecode(EME_CODEC_VP9);
}
widevine.mWebM.SetCanDecrypt(EME_CODEC_VORBIS);
widevine.mWebM.SetCanDecrypt(EME_CODEC_OPUS);
widevine.mWebM.SetCanDecryptAndDecode(EME_CODEC_VP8);

View File

@ -132,6 +132,12 @@ MP4Decoder::IsSupportedType(const MediaContainerType& aType,
NS_LITERAL_CSTRING("audio/flac"), aType));
continue;
}
if (codec.EqualsLiteral("vp9") || codec.EqualsLiteral("vp9.0")) {
trackInfos.AppendElement(
CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
NS_LITERAL_CSTRING("video/vp9"), aType));
continue;
}
// Note: Only accept H.264 in a video content type, not in an audio
// content type.
if (IsWhitelistedH264Codec(codec) && isVideo) {

View File

@ -789,6 +789,29 @@ var gMetadataTests = [
// Test files for Encrypted Media Extensions
var gEMETests = [
{
name:"vp9 in mp4",
tracks: [
{
name:"video",
type:"video/mp4; codecs=\"vp9.0\"",
fragments:[ "short-vp9-encrypted-video.mp4",
]
},
{
name:"audio",
type:"audio/mp4; codecs=\"mp4a.40.2\"",
fragments:[ "short-aac-encrypted-audio.mp4",
]
}
],
keys: {
"2cdb0ed6119853e7850671c3e9906c3c":"808B9ADAC384DE1E4F56140F4AD76194"
},
sessionType:"temporary",
sessionCount:2,
duration:0.47
},
{
name:"video-only with 2 keys",
tracks: [

View File

@ -552,10 +552,14 @@ support-files =
sintel-short-clearkey-subsample-encrypted-video.webm^headers^
short.mp4
short.mp4^headers^
short-aac-encrypted-audio.mp4
short-aac-encrypted-audio.mp4^headers^
short-audio-fragmented-cenc-without-pssh.mp4
short-audio-fragmented-cenc-without-pssh.mp4^headers^
short-video.ogv
short-video.ogv^headers^
short-vp9-encrypted-video.mp4
short-vp9-encrypted-video.mp4^headers^
small-shot-mp3.mp4
small-shot-mp3.mp4^headers^
small-shot.m4a

Binary file not shown.

View File

@ -0,0 +1 @@
Cache-Control: no-store

Binary file not shown.

View File

@ -0,0 +1 @@
Cache-Control: no-store

View File

@ -88,6 +88,23 @@ function check_mp4(v, enabled) {
var expectedResult = IsSupportedAndroid() ? "" : "probably";
check("audio/mp4; codecs=\"flac\"", expectedResult);
check("audio/mp4; codecs=flac", expectedResult);
// VP9.
// Note: canPlayType assumes non-fragmented MP4. Once we support VP9 in
// non-fragmented MP4, we need to change this to report supported.
[ "video/mp4; codecs=vp9",
"video/mp4; codecs=\"vp9\"",
"video/mp4; codecs=\"vp9.0\""
].forEach((codec) => {
// canPlayType should not support VP9 in MP4...
check(codec, "");
// But VP9 in MP4 is supported in MSE.
ok(MediaSource.isTypeSupported(codec), "VP9 in MP4 should be supported in MSE");
});
check("video/mp4; codecs=vp9", "");
check("video/mp4; codecs=\"vp9\"", "");
check("video/mp4; codecs=\"vp9.0\"", "");
}
function check_mp3(v, enabled) {

View File

@ -27,6 +27,7 @@ support-files =
ting-44.1k-2ch.wav
ting-48k-1ch.wav
ting-48k-2ch.wav
sine-440-10s.opus
webaudio.js
[test_analyserNode.html]

Binary file not shown.

View File

@ -10,27 +10,6 @@
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// Get an Opus file containing a sine wave at maximum amplitude, of duration
// `lengthSeconds`, and of frequency `frequency`.
function getSineWaveFile(frequency, lengthSeconds, callback) {
var chunks = [];
var off = new OfflineAudioContext(1, lengthSeconds * 48000, 48000);
var osc = off.createOscillator();
var rec = new MediaRecorder(osc);
rec.ondataavailable = function(e) {
chunks.push(e.data);
};
rec.onstop = function(e) {
var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
callback(blob);
}
osc.frequency.value = 1.0;
osc.start();
rec.start();
off.startRendering().then(function(buffer) {
rec.stop();
});
}
function binIndexForFrequency(frequency, analyser) {
return 1 + Math.round(frequency *
@ -76,60 +55,74 @@ function checkFrequency(an) {
return false;
}
}
// On the other hand, we should find a peak at 440Hz. Our sine wave is not
// attenuated, we're expecting the peak to reach 0dBFs.
index = binIndexForFrequency(440, an);
info("energy at 440: " + frequencyArray[index] + ", threshold " + (an.maxDecibels - 10));
if (frequencyArray[index] < (an.maxDecibels - 10)) {
return false;
}
return true;
}
function test() {
getSineWaveFile(440, 1, (blob) => {
var audioElement = new Audio();
audioElement.src = URL.createObjectURL(blob);
audioElement.loop = true;
var ac = new AudioContext();
var mediaElementSource = ac.createMediaElementSource(audioElement);
var an = ac.createAnalyser();
frequencyArray = new Float32Array(an.frequencyBinCount);
var audioElement = new Audio();
audioElement.src = 'sine-440-10s.opus'
audioElement.loop = true;
var ac = new AudioContext();
var mediaElementSource = ac.createMediaElementSource(audioElement);
var an = ac.createAnalyser();
frequencyArray = new Float32Array(an.frequencyBinCount);
// Uncomment this to check what the analyser is doing.
// debugCanvas(an);
// Uncomment this to check what the analyser is doing.
// debugCanvas(an);
mediaElementSource.connect(an);
mediaElementSource.connect(an)
audioElement.play();
// We want to check the we have the expected audio for at least one loop of
// the HTMLMediaElement. The file is one second, and we use the default FFT
// size.
var lastCurrentTime = 0;
var looped = false;
audioElement.onplaying = function() {
audioElement.ontimeupdate = function() {
if (checkFrequency(an)) {
ok(true, "Found correct audio signal during analysis");
dump(lastCurrentTime + " " + audioElement.currentTime + "\n");
if (lastCurrentTime > audioElement.currentTime) {
if (looped) {
audioElement.ontimeupdate = null;
audioElement.onplaying = null;
SimpleTest.finish()
}
lastCurrentTime = audioElement.currentTime;
looped = true;
} else {
lastCurrentTime = audioElement.currentTime;
}
} else {
ok(false, "Found unexpected noise during analysis.");
audioElement.ontimeupdate = null;
audioElement.onplaying = null;
ac.close();
audioElement.src = '';
SimpleTest.finish()
}
}
audioElement.play();
// We want to check the we have the expected audio for at least two loop of
// the HTMLMediaElement, piped into an AudioContext. The file is ten seconds,
// and we use the default FFT size.
var lastCurrentTime = 0;
var loopCount = 0;
audioElement.onplaying = function() {
audioElement.ontimeupdate = function() {
// We don't run the analysis when close to loop point or at the
// beginning, since looping is not seamless, there could be an
// unpredictable amount of silence
var rv = checkFrequency(an);
info("currentTime: " + audioElement.currentTime);
if (audioElement.currentTime < 4 ||
audioElement.currentTIme > 8){
return;
}
if (!rv) {
ok(false, "Found unexpected noise during analysis.");
audioElement.ontimeupdate = null;
audioElement.onplaying = null;
ac.close();
audioElement.src = '';
SimpleTest.finish()
return;
}
ok(true, "Found correct audio signal during analysis");
info(lastCurrentTime + " " + audioElement.currentTime);
if (lastCurrentTime > audioElement.currentTime) {
info("loopCount: " + loopCount);
if (loopCount > 1) {
audioElement.ontimeupdate = null;
audioElement.onplaying = null;
ac.close();
audioElement.src = '';
SimpleTest.finish();
}
});
lastCurrentTime = audioElement.currentTime;
loopCount++;
} else {
lastCurrentTime = audioElement.currentTime;
}
}
}
SpecialPowers.pushPrefEnv(
{'set': [['media.recorder.audio_node.enabled', true]]}, test);
</script>

View File

@ -2690,6 +2690,27 @@ PluginModuleParent::AccumulateModuleInitBlockedTime()
mTimeBlocked = TimeDuration();
}
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
static void
ForceWindowless(InfallibleTArray<nsCString>& names,
InfallibleTArray<nsCString>& values)
{
nsCaseInsensitiveUTF8StringArrayComparator comparator;
NS_NAMED_LITERAL_CSTRING(wmodeAttributeName, "wmode");
NS_NAMED_LITERAL_CSTRING(opaqueAttributeValue, "opaque");
auto wmodeAttributeIndex =
names.IndexOf(wmodeAttributeName, 0, comparator);
if (wmodeAttributeIndex != names.NoIndex) {
if (!values[wmodeAttributeIndex].EqualsLiteral("transparent")) {
values[wmodeAttributeIndex].Assign(opaqueAttributeValue);
}
} else {
names.AppendElement(wmodeAttributeName);
values.AppendElement(opaqueAttributeValue);
}
}
#endif // windows or linux
nsresult
PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
uint16_t mode,
@ -2741,19 +2762,11 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
// async rendering and the sandbox level is 2 or greater.
if (!supportsAsyncRender && mSandboxLevel >= 2) {
#endif
NS_NAMED_LITERAL_CSTRING(wmodeAttributeName, "wmode");
NS_NAMED_LITERAL_CSTRING(opaqueAttributeValue, "opaque");
auto wmodeAttributeIndex =
names.IndexOf(wmodeAttributeName, 0, comparator);
if (wmodeAttributeIndex != names.NoIndex) {
if (!values[wmodeAttributeIndex].EqualsLiteral("transparent")) {
values[wmodeAttributeIndex].Assign(opaqueAttributeValue);
}
} else {
names.AppendElement(wmodeAttributeName);
values.AppendElement(opaqueAttributeValue);
}
ForceWindowless(names, values);
}
#elif defined(MOZ_WIDGET_GTK)
// We no longer support windowed mode on Linux.
ForceWindowless(names, values);
#endif
}

View File

@ -259,11 +259,11 @@ class DirectoryLockImpl final
public:
DirectoryLockImpl(QuotaManager* aQuotaManager,
Nullable<PersistenceType> aPersistenceType,
const Nullable<PersistenceType>& aPersistenceType,
const nsACString& aGroup,
const OriginScope& aOriginScope,
Nullable<bool> aIsApp,
Nullable<Client::Type> aClientType,
const Nullable<bool>& aIsApp,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
bool aInternal,
OpenDirectoryListener* aOpenListener);
@ -920,7 +920,7 @@ public:
}
protected:
NormalOriginOperationBase(Nullable<PersistenceType> aPersistenceType,
NormalOriginOperationBase(const Nullable<PersistenceType>& aPersistenceType,
const OriginScope& aOriginScope,
bool aExclusive)
: mPersistenceType(aPersistenceType)
@ -2116,11 +2116,11 @@ DeallocPQuotaParent(PQuotaParent* aActor)
******************************************************************************/
DirectoryLockImpl::DirectoryLockImpl(QuotaManager* aQuotaManager,
Nullable<PersistenceType> aPersistenceType,
const Nullable<PersistenceType>& aPersistenceType,
const nsACString& aGroup,
const OriginScope& aOriginScope,
Nullable<bool> aIsApp,
Nullable<Client::Type> aClientType,
const Nullable<bool>& aIsApp,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
bool aInternal,
OpenDirectoryListener* aOpenListener)
@ -2808,11 +2808,11 @@ QuotaManager::IsShuttingDown()
}
auto
QuotaManager::CreateDirectoryLock(Nullable<PersistenceType> aPersistenceType,
QuotaManager::CreateDirectoryLock(const Nullable<PersistenceType>& aPersistenceType,
const nsACString& aGroup,
const OriginScope& aOriginScope,
Nullable<bool> aIsApp,
Nullable<Client::Type> aClientType,
const Nullable<bool>& aIsApp,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
bool aInternal,
OpenDirectoryListener* aOpenListener)
@ -4422,9 +4422,9 @@ QuotaManager::OpenDirectory(PersistenceType aPersistenceType,
}
void
QuotaManager::OpenDirectoryInternal(Nullable<PersistenceType> aPersistenceType,
QuotaManager::OpenDirectoryInternal(const Nullable<PersistenceType>& aPersistenceType,
const OriginScope& aOriginScope,
Nullable<Client::Type> aClientType,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
OpenDirectoryListener* aOpenListener)
{

View File

@ -252,9 +252,9 @@ public:
// XXX RemoveMe once bug 1170279 gets fixed.
void
OpenDirectoryInternal(Nullable<PersistenceType> aPersistenceType,
OpenDirectoryInternal(const Nullable<PersistenceType>& aPersistenceType,
const OriginScope& aOriginScope,
Nullable<Client::Type> aClientType,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
OpenDirectoryListener* aOpenListener);
@ -407,11 +407,11 @@ private:
Shutdown();
already_AddRefed<DirectoryLockImpl>
CreateDirectoryLock(Nullable<PersistenceType> aPersistenceType,
CreateDirectoryLock(const Nullable<PersistenceType>& aPersistenceType,
const nsACString& aGroup,
const OriginScope& aOriginScope,
Nullable<bool> aIsApp,
Nullable<Client::Type> aClientType,
const Nullable<bool>& aIsApp,
const Nullable<Client::Type>& aClientType,
bool aExclusive,
bool aInternal,
OpenDirectoryListener* aOpenListener);

View File

@ -8,7 +8,7 @@
* http://fetch.spec.whatwg.org/#headers-class
*/
typedef (Headers or sequence<sequence<ByteString>> or MozMap<ByteString>) HeadersInit;
typedef (Headers or sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit;
enum HeadersGuardEnum {
"none",

View File

@ -57,7 +57,7 @@ interface InstallTriggerImpl {
* A callback to call as each installation succeeds or fails
* @return true if the installations were successfully started
*/
boolean install(MozMap<(DOMString or InstallTriggerData)> installs,
boolean install(record<DOMString, (DOMString or InstallTriggerData)> installs,
optional InstallTriggerCallback callback);
/**

View File

@ -24,7 +24,7 @@ interface TestInterfaceJS : EventTarget {
any pingPongObjectOrString((object or DOMString) objOrString);
TestInterfaceJSDictionary pingPongDictionary(optional TestInterfaceJSDictionary dict);
long pingPongDictionaryOrLong(optional (TestInterfaceJSUnionableDictionary or long) dictOrLong);
DOMString pingPongMap(MozMap<any> map);
DOMString pingPongMap(record<DOMString, any> map);
long objectSequenceLength(sequence<object> seq);
long anySequenceLength(sequence<any> seq);

View File

@ -574,7 +574,7 @@ class FulfillUnregisterPromiseRunnable final : public WorkerRunnable
Maybe<bool> mState;
public:
FulfillUnregisterPromiseRunnable(PromiseWorkerProxy* aProxy,
Maybe<bool> aState)
const Maybe<bool>& aState)
: WorkerRunnable(aProxy->GetWorkerPrivate())
, mPromiseWorkerProxy(aProxy)
, mState(aState)
@ -631,7 +631,7 @@ private:
{}
void
Finish(Maybe<bool> aState)
Finish(const Maybe<bool>& aState)
{
AssertIsOnMainThread();
if (!mPromiseWorkerProxy) {

View File

@ -13,47 +13,38 @@ namespace gfx {
static MOZ_ALWAYS_INLINE uint16x8_t
LoadRemainder_NEON(const uint8_t* aSrc, size_t aLength)
{
uint16x8_t px;
const uint32_t* src32 = reinterpret_cast<const uint32_t*>(aSrc);
uint32x4_t dst32;
if (aLength >= 2) {
// Load first 2 pixels
px =
vreinterpretq_u16_u64(
vld1q_lane_u64(reinterpret_cast<const uint64_t*>(aSrc),
vdupq_n_u64(0), 0));
dst32 = vcombine_u32(vld1_u32(src32), vdup_n_u32(0));
// Load third pixel
if (aLength >= 3) {
px =
vreinterpretq_u16_u32(
vld1q_lane_u32(reinterpret_cast<const uint32_t*>(aSrc + 2 * 4),
vreinterpretq_u32_u16(px), 2));
dst32 = vld1q_lane_u32(src32 + 2, dst32, 2);
}
} else {
// Load single pixel
px =
vreinterpretq_u16_u32(
vld1q_lane_u32(reinterpret_cast<const uint32_t*>(aSrc),
vdupq_n_u32(0), 0));
dst32 = vld1q_lane_u32(src32, vdupq_n_u32(0), 0);
}
return px;
return vreinterpretq_u16_u32(dst32);
}
// Store 1-3 pixels from a vector into memory without overwriting.
static MOZ_ALWAYS_INLINE void
StoreRemainder_NEON(uint8_t* aDst, size_t aLength, const uint16x8_t& aSrc)
{
uint32_t* dst32 = reinterpret_cast<uint32_t*>(aDst);
uint32x4_t src32 = vreinterpretq_u32_u16(aSrc);
if (aLength >= 2) {
// Store first 2 pixels
vst1q_lane_u64(reinterpret_cast<uint64_t*>(aDst),
vreinterpretq_u64_u16(aSrc), 0);
vst1_u32(dst32, vget_low_u32(src32));
// Store third pixel
if (aLength >= 3) {
vst1q_lane_u32(reinterpret_cast<uint32_t*>(aDst + 2 * 4),
vreinterpretq_u32_u16(aSrc), 2);
vst1q_lane_u32(dst32 + 2, src32, 2);
}
} else {
// Store single pixel
vst1q_lane_u32(reinterpret_cast<uint32_t*>(aDst),
vreinterpretq_u32_u16(aSrc), 0);
vst1q_lane_u32(dst32, src32, 0);
}
}

View File

@ -77,7 +77,6 @@ struct TexturedEffect : public Effect
TextureSource* mTexture;
bool mPremultiplied;
gfx::SamplingFilter mSamplingFilter;
LayerRenderState mState;
};
// Support an alpha mask.
@ -233,8 +232,7 @@ inline already_AddRefed<TexturedEffect>
CreateTexturedEffect(gfx::SurfaceFormat aFormat,
TextureSource* aSource,
const gfx::SamplingFilter aSamplingFilter,
bool isAlphaPremultiplied,
const LayerRenderState &state = LayerRenderState())
bool isAlphaPremultiplied)
{
MOZ_ASSERT(aSource);
RefPtr<TexturedEffect> result;
@ -257,8 +255,6 @@ CreateTexturedEffect(gfx::SurfaceFormat aFormat,
break;
}
result->mState = state;
return result.forget();
}
@ -266,8 +262,7 @@ inline already_AddRefed<TexturedEffect>
CreateTexturedEffect(TextureHost* aHost,
TextureSource* aSource,
const gfx::SamplingFilter aSamplingFilter,
bool isAlphaPremultiplied,
const LayerRenderState &state = LayerRenderState())
bool isAlphaPremultiplied)
{
MOZ_ASSERT(aHost);
MOZ_ASSERT(aSource);
@ -280,8 +275,7 @@ CreateTexturedEffect(TextureHost* aHost,
result = CreateTexturedEffect(aHost->GetReadFormat(),
aSource,
aSamplingFilter,
isAlphaPremultiplied,
state);
isAlphaPremultiplied);
}
return result.forget();
}
@ -296,8 +290,7 @@ inline already_AddRefed<TexturedEffect>
CreateTexturedEffect(TextureSource* aSource,
TextureSource* aSourceOnWhite,
const gfx::SamplingFilter aSamplingFilter,
bool isAlphaPremultiplied,
const LayerRenderState &state = LayerRenderState())
bool isAlphaPremultiplied)
{
MOZ_ASSERT(aSource);
if (aSourceOnWhite) {
@ -311,8 +304,7 @@ CreateTexturedEffect(TextureSource* aSource,
return CreateTexturedEffect(aSource->GetFormat(),
aSource,
aSamplingFilter,
isAlphaPremultiplied,
state);
isAlphaPremultiplied);
}
/**
@ -322,10 +314,9 @@ CreateTexturedEffect(TextureSource* aSource,
*/
inline already_AddRefed<TexturedEffect>
CreateTexturedEffect(TextureSource *aTexture,
const gfx::SamplingFilter aSamplingFilter,
const LayerRenderState &state = LayerRenderState())
const gfx::SamplingFilter aSamplingFilter)
{
return CreateTexturedEffect(aTexture, nullptr, aSamplingFilter, true, state);
return CreateTexturedEffect(aTexture, nullptr, aSamplingFilter, true);
}

View File

@ -8,7 +8,6 @@
#include "LayerScope.h"
#include "nsAppRunner.h"
#include "Composer2D.h"
#include "Effects.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/MathAlgorithms.h"

View File

@ -1792,8 +1792,6 @@ public:
uint32_t GetDebugColorIndex() { return mDebugColorIndex; }
#endif
virtual LayerRenderState GetRenderState() { return LayerRenderState(); }
void Mutated() {
mManager->Mutated(this);
}

View File

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LayersTypes.h"
namespace mozilla {
namespace layers {
LayerRenderState::LayerRenderState()
: mFlags(LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT)
, mHasOwnOffset(false)
{
}
LayerRenderState::LayerRenderState(const LayerRenderState& aOther)
: mFlags(aOther.mFlags)
, mHasOwnOffset(aOther.mHasOwnOffset)
, mOffset(aOther.mOffset)
{
}
LayerRenderState::~LayerRenderState()
{
}
} // namespace layers
} // namespace mozilla

View File

@ -70,43 +70,6 @@ enum class SurfaceMode : int8_t {
SURFACE_COMPONENT_ALPHA
};
// LayerRenderState for Composer2D
enum class LayerRenderStateFlags : int8_t {
LAYER_RENDER_STATE_DEFAULT = 0,
ORIGIN_BOTTOM_LEFT = 1 << 0,
BUFFER_ROTATION = 1 << 1,
// Notify Composer2D to swap the RB pixels of gralloc buffer
FORMAT_RB_SWAP = 1 << 2,
// We record opaqueness here alongside the actual surface we're going to
// render. This avoids confusion when a layer might return different kinds
// of surfaces over time (e.g. video frames).
OPAQUE = 1 << 3
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(LayerRenderStateFlags)
struct LayerRenderState {
// Constructors and destructor are defined in LayersTypes.cpp so we don't
// have to pull in a definition for GraphicBuffer.h here. In KK at least,
// that results in nasty pollution such as libui's hardware.h #defining
// 'version_major' and 'version_minor' which conflict with Theora's codec.c...
LayerRenderState();
LayerRenderState(const LayerRenderState& aOther);
~LayerRenderState();
void SetOffset(const nsIntPoint& aOffset)
{
mOffset = aOffset;
mHasOwnOffset = true;
}
// see LayerRenderStateFlags
LayerRenderStateFlags mFlags;
// true if mOffset is applicable
bool mHasOwnOffset;
// the location of the layer's origin on mSurface
nsIntPoint mOffset;
};
enum class ScaleMode : int8_t {
SCALE_NONE,
STRETCH,

View File

@ -68,15 +68,6 @@ CanvasLayerComposite::SetLayerManager(HostLayerManager* aManager)
}
}
LayerRenderState
CanvasLayerComposite::GetRenderState()
{
if (mDestroyed || !mCompositableHost || !mCompositableHost->IsAttached()) {
return LayerRenderState();
}
return mCompositableHost->GetRenderState();
}
void
CanvasLayerComposite::RenderLayer(const IntRect& aClipRect,
const Maybe<gfx::Polygon>& aGeometry)

View File

@ -39,8 +39,6 @@ public:
MOZ_CRASH("Incompatibe surface type");
}
virtual LayerRenderState GetRenderState() override;
virtual bool SetCompositableHost(CompositableHost* aHost) override;
virtual void Disconnect() override

View File

@ -124,8 +124,6 @@ public:
return nullptr;
}
virtual LayerRenderState GetRenderState() = 0;
virtual gfx::IntSize GetImageSize() const
{
MOZ_ASSERT(false, "Should have been overridden");

View File

@ -159,7 +159,7 @@ struct PreparedLayer
{
PreparedLayer(LayerComposite *aLayer,
RenderTargetIntRect aClipRect,
Maybe<gfx::Polygon> aGeometry)
const Maybe<gfx::Polygon>& aGeometry)
: mLayer(aLayer), mClipRect(aClipRect), mGeometry(aGeometry) {}
LayerComposite* mLayer;

View File

@ -62,8 +62,7 @@ ContentHostTexture::Composite(LayerComposite* aLayer,
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mTextureSource.get(),
mTextureSourceOnWhite.get(),
aSamplingFilter, true,
GetRenderState());
aSamplingFilter, true);
if (!effect) {
return;
}
@ -435,22 +434,6 @@ ContentHostTexture::PrintInfo(std::stringstream& aStream, const char* aPrefix)
}
LayerRenderState
ContentHostTexture::GetRenderState()
{
if (!mTextureHost) {
return LayerRenderState();
}
LayerRenderState result = mTextureHost->GetRenderState();
if (mBufferRotation != nsIntPoint()) {
result.mFlags |= LayerRenderStateFlags::BUFFER_ROTATION;
}
result.SetOffset(GetOriginOffset());
return result;
}
already_AddRefed<TexturedEffect>
ContentHostTexture::GenEffect(const gfx::SamplingFilter aSamplingFilter)
{
@ -468,8 +451,7 @@ ContentHostTexture::GenEffect(const gfx::SamplingFilter aSamplingFilter)
}
return CreateTexturedEffect(mTextureSource.get(),
mTextureSourceOnWhite.get(),
aSamplingFilter, true,
GetRenderState());
aSamplingFilter, true);
}
already_AddRefed<gfx::DataSourceSurface>

View File

@ -165,8 +165,6 @@ public:
mLocked = false;
}
LayerRenderState GetRenderState() override;
virtual already_AddRefed<TexturedEffect> GenEffect(const gfx::SamplingFilter aSamplingFilter) override;
protected:

View File

@ -238,8 +238,7 @@ ImageHost::Composite(LayerComposite* aLayer,
!(mCurrentTextureHost->GetFlags() & TextureFlags::NON_PREMULTIPLIED);
RefPtr<TexturedEffect> effect =
CreateTexturedEffect(mCurrentTextureHost,
mCurrentTextureSource.get(), aSamplingFilter, isAlphaPremultiplied,
GetRenderState());
mCurrentTextureSource.get(), aSamplingFilter, isAlphaPremultiplied);
if (!effect) {
return;
}
@ -384,17 +383,6 @@ ImageHost::Dump(std::stringstream& aStream,
}
}
LayerRenderState
ImageHost::GetRenderState()
{
TimedImage* img = ChooseImage();
if (img) {
SetCurrentTextureHost(img->mTextureHost);
return img->mTextureHost->GetRenderState();
}
return LayerRenderState();
}
already_AddRefed<gfx::DataSourceSurface>
ImageHost::GetAsSurface()
{
@ -484,8 +472,7 @@ ImageHost::GenEffect(const gfx::SamplingFilter aSamplingFilter)
return CreateTexturedEffect(mCurrentTextureHost,
mCurrentTextureSource,
aSamplingFilter,
isAlphaPremultiplied,
GetRenderState());
isAlphaPremultiplied);
}
} // namespace layers

View File

@ -67,8 +67,6 @@ public:
gfx::IntSize GetImageSize() const override;
virtual LayerRenderState GetRenderState() override;
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
virtual void Dump(std::stringstream& aStream,

View File

@ -64,15 +64,6 @@ ImageLayerComposite::Disconnect()
Destroy();
}
LayerRenderState
ImageLayerComposite::GetRenderState()
{
if (mImageHost && mImageHost->IsAttached()) {
return mImageHost->GetRenderState();
}
return LayerRenderState();
}
Layer*
ImageLayerComposite::GetLayer()
{

View File

@ -35,8 +35,6 @@ protected:
virtual ~ImageLayerComposite();
public:
virtual LayerRenderState GetRenderState() override;
virtual void Disconnect() override;
virtual bool SetCompositableHost(CompositableHost* aHost) override;

View File

@ -89,15 +89,6 @@ PaintedLayerComposite::SetLayerManager(HostLayerManager* aManager)
}
}
LayerRenderState
PaintedLayerComposite::GetRenderState()
{
if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) {
return LayerRenderState();
}
return mBuffer->GetRenderState();
}
void
PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
const Maybe<gfx::Polygon>& aGeometry)

View File

@ -41,8 +41,6 @@ protected:
public:
virtual void Disconnect() override;
virtual LayerRenderState GetRenderState() override;
CompositableHost* GetCompositableHost() override;
virtual void Destroy() override;

Some files were not shown because too many files have changed in this diff Show More