This commit is contained in:
Carsten "Tomcat" Book 2014-10-17 16:41:45 +02:00
Родитель 9b4c29f73f e658a539a6
Коммит 90db5d3cce
174 изменённых файлов: 3254 добавлений и 2005 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Bug 1061335 - CLOBBER for Win32 compiler update. Bug 609976 - CLOBBER

Просмотреть файл

@ -28,7 +28,6 @@ html xul|scrollbar {
background-image: none !important; background-image: none !important;
border: 0px solid transparent !important; border: 0px solid transparent !important;
pointer-events: none; pointer-events: none;
opacity: 1;
} }
xul|scrollbar[orient="vertical"] { xul|scrollbar[orient="vertical"] {
@ -56,7 +55,6 @@ xul|scrollbar[orient="horizontal"] xul|thumb {
xul|scrollbar:not([active="true"]), xul|scrollbar:not([active="true"]),
xul|scrollbar[disabled] { xul|scrollbar[disabled] {
opacity: 0; opacity: 0;
transition: opacity 1s ease;
} }
xul|scrollbarbutton { xul|scrollbarbutton {

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "", "remote": "",
"branch": "" "branch": ""
}, },
"revision": "63436aa17e7fa3ad521fdeffdc22b81c36e5d69b", "revision": "934b8c3014a3e20dd5d90ecf95f4b6b704dddb1e",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1daf2dadcd0d554c733661a4c0be1b82001e9da0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -74,3 +74,13 @@ tabpanels {
browser[pending] { browser[pending] {
display: none; display: none;
} }
browser[pendingpaint] {
opacity: 0;
}
tabbrowser[pendingpaint] {
background-image: url(chrome://global/skin/spinner.png);
background-repeat: no-repeat;
background-position: center center;
}

Просмотреть файл

@ -136,6 +136,10 @@
"" ""
</field> </field>
<field name="_contentWaitingCount">
0
</field>
<property name="_numPinnedTabs" readonly="true"> <property name="_numPinnedTabs" readonly="true">
<getter><![CDATA[ <getter><![CDATA[
for (var i = 0; i < this.tabs.length; i++) { for (var i = 0; i < this.tabs.length; i++) {
@ -3228,6 +3232,31 @@
</body> </body>
</method> </method>
<method name="_showBusySpinnerRemoteBrowser">
<parameter name="aBrowser"/>
<body><![CDATA[
aBrowser.setAttribute("pendingpaint", "true");
if (this._contentWaitingCount <= 0) {
// We are not currently spinning
this.setAttribute("pendingpaint", "true");
this._contentWaitingCount = 1;
} else {
this._contentWaitingCount++;
}
]]></body>
</method>
<method name="_hideBusySpinnerRemoteBrowser">
<parameter name="aBrowser"/>
<body><![CDATA[
aBrowser.removeAttribute("pendingpaint");
this._contentWaitingCount--;
if (this._contentWaitingCount <= 0) {
this.removeAttribute("pendingpaint");
}
]]></body>
</method>
<method name="_prepareForTabSwitch"> <method name="_prepareForTabSwitch">
<parameter name="toTab"/> <parameter name="toTab"/>
<parameter name="fromTab"/> <parameter name="fromTab"/>
@ -3266,16 +3295,19 @@
let timeoutPromise = new Promise((aResolve, aReject) => { let timeoutPromise = new Promise((aResolve, aReject) => {
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
this._showBusySpinnerRemoteBrowser(toBrowser);
attemptTabSwitch(aResolve, aReject); attemptTabSwitch(aResolve, aReject);
}, kTabSwitchTimeout); }, kTabSwitchTimeout);
}); });
let paintPromise = new Promise((aResolve, aReject) => { let paintPromise = new Promise((aResolve, aReject) => {
toBrowser.addEventListener("MozAfterRemotePaint", function onRemotePaint() { let onRemotePaint = () => {
toBrowser.removeEventListener("MozAfterRemotePaint", onRemotePaint); toBrowser.removeEventListener("MozAfterRemotePaint", onRemotePaint);
this._hideBusySpinnerRemoteBrowser(toBrowser);
clearTimeout(timeoutId); clearTimeout(timeoutId);
attemptTabSwitch(aResolve, aReject); attemptTabSwitch(aResolve, aReject);
}); };
toBrowser.addEventListener("MozAfterRemotePaint", onRemotePaint);
toBrowser.QueryInterface(Ci.nsIFrameLoaderOwner) toBrowser.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader .frameLoader
.requestNotifyAfterRemotePaint(); .requestNotifyAfterRemotePaint();

Просмотреть файл

@ -1376,7 +1376,7 @@ PlacesToolbar.prototype = {
elt.localName != "menupopup") { elt.localName != "menupopup") {
let eltRect = elt.getBoundingClientRect(); let eltRect = elt.getBoundingClientRect();
let eltIndex = Array.indexOf(this._rootElt.childNodes, elt); let eltIndex = Array.indexOf(this._rootElt.childNodes, elt);
if (PlacesUIUtils.nodeIsFolder(elt._placesNode) && if (PlacesUtils.nodeIsFolder(elt._placesNode) &&
!PlacesUIUtils.isContentsReadOnly(elt._placesNode)) { !PlacesUIUtils.isContentsReadOnly(elt._placesNode)) {
// This is a folder. // This is a folder.
// If we are in the middle of it, drop inside it. // If we are in the middle of it, drop inside it.

Просмотреть файл

@ -137,6 +137,9 @@ DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
ifdef CLANG_CXX ifdef CLANG_CXX
DEFINES += -DCLANG_CXX DEFINES += -DCLANG_CXX
endif endif
ifdef CLANG_CL
DEFINES += -DCLANG_CL
endif
libs:: libs::
$(MAKE) -C $(DEPTH)/browser/locales langpack $(MAKE) -C $(DEPTH)/browser/locales langpack

Просмотреть файл

@ -921,4 +921,7 @@ bin/libfreebl_32int64_3.so
#ifdef CLANG_CXX #ifdef CLANG_CXX
@BINPATH@/llvm-symbolizer @BINPATH@/llvm-symbolizer
#endif #endif
#ifdef CLANG_CL
@BINPATH@/clang_rt.asan_dynamic-i386.dll
#endif
#endif #endif

Просмотреть файл

@ -94,6 +94,9 @@ PluginContent.prototype = {
return; return;
} }
if (Services.telemetry.canSend) {
this._finishRecordingFlashPluginTelemetry();
}
this.clearPluginDataCache(); this.clearPluginDataCache();
}, },
@ -378,6 +381,11 @@ PluginContent.prototype = {
break; break;
} }
if (Services.telemetry.canSend && this._getPluginInfo(plugin).mimetype ===
"application/x-shockwave-flash") {
this._recordFlashPluginTelemetry(eventType, plugin);
}
// Show the in-content UI if it's not too big. The crashed plugin handler already did this. // Show the in-content UI if it's not too big. The crashed plugin handler already did this.
if (eventType != "PluginCrashed") { if (eventType != "PluginCrashed") {
let overlay = this.getPluginUI(plugin, "main"); let overlay = this.getPluginUI(plugin, "main");
@ -407,6 +415,42 @@ PluginContent.prototype = {
} }
}, },
_recordFlashPluginTelemetry: function (eventType, plugin) {
if (!this.flashPluginStats) {
this.flashPluginStats = {
instancesCount: 0,
plugins: new WeakSet()
};
}
if (!this.flashPluginStats.plugins.has(plugin)) {
// Reporting plugin instance and its dimensions only once.
this.flashPluginStats.plugins.add(plugin);
this.flashPluginStats.instancesCount++;
let pluginRect = plugin.getBoundingClientRect();
Services.telemetry.getHistogramById('FLASH_PLUGIN_WIDTH')
.add(pluginRect.width);
Services.telemetry.getHistogramById('FLASH_PLUGIN_HEIGHT')
.add(pluginRect.height);
Services.telemetry.getHistogramById('FLASH_PLUGIN_AREA')
.add(pluginRect.width * pluginRect.height);
let state = this._getPluginInfo(plugin).fallbackType;
Services.telemetry.getHistogramById('FLASH_PLUGIN_STATES')
.add(state);
}
},
_finishRecordingFlashPluginTelemetry: function () {
if (this.flashPluginStats) {
Services.telemetry.getHistogramById('FLASH_PLUGIN_INSTANCES_ON_PAGE')
.add(this.flashPluginStats.instancesCount);
delete this.flashPluginStats;
}
},
isKnownPlugin: function (objLoadingContent) { isKnownPlugin: function (objLoadingContent) {
return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) == return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN); Ci.nsIObjectLoadingContent.TYPE_PLUGIN);

Просмотреть файл

@ -66,6 +66,13 @@ LLDBINIT_FINAL_TARGET_FILES := $(DEPTH)/.lldbinit
LLDBINIT_FINAL_TARGET_DEST = $(FINAL_TARGET) LLDBINIT_FINAL_TARGET_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += LLDBINIT_FINAL_TARGET INSTALL_TARGETS += LLDBINIT_FINAL_TARGET
ifeq (1_1,$(MOZ_ASAN)_$(CLANG_CL))
# Install the clang-cl runtime library for ASAN next to the binaries we produce.
CLANG_RT_ASAN_FILES := $(MOZ_CLANG_RT_ASAN_LIB_PATH)
CLANG_RT_ASAN_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += CLANG_RT_ASAN
endif
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
TARGET_DEPTH = .. TARGET_DEPTH = ..

Просмотреть файл

@ -506,6 +506,11 @@ case "$target" in
if test -z "$CLANG_CL"; then if test -z "$CLANG_CL"; then
AC_DEFINE(HAVE_SEH_EXCEPTIONS) AC_DEFINE(HAVE_SEH_EXCEPTIONS)
else else
# Build on clang-cl with MSVC 2013 with fallback emulation.
CFLAGS="$CFLAGS -fmsc-version=1800 -fallback"
CXXFLAGS="$CXXFLAGS -fmsc-version=1800 -fallback"
# Send our CFLAGS to NSS too
MOZ_CFLAGS_NSS=1
AC_DEFINE_UNQUOTED(GTEST_HAS_SEH, 0) AC_DEFINE_UNQUOTED(GTEST_HAS_SEH, 0)
fi fi
@ -1260,6 +1265,16 @@ MOZ_ARG_ENABLE_BOOL(address-sanitizer,
MOZ_ASAN= ) MOZ_ASAN= )
if test -n "$MOZ_ASAN"; then if test -n "$MOZ_ASAN"; then
MOZ_LLVM_HACKS=1 MOZ_LLVM_HACKS=1
if test -n "$CLANG_CL"; then
# Look for clang_rt.asan_dynamic-i386.dll
MOZ_CLANG_RT_ASAN_LIB=clang_rt.asan_dynamic-i386.dll
# We use MOZ_PATH_PROG in order to get a Windows style path.
MOZ_PATH_PROG(MOZ_CLANG_RT_ASAN_LIB_PATH, $MOZ_CLANG_RT_ASAN_LIB)
if test -z "$MOZ_CLANG_RT_ASAN_LIB_PATH"; then
AC_MSG_ERROR([Couldn't find $MOZ_CLANG_RT_ASAN_LIB. It should be available in the same location as clang-cl.])
fi
AC_SUBST(MOZ_CLANG_RT_ASAN_LIB_PATH)
fi
AC_DEFINE(MOZ_ASAN) AC_DEFINE(MOZ_ASAN)
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer) MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi fi
@ -3796,11 +3811,6 @@ dnl system libffi Support
dnl ======================================================== dnl ========================================================
MOZ_CONFIG_FFI() MOZ_CONFIG_FFI()
# split JS out by default to avoid VS2005 PGO crash (bug 591836).
if test "$OS_ARCH" = "WINNT"; then
JS_SHARED_LIBRARY=1
fi
MOZ_ARG_ENABLE_BOOL(shared-js, MOZ_ARG_ENABLE_BOOL(shared-js,
[ --enable-shared-js [ --enable-shared-js
Create a shared JavaScript library.], Create a shared JavaScript library.],
@ -7953,8 +7963,7 @@ dnl =
dnl ======================================================== dnl ========================================================
MOZ_ARG_HEADER(Static build options) MOZ_ARG_HEADER(Static build options)
if test "$OS_ARCH" = "WINNT"; then if test -n "$GKMEDIAS_SHARED_LIBRARY"; then
GKMEDIAS_SHARED_LIBRARY=1
AC_DEFINE(GKMEDIAS_SHARED_LIBRARY) AC_DEFINE(GKMEDIAS_SHARED_LIBRARY)
fi fi
AC_SUBST(GKMEDIAS_SHARED_LIBRARY) AC_SUBST(GKMEDIAS_SHARED_LIBRARY)

Просмотреть файл

@ -412,7 +412,7 @@ public:
/** /**
* Web components custom element data. * Web components custom element data.
*/ */
nsAutoPtr<CustomElementData> mCustomElementData; nsRefPtr<CustomElementData> mCustomElementData;
}; };
protected: protected:

Просмотреть файл

@ -238,18 +238,15 @@ DOMParser::ParseFromStream(nsIInputStream *stream,
// Create a fake channel // Create a fake channel
nsCOMPtr<nsIChannel> parserChannel; nsCOMPtr<nsIChannel> parserChannel;
NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, nullptr, NS_NewInputStreamChannel(getter_AddRefs(parserChannel),
nsDependentCString(contentType), nullptr); mDocumentURI,
nullptr, // aStream
mOriginalPrincipal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER,
nsDependentCString(contentType));
NS_ENSURE_STATE(parserChannel); NS_ENSURE_STATE(parserChannel);
// More principal-faking here
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(mOriginalPrincipal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
parserChannel->SetLoadInfo(loadInfo);
if (charset) { if (charset) {
parserChannel->SetContentCharset(nsDependentCString(charset)); parserChannel->SetContentCharset(nsDependentCString(charset));
} }

Просмотреть файл

@ -193,6 +193,8 @@ public:
WorkerPrivate* mWorkerPrivate; WorkerPrivate* mWorkerPrivate;
nsAutoPtr<WorkerFeature> mWorkerFeature; nsAutoPtr<WorkerFeature> mWorkerFeature;
nsWeakPtr mWeakLoadGroup;
private: private:
~WebSocketImpl() ~WebSocketImpl()
{ {
@ -528,8 +530,7 @@ WebSocketImpl::DisconnectInternal()
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
nsCOMPtr<nsILoadGroup> loadGroup; nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mWeakLoadGroup);
GetLoadGroup(getter_AddRefs(loadGroup));
if (loadGroup) { if (loadGroup) {
loadGroup->RemoveRequest(this, nullptr, NS_OK); loadGroup->RemoveRequest(this, nullptr, NS_OK);
} }
@ -1390,6 +1391,8 @@ WebSocketImpl::InitializeConnection()
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = loadGroup->AddRequest(this, nullptr); rv = loadGroup->AddRequest(this, nullptr);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
mWeakLoadGroup = do_GetWeakReference(loadGroup);
} }
// manually adding loadinfo to the channel since it // manually adding loadinfo to the channel since it

Просмотреть файл

@ -5844,12 +5844,7 @@ nsDocument::ProcessTopElementQueue(bool aIsBaseQueue)
{ {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript()); MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
if (sProcessingStack.isNothing()) { nsTArray<nsRefPtr<CustomElementData>>& stack = *sProcessingStack;
// If XPCOM shutdown has reset the processing stack, don't do anything.
return;
}
nsTArray<CustomElementData*>& stack = *sProcessingStack;
uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr); uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr);
if (aIsBaseQueue && firstQueue != 0) { if (aIsBaseQueue && firstQueue != 0) {
@ -5886,7 +5881,7 @@ nsDocument::RegisterEnabled()
} }
// static // static
Maybe<nsTArray<mozilla::dom::CustomElementData*>> Maybe<nsTArray<nsRefPtr<mozilla::dom::CustomElementData>>>
nsDocument::sProcessingStack; nsDocument::sProcessingStack;
// static // static

Просмотреть файл

@ -325,6 +325,8 @@ private:
// being created flag. // being created flag.
struct CustomElementData struct CustomElementData
{ {
NS_INLINE_DECL_REFCOUNTING(CustomElementData)
explicit CustomElementData(nsIAtom* aType); explicit CustomElementData(nsIAtom* aType);
// Objects in this array are transient and empty after each microtask // Objects in this array are transient and empty after each microtask
// checkpoint. // checkpoint.
@ -346,6 +348,9 @@ struct CustomElementData
// Empties the callback queue. // Empties the callback queue.
void RunCallbackQueue(); void RunCallbackQueue();
private:
virtual ~CustomElementData() {}
}; };
// The required information for a custom element as defined in: // The required information for a custom element as defined in:
@ -1520,7 +1525,7 @@ private:
// CustomElementData in this array, separated by nullptr that // CustomElementData in this array, separated by nullptr that
// represent the boundaries of the items in the stack. The first // represent the boundaries of the items in the stack. The first
// queue in the stack is the base element queue. // queue in the stack is the base element queue.
static mozilla::Maybe<nsTArray<mozilla::dom::CustomElementData*>> sProcessingStack; static mozilla::Maybe<nsTArray<nsRefPtr<mozilla::dom::CustomElementData>>> sProcessingStack;
// Flag to prevent re-entrance into base element queue as described in the // Flag to prevent re-entrance into base element queue as described in the
// custom elements speicification. // custom elements speicification.

Просмотреть файл

@ -519,7 +519,11 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIChannel> channel;
rv = NS_NewInputStreamChannel(getter_AddRefs(channel), rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
uri, uri,
stream); stream,
info->mPrincipal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsString type; nsString type;
@ -537,12 +541,6 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
return error.ErrorCode(); return error.ErrorCode();
} }
nsCOMPtr<nsILoadInfo> loadInfo =
new mozilla::LoadInfo(info->mPrincipal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
channel->SetLoadInfo(loadInfo);
channel->SetOriginalURI(uri); channel->SetOriginalURI(uri);
channel->SetContentType(NS_ConvertUTF16toUTF8(type)); channel->SetContentType(NS_ConvertUTF16toUTF8(type));
channel->SetContentLength(size); channel->SetContentLength(size);

Просмотреть файл

@ -12,6 +12,9 @@ var is_remote;
error_reporting_test(); error_reporting_test();
dom_test(); dom_test();
xray_test(); xray_test();
if (typeof Symbol === "function") {
symbol_test();
}
compartment_test(); compartment_test();
regexp_test(); regexp_test();
sync_test(); sync_test();
@ -119,15 +122,13 @@ function symbol_test()
{ {
let iterator = Symbol.iterator; let iterator = Symbol.iterator;
let named = Symbol.for("cpow-test"); let named = Symbol.for("cpow-test");
// let unique = Symbol();
let object = { let object = {
[iterator]: iterator, [iterator]: iterator,
[named]: named, [named]: named,
// [unique]: unique,
// "unique": unique
}; };
sendSyncMessage("cpows:symbol_test", {}, object); let test = ['a'];
sendSyncMessage("cpows:symbol_test", {}, {object: object, test: test});
} }
// Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y // Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y

Просмотреть файл

@ -206,10 +206,16 @@
} }
function recvSymbolTest(message) { function recvSymbolTest(message) {
let object = message.objects; let object = message.objects.object;
is(object[Symbol.iterator], Symbol.iterator, "Should use Symbol.iterator"); is(object[Symbol.iterator], Symbol.iterator, "Should use Symbol.iterator");
is(Symbol.keyFor(object[Symbol.for("cpow-test")]), "cpow-test", "Symbols aren't registered correctly"); is(Symbol.keyFor(object[Symbol.for("cpow-test")]), "cpow-test", "Symbols aren't registered correctly");
// is(object.unique, object[object.unique], "Unique symbols as ids and values don't seem to work"); let symbols = Object.getOwnPropertySymbols(object);
is(symbols.length, 2, "Object should have two symbol keys");
let test = undefined;
for (let x of message.objects.test) {
test = x;
}
is(test, "a", "for .. of iteration should work");
} }
let systemGlobal = this; let systemGlobal = this;
@ -307,7 +313,9 @@
mm.addMessageListener("cpows:dom_test", recvDomTest); mm.addMessageListener("cpows:dom_test", recvDomTest);
mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC); mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC);
mm.addMessageListener("cpows:xray_test", recvXrayTest); mm.addMessageListener("cpows:xray_test", recvXrayTest);
mm.addMessageListener("cpows:symbol_test", recvSymbolTest); if (typeof Symbol === "function") {
mm.addMessageListener("cpows:symbol_test", recvSymbolTest);
}
mm.addMessageListener("cpows:compartment_test", recvCompartmentTest); mm.addMessageListener("cpows:compartment_test", recvCompartmentTest);
mm.addMessageListener("cpows:regexp_test", recvRegExpTest); mm.addMessageListener("cpows:regexp_test", recvRegExpTest);
mm.addMessageListener("cpows:lifetime_test_1", recvLifetimeTest1); mm.addMessageListener("cpows:lifetime_test_1", recvLifetimeTest1);

Просмотреть файл

@ -1655,12 +1655,25 @@ nsDocShell::LoadStream(nsIInputStream *aStream, nsIURI * aURI,
mLoadType = loadType; mLoadType = loadType;
nsCOMPtr<nsISupports> owner;
aLoadInfo->GetOwner(getter_AddRefs(owner));
nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(owner);
if (!requestingPrincipal) {
requestingPrincipal = nsContentUtils::GetSystemPrincipal();
}
// build up a channel for this stream. // build up a channel for this stream.
nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIChannel> channel;
NS_ENSURE_SUCCESS(NS_NewInputStreamChannel nsresult rv =
(getter_AddRefs(channel), uri, aStream, NS_NewInputStreamChannel(getter_AddRefs(channel),
aContentType, aContentCharset), uri,
NS_ERROR_FAILURE); aStream,
requestingPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
aContentType,
aContentCharset);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIURILoader> nsCOMPtr<nsIURILoader>
uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID)); uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID));
@ -10266,25 +10279,28 @@ nsDocShell::DoURILoad(nsIURI * aURI,
rv = vsh->NewSrcdocChannel(aURI, aSrcdoc, aBaseURI, rv = vsh->NewSrcdocChannel(aURI, aSrcdoc, aBaseURI,
getter_AddRefs(channel)); getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(requestingPrincipal,
requestingNode,
securityFlags,
aContentPolicyType);
channel->SetLoadInfo(loadInfo);
} }
else { else {
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),aURI, rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
aSrcdoc, aURI,
NS_LITERAL_CSTRING("text/html"), aSrcdoc,
true); NS_LITERAL_CSTRING("text/html"),
requestingNode,
requestingPrincipal,
securityFlags,
aContentPolicyType,
true);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(channel); nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(channel);
MOZ_ASSERT(isc); MOZ_ASSERT(isc);
isc->SetBaseURI(aBaseURI); isc->SetBaseURI(aBaseURI);
} }
// NS_NewInputStreamChannel does not yet attach the loadInfo in nsNetutil.h,
// hence we have to manually attach the loadInfo for that channel.
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(requestingPrincipal,
requestingNode,
securityFlags,
aContentPolicyType);
channel->SetLoadInfo(loadInfo);
} }
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel = nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =

Просмотреть файл

@ -599,20 +599,7 @@ public:
return false; return false;
} }
virtual const char *className(JSContext *cx, // Standard internal methods
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
// Fundamental traps
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc)
const MOZ_OVERRIDE;
virtual bool getOwnPropertyDescriptor(JSContext* cx, virtual bool getOwnPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, JS::Handle<jsid> id,
@ -631,23 +618,12 @@ public:
bool *bp) const MOZ_OVERRIDE; bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy, virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE; JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
virtual bool watch(JSContext *cx, JS::Handle<JSObject*> proxy, const MOZ_OVERRIDE;
JS::Handle<jsid> id, JS::Handle<JSObject*> callable) const MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx,
virtual bool unwatch(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
JS::Handle<jsid> id) const MOZ_OVERRIDE;
virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
// Derived traps
virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy, virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE; JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy, virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<JSObject*> receiver, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::Handle<jsid> id,
@ -657,11 +633,36 @@ public:
JS::Handle<jsid> id, JS::Handle<jsid> id,
bool strict, bool strict,
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE; JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE; // SpiderMonkey extensions
virtual bool getPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc)
const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy, virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
unsigned flags, unsigned flags,
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE; JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
virtual const char *className(JSContext *cx,
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
virtual bool isConstructor(JSObject *obj) const MOZ_OVERRIDE {
return false;
}
virtual bool watch(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
virtual bool unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const MOZ_OVERRIDE;
static void ObjectMoved(JSObject *obj, const JSObject *old); static void ObjectMoved(JSObject *obj, const JSObject *old);
@ -930,12 +931,12 @@ nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
} }
bool bool
nsOuterWindowProxy::keys(JSContext *cx, JS::Handle<JSObject*> proxy, nsOuterWindowProxy::getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const JS::AutoIdVector &props) const
{ {
// BaseProxyHandler::keys seems to do what we want here: call // BaseProxyHandler::keys seems to do what we want here: call
// ownPropertyKeys and then filter out the non-enumerable properties. // ownPropertyKeys and then filter out the non-enumerable properties.
return js::BaseProxyHandler::keys(cx, proxy, props); return js::BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
} }
bool bool

Просмотреть файл

@ -82,6 +82,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_urlutils_stringify.html] [test_urlutils_stringify.html]
[test_window_constructor.html] [test_window_constructor.html]
[test_window_cross_origin_props.html] [test_window_cross_origin_props.html]
[test_window_define_symbol.html]
[test_window_enumeration.html] [test_window_enumeration.html]
[test_window_extensible.html] [test_window_extensible.html]
[test_window_indexing.html] [test_window_indexing.html]

Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1082672
-->
<head>
<meta charset="UTF-8">
<title>Test for Bug 1082672 part 2</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1082672">Mozilla Bug 1082672</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
var sym = Symbol("ponies");
Object.defineProperty(window, sym, {configurable: true, value: 3});
is(window[sym], 3);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1406,8 +1406,11 @@ XrayAttributeOrMethodKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
// looking at now. // looking at now.
size_t i = list->specs - specList; size_t i = list->specs - specList;
for ( ; ids[i] != JSID_VOID; ++i) { for ( ; ids[i] != JSID_VOID; ++i) {
// Skip non-enumerable properties and symbol-keyed properties unless
// they are specially requested via flags.
if (((flags & JSITER_HIDDEN) || if (((flags & JSITER_HIDDEN) ||
(specList[i].flags & JSPROP_ENUMERATE)) && (specList[i].flags & JSPROP_ENUMERATE)) &&
((flags & JSITER_SYMBOLS) || !JSID_IS_SYMBOL(ids[i])) &&
!props.append(ids[i])) { !props.append(ids[i])) {
return false; return false;
} }

Просмотреть файл

@ -1685,7 +1685,7 @@ InitIds(JSContext* cx, const Prefable<Spec>* prefableSpecs, jsid* ids)
// because this is only done once per application runtime. // because this is only done once per application runtime.
Spec* spec = prefableSpecs->specs; Spec* spec = prefableSpecs->specs;
do { do {
if (!InternJSString(cx, *ids, spec->name)) { if (!JS::PropertySpecNameToPermanentId(cx, spec->name, ids)) {
return false; return false;
} }
} while (++ids, (++spec)->name); } while (++ids, (++spec)->name);

Просмотреть файл

@ -277,7 +277,7 @@ BaseDOMProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
if (!JS_GetPrototype(cx, proxy, &proto)) { if (!JS_GetPrototype(cx, proxy, &proto)) {
return false; return false;
} }
return keys(cx, proxy, props) && return getOwnEnumerablePropertyKeys(cx, proxy, props) &&
(!proto || js::GetPropertyKeys(cx, proto, 0, &props)); (!proto || js::GetPropertyKeys(cx, proto, 0, &props));
} }
@ -299,13 +299,13 @@ BaseDOMProxyHandler::ownPropertyKeys(JSContext* cx,
JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const JS::AutoIdVector& props) const
{ {
return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props); return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
} }
bool bool
BaseDOMProxyHandler::keys(JSContext* cx, BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const JS::AutoIdVector& props) const
{ {
return ownPropNames(cx, proxy, JSITER_OWNONLY, props); return ownPropNames(cx, proxy, JSITER_OWNONLY, props);
} }
@ -345,7 +345,8 @@ IdToInt32(JSContext* cx, JS::Handle<jsid> id)
JS::Rooted<JS::Value> idval(cx); JS::Rooted<JS::Value> idval(cx);
double array_index; double array_index;
int32_t i; int32_t i;
if (!::JS_IdToValue(cx, id, &idval) || if (JSID_IS_SYMBOL(id) ||
!::JS_IdToValue(cx, id, &idval) ||
!JS::ToNumber(cx, idval, &array_index) || !JS::ToNumber(cx, idval, &array_index) ||
!::JS_DoubleIsInt32(array_index, &i)) { !::JS_DoubleIsInt32(array_index, &i)) {
return -1; return -1;

Просмотреть файл

@ -50,34 +50,38 @@ public:
: js::BaseProxyHandler(aProxyFamily, aHasPrototype) : js::BaseProxyHandler(aProxyFamily, aHasPrototype)
{} {}
// Implementations of traps that can be implemented in terms of // Implementations of methods that can be implemented in terms of
// fundamental traps. // other lower-level methods.
bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const MOZ_OVERRIDE;
bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE; JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector& props) const MOZ_OVERRIDE;
bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
// We override getOwnEnumerablePropertyKeys() and implement it directly
// instead of using the default implementation, which would call
// ownPropertyKeys and then filter out the non-enumerable ones. This avoids
// unnecessary work during enumeration.
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
bool watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::Handle<JSObject*> callable) const MOZ_OVERRIDE; JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
bool unwatch(JSContext* cx, JS::Handle<JSObject*> proxy, bool unwatch(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const MOZ_OVERRIDE; JS::Handle<jsid> id) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
// We override keys() and implement it directly instead of using the
// default implementation, which would getOwnPropertyNames and then
// filter out the non-enumerable ones. This avoids doing
// unnecessary work during enumeration.
virtual bool keys(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
protected: protected:
// Hook for subclasses to implement shared ownPropertyKeys()/keys() // Hook for subclasses to implement shared ownPropertyKeys()/keys()
// functionality. The "flags" argument is either JSITER_OWNONLY (for keys()) // functionality. The "flags" argument is either JSITER_OWNONLY (for keys())
// or JSITER_OWNONLY | JSITER_HIDDEN (for ownPropertyKeys()). // or JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS (for
// ownPropertyKeys()).
virtual bool ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, virtual bool ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy,
unsigned flags, unsigned flags,
JS::AutoIdVector& props) const = 0; JS::AutoIdVector& props) const = 0;
@ -100,7 +104,6 @@ public:
: BaseDOMProxyHandler(&family) : BaseDOMProxyHandler(&family)
{} {}
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE
{ {
@ -110,15 +113,16 @@ public:
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined) JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined)
const; const;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const MOZ_OVERRIDE;
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver, bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp) JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp)
const MOZ_OVERRIDE; const MOZ_OVERRIDE;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
/* /*
* If assigning to proxy[id] hits a named setter with OverrideBuiltins or * If assigning to proxy[id] hits a named setter with OverrideBuiltins or

Просмотреть файл

@ -39,4 +39,9 @@
/* CHLD values */ /* CHLD values */
#define BTA_AG_CHLD_VAL "(0,1,2,3)" #define BTA_AG_CHLD_VAL "(0,1,2,3)"
/* BLE Feature */
#define BTA_GATT_INCLUDED TRUE
#define BLE_INCLUDED TRUE
#define SMP_INCLUDED TRUE
#endif /* B2G_BDROID_BUILDCFG_H */ #endif /* B2G_BDROID_BUILDCFG_H */

Просмотреть файл

@ -66,7 +66,11 @@ public:
void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth); GLsizei depth);
void TexImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const Nullable<dom::ArrayBufferView> &pixels,
ErrorResult& rv);
void TexSubImage3D(GLenum target, GLint level, void TexSubImage3D(GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLsizei width, GLsizei height, GLsizei depth,

Просмотреть файл

@ -204,6 +204,119 @@ WebGL2Context::TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat
} }
} }
void
WebGL2Context::TexImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const Nullable<dom::ArrayBufferView> &pixels,
ErrorResult& rv)
{
if (IsContextLost())
return;
void* data;
size_t dataLength;
js::Scalar::Type jsArrayType;
if (pixels.IsNull()) {
data = nullptr;
dataLength = 0;
jsArrayType = js::Scalar::TypeMax;
} else {
const ArrayBufferView& view = pixels.Value();
view.ComputeLengthAndData();
data = view.Data();
dataLength = view.Length();
jsArrayType = JS_GetArrayBufferViewType(view.Obj());
}
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
const WebGLTexDimensions dims = WebGLTexDimensions::Tex3D;
if (!ValidateTexImageTarget(target, func, dims))
return;
TexImageTarget texImageTarget = target;
if (!ValidateTexImage(texImageTarget, level, internalformat,
0, 0, 0,
width, height, depth,
border, format, type, func, dims))
{
return;
}
if (!ValidateTexInputData(type, jsArrayType, func, dims))
return;
TexInternalFormat effectiveInternalFormat =
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
if (effectiveInternalFormat == LOCAL_GL_NONE) {
return ErrorInvalidOperation("texImage3D: bad combination of internalformat and type");
}
// we need to find the exact sized format of the source data. Slightly abusing
// EffectiveInternalFormatFromInternalFormatAndType for that purpose. Really, an unsized source format
// is the same thing as an unsized internalformat.
TexInternalFormat effectiveSourceFormat =
EffectiveInternalFormatFromInternalFormatAndType(format, type);
MOZ_ASSERT(effectiveSourceFormat != LOCAL_GL_NONE); // should have validated format/type combo earlier
const size_t srcbitsPerTexel = GetBitsPerTexel(effectiveSourceFormat);
MOZ_ASSERT((srcbitsPerTexel % 8) == 0); // should not have compressed formats here.
size_t srcTexelSize = srcbitsPerTexel / 8;
CheckedUint32 checked_neededByteLength =
GetImageSize(height, width, depth, srcTexelSize, mPixelStoreUnpackAlignment);
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
uint32_t bytesNeeded = checked_neededByteLength.value();
if (dataLength && dataLength < bytesNeeded)
return ErrorInvalidOperation("texImage3D: not enough data for operation (need %d, have %d)",
bytesNeeded, dataLength);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texImage3D: no texture is bound to this target");
if (tex->IsImmutable()) {
return ErrorInvalidOperation(
"texImage3D: disallowed because the texture "
"bound to this target has already been made immutable by texStorage3D");
}
GLenum driverType = LOCAL_GL_NONE;
GLenum driverInternalFormat = LOCAL_GL_NONE;
GLenum driverFormat = LOCAL_GL_NONE;
DriverFormatsFromEffectiveInternalFormat(gl,
effectiveInternalFormat,
&driverInternalFormat,
&driverFormat,
&driverType);
MakeContextCurrent();
GetAndFlushUnderlyingGLErrors();
gl->fTexImage3D(texImageTarget.get(), level,
driverInternalFormat,
width, height, depth,
0, driverFormat, driverType,
data);
GLenum error = GetAndFlushUnderlyingGLErrors();
if (error) {
return GenerateWarning("texImage3D generated error %s", ErrorName(error));
}
tex->SetImageInfo(texImageTarget, level,
width, height, depth,
effectiveInternalFormat,
data ? WebGLImageDataStatus::InitializedImageData
: WebGLImageDataStatus::UninitializedImageData);
}
void void
WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level, WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset, GLint xoffset, GLint yoffset, GLint zoffset,

Просмотреть файл

@ -922,7 +922,11 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
const TexImageTarget imageTarget = (target == LOCAL_GL_TEXTURE_2D) const TexImageTarget imageTarget = (target == LOCAL_GL_TEXTURE_2D)
? LOCAL_GL_TEXTURE_2D ? LOCAL_GL_TEXTURE_2D
: LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X; : LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
if (!tex->HasImageInfoAt(imageTarget, tex->GetBaseMipmapLevel())) if (!tex->IsMipmapRangeValid())
{
return ErrorInvalidOperation("generateMipmap: Texture does not have a valid mipmap range.");
}
if (!tex->HasImageInfoAt(imageTarget, tex->EffectiveBaseMipmapLevel()))
{ {
return ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined."); return ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined.");
} }

Просмотреть файл

@ -867,6 +867,7 @@ InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims)
} }
case WebGLTexDimensions::Tex3D: case WebGLTexDimensions::Tex3D:
switch (func) { switch (func) {
case WebGLTexImageFunc::TexImage: return "texImage3D";
case WebGLTexImageFunc::TexSubImage: return "texSubImage3D"; case WebGLTexImageFunc::TexSubImage: return "texSubImage3D";
case WebGLTexImageFunc::CopyTexSubImage: return "copyTexSubImage3D"; case WebGLTexImageFunc::CopyTexSubImage: return "copyTexSubImage3D";
case WebGLTexImageFunc::CompTexSubImage: return "compressedTexSubImage3D"; case WebGLTexImageFunc::CompTexSubImage: return "compressedTexSubImage3D";

Просмотреть файл

@ -14,6 +14,7 @@
#include "WebGLTexelConversions.h" #include "WebGLTexelConversions.h"
#include <algorithm> #include <algorithm>
#include "mozilla/MathAlgorithms.h"
using namespace mozilla; using namespace mozilla;
@ -64,36 +65,50 @@ WebGLTexture::MemoryUsage() const {
return 0; return 0;
size_t result = 0; size_t result = 0;
for(size_t face = 0; face < mFacesCount; face++) { for(size_t face = 0; face < mFacesCount; face++) {
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++) for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
result += ImageInfoAtFace(face, level).MemoryUsage(); result += ImageInfoAtFace(face, level).MemoryUsage();
} }
return result; return result;
} }
static inline size_t
MipmapLevelsForSize(const WebGLTexture::ImageInfo &info)
{
GLsizei size = std::max(std::max(info.Width(), info.Height()), info.Depth());
// Find floor(log2(size)). (ES 3.0.4, 3.8 - Mipmapping).
return mozilla::FloorLog2(size);
}
bool bool
WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImageTarget) const WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImageTarget) const
{ {
// We could not have generated a mipmap if the base image wasn't defined.
if (mHaveGeneratedMipmap) if (mHaveGeneratedMipmap)
return true; return true;
if (GetMaxMipmapLevel() < GetBaseMipmapLevel()) if (!IsMipmapRangeValid())
return false; return false;
// We want a copy here so we can modify it temporarily. // We want a copy here so we can modify it temporarily.
ImageInfo expected = ImageInfoAt(texImageTarget, GetBaseMipmapLevel()); ImageInfo expected = ImageInfoAt(texImageTarget, EffectiveBaseMipmapLevel());
if (!expected.IsPositive())
return false;
// checks if custom level>0 images are all defined up to the highest level defined // If Level{max} is > mMaxLevelWithCustomImages, then check if we are
// and have the expected dimensions // missing any image levels.
for (size_t level = GetBaseMipmapLevel(); level <= GetMaxMipmapLevel(); ++level) { if (mMaxMipmapLevel > mMaxLevelWithCustomImages) {
if (MipmapLevelsForSize(expected) > mMaxLevelWithCustomImages)
return false;
}
// Checks if custom images are all defined up to the highest level and
// have the expected dimensions.
for (size_t level = EffectiveBaseMipmapLevel(); level <= EffectiveMaxMipmapLevel(); ++level) {
const ImageInfo& actual = ImageInfoAt(texImageTarget, level); const ImageInfo& actual = ImageInfoAt(texImageTarget, level);
if (actual != expected) if (actual != expected)
return false; return false;
// Check the raw value here, not the clamped one, since we don't want
// to terminate early if there aren't enough levels defined.
if (level == mMaxMipmapLevel)
return true;
expected.mWidth = std::max(1, expected.mWidth / 2); expected.mWidth = std::max(1, expected.mWidth / 2);
expected.mHeight = std::max(1, expected.mHeight / 2); expected.mHeight = std::max(1, expected.mHeight / 2);
expected.mDepth = std::max(1, expected.mDepth / 2); expected.mDepth = std::max(1, expected.mDepth / 2);
@ -108,8 +123,7 @@ WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImage
} }
} }
// if we're here, we've exhausted all levels without finding a 1x1 image return true;
return false;
} }
void void
@ -177,25 +191,19 @@ WebGLTexture::SetGeneratedMipmap() {
void void
WebGLTexture::SetCustomMipmap() { WebGLTexture::SetCustomMipmap() {
if (mHaveGeneratedMipmap) { if (mHaveGeneratedMipmap) {
// if we were in GeneratedMipmap mode and are now switching to CustomMipmap mode, if (!IsMipmapRangeValid())
// we need to compute now all the mipmap image info. return;
// since we were in GeneratedMipmap mode, we know that the level 0 images all have the same info, // If we were in GeneratedMipmap mode and are now switching to CustomMipmap mode,
// and are power-of-two. // we now need to compute all the mipmap image info.
ImageInfo imageInfo = ImageInfoAtFace(0, GetBaseMipmapLevel()); ImageInfo imageInfo = ImageInfoAtFace(0, EffectiveBaseMipmapLevel());
NS_ASSERTION(mContext->IsWebGL2() || imageInfo.IsPowerOfTwo(), NS_ASSERTION(mContext->IsWebGL2() || imageInfo.IsPowerOfTwo(),
"this texture is NPOT, so how could GenerateMipmap() ever accept it?"); "this texture is NPOT, so how could GenerateMipmap() ever accept it?");
GLsizei size = std::max(std::max(imageInfo.mWidth, imageInfo.mHeight), imageInfo.mDepth); size_t maxLevel = MipmapLevelsForSize(imageInfo);
EnsureMaxLevelWithCustomImagesAtLeast(EffectiveBaseMipmapLevel() + maxLevel);
// Find floor(log2(size)). (ES 3.0.4, 3.8 - Mipmapping). for (size_t level = EffectiveBaseMipmapLevel() + 1; level <= EffectiveMaxMipmapLevel(); ++level) {
size_t maxLevel = 0;
for (GLsizei n = size; n > 1; n >>= 1)
++maxLevel;
EnsureMaxLevelWithCustomImagesAtLeast(maxLevel);
for (size_t level = GetBaseMipmapLevel() + 1; level <= GetMaxMipmapLevel(); ++level) {
imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1); imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1);
imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1); imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1);
imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1); imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1);
@ -219,11 +227,6 @@ bool
WebGLTexture::IsMipmapComplete() const { WebGLTexture::IsMipmapComplete() const {
MOZ_ASSERT(mTarget == LOCAL_GL_TEXTURE_2D || MOZ_ASSERT(mTarget == LOCAL_GL_TEXTURE_2D ||
mTarget == LOCAL_GL_TEXTURE_3D); mTarget == LOCAL_GL_TEXTURE_3D);
if (!ImageInfoAtFace(0, GetBaseMipmapLevel()).IsPositive())
return false;
if (mHaveGeneratedMipmap)
return true;
return DoesMipmapHaveAllLevelsConsistentlyDefined(LOCAL_GL_TEXTURE_2D); return DoesMipmapHaveAllLevelsConsistentlyDefined(LOCAL_GL_TEXTURE_2D);
} }
@ -249,6 +252,17 @@ WebGLTexture::IsMipmapCubeComplete() const {
return true; return true;
} }
bool
WebGLTexture::IsMipmapRangeValid() const
{
// In ES3, if a texture is immutable, the mipmap levels are clamped.
if (IsImmutable())
return true;
if (mBaseMipmapLevel > std::min(mMaxLevelWithCustomImages, mMaxMipmapLevel))
return false;
return true;
}
WebGLTextureFakeBlackStatus WebGLTextureFakeBlackStatus
WebGLTexture::ResolvedFakeBlackStatus() { WebGLTexture::ResolvedFakeBlackStatus() {
if (MOZ_LIKELY(mFakeBlackStatus != WebGLTextureFakeBlackStatus::Unknown)) { if (MOZ_LIKELY(mFakeBlackStatus != WebGLTextureFakeBlackStatus::Unknown)) {
@ -256,10 +270,14 @@ WebGLTexture::ResolvedFakeBlackStatus() {
} }
// Determine if the texture needs to be faked as a black texture. // Determine if the texture needs to be faked as a black texture.
// See 3.8.2 Shader Execution in the OpenGL ES 2.0.24 spec. // See 3.8.2 Shader Execution in the OpenGL ES 2.0.24 spec, and 3.8.13 in
// the OpenGL ES 3.0.4 spec.
if (!IsMipmapRangeValid()) {
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
return mFakeBlackStatus;
}
for (size_t face = 0; face < mFacesCount; ++face) { for (size_t face = 0; face < mFacesCount; ++face) {
if (ImageInfoAtFace(face, GetBaseMipmapLevel()).mImageDataStatus == WebGLImageDataStatus::NoImageData) { if (ImageInfoAtFace(face, EffectiveBaseMipmapLevel()).mImageDataStatus == WebGLImageDataStatus::NoImageData) {
// In case of undefined texture image, we don't print any message because this is a very common // In case of undefined texture image, we don't print any message because this is a very common
// and often legitimate case (asynchronous texture loading). // and often legitimate case (asynchronous texture loading).
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture; mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;

Просмотреть файл

@ -17,6 +17,7 @@
#include "mozilla/LinkedList.h" #include "mozilla/LinkedList.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include <algorithm> #include <algorithm>
#include "nsAlgorithm.h"
namespace mozilla { namespace mozilla {
@ -286,16 +287,22 @@ public:
bool IsImmutable() const { return mImmutable; } bool IsImmutable() const { return mImmutable; }
void SetImmutable() { mImmutable = true; } void SetImmutable() { mImmutable = true; }
void SetBaseMipmapLevel(unsigned level) { mBaseMipmapLevel = level; } void SetBaseMipmapLevel(size_t level) { mBaseMipmapLevel = level; }
void SetMaxMipmapLevel(unsigned level) { mMaxMipmapLevel = level; } void SetMaxMipmapLevel(size_t level) { mMaxMipmapLevel = level; }
size_t GetBaseMipmapLevel() const {
// Clamp to [0, levels - 1] // Clamping (from ES 3.0.4, section 3.8 - Texturing). When not immutable,
return std::min(mBaseMipmapLevel, mMaxLevelWithCustomImages); // the ranges must be guarded.
size_t EffectiveBaseMipmapLevel() const {
if (IsImmutable())
return std::min(mBaseMipmapLevel, mMaxLevelWithCustomImages);
return mBaseMipmapLevel;
} }
size_t GetMaxMipmapLevel() const { size_t EffectiveMaxMipmapLevel() const {
// Clamp to [base, levels - 1] if (IsImmutable())
return mozilla::clamped(mMaxMipmapLevel, EffectiveBaseMipmapLevel(), mMaxLevelWithCustomImages);
return std::min(mMaxMipmapLevel, mMaxLevelWithCustomImages); return std::min(mMaxMipmapLevel, mMaxLevelWithCustomImages);
} }
bool IsMipmapRangeValid() const;
size_t MaxLevelWithCustomImages() const { return mMaxLevelWithCustomImages; } size_t MaxLevelWithCustomImages() const { return mMaxLevelWithCustomImages; }

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsCRTGlue.h" #include "nsCRTGlue.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsNullPrincipal.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include <algorithm> #include <algorithm>
@ -409,9 +410,19 @@ nsJSON::DecodeInternal(JSContext* cx,
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
nsresult rv = nsresult rv;
NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), mURI, aStream, nsCOMPtr<nsIPrincipal> nullPrincipal =
NS_LITERAL_CSTRING("application/json")); do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewInputStreamChannel(getter_AddRefs(jsonChannel),
mURI,
aStream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING("application/json"));
if (!jsonChannel || NS_FAILED(rv)) if (!jsonChannel || NS_FAILED(rv))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

Просмотреть файл

@ -36,6 +36,7 @@
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsNullPrincipal.h"
#include "nsJSUtils.h" #include "nsJSUtils.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsIScriptChannel.h" #include "nsIScriptChannel.h"
@ -427,9 +428,18 @@ nsresult nsJSChannel::Init(nsIURI *aURI)
// and the underlying Input Stream will not be created... // and the underlying Input Stream will not be created...
nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// If the resultant script evaluation actually does return a value, we // If the resultant script evaluation actually does return a value, we
// treat it as html. // treat it as html.
rv = NS_NewInputStreamChannel(getter_AddRefs(channel), aURI, mIOThunk, rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
aURI,
mIOThunk,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING("text/html")); NS_LITERAL_CSTRING("text/html"));
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;

Просмотреть файл

@ -21,7 +21,6 @@ interface MediaKeySession : EventTarget {
readonly attribute unrestricted double expiration; readonly attribute unrestricted double expiration;
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
readonly attribute Promise<void> closed; readonly attribute Promise<void> closed;
[NewObject, Throws] [NewObject, Throws]
@ -31,15 +30,12 @@ interface MediaKeySession : EventTarget {
Promise<boolean> load(DOMString sessionId); Promise<boolean> load(DOMString sessionId);
// session operations // session operations
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws] [NewObject, Throws]
Promise<void> update((ArrayBufferView or ArrayBuffer) response); Promise<void> update((ArrayBufferView or ArrayBuffer) response);
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws] [NewObject, Throws]
Promise<void> close(); Promise<void> close();
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws] [NewObject, Throws]
Promise<void> remove(); Promise<void> remove();

Просмотреть файл

@ -20,7 +20,6 @@ interface MediaKeys {
[NewObject, Throws] [NewObject, Throws]
MediaKeySession createSession(optional SessionType sessionType = "temporary"); MediaKeySession createSession(optional SessionType sessionType = "temporary");
// void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
[NewObject, Throws] [NewObject, Throws]
Promise<void> setServerCertificate((ArrayBufferView or ArrayBuffer) serverCertificate); Promise<void> setServerCertificate((ArrayBufferView or ArrayBuffer) serverCertificate);

Просмотреть файл

@ -342,6 +342,11 @@ interface WebGL2RenderingContext : WebGLRenderingContext
void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth); GLsizei depth);
[Throws]
void texImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format,
GLenum type, ArrayBufferView? pixels);
[Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, [Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
ArrayBufferView? pixels); ArrayBufferView? pixels);

Просмотреть файл

@ -72,6 +72,11 @@ nsresult
nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent) nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
{ {
nsHTMLEditor* htmlEditor = GetHTMLEditor(); nsHTMLEditor* htmlEditor = GetHTMLEditor();
// Contenteditable should disregard mousedowns outside it.
// IsAcceptableInputEvent() checks it for a mouse event.
if (!htmlEditor->IsAcceptableInputEvent(aMouseEvent)) {
return NS_OK;
}
// Detect only "context menu" click // Detect only "context menu" click
// XXX This should be easier to do! // XXX This should be easier to do!
@ -93,11 +98,6 @@ nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target); nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
// Contenteditable should disregard mousedowns outside it
if (element && !htmlEditor->IsDescendantOfEditorRoot(element)) {
return NS_OK;
}
if (isContextClick || (buttonNumber == 0 && clickCount == 2)) { if (isContextClick || (buttonNumber == 0 && clickCount == 2)) {
nsCOMPtr<nsISelection> selection; nsCOMPtr<nsISelection> selection;
mEditor->GetSelection(getter_AddRefs(selection)); mEditor->GetSelection(getter_AddRefs(selection));

Просмотреть файл

@ -17,6 +17,7 @@
#include "nsIStandardURL.h" #include "nsIStandardURL.h"
#include "nsMimeTypes.h" #include "nsMimeTypes.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "mozilla/Monitor.h" #include "mozilla/Monitor.h"
#include <gio/gio.h> #include <gio/gio.h>
#include <algorithm> #include <algorithm>
@ -1062,11 +1063,18 @@ nsGIOProtocolHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
} }
else else
{ {
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// start out assuming an unknown content-type. we'll set the content-type // start out assuming an unknown content-type. we'll set the content-type
// to something better once we open the URI. // to something better once we open the URI.
rv = NS_NewInputStreamChannel(aResult, rv = NS_NewInputStreamChannel(aResult,
aURI, aURI,
stream, stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE)); NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE));
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
stream->SetChannel(*aResult); stream->SetChannel(*aResult);

Просмотреть файл

@ -548,11 +548,12 @@ Factory::SetDirect3D10Device(ID3D10Device1 *aDevice)
ID3D10Device1* ID3D10Device1*
Factory::GetDirect3D10Device() Factory::GetDirect3D10Device()
{ {
#ifdef DEBUG #ifdef DEBUG
UINT mode = mD3D10Device->GetExceptionMode(); if (mD3D10Device) {
MOZ_ASSERT(0 == mode); UINT mode = mD3D10Device->GetExceptionMode();
MOZ_ASSERT(0 == mode);
}
#endif #endif
return mD3D10Device; return mD3D10Device;
} }

Просмотреть файл

@ -17,8 +17,3 @@ endif
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
# We have to filter out -pedantic, because of
# comma-at-end-of-enumerator list failures. We can try to get this fixed
# upstream at some point.
CXXFLAGS := $(filter-out -pedantic,$(CXXFLAGS))
CFLAGS := $(filter-out -pedantic,$(CFLAGS))

Просмотреть файл

@ -1253,7 +1253,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (IsSupported(GLFeature::texture_3D)) { if (IsSupported(GLFeature::texture_3D)) {
SymLoadStruct coreSymbols[] = { SymLoadStruct coreSymbols[] = {
// TexImage3D is not required for WebGL2 so not queried here. { (PRFuncPtr*) &mSymbols.fTexImage3D, { "TexImage3D", nullptr } },
{ (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3D", nullptr } }, { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3D", nullptr } },
END_SYMBOLS END_SYMBOLS
}; };

Просмотреть файл

@ -3132,6 +3132,21 @@ public:
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// 3D Textures // 3D Textures
void fTexImage3D(GLenum target, GLint level,
GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const GLvoid * data)
{
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fTexImage3D);
mSymbols.fTexImage3D(target, level, internalFormat,
width, height, depth,
border, format, type,
data);
AFTER_GL_CALL;
}
void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid* pixels) GLenum format, GLenum type, const GLvoid* pixels)

Просмотреть файл

@ -642,6 +642,12 @@ struct GLContextSymbols
PFNGLGETFRAGDATALOCATIONPROC fGetFragDataLocation; PFNGLGETFRAGDATALOCATIONPROC fGetFragDataLocation;
// 3D Textures // 3D Textures
typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level,
GLenum internalFormat,
GLenum width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
const GLvoid* pixels);
PFNGLTEXIMAGE3DPROC fTexImage3D;
typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLint zoffset, GLsizei width, GLint yoffset, GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth, GLenum format, GLsizei height, GLsizei depth, GLenum format,

Просмотреть файл

@ -369,17 +369,16 @@ gfxSVGGlyphsDocument::ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen)
} }
nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsIChannel> channel;
rv = NS_NewInputStreamChannel(getter_AddRefs(channel), uri, nullptr /* stream */, rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
SVG_CONTENT_TYPE, UTF8_CHARSET); uri,
nullptr, //aStream
principal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER,
SVG_CONTENT_TYPE,
UTF8_CHARSET);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(principal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
channel->SetLoadInfo(loadInfo);
// Set this early because various decisions during page-load depend on it. // Set this early because various decisions during page-load depend on it.
document->SetIsBeingUsedAsImage(); document->SetIsBeingUsedAsImage();
document->SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED); document->SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED);

Просмотреть файл

@ -413,7 +413,7 @@ gfxUserFontEntry::LoadNextSrc()
mItalic); mItalic);
mFontSet->SetLocalRulesUsed(); mFontSet->SetLocalRulesUsed();
if (fe) { if (fe) {
LOG(("fontset (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n", LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
mFontSet, mSrcIndex, mFontSet, mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(), NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(mFamilyName).get(), NS_ConvertUTF16toUTF8(mFamilyName).get(),
@ -430,7 +430,7 @@ gfxUserFontEntry::LoadNextSrc()
SetLoadState(STATUS_LOADED); SetLoadState(STATUS_LOADED);
return; return;
} else { } else {
LOG(("fontset (%p) [src %d] failed local: (%s) for (%s)\n", LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n",
mFontSet, mSrcIndex, mFontSet, mSrcIndex,
NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(), NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(),
NS_ConvertUTF16toUTF8(mFamilyName).get())); NS_ConvertUTF16toUTF8(mFamilyName).get()));
@ -647,7 +647,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
nsAutoCString fontURI; nsAutoCString fontURI;
mSrcList[mSrcIndex].mURI->GetSpec(fontURI); mSrcList[mSrcIndex].mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) gen: %8.8x\n", LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) gen: %8.8x\n",
this, mSrcIndex, fontURI.get(), mFontSet, mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(mFamilyName).get(), NS_ConvertUTF16toUTF8(mFamilyName).get(),
uint32_t(mFontSet->mGeneration))); uint32_t(mFontSet->mGeneration)));
} }
@ -662,7 +662,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
mSrcList[mSrcIndex].mURI->GetSpec(fontURI); mSrcList[mSrcIndex].mURI->GetSpec(fontURI);
LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s)" LOG(("userfonts (%p) [src %d] failed uri: (%s) for (%s)"
" error making platform font\n", " error making platform font\n",
this, mSrcIndex, fontURI.get(), mFontSet, mSrcIndex, fontURI.get(),
NS_ConvertUTF16toUTF8(mFamilyName).get())); NS_ConvertUTF16toUTF8(mFamilyName).get()));
} }
#endif #endif

Просмотреть файл

@ -467,6 +467,10 @@ public:
mLocalRulesUsed = true; mLocalRulesUsed = true;
} }
#ifdef PR_LOGGING
static PRLogModuleInfo* GetUserFontsLog();
#endif
protected: protected:
// Protected destructor, to discourage deletion outside of Release(): // Protected destructor, to discourage deletion outside of Release():
virtual ~gfxUserFontSet(); virtual ~gfxUserFontSet();
@ -512,8 +516,6 @@ protected:
// true when local names have been looked up, false otherwise // true when local names have been looked up, false otherwise
bool mLocalRulesUsed; bool mLocalRulesUsed;
static PRLogModuleInfo* GetUserFontsLog();
}; };
// acts a placeholder until the real font is downloaded // acts a placeholder until the real font is downloaded

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsIconChannel.h" #include "nsIconChannel.h"
#include "nsIStringStream.h" #include "nsIStringStream.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsNullPrincipal.h"
NS_IMPL_ISUPPORTS(nsIconChannel, NS_IMPL_ISUPPORTS(nsIconChannel,
nsIRequest, nsIRequest,
@ -102,7 +103,16 @@ moz_icon_to_channel(nsIURI *aURI, const nsACString& aFileExt, uint32_t aIconSize
rv = stream->AdoptData((char*)buf, buf_size); rv = stream->AdoptData((char*)buf, buf_size);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel, aURI, stream, nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(IMAGE_ICON_MS)); NS_LITERAL_CSTRING(IMAGE_ICON_MS));
} }

Просмотреть файл

@ -33,6 +33,7 @@ extern "C" {
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "prlink.h" #include "prlink.h"
@ -137,9 +138,17 @@ moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI *aURI,
MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(NS_SUCCEEDED(rv));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewInputStreamChannel(aChannel, aURI, stream, nsCOMPtr<nsIPrincipal> nullPrincipal =
NS_LITERAL_CSTRING(IMAGE_ICON_MS)); do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
return rv; NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(IMAGE_ICON_MS));
} }
static GtkWidget *gProtoWindow = nullptr; static GtkWidget *gProtoWindow = nullptr;

Просмотреть файл

@ -16,6 +16,7 @@
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsIconChannel.h" #include "nsIconChannel.h"
@ -83,7 +84,16 @@ moz_qicon_to_channel(QImage *image, nsIURI *aURI,
rv = stream->AdoptData((char*)buf, buf_size); rv = stream->AdoptData((char*)buf, buf_size);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel, aURI, stream, nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
NS_LITERAL_CSTRING(IMAGE_ICON_MS)); NS_LITERAL_CSTRING(IMAGE_ICON_MS));
} }

Просмотреть файл

@ -125,6 +125,9 @@ MessageLoop::MessageLoop(Type type)
pump_ = new mozilla::ipc::MessagePumpForNonMainUIThreads(); pump_ = new mozilla::ipc::MessagePumpForNonMainUIThreads();
return; return;
#endif #endif
default:
// Create one of Chromium's standard MessageLoop types below.
break;
} }
#if defined(OS_WIN) #if defined(OS_WIN)

Просмотреть файл

@ -102,8 +102,8 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
} }
bool RecvGetPropertyKeys(const uint64_t &objId, const uint32_t &flags, bool RecvGetPropertyKeys(const uint64_t &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) { ReturnStatus *rs, nsTArray<JSIDVariant> *ids) {
return Answer::RecvGetPropertyKeys(ObjectId::deserialize(objId), flags, rs, names); return Answer::RecvGetPropertyKeys(ObjectId::deserialize(objId), flags, rs, ids);
} }
bool RecvInstanceOf(const uint64_t &objId, const JSIID &iid, bool RecvInstanceOf(const uint64_t &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof) { ReturnStatus *rs, bool *instanceof) {
@ -200,8 +200,8 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
} }
bool SendGetPropertyKeys(const ObjectId &objId, const uint32_t &flags, bool SendGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) { ReturnStatus *rs, nsTArray<JSIDVariant> *ids) {
return Base::SendGetPropertyKeys(objId.serialize(), flags, rs, names); return Base::SendGetPropertyKeys(objId.serialize(), flags, rs, ids);
} }
bool SendInstanceOf(const ObjectId &objId, const JSIID &iid, bool SendInstanceOf(const ObjectId &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof) { ReturnStatus *rs, bool *instanceof) {

Просмотреть файл

@ -440,7 +440,8 @@ JavaScriptShared::toSymbolVariant(JSContext *cx, JS::Symbol *symArg, SymbolVaria
*symVarp = RegisteredSymbol(autoStr); *symVarp = RegisteredSymbol(autoStr);
return true; return true;
} }
MOZ_CRASH("unique symbols not yet implemented");
JS_ReportError(cx, "unique symbol can't be used with CPOW");
return false; return false;
} }

Просмотреть файл

@ -42,7 +42,7 @@ both:
prio(high) sync ClassName(uint64_t objId) returns (nsString name); prio(high) sync ClassName(uint64_t objId) returns (nsString name);
prio(high) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags); prio(high) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
prio(high) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names); prio(high) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, JSIDVariant[] ids);
prio(high) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof); prio(high) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
prio(high) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof); prio(high) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);

Просмотреть файл

@ -580,7 +580,7 @@ WrapperAnswer::RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
bool bool
WrapperAnswer::RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags, WrapperAnswer::RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) ReturnStatus *rs, nsTArray<JSIDVariant> *ids)
{ {
AutoSafeJSContext cx; AutoSafeJSContext cx;
JSAutoRequest request(cx); JSAutoRequest request(cx);
@ -598,11 +598,11 @@ WrapperAnswer::RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
return fail(cx, rs); return fail(cx, rs);
for (size_t i = 0; i < props.length(); i++) { for (size_t i = 0; i < props.length(); i++) {
nsString name; JSIDVariant id;
if (!convertIdToGeckoString(cx, props[i], &name)) if (!toJSIDVariant(cx, props[i], &id))
return fail(cx, rs); return fail(cx, rs);
names->AppendElement(name); ids->AppendElement(id);
} }
return ok(rs); return ok(rs);

Просмотреть файл

@ -55,7 +55,7 @@ class WrapperAnswer : public virtual JavaScriptShared
bool RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags); bool RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags);
bool RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags, bool RecvGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names); ReturnStatus *rs, nsTArray<JSIDVariant> *ids);
bool RecvInstanceOf(const ObjectId &objId, const JSIID &iid, bool RecvInstanceOf(const ObjectId &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof); ReturnStatus *rs, bool *instanceof);
bool RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth, bool RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,

Просмотреть файл

@ -63,9 +63,6 @@ class CPOWProxyHandler : public BaseProxyHandler
return false; return false;
} }
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE; MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
@ -74,18 +71,21 @@ class CPOWProxyHandler : public BaseProxyHandler
AutoIdVector &props) const MOZ_OVERRIDE; AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE; virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE; virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE; HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;
virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, bool strict, JS::MutableHandleValue vp) const MOZ_OVERRIDE; JS::HandleId id, bool strict, JS::MutableHandleValue vp) const MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE; virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject proxy, virtual bool hasInstance(JSContext *cx, HandleObject proxy,
MutableHandleValue v, bool *bp) const MOZ_OVERRIDE; MutableHandleValue v, bool *bp) const MOZ_OVERRIDE;
virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue, virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue,
@ -232,7 +232,7 @@ CPOWProxyHandler::ownPropertyKeys(JSContext *cx, HandleObject proxy,
bool bool
WrapperOwner::ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props) WrapperOwner::ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{ {
return getPropertyKeys(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props); return getPropertyKeys(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
} }
bool bool
@ -463,13 +463,14 @@ WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiv
} }
bool bool
CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) const CPOWProxyHandler::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const
{ {
FORWARD(keys, (cx, proxy, props)); FORWARD(getOwnEnumerablePropertyKeys, (cx, proxy, props));
} }
bool bool
WrapperOwner::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) WrapperOwner::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{ {
return getPropertyKeys(cx, proxy, JSITER_OWNONLY, props); return getPropertyKeys(cx, proxy, JSITER_OWNONLY, props);
} }
@ -776,8 +777,8 @@ WrapperOwner::getPropertyKeys(JSContext *cx, HandleObject proxy, uint32_t flags,
ObjectId objId = idOf(proxy); ObjectId objId = idOf(proxy);
ReturnStatus status; ReturnStatus status;
InfallibleTArray<nsString> names; InfallibleTArray<JSIDVariant> ids;
if (!SendGetPropertyKeys(objId, flags, &status, &names)) if (!SendGetPropertyKeys(objId, flags, &status, &ids))
return ipcfail(cx); return ipcfail(cx);
LOG_STACK(); LOG_STACK();
@ -785,11 +786,11 @@ WrapperOwner::getPropertyKeys(JSContext *cx, HandleObject proxy, uint32_t flags,
if (!ok(cx, status)) if (!ok(cx, status))
return false; return false;
for (size_t i = 0; i < names.Length(); i++) { for (size_t i = 0; i < ids.Length(); i++) {
RootedId name(cx); RootedId id(cx);
if (!convertGeckoStringToId(cx, names[i], &name)) if (!fromJSIDVariant(cx, ids[i], &id))
return false; return false;
if (!props.append(name)) if (!props.append(id))
return false; return false;
} }

Просмотреть файл

@ -31,11 +31,8 @@ class WrapperOwner : public virtual JavaScriptShared
explicit WrapperOwner(JSRuntime *rt); explicit WrapperOwner(JSRuntime *rt);
bool init(); bool init();
// Fundamental proxy traps. These are required. // Standard internal methods.
// (The traps should be in the same order like js/src/jsproxy.h) // (The traps should be in the same order like js/src/jsproxy.h)
bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc); JS::MutableHandle<JSPropertyDescriptor> desc);
bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
@ -43,25 +40,27 @@ class WrapperOwner : public virtual JavaScriptShared
bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props); bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props); bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
// Derived proxy traps. Implementing these is useful for perfomance. bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp); bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp); JS::HandleId id, JS::MutableHandleValue vp);
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, bool strict, JS::MutableHandleValue vp); JS::HandleId id, bool strict, JS::MutableHandleValue vp);
bool keys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
// We use "iterate" provided by the base class here.
// SpiderMonkey Extensions.
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args, bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args,
bool construct); bool construct);
// SpiderMonkey extensions.
bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::HandleObject proxy,
JS::AutoIdVector &props);
// We use "iterate" provided by the base class here.
bool hasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp); bool hasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp);
bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
const char* className(JSContext *cx, JS::HandleObject proxy); const char* className(JSContext *cx, JS::HandleObject proxy);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
bool isCallable(JSObject *obj); bool isCallable(JSObject *obj);
bool isConstructor(JSObject *obj); bool isConstructor(JSObject *obj);
@ -146,7 +145,7 @@ class WrapperOwner : public virtual JavaScriptShared
uint32_t *flags) = 0; uint32_t *flags) = 0;
virtual bool SendGetPropertyKeys(const ObjectId &objId, const uint32_t &flags, virtual bool SendGetPropertyKeys(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) = 0; ReturnStatus *rs, nsTArray<JSIDVariant> *ids) = 0;
virtual bool SendInstanceOf(const ObjectId &objId, const JSIID &iid, virtual bool SendInstanceOf(const ObjectId &objId, const JSIID &iid,
ReturnStatus *rs, bool *instanceof) = 0; ReturnStatus *rs, bool *instanceof) = 0;
virtual bool SendDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth, virtual bool SendDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,

Просмотреть файл

@ -315,6 +315,7 @@ selfhosting_srcs := \
$(srcdir)/builtin/Array.js \ $(srcdir)/builtin/Array.js \
$(srcdir)/builtin/Date.js \ $(srcdir)/builtin/Date.js \
$(srcdir)/builtin/Error.js \ $(srcdir)/builtin/Error.js \
$(srcdir)/builtin/Generator.js \
$(srcdir)/builtin/Intl.js \ $(srcdir)/builtin/Intl.js \
$(srcdir)/builtin/IntlData.js \ $(srcdir)/builtin/IntlData.js \
$(srcdir)/builtin/Iterator.js \ $(srcdir)/builtin/Iterator.js \

104
js/src/builtin/Generator.js Normal file
Просмотреть файл

@ -0,0 +1,104 @@
/* 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/. */
function StarGeneratorNext(val) {
if (!IsObject(this) || !IsStarGeneratorObject(this))
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorNext");
if (StarGeneratorObjectIsClosed(this))
return { value: undefined, done: true };
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'next');
} catch (e) {
if (!StarGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
function StarGeneratorThrow(val) {
if (!IsObject(this) || !IsStarGeneratorObject(this))
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorThrow");
if (StarGeneratorObjectIsClosed(this))
throw val;
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'throw');
} catch (e) {
if (!StarGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
function LegacyGeneratorNext(val) {
if (!IsObject(this) || !IsLegacyGeneratorObject(this))
return callFunction(CallLegacyGeneratorMethodIfWrapped, this, val, "LegacyGeneratorNext");
if (LegacyGeneratorObjectIsClosed(this))
ThrowStopIteration();
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'next');
} catch(e) {
if (!LegacyGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
function LegacyGeneratorThrow(val) {
if (!IsObject(this) || !IsLegacyGeneratorObject(this))
return callFunction(CallLegacyGeneratorMethodIfWrapped, this, val, "LegacyGeneratorThrow");
if (LegacyGeneratorObjectIsClosed(this))
throw val;
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
try {
return resumeGenerator(this, val, 'throw');
} catch(e) {
if (!LegacyGeneratorObjectIsClosed(this))
GeneratorSetClosed(this);
throw e;
}
}
// Called by js::CloseIterator.
function LegacyGeneratorCloseInternal() {
assert(IsObject(this), "Not an object: " + ToString(this));
assert(IsLegacyGeneratorObject(this), "Not a legacy generator object: " + ToString(this));
assert(!LegacyGeneratorObjectIsClosed(this), "Already closed: " + ToString(this));
assert(!CloseNewbornLegacyGeneratorObject(this), "Newborn: " + ToString(this));
if (GeneratorIsRunning(this))
ThrowError(JSMSG_NESTING_GENERATOR);
resumeGenerator(this, undefined, 'close');
if (!LegacyGeneratorObjectIsClosed(this))
CloseClosingLegacyGeneratorObject(this);
}
function LegacyGeneratorClose() {
if (!IsObject(this) || !IsLegacyGeneratorObject(this))
return callFunction(CallLegacyGeneratorMethodIfWrapped, this, "LegacyGeneratorClose");
if (LegacyGeneratorObjectIsClosed(this) || CloseNewbornLegacyGeneratorObject(this))
return;
callFunction(LegacyGeneratorCloseInternal, this);
}

Просмотреть файл

@ -1294,7 +1294,6 @@ if test "$GNU_CXX"; then
# -Wwrite-strings - catches non-const char* pointers to string literals # -Wwrite-strings - catches non-const char* pointers to string literals
# #
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
@ -1303,6 +1302,7 @@ if test "$GNU_CXX"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=comment" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=comment"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=empty-body" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=empty-body"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=overloaded-virtual" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=overloaded-virtual"

Просмотреть файл

@ -2625,8 +2625,8 @@ ImplicitConvert(JSContext* cx,
if (val.isObject() && !sourceData) { if (val.isObject() && !sourceData) {
// Enumerate the properties of the object; if they match the struct // Enumerate the properties of the object; if they match the struct
// specification, convert the fields. // specification, convert the fields.
RootedObject iter(cx, JS_NewPropertyIterator(cx, valObj)); AutoIdArray props(cx, JS_Enumerate(cx, valObj));
if (!iter) if (!props)
return false; return false;
// Convert into an intermediate, in case of failure. // Convert into an intermediate, in case of failure.
@ -2637,13 +2637,15 @@ ImplicitConvert(JSContext* cx,
return false; return false;
} }
const FieldInfoHash* fields = StructType::GetFieldInfo(targetType);
if (props.length() != fields->count()) {
JS_ReportError(cx, "missing fields");
return false;
}
RootedId id(cx); RootedId id(cx);
size_t i = 0; for (size_t i = 0; i < props.length(); ++i) {
while (1) { id = props[i];
if (!JS_NextProperty(cx, iter, &id))
return false;
if (JSID_IS_VOID(id))
break;
if (!JSID_IS_STRING(id)) { if (!JSID_IS_STRING(id)) {
JS_ReportError(cx, "property name is not a string"); JS_ReportError(cx, "property name is not a string");
@ -2663,14 +2665,6 @@ ImplicitConvert(JSContext* cx,
char* fieldData = intermediate.get() + field->mOffset; char* fieldData = intermediate.get() + field->mOffset;
if (!ImplicitConvert(cx, prop, field->mType, fieldData, false, nullptr)) if (!ImplicitConvert(cx, prop, field->mType, fieldData, false, nullptr))
return false; return false;
++i;
}
const FieldInfoHash* fields = StructType::GetFieldInfo(targetType);
if (i != fields->count()) {
JS_ReportError(cx, "missing fields");
return false;
} }
memcpy(buffer, intermediate.get(), structSize); memcpy(buffer, intermediate.get(), structSize);
@ -4705,33 +4699,23 @@ ExtractStructField(JSContext* cx, jsval val, MutableHandleObject typeObj)
return nullptr; return nullptr;
} }
RootedObject obj(cx, val.toObjectOrNull()); RootedObject obj(cx, &val.toObject());
RootedObject iter(cx, JS_NewPropertyIterator(cx, obj)); AutoIdArray props(cx, JS_Enumerate(cx, obj));
if (!iter) if (!props)
return nullptr; return nullptr;
RootedId nameid(cx);
if (!JS_NextProperty(cx, iter, &nameid))
return nullptr;
if (JSID_IS_VOID(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return nullptr;
}
if (!JSID_IS_STRING(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return nullptr;
}
// make sure we have one, and only one, property // make sure we have one, and only one, property
RootedId id(cx); if (props.length() != 1) {
if (!JS_NextProperty(cx, iter, &id))
return nullptr;
if (!JSID_IS_VOID(id)) {
JS_ReportError(cx, "struct field descriptors must contain one property"); JS_ReportError(cx, "struct field descriptors must contain one property");
return nullptr; return nullptr;
} }
RootedId nameid(cx, props[0]);
if (!JSID_IS_STRING(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
return nullptr;
}
RootedValue propVal(cx); RootedValue propVal(cx);
if (!JS_GetPropertyById(cx, obj, nameid, &propVal)) if (!JS_GetPropertyById(cx, obj, nameid, &propVal))
return nullptr; return nullptr;

Просмотреть файл

@ -31,6 +31,7 @@
#include "frontend/Parser.h" #include "frontend/Parser.h"
#include "frontend/TokenStream.h" #include "frontend/TokenStream.h"
#include "vm/Debugger.h" #include "vm/Debugger.h"
#include "vm/GeneratorObject.h"
#include "vm/Stack.h" #include "vm/Stack.h"
#include "jsatominlines.h" #include "jsatominlines.h"
@ -1989,10 +1990,10 @@ CheckSideEffects(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool
default: default:
/* /*
* All of PNK_INC, PNK_DEC, PNK_THROW, PNK_YIELD, and PNK_YIELD_STAR * All of PNK_INC, PNK_DEC and PNK_THROW have direct effects. Of
* have direct effects. Of the remaining unary-arity node types, we * the remaining unary-arity node types, we can't easily prove that
* can't easily prove that the operand never denotes an object with * the operand never denotes an object with a toString or valueOf
* a toString or valueOf method. * method.
*/ */
*answer = true; *answer = true;
return true; return true;
@ -2973,13 +2974,6 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
bce->switchToMain(); bce->switchToMain();
} }
if (funbox->isGenerator()) {
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_GENERATOR) < 0)
return false;
bce->switchToMain();
}
/* /*
* Emit a prologue for run-once scripts which will deoptimize JIT code if * Emit a prologue for run-once scripts which will deoptimize JIT code if
* the script ends up running multiple times via foo.caller related * the script ends up running multiple times via foo.caller related
@ -2996,18 +2990,27 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
if (!EmitTree(cx, bce, body)) if (!EmitTree(cx, bce, body))
return false; return false;
// If we fall off the end of an ES6 generator, return a boxed iterator // If we fall off the end of a generator, do a final yield.
// result object of the form { value: undefined, done: true }. if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isGenerator()) {
if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isStarGenerator()) { if (bce->sc->asFunctionBox()->isStarGenerator() && !EmitPrepareIteratorResult(cx, bce))
if (!EmitPrepareIteratorResult(cx, bce))
return false; return false;
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false; return false;
if (!EmitFinishIteratorResult(cx, bce, true))
if (bce->sc->asFunctionBox()->isStarGenerator() && !EmitFinishIteratorResult(cx, bce, true))
return false;
ScopeCoordinate sc;
// We know that .generator is on the top scope chain node, as we are
// at the function end.
sc.setHops(0);
MOZ_ALWAYS_TRUE(LookupAliasedNameSlot(bce, bce->script, cx->names().dotGenerator, &sc));
if (!EmitAliasedVarOp(cx, JSOP_GETALIASEDVAR, sc, DontCheckLexical, bce))
return false; return false;
// No need to check for finally blocks, etc as in EmitReturn. // No need to check for finally blocks, etc as in EmitReturn.
if (Emit1(cx, bce, JSOP_RETURN) < 0) if (Emit1(cx, bce, JSOP_FINALYIELD) < 0)
return false; return false;
} }
@ -5463,15 +5466,26 @@ EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
*/ */
ptrdiff_t top = bce->offset(); ptrdiff_t top = bce->offset();
if (Emit1(cx, bce, JSOP_RETURN) < 0) bool isGenerator = bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isGenerator();
return false; if (Emit1(cx, bce, isGenerator ? JSOP_SETRVAL : JSOP_RETURN) < 0)
return false;
NonLocalExitScope nle(cx, bce); NonLocalExitScope nle(cx, bce);
if (!nle.prepareForNonLocalJump(nullptr)) if (!nle.prepareForNonLocalJump(nullptr))
return false; return false;
if (top + static_cast<ptrdiff_t>(JSOP_RETURN_LENGTH) != bce->offset()) { if (isGenerator) {
ScopeCoordinate sc;
// We know that .generator is on the top scope chain node, as we just
// exited nested scopes.
sc.setHops(0);
MOZ_ALWAYS_TRUE(LookupAliasedNameSlot(bce, bce->script, cx->names().dotGenerator, &sc));
if (!EmitAliasedVarOp(cx, JSOP_GETALIASEDVAR, sc, DontCheckLexical, bce))
return false;
if (Emit1(cx, bce, JSOP_FINALYIELDRVAL) < 0)
return false;
} else if (top + static_cast<ptrdiff_t>(JSOP_RETURN_LENGTH) != bce->offset()) {
bce->code()[top] = JSOP_SETRVAL; bce->code()[top] = JSOP_SETRVAL;
if (Emit1(cx, bce, JSOP_RETRVAL) < 0) if (Emit1(cx, bce, JSOP_RETRVAL) < 0)
return false; return false;
@ -5481,7 +5495,41 @@ EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
} }
static bool static bool
EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter) EmitYield(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
MOZ_ASSERT(bce->sc->isFunctionBox());
if (pn->getOp() == JSOP_YIELD) {
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitPrepareIteratorResult(cx, bce))
return false;
}
if (pn->pn_left) {
if (!EmitTree(cx, bce, pn->pn_left))
return false;
} else {
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false;
}
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitFinishIteratorResult(cx, bce, false))
return false;
}
} else {
MOZ_ASSERT(pn->getOp() == JSOP_INITIALYIELD);
}
if (!EmitTree(cx, bce, pn->pn_right))
return false;
if (Emit1(cx, bce, pn->getOp()) < 0)
return false;
return true;
}
static bool
EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter, ParseNode *gen)
{ {
MOZ_ASSERT(bce->sc->isFunctionBox()); MOZ_ASSERT(bce->sc->isFunctionBox());
MOZ_ASSERT(bce->sc->asFunctionBox()->isStarGenerator()); MOZ_ASSERT(bce->sc->asFunctionBox()->isStarGenerator());
@ -5500,12 +5548,13 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
return false; return false;
CheckTypeSet(cx, bce, JSOP_CALL); CheckTypeSet(cx, bce, JSOP_CALL);
int depth = bce->stackDepth;
MOZ_ASSERT(depth >= 1);
// Initial send value is undefined. // Initial send value is undefined.
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) // ITER RECEIVED if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) // ITER RECEIVED
return false; return false;
int depth = bce->stackDepth;
MOZ_ASSERT(depth >= 2);
ptrdiff_t initialSend = -1; ptrdiff_t initialSend = -1;
if (EmitBackPatchOp(cx, bce, &initialSend) < 0) // goto initialSend if (EmitBackPatchOp(cx, bce, &initialSend) < 0) // goto initialSend
return false; return false;
@ -5514,17 +5563,21 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
StmtInfoBCE stmtInfo(cx); StmtInfoBCE stmtInfo(cx);
PushStatementBCE(bce, &stmtInfo, STMT_TRY, bce->offset()); PushStatementBCE(bce, &stmtInfo, STMT_TRY, bce->offset());
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_TRY); ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_TRY);
ptrdiff_t tryStart = bce->offset(); // tryStart:
if (noteIndex < 0 || Emit1(cx, bce, JSOP_TRY) < 0) if (noteIndex < 0 || Emit1(cx, bce, JSOP_TRY) < 0)
return false; return false;
ptrdiff_t tryStart = bce->offset(); // tryStart: MOZ_ASSERT(bce->stackDepth == depth);
MOZ_ASSERT(bce->stackDepth == depth + 1);
// Load the generator object.
if (!EmitTree(cx, bce, gen)) // ITER RESULT GENOBJ
return false;
// Yield RESULT as-is, without re-boxing. // Yield RESULT as-is, without re-boxing.
if (Emit1(cx, bce, JSOP_YIELD) < 0) // ITER RECEIVED if (Emit1(cx, bce, JSOP_YIELD) < 0) // ITER RECEIVED
return false; return false;
// Try epilogue. // Try epilogue.
if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, bce->offset() - tryStart + JSOP_TRY_LENGTH)) if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, bce->offset() - tryStart))
return false; return false;
ptrdiff_t subsequentSend = -1; ptrdiff_t subsequentSend = -1;
if (EmitBackPatchOp(cx, bce, &subsequentSend) < 0) // goto subsequentSend if (EmitBackPatchOp(cx, bce, &subsequentSend) < 0) // goto subsequentSend
@ -5532,8 +5585,10 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
ptrdiff_t tryEnd = bce->offset(); // tryEnd: ptrdiff_t tryEnd = bce->offset(); // tryEnd:
// Catch location. // Catch location.
// THROW? = 'throw' in ITER // ITER bce->stackDepth = uint32_t(depth); // ITER RESULT
bce->stackDepth = (uint32_t) depth; if (Emit1(cx, bce, JSOP_POP) < 0) // ITER
return false;
// THROW? = 'throw' in ITER
if (Emit1(cx, bce, JSOP_EXCEPTION) < 0) // ITER EXCEPTION if (Emit1(cx, bce, JSOP_EXCEPTION) < 0) // ITER EXCEPTION
return false; return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0) // EXCEPTION ITER if (Emit1(cx, bce, JSOP_SWAP) < 0) // EXCEPTION ITER
@ -5557,7 +5612,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
SetJumpOffsetAt(bce, checkThrow); // delegate: SetJumpOffsetAt(bce, checkThrow); // delegate:
// RESULT = ITER.throw(EXCEPTION) // EXCEPTION ITER // RESULT = ITER.throw(EXCEPTION) // EXCEPTION ITER
bce->stackDepth = (uint32_t) depth + 1; bce->stackDepth = uint32_t(depth);
if (Emit1(cx, bce, JSOP_DUP) < 0) // EXCEPTION ITER ITER if (Emit1(cx, bce, JSOP_DUP) < 0) // EXCEPTION ITER ITER
return false; return false;
if (Emit1(cx, bce, JSOP_DUP) < 0) // EXCEPTION ITER ITER ITER if (Emit1(cx, bce, JSOP_DUP) < 0) // EXCEPTION ITER ITER ITER
@ -5571,7 +5626,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
if (EmitCall(cx, bce, JSOP_CALL, 1, iter) < 0) // ITER RESULT if (EmitCall(cx, bce, JSOP_CALL, 1, iter) < 0) // ITER RESULT
return false; return false;
CheckTypeSet(cx, bce, JSOP_CALL); CheckTypeSet(cx, bce, JSOP_CALL);
MOZ_ASSERT(bce->stackDepth == depth + 1); MOZ_ASSERT(bce->stackDepth == depth);
ptrdiff_t checkResult = -1; ptrdiff_t checkResult = -1;
if (EmitBackPatchOp(cx, bce, &checkResult) < 0) // goto checkResult if (EmitBackPatchOp(cx, bce, &checkResult) < 0) // goto checkResult
return false; return false;
@ -5582,7 +5637,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
// This is a peace offering to ReconstructPCStack. See the note in EmitTry. // This is a peace offering to ReconstructPCStack. See the note in EmitTry.
if (Emit1(cx, bce, JSOP_NOP) < 0) if (Emit1(cx, bce, JSOP_NOP) < 0)
return false; return false;
if (!bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart, tryEnd)) if (!bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart + JSOP_TRY_LENGTH, tryEnd))
return false; return false;
// After the try/catch block: send the received value to the iterator. // After the try/catch block: send the received value to the iterator.
@ -5608,7 +5663,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
if (EmitCall(cx, bce, JSOP_CALL, 1, iter) < 0) // ITER RESULT if (EmitCall(cx, bce, JSOP_CALL, 1, iter) < 0) // ITER RESULT
return false; return false;
CheckTypeSet(cx, bce, JSOP_CALL); CheckTypeSet(cx, bce, JSOP_CALL);
MOZ_ASSERT(bce->stackDepth == depth + 1); MOZ_ASSERT(bce->stackDepth == depth);
if (!BackPatch(cx, bce, checkResult, bce->code().end(), JSOP_GOTO)) // checkResult: if (!BackPatch(cx, bce, checkResult, bce->code().end(), JSOP_GOTO)) // checkResult:
return false; return false;
@ -5629,7 +5684,7 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
if (!EmitAtomOp(cx, cx->names().value, JSOP_GETPROP, bce)) // VALUE if (!EmitAtomOp(cx, cx->names().value, JSOP_GETPROP, bce)) // VALUE
return false; return false;
MOZ_ASSERT(bce->stackDepth == depth); MOZ_ASSERT(bce->stackDepth == depth - 1);
return true; return true;
} }
@ -5807,6 +5862,80 @@ EmitDelete(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
static bool static bool
EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t count); EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, uint32_t count);
static bool
EmitSelfHostedCallFunction(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
// Special-casing of callFunction to emit bytecode that directly
// invokes the callee with the correct |this| object and arguments.
// callFunction(fun, thisArg, arg0, arg1) thus becomes:
// - emit lookup for fun
// - emit lookup for thisArg
// - emit lookups for arg0, arg1
//
// argc is set to the amount of actually emitted args and the
// emitting of args below is disabled by setting emitArgs to false.
if (pn->pn_count < 3) {
bce->reportError(pn, JSMSG_MORE_ARGS_NEEDED, "callFunction", "1", "s");
return false;
}
ParseNode *pn2 = pn->pn_head;
ParseNode *funNode = pn2->pn_next;
if (!EmitTree(cx, bce, funNode))
return false;
ParseNode *thisArg = funNode->pn_next;
if (!EmitTree(cx, bce, thisArg))
return false;
bool oldEmittingForInit = bce->emittingForInit;
bce->emittingForInit = false;
for (ParseNode *argpn = thisArg->pn_next; argpn; argpn = argpn->pn_next) {
if (!EmitTree(cx, bce, argpn))
return false;
}
bce->emittingForInit = oldEmittingForInit;
uint32_t argc = pn->pn_count - 3;
if (EmitCall(cx, bce, pn->getOp(), argc) < 0)
return false;
CheckTypeSet(cx, bce, pn->getOp());
return true;
}
static bool
EmitSelfHostedResumeGenerator(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
// Syntax: resumeGenerator(gen, value, 'next'|'throw'|'close')
if (pn->pn_count != 4) {
bce->reportError(pn, JSMSG_MORE_ARGS_NEEDED, "resumeGenerator", "1", "s");
return false;
}
ParseNode *funNode = pn->pn_head; // The resumeGenerator node.
ParseNode *genNode = funNode->pn_next;
if (!EmitTree(cx, bce, genNode))
return false;
ParseNode *valNode = genNode->pn_next;
if (!EmitTree(cx, bce, valNode))
return false;
ParseNode *kindNode = valNode->pn_next;
MOZ_ASSERT(kindNode->isKind(PNK_STRING));
uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->pn_atom);
MOZ_ASSERT(!kindNode->pn_next);
if (EmitCall(cx, bce, JSOP_RESUME, operand) < 0)
return false;
return true;
}
static bool static bool
EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn) EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{ {
@ -5835,46 +5964,21 @@ EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false; return false;
} }
bool emitArgs = true;
ParseNode *pn2 = pn->pn_head; ParseNode *pn2 = pn->pn_head;
bool spread = JOF_OPTYPE(pn->getOp()) == JOF_BYTE; bool spread = JOF_OPTYPE(pn->getOp()) == JOF_BYTE;
switch (pn2->getKind()) { switch (pn2->getKind()) {
case PNK_NAME: case PNK_NAME:
if (bce->emitterMode == BytecodeEmitter::SelfHosting && if (bce->emitterMode == BytecodeEmitter::SelfHosting && !spread) {
pn2->name() == cx->names().callFunction && // We shouldn't see foo(bar) = x in self-hosted code.
!spread) MOZ_ASSERT(!(pn->pn_xflags & PNX_SETCALL));
{
/* // Calls to "callFunction" or "resumeGenerator" in self-hosted code
* Special-casing of callFunction to emit bytecode that directly // generate inline bytecode.
* invokes the callee with the correct |this| object and arguments. if (pn2->name() == cx->names().callFunction)
* callFunction(fun, thisArg, arg0, arg1) thus becomes: return EmitSelfHostedCallFunction(cx, bce, pn);
* - emit lookup for fun if (pn2->name() == cx->names().resumeGenerator)
* - emit lookup for thisArg return EmitSelfHostedResumeGenerator(cx, bce, pn);
* - emit lookups for arg0, arg1 // Fall through.
*
* argc is set to the amount of actually emitted args and the
* emitting of args below is disabled by setting emitArgs to false.
*/
if (pn->pn_count < 3) {
bce->reportError(pn, JSMSG_MORE_ARGS_NEEDED, "callFunction", "1", "s");
return false;
}
ParseNode *funNode = pn2->pn_next;
if (!EmitTree(cx, bce, funNode))
return false;
ParseNode *thisArg = funNode->pn_next;
if (!EmitTree(cx, bce, thisArg))
return false;
bool oldEmittingForInit = bce->emittingForInit;
bce->emittingForInit = false;
for (ParseNode *argpn = thisArg->pn_next; argpn; argpn = argpn->pn_next) {
if (!EmitTree(cx, bce, argpn))
return false;
}
bce->emittingForInit = oldEmittingForInit;
argc -= 2;
emitArgs = false;
break;
} }
if (!EmitNameOp(cx, bce, pn2, callop)) if (!EmitNameOp(cx, bce, pn2, callop))
return false; return false;
@ -5922,25 +6026,23 @@ EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false; return false;
} }
if (emitArgs) { /*
/* * Emit code for each argument in order, then emit the JSOP_*CALL or
* Emit code for each argument in order, then emit the JSOP_*CALL or * JSOP_NEW bytecode with a two-byte immediate telling how many args
* JSOP_NEW bytecode with a two-byte immediate telling how many args * were pushed on the operand stack.
* were pushed on the operand stack. */
*/ bool oldEmittingForInit = bce->emittingForInit;
bool oldEmittingForInit = bce->emittingForInit; bce->emittingForInit = false;
bce->emittingForInit = false; if (!spread) {
if (!spread) { for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) { if (!EmitTree(cx, bce, pn3))
if (!EmitTree(cx, bce, pn3))
return false;
}
} else {
if (!EmitArray(cx, bce, pn2->pn_next, argc))
return false; return false;
} }
bce->emittingForInit = oldEmittingForInit; } else {
if (!EmitArray(cx, bce, pn2->pn_next, argc))
return false;
} }
bce->emittingForInit = oldEmittingForInit;
if (!spread) { if (!spread) {
if (EmitCall(cx, bce, pn->getOp(), argc, pn) < 0) if (EmitCall(cx, bce, pn->getOp(), argc, pn) < 0)
@ -6687,28 +6789,16 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break; break;
case PNK_YIELD_STAR: case PNK_YIELD_STAR:
ok = EmitYieldStar(cx, bce, pn->pn_kid); ok = EmitYieldStar(cx, bce, pn->pn_left, pn->pn_right);
break;
case PNK_GENERATOR:
if (Emit1(cx, bce, JSOP_GENERATOR) < 0)
return false;
break; break;
case PNK_YIELD: case PNK_YIELD:
MOZ_ASSERT(bce->sc->isFunctionBox()); ok = EmitYield(cx, bce, pn);
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitPrepareIteratorResult(cx, bce))
return false;
}
if (pn->pn_kid) {
if (!EmitTree(cx, bce, pn->pn_kid))
return false;
} else {
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
return false;
}
if (bce->sc->asFunctionBox()->isStarGenerator()) {
if (!EmitFinishIteratorResult(cx, bce, false))
return false;
}
if (Emit1(cx, bce, JSOP_YIELD) < 0)
return false;
break; break;
case PNK_STATEMENTLIST: case PNK_STATEMENTLIST:

Просмотреть файл

@ -323,6 +323,17 @@ class FullParseHandler
return true; return true;
} }
ParseNode *newYieldExpression(uint32_t begin, ParseNode *value, ParseNode *gen,
JSOp op = JSOP_YIELD) {
TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
return new_<BinaryNode>(PNK_YIELD, op, pos, value, gen);
}
ParseNode *newYieldStarExpression(uint32_t begin, ParseNode *value, ParseNode *gen) {
TokenPos pos(begin, value->pn_pos.end);
return new_<BinaryNode>(PNK_YIELD_STAR, JSOP_NOP, pos, value, gen);
}
// Statements // Statements
ParseNode *newStatementList(unsigned blockid, const TokenPos &pos) { ParseNode *newStatementList(unsigned blockid, const TokenPos &pos) {
@ -352,6 +363,31 @@ class FullParseHandler
list->append(stmt); list->append(stmt);
} }
bool prependInitialYield(ParseNode *stmtList, ParseNode *genName) {
MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST));
TokenPos yieldPos(stmtList->pn_pos.begin, stmtList->pn_pos.begin + 1);
ParseNode *makeGen = new_<NullaryNode>(PNK_GENERATOR, yieldPos);
if (!makeGen)
return false;
MOZ_ASSERT(genName->getOp() == JSOP_NAME);
genName->setOp(JSOP_SETNAME);
genName->markAsAssigned();
ParseNode *genInit = newBinary(PNK_ASSIGN, genName, makeGen);
ParseNode *initialYield = newYieldExpression(yieldPos.begin, nullptr, genInit,
JSOP_INITIALYIELD);
if (!initialYield)
return false;
initialYield->pn_next = stmtList->pn_head;
stmtList->pn_head = initialYield;
stmtList->pn_count++;
return true;
}
ParseNode *newEmptyStatement(const TokenPos &pos) { ParseNode *newEmptyStatement(const TokenPos &pos) {
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode *) nullptr); return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode *) nullptr);
} }

Просмотреть файл

@ -124,6 +124,7 @@ class UpvarCookie
F(FINALLY) \ F(FINALLY) \
F(THROW) \ F(THROW) \
F(DEBUGGER) \ F(DEBUGGER) \
F(GENERATOR) \
F(YIELD) \ F(YIELD) \
F(YIELD_STAR) \ F(YIELD_STAR) \
F(GENEXP) \ F(GENEXP) \
@ -422,6 +423,9 @@ enum ParseNodeKind
* *
* PNK_LEXICALSCOPE name pn_objbox: block object in ObjectBox holder * PNK_LEXICALSCOPE name pn_objbox: block object in ObjectBox holder
* pn_expr: block body * pn_expr: block body
* PNK_GENERATOR nullary
* PNK_YIELD, binary pn_left: expr or null; pn_right: generator object
* PNK_YIELD_STAR
* PNK_ARRAYCOMP list pn_count: 1 * PNK_ARRAYCOMP list pn_count: 1
* pn_head: list of 1 element, which is block * pn_head: list of 1 element, which is block
* enclosing for loop(s) and optionally * enclosing for loop(s) and optionally
@ -773,8 +777,9 @@ class ParseNode
MOZ_ASSERT(isKind(PNK_GENEXP)); MOZ_ASSERT(isKind(PNK_GENEXP));
ParseNode *callee = this->pn_head; ParseNode *callee = this->pn_head;
ParseNode *body = callee->pn_body; ParseNode *body = callee->pn_body;
MOZ_ASSERT(body->isKind(PNK_LEXICALSCOPE) || body->isKind(PNK_FOR)); MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST));
return body; MOZ_ASSERT(body->last()->isKind(PNK_LEXICALSCOPE) || body->last()->isKind(PNK_FOR));
return body->last();
} }
#endif #endif

Просмотреть файл

@ -1035,6 +1035,23 @@ Parser<ParseHandler>::functionBody(FunctionSyntaxKind kind, FunctionBodyType typ
break; break;
} }
if (pc->isGenerator()) {
MOZ_ASSERT(type == StatementListBody);
Node generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!pc->define(tokenStream, context->names().dotGenerator, generator, Definition::VAR))
return null();
generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!noteNameUse(context->names().dotGenerator, generator))
return null();
if (!handler.prependInitialYield(pn, generator))
return null();
}
/* Define the 'arguments' binding if necessary. */ /* Define the 'arguments' binding if necessary. */
if (!checkFunctionArguments()) if (!checkFunctionArguments())
return null(); return null();
@ -5007,6 +5024,21 @@ Parser<ParseHandler>::returnStatement()
return pn; return pn;
} }
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::newYieldExpression(uint32_t begin, typename ParseHandler::Node expr,
bool isYieldStar)
{
Node generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!noteNameUse(context->names().dotGenerator, generator))
return null();
if (isYieldStar)
return handler.newYieldStarExpression(begin, expr, generator);
return handler.newYieldExpression(begin, expr, generator);
}
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::Node
Parser<ParseHandler>::yieldExpression() Parser<ParseHandler>::yieldExpression()
@ -5052,7 +5084,7 @@ Parser<ParseHandler>::yieldExpression()
if (!exprNode) if (!exprNode)
return null(); return null();
} }
return handler.newUnary(kind, JSOP_NOP, begin, exprNode); return newYieldExpression(begin, exprNode, kind == PNK_YIELD_STAR);
} }
case NotGenerator: case NotGenerator:
@ -5110,7 +5142,7 @@ Parser<ParseHandler>::yieldExpression()
return null(); return null();
} }
return handler.newUnary(PNK_YIELD, JSOP_NOP, begin, exprNode); return newYieldExpression(begin, exprNode);
} }
} }
@ -6189,9 +6221,17 @@ LegacyCompExprTransplanter::transplant(ParseNode *pn)
MOZ_ASSERT(!stmt || stmt != pc->topStmt); MOZ_ASSERT(!stmt || stmt != pc->topStmt);
#endif #endif
if (isGenexp && !dn->isOp(JSOP_CALLEE)) { if (isGenexp && !dn->isOp(JSOP_CALLEE)) {
MOZ_ASSERT(!pc->decls().lookupFirst(atom)); MOZ_ASSERT_IF(atom != parser->context->names().dotGenerator,
!pc->decls().lookupFirst(atom));
if (dn->pn_pos < root->pn_pos) { if (atom == parser->context->names().dotGenerator) {
if (dn->dn_uses == pn) {
if (!BumpStaticLevel(parser->tokenStream, dn, pc))
return false;
if (!AdjustBlockId(parser->tokenStream, dn, adjust, pc))
return false;
}
} else if (dn->pn_pos < root->pn_pos) {
/* /*
* The variable originally appeared to be a use of a * The variable originally appeared to be a use of a
* definition or placeholder outside the generator, but now * definition or placeholder outside the generator, but now
@ -6304,7 +6344,7 @@ LegacyComprehensionHeadBlockScopeDepth(ParseContext<ParseHandler> *pc)
*/ */
template <> template <>
ParseNode * ParseNode *
Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyStmt, unsigned blockid, Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyExpr, unsigned blockid,
GeneratorKind comprehensionKind, GeneratorKind comprehensionKind,
ParseContext<FullParseHandler> *outerpc, ParseContext<FullParseHandler> *outerpc,
unsigned innerBlockScopeDepth) unsigned innerBlockScopeDepth)
@ -6368,15 +6408,15 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyStmt, unsigned
adjust = blockid - adjust; adjust = blockid - adjust;
} }
handler.setBeginPosition(pn, bodyStmt); handler.setBeginPosition(pn, bodyExpr);
pnp = &pn->pn_expr; pnp = &pn->pn_expr;
LegacyCompExprTransplanter transplanter(bodyStmt, this, outerpc, comprehensionKind, adjust); LegacyCompExprTransplanter transplanter(bodyExpr, this, outerpc, comprehensionKind, adjust);
if (!transplanter.init()) if (!transplanter.init())
return null(); return null();
if (!transplanter.transplant(bodyStmt)) if (!transplanter.transplant(bodyExpr))
return null(); return null();
MOZ_ASSERT(pc->staticScope && pc->staticScope == pn->pn_objbox->object); MOZ_ASSERT(pc->staticScope && pc->staticScope == pn->pn_objbox->object);
@ -6532,6 +6572,23 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyStmt, unsigned
pnp = &pn2->pn_kid2; pnp = &pn2->pn_kid2;
} }
ParseNode *bodyStmt;
if (isGenexp) {
ParseNode *yieldExpr = newYieldExpression(bodyExpr->pn_pos.begin, bodyExpr);
if (!yieldExpr)
return null();
yieldExpr->setInParens(true);
bodyStmt = handler.newExprStatement(yieldExpr, bodyExpr->pn_pos.end);
if (!bodyStmt)
return null();
} else {
bodyStmt = handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH,
bodyExpr->pn_pos.begin, bodyExpr);
if (!bodyStmt)
return null();
}
*pnp = bodyStmt; *pnp = bodyStmt;
pc->topStmt->innerBlockScopeDepth += innerBlockScopeDepth; pc->topStmt->innerBlockScopeDepth += innerBlockScopeDepth;
@ -6568,12 +6625,7 @@ Parser<FullParseHandler>::legacyArrayComprehension(ParseNode *array)
array->pn_tail = &array->pn_head; array->pn_tail = &array->pn_head;
*array->pn_tail = nullptr; *array->pn_tail = nullptr;
ParseNode *arrayPush = handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH, ParseNode *comp = legacyComprehensionTail(bodyExpr, array->pn_blockid, NotGenerator,
bodyExpr->pn_pos.begin, bodyExpr);
if (!arrayPush)
return null();
ParseNode *comp = legacyComprehensionTail(arrayPush, array->pn_blockid, NotGenerator,
nullptr, LegacyComprehensionHeadBlockScopeDepth(pc)); nullptr, LegacyComprehensionHeadBlockScopeDepth(pc));
if (!comp) if (!comp)
return null(); return null();
@ -6596,10 +6648,10 @@ Parser<SyntaxParseHandler>::legacyArrayComprehension(Node array)
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::Node
Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKind, Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKind,
unsigned begin, Node innerStmt) unsigned begin, Node innerExpr)
{ {
MOZ_ASSERT(comprehensionKind == LegacyGenerator || comprehensionKind == StarGenerator); MOZ_ASSERT(comprehensionKind == LegacyGenerator || comprehensionKind == StarGenerator);
MOZ_ASSERT(!!innerStmt == (comprehensionKind == LegacyGenerator)); MOZ_ASSERT(!!innerExpr == (comprehensionKind == LegacyGenerator));
Node genfn = handler.newFunctionDefinition(); Node genfn = handler.newFunctionDefinition();
if (!genfn) if (!genfn)
@ -6650,29 +6702,47 @@ Parser<ParseHandler>::generatorComprehensionLambda(GeneratorKind comprehensionKi
genFunbox->inGenexpLambda = true; genFunbox->inGenexpLambda = true;
handler.setBlockId(genfn, genpc.bodyid); handler.setBlockId(genfn, genpc.bodyid);
Node body; Node generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!pc->define(tokenStream, context->names().dotGenerator, generator, Definition::VAR))
return null();
Node body = handler.newStatementList(pc->blockid(), TokenPos(begin, pos().end));
if (!body)
return null();
Node comp;
if (comprehensionKind == StarGenerator) { if (comprehensionKind == StarGenerator) {
body = comprehension(StarGenerator); comp = comprehension(StarGenerator);
if (!body) if (!comp)
return null(); return null();
} else { } else {
MOZ_ASSERT(comprehensionKind == LegacyGenerator); MOZ_ASSERT(comprehensionKind == LegacyGenerator);
body = legacyComprehensionTail(innerStmt, outerpc->blockid(), LegacyGenerator, comp = legacyComprehensionTail(innerExpr, outerpc->blockid(), LegacyGenerator,
outerpc, LegacyComprehensionHeadBlockScopeDepth(outerpc)); outerpc, LegacyComprehensionHeadBlockScopeDepth(outerpc));
if (!body) if (!comp)
return null(); return null();
} }
if (comprehensionKind == StarGenerator) if (comprehensionKind == StarGenerator)
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN); MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
handler.setBeginPosition(body, begin); handler.setBeginPosition(comp, begin);
handler.setEndPosition(comp, pos().end);
handler.addStatementToList(body, comp, pc);
handler.setEndPosition(body, pos().end); handler.setEndPosition(body, pos().end);
handler.setBeginPosition(genfn, begin); handler.setBeginPosition(genfn, begin);
handler.setEndPosition(genfn, pos().end); handler.setEndPosition(genfn, pos().end);
generator = newName(context->names().dotGenerator);
if (!generator)
return null();
if (!noteNameUse(context->names().dotGenerator, generator))
return null();
if (!handler.prependInitialYield(body, generator))
return null();
// Note that if we ever start syntax-parsing generators, we will also // Note that if we ever start syntax-parsing generators, we will also
// need to propagate the closed-over variable set to the inner // need to propagate the closed-over variable set to the inner
// lazyscript, as in finishFunctionDefinition. // lazyscript, as in finishFunctionDefinition.
@ -6709,19 +6779,8 @@ Parser<FullParseHandler>::legacyGeneratorExpr(ParseNode *expr)
{ {
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FOR)); MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FOR));
/* Create a |yield| node for |kid|. */
ParseNode *yieldExpr = handler.newUnary(PNK_YIELD, JSOP_NOP, expr->pn_pos.begin, expr);
if (!yieldExpr)
return null();
yieldExpr->setInParens(true);
// A statement to wrap the yield expression.
ParseNode *yieldStmt = handler.newExprStatement(yieldExpr, expr->pn_pos.end);
if (!yieldStmt)
return null();
/* Make a new node for the desugared generator function. */ /* Make a new node for the desugared generator function. */
ParseNode *genfn = generatorComprehensionLambda(LegacyGenerator, expr->pn_pos.begin, yieldStmt); ParseNode *genfn = generatorComprehensionLambda(LegacyGenerator, expr->pn_pos.begin, expr);
if (!genfn) if (!genfn)
return null(); return null();
@ -6871,7 +6930,7 @@ Parser<ParseHandler>::comprehensionTail(GeneratorKind comprehensionKind)
return handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH, begin, bodyExpr); return handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH, begin, bodyExpr);
MOZ_ASSERT(comprehensionKind == StarGenerator); MOZ_ASSERT(comprehensionKind == StarGenerator);
Node yieldExpr = handler.newUnary(PNK_YIELD, JSOP_NOP, begin, bodyExpr); Node yieldExpr = newYieldExpression(begin, bodyExpr);
if (!yieldExpr) if (!yieldExpr)
return null(); return null();
handler.setInParens(yieldExpr); handler.setInParens(yieldExpr);

Просмотреть файл

@ -464,6 +464,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
bool addExprAndGetNextTemplStrToken(Node nodeList, TokenKind &tt); bool addExprAndGetNextTemplStrToken(Node nodeList, TokenKind &tt);
inline Node newName(PropertyName *name); inline Node newName(PropertyName *name);
inline Node newYieldExpression(uint32_t begin, Node expr, bool isYieldStar = false);
inline bool abortIfSyntaxParser(); inline bool abortIfSyntaxParser();

Просмотреть файл

@ -135,11 +135,14 @@ class SyntaxParseHandler
bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; } bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
bool addPropertyDefinition(Node literal, Node name, Node expr, bool isShorthand = false) { return true; } bool addPropertyDefinition(Node literal, Node name, Node expr, bool isShorthand = false) { return true; }
bool addMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; } bool addMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
Node newYieldExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
Node newYieldStarExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
// Statements // Statements
Node newStatementList(unsigned blockid, const TokenPos &pos) { return NodeGeneric; } Node newStatementList(unsigned blockid, const TokenPos &pos) { return NodeGeneric; }
void addStatementToList(Node list, Node stmt, ParseContext<SyntaxParseHandler> *pc) {} void addStatementToList(Node list, Node stmt, ParseContext<SyntaxParseHandler> *pc) {}
bool prependInitialYield(Node stmtList, Node gen) { return true; }
Node newEmptyStatement(const TokenPos &pos) { return NodeGeneric; } Node newEmptyStatement(const TokenPos &pos) { return NodeGeneric; }
Node newExprStatement(Node expr, uint32_t end) { Node newExprStatement(Node expr, uint32_t end) {

Просмотреть файл

@ -25,7 +25,7 @@
* - writes to object properties * - writes to object properties
* - writes to array slots * - writes to array slots
* - writes to fields like JSObject::shape_ that we trace through * - writes to fields like JSObject::shape_ that we trace through
* - writes to fields in private data, like JSGenerator::obj * - writes to fields in private data
* - writes to non-markable fields like JSObject::private that point to * - writes to non-markable fields like JSObject::private that point to
* markable data * markable data
* The last category is the trickiest. Even though the private pointers does not * The last category is the trickiest. Even though the private pointers does not

Просмотреть файл

@ -1,5 +1,6 @@
// |jit-test| error: StopIteration
// Returning {throw:} from an onPop handler when yielding works and // Returning {throw:} from an onPop handler when yielding works and
// does not close the generator-iterator. // does closes the generator-iterator.
load(libdir + "asserts.js"); load(libdir + "asserts.js");
@ -17,4 +18,4 @@ var rv = gw.evalInGlobal("it.next();");
assertEq(rv.throw, "fit"); assertEq(rv.throw, "fit");
dbg.enabled = false; dbg.enabled = false;
assertEq(g.it.next(), 1); g.it.next();

Просмотреть файл

@ -1,5 +1,5 @@
// Returning {throw:} from an onPop handler when yielding works and // Returning {throw:} from an onPop handler when yielding works and
// does not close the generator-iterator. // closes the generator-iterator.
load(libdir + "iteration.js"); load(libdir + "iteration.js");
@ -17,4 +17,4 @@ var rv = gw.evalInGlobal("it.next();");
assertEq(rv.throw, "fit"); assertEq(rv.throw, "fit");
dbg.enabled = false; dbg.enabled = false;
assertIteratorNext(g.it, 1); assertIteratorDone(g.it);

Просмотреть файл

@ -1,3 +1,4 @@
// |jit-test| error: already executing generator
// Forced return from a generator frame. // Forced return from a generator frame.
var g = newGlobal(); var g = newGlobal();
@ -10,5 +11,9 @@ function gen() {
debugger; // Force return here. The value is ignored. debugger; // Force return here. The value is ignored.
yield '2'; yield '2';
} }
var x = [v for (v in gen())];
assertEq(x.join(","), "1"); var iter = gen();
assertEq(iter.next(), "1");
assertEq(iter.next(), "!");
iter.next();
assertEq(0, 1);

Просмотреть файл

@ -1,3 +1,4 @@
// |jit-test| error: already executing generator
// Forced return from a star generator frame. // Forced return from a star generator frame.
load(libdir + 'asserts.js') load(libdir + 'asserts.js')
@ -16,4 +17,5 @@ function* gen() {
var iter = gen(); var iter = gen();
assertIteratorNext(iter, '1'); assertIteratorNext(iter, '1');
assertEq(iter.next(), '!'); assertEq(iter.next(), '!');
assertIteratorDone(iter); iter.next();
assertEq(0, 1);

Просмотреть файл

@ -0,0 +1,49 @@
// When a generator function throws, the generator is closed.
load(libdir + "asserts.js");
load(libdir + "iteration.js");
// Star generator, next() throws.
function *g() {
yield 1;
yield 2;
throw 3;
yield 4;
}
var i = g();
assertIteratorNext(i, 1);
assertIteratorNext(i, 2);
assertThrowsValue(() => i.next(), 3);
assertIteratorDone(i);
assertIteratorDone(i);
// Star generator, throw() throws.
function *h() {
yield 1;
yield 2;
}
var i = h();
assertIteratorNext(i, 1);
assertThrowsValue(() => i.throw(4), 4);
assertIteratorDone(i);
// Legacy generator, throw() throws.
function l1() {
yield 1;
yield 2;
}
var i = l1();
assertEq(i.next(), 1);
assertThrowsValue(() => i.throw(5), 5);
assertThrowsInstanceOf(() => i.next(), StopIteration);
// Legacy generator, next() throws.
function l2() {
yield 1;
throw 6;
yield 2;
}
var i = l2();
assertEq(i.next(), 1);
assertThrowsValue(() => i.next(), 6);
assertThrowsInstanceOf(() => i.next(), StopIteration);

Просмотреть файл

@ -0,0 +1,34 @@
// Generator methods work transparently on CrossCompartmentWrappers.
load(libdir + "asserts.js");
load(libdir + "iteration.js");
function gen() { yield 1; yield 2; }
var it = gen();
var g = newGlobal();
g.eval("function gen2() { yield 3; yield 4; }; var it2 = gen2();");
// LegacyGenerator.next
assertEq(it.next.call(g.it2), 3);
// LegacyGenerator.throw
assertThrowsValue(() => it.throw.call(g.it2, 7), 7);
function *gen3() { yield 1; yield 2; }
it = gen3();
g.eval("function *gen4() { yield 5; yield 6; }; var it4 = gen4();");
// StarGenerator.next
assertIteratorResult(it.next.call(g.it4), 5, false)
// StarGenerator.throw
assertThrowsValue(() => it.throw.call(g.it4, 8), 8);
// Other objects should throw.
try {
it.next.call([]);
assertEq(0, 1);
} catch (e) {
assertEq(e.toString().contains("called on incompatible Array"), true);
}

Просмотреть файл

@ -10,6 +10,7 @@ const { value: frame } = (function iife1() {
assertEq(frame.functionDisplayName, "iife2"); assertEq(frame.functionDisplayName, "iife2");
assertEq(frame.parent.functionDisplayName, "generator"); assertEq(frame.parent.functionDisplayName, "generator");
assertEq(frame.parent.parent.functionDisplayName, "iife1"); assertEq(frame.parent.parent.functionDisplayName, "next");
assertEq(frame.parent.parent.parent.functionDisplayName, null); assertEq(frame.parent.parent.parent.functionDisplayName, "iife1");
assertEq(frame.parent.parent.parent.parent, null); assertEq(frame.parent.parent.parent.parent.functionDisplayName, null);
assertEq(frame.parent.parent.parent.parent.parent, null);

Просмотреть файл

@ -49,7 +49,9 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
MOZ_ASSERT(IsBaselineEnabled(cx)); MOZ_ASSERT(IsBaselineEnabled(cx));
*bailoutInfo = nullptr; *bailoutInfo = nullptr;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, false, bailoutInfo); bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, false, bailoutInfo,
/* excInfo = */ nullptr, &poppedLastSPSFrame);
MOZ_ASSERT(retval == BAILOUT_RETURN_OK || MOZ_ASSERT(retval == BAILOUT_RETURN_OK ||
retval == BAILOUT_RETURN_FATAL_ERROR || retval == BAILOUT_RETURN_FATAL_ERROR ||
retval == BAILOUT_RETURN_OVERRECURSED); retval == BAILOUT_RETURN_OVERRECURSED);
@ -68,7 +70,8 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
// pseudostack frame would not have been pushed in the first // pseudostack frame would not have been pushed in the first
// place, so don't pop anything in that case. // place, so don't pop anything in that case.
bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() && bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() &&
(SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck); (SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck) &&
!poppedLastSPSFrame;
JSScript *script = iter.script(); JSScript *script = iter.script();
probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame); probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame);
@ -105,7 +108,9 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
MOZ_ASSERT(IsBaselineEnabled(cx)); MOZ_ASSERT(IsBaselineEnabled(cx));
*bailoutInfo = nullptr; *bailoutInfo = nullptr;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, bailoutInfo); bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, bailoutInfo,
/* excInfo = */ nullptr, &poppedLastSPSFrame);
MOZ_ASSERT(retval == BAILOUT_RETURN_OK || MOZ_ASSERT(retval == BAILOUT_RETURN_OK ||
retval == BAILOUT_RETURN_FATAL_ERROR || retval == BAILOUT_RETURN_FATAL_ERROR ||
retval == BAILOUT_RETURN_OVERRECURSED); retval == BAILOUT_RETURN_OVERRECURSED);
@ -124,7 +129,8 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut,
// pseudostack frame would not have been pushed in the first // pseudostack frame would not have been pushed in the first
// place, so don't pop anything in that case. // place, so don't pop anything in that case.
bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() && bool popSPSFrame = iter.ionScript()->hasSPSInstrumentation() &&
(SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck); (SnapshotIterator(iter).bailoutKind() != Bailout_ArgumentCheck) &&
!poppedLastSPSFrame;
JSScript *script = iter.script(); JSScript *script = iter.script();
probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame); probes::ExitScript(cx, script, script->functionNonDelazifying(), popSPSFrame);
@ -180,7 +186,9 @@ jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
JitFrameIterator iter(jitActivations); JitFrameIterator iter(jitActivations);
BaselineBailoutInfo *bailoutInfo = nullptr; BaselineBailoutInfo *bailoutInfo = nullptr;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, &bailoutInfo, &excInfo); bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true,
&bailoutInfo, &excInfo, &poppedLastSPSFrame);
if (retval == BAILOUT_RETURN_OK) { if (retval == BAILOUT_RETURN_OK) {
MOZ_ASSERT(bailoutInfo); MOZ_ASSERT(bailoutInfo);

Просмотреть файл

@ -515,9 +515,12 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
HandleFunction fun, HandleScript script, IonScript *ionScript, HandleFunction fun, HandleScript script, IonScript *ionScript,
SnapshotIterator &iter, bool invalidate, BaselineStackBuilder &builder, SnapshotIterator &iter, bool invalidate, BaselineStackBuilder &builder,
AutoValueVector &startFrameFormals, MutableHandleFunction nextCallee, AutoValueVector &startFrameFormals, MutableHandleFunction nextCallee,
jsbytecode **callPC, const ExceptionBailoutInfo *excInfo) jsbytecode **callPC, const ExceptionBailoutInfo *excInfo,
bool *poppedLastSPSFrameOut)
{ {
MOZ_ASSERT(script->hasBaselineScript()); MOZ_ASSERT(script->hasBaselineScript());
MOZ_ASSERT(poppedLastSPSFrameOut);
MOZ_ASSERT(!*poppedLastSPSFrameOut);
// Are we catching an exception? // Are we catching an exception?
bool catchingException = excInfo && excInfo->catchingException(); bool catchingException = excInfo && excInfo->catchingException();
@ -1035,6 +1038,11 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
JitSpew(JitSpew_BaselineBailouts, JitSpew(JitSpew_BaselineBailouts,
" Popping SPS entry for outermost frame"); " Popping SPS entry for outermost frame");
cx->runtime()->spsProfiler.exit(script, fun); cx->runtime()->spsProfiler.exit(script, fun);
// Notify caller that the last SPS frame was popped, so not
// to do it again.
if (poppedLastSPSFrameOut)
*poppedLastSPSFrameOut = true;
} }
} }
} else { } else {
@ -1291,7 +1299,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
uint32_t uint32_t
jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter, jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter,
bool invalidate, BaselineBailoutInfo **bailoutInfo, bool invalidate, BaselineBailoutInfo **bailoutInfo,
const ExceptionBailoutInfo *excInfo) const ExceptionBailoutInfo *excInfo, bool *poppedLastSPSFrameOut)
{ {
// The Baseline frames we will reconstruct on the heap are not rooted, so GC // The Baseline frames we will reconstruct on the heap are not rooted, so GC
// must be suppressed here. // must be suppressed here.
@ -1300,6 +1308,9 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter
MOZ_ASSERT(bailoutInfo != nullptr); MOZ_ASSERT(bailoutInfo != nullptr);
MOZ_ASSERT(*bailoutInfo == nullptr); MOZ_ASSERT(*bailoutInfo == nullptr);
MOZ_ASSERT(poppedLastSPSFrameOut);
MOZ_ASSERT(!*poppedLastSPSFrameOut);
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime()); TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
TraceLogStopEvent(logger, TraceLogger::IonMonkey); TraceLogStopEvent(logger, TraceLogger::IonMonkey);
TraceLogStartEvent(logger, TraceLogger::Baseline); TraceLogStartEvent(logger, TraceLogger::Baseline);
@ -1429,7 +1440,8 @@ jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIter
RootedFunction nextCallee(cx, nullptr); RootedFunction nextCallee(cx, nullptr);
if (!InitFromBailout(cx, caller, callerPC, fun, scr, iter.ionScript(), if (!InitFromBailout(cx, caller, callerPC, fun, scr, iter.ionScript(),
snapIter, invalidate, builder, startFrameFormals, snapIter, invalidate, builder, startFrameFormals,
&nextCallee, &callPC, passExcInfo ? excInfo : nullptr)) &nextCallee, &callPC, passExcInfo ? excInfo : nullptr,
poppedLastSPSFrameOut))
{ {
return BAILOUT_RETURN_FATAL_ERROR; return BAILOUT_RETURN_FATAL_ERROR;
} }

Просмотреть файл

@ -323,16 +323,13 @@ jit::CanEnterBaselineMethod(JSContext *cx, RunState &state)
if (!state.maybeCreateThisForConstructor(cx)) if (!state.maybeCreateThisForConstructor(cx))
return Method_Skipped; return Method_Skipped;
} else if (state.isExecute()) { } else {
MOZ_ASSERT(state.isExecute());
ExecuteType type = state.asExecute()->type(); ExecuteType type = state.asExecute()->type();
if (type == EXECUTE_DEBUG || type == EXECUTE_DEBUG_GLOBAL) { if (type == EXECUTE_DEBUG || type == EXECUTE_DEBUG_GLOBAL) {
JitSpew(JitSpew_BaselineAbort, "debugger frame"); JitSpew(JitSpew_BaselineAbort, "debugger frame");
return Method_CantCompile; return Method_CantCompile;
} }
} else {
MOZ_ASSERT(state.isGenerator());
JitSpew(JitSpew_BaselineAbort, "generator frame");
return Method_CantCompile;
} }
RootedScript script(cx, state.script()); RootedScript script(cx, state.script());

Просмотреть файл

@ -439,7 +439,8 @@ struct BaselineBailoutInfo
uint32_t uint32_t
BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter, BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter,
bool invalidate, BaselineBailoutInfo **bailoutInfo, bool invalidate, BaselineBailoutInfo **bailoutInfo,
const ExceptionBailoutInfo *exceptionInfo = nullptr); const ExceptionBailoutInfo *exceptionInfo,
bool *poppedLastSPSFrame);
// Mark baseline scripts on the stack as active, so that they are not discarded // Mark baseline scripts on the stack as active, so that they are not discarded
// during GC. // during GC.

Просмотреть файл

@ -2401,10 +2401,6 @@ jit::CanEnter(JSContext *cx, RunState &state)
if (!state.maybeCreateThisForConstructor(cx)) if (!state.maybeCreateThisForConstructor(cx))
return Method_Skipped; return Method_Skipped;
} else if (state.isGenerator()) {
JitSpew(JitSpew_IonAbort, "generator frame");
ForbidCompilation(cx, script);
return Method_CantCompile;
} }
// If --ion-eager is used, compile with Baseline first, so that we // If --ion-eager is used, compile with Baseline first, so that we

Просмотреть файл

@ -2781,7 +2781,8 @@ JS_AlreadyHasOwnUCProperty(JSContext *cx, HandleObject obj, const char16_t *name
return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp); return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
} }
/* Wrapper functions to create wrappers with no corresponding JSJitInfo from API /*
* Wrapper functions to create wrappers with no corresponding JSJitInfo from API
* function arguments. * function arguments.
*/ */
static JSPropertyOpWrapper static JSPropertyOpWrapper
@ -2825,8 +2826,6 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
JSFunction::Flags zeroFlags = JSAPIToJSFunctionFlags(0); JSFunction::Flags zeroFlags = JSAPIToJSFunctionFlags(0);
// We can't just use JS_NewFunctionById here because it assumes a
// string id.
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr); RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr);
attrs &= ~JSPROP_NATIVE_ACCESSORS; attrs &= ~JSPROP_NATIVE_ACCESSORS;
if (getter) { if (getter) {
@ -2863,12 +2862,12 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
AssertHeapIsIdle(cx); AssertHeapIsIdle(cx);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id, value, assertSameCompartment(cx, obj, id, value,
(attrs & JSPROP_GETTER) (attrs & JSPROP_GETTER)
? JS_FUNC_TO_DATA_PTR(JSObject *, getter) ? JS_FUNC_TO_DATA_PTR(JSObject *, getter)
: nullptr, : nullptr,
(attrs & JSPROP_SETTER) (attrs & JSPROP_SETTER)
? JS_FUNC_TO_DATA_PTR(JSObject *, setter) ? JS_FUNC_TO_DATA_PTR(JSObject *, setter)
: nullptr); : nullptr);
return JSObject::defineGeneric(cx, obj, id, value, getter, setter, attrs); return JSObject::defineGeneric(cx, obj, id, value, getter, setter, attrs);
} }
@ -3012,30 +3011,22 @@ DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleValue va
return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags); return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags);
} }
static bool static bool
DefineSelfHostedProperty(JSContext *cx, DefineSelfHostedProperty(JSContext *cx, HandleObject obj, HandleId id,
HandleObject obj, const char *getterName, const char *setterName,
const char *name, unsigned attrs, unsigned flags)
const char *getterName,
const char *setterName,
unsigned attrs,
unsigned flags)
{ {
RootedAtom nameAtom(cx, Atomize(cx, name, strlen(name)));
if (!nameAtom)
return false;
RootedAtom getterNameAtom(cx, Atomize(cx, getterName, strlen(getterName))); RootedAtom getterNameAtom(cx, Atomize(cx, getterName, strlen(getterName)));
if (!getterNameAtom) if (!getterNameAtom)
return false; return false;
RootedValue getterValue(cx); RootedAtom name(cx, IdToFunctionName(cx, id));
if (!cx->global()->getSelfHostedFunction(cx, getterNameAtom, nameAtom, if (!name)
0, &getterValue)) return false;
{
RootedValue getterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, getterNameAtom, name, 0, &getterValue))
return false; return false;
}
MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>()); MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>()); RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
JSPropertyOp getterOp = JS_DATA_TO_FUNC_PTR(PropertyOp, getterFunc.get()); JSPropertyOp getterOp = JS_DATA_TO_FUNC_PTR(PropertyOp, getterFunc.get());
@ -3047,19 +3038,16 @@ DefineSelfHostedProperty(JSContext *cx,
return false; return false;
RootedValue setterValue(cx); RootedValue setterValue(cx);
if (!cx->global()->getSelfHostedFunction(cx, setterNameAtom, nameAtom, if (!cx->global()->getSelfHostedFunction(cx, setterNameAtom, name, 0, &setterValue))
0, &setterValue))
{
return false; return false;
}
MOZ_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>()); MOZ_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
setterFunc = &getterValue.toObject().as<JSFunction>(); setterFunc = &getterValue.toObject().as<JSFunction>();
} }
JSStrictPropertyOp setterOp = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setterFunc.get()); JSStrictPropertyOp setterOp = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setterFunc.get());
return DefineProperty(cx, obj, name, JS::UndefinedHandleValue, return DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
GetterWrapper(getterOp), SetterWrapper(setterOp), GetterWrapper(getterOp), SetterWrapper(setterOp),
attrs, flags); attrs, flags);
} }
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
@ -3256,37 +3244,81 @@ JS_DefineConstIntegers(JSContext *cx, HandleObject obj, const JSConstIntegerSpec
return DefineConstScalar(cx, obj, cis); return DefineConstScalar(cx, obj, cis);
} }
static JS::SymbolCode
PropertySpecNameToSymbolCode(const char *name)
{
MOZ_ASSERT(JS::PropertySpecNameIsSymbol(name));
uintptr_t u = reinterpret_cast<uintptr_t>(name);
return JS::SymbolCode(u - 1);
}
static bool
PropertySpecNameToId(JSContext *cx, const char *name, MutableHandleId id,
js::InternBehavior ib = js::DoNotInternAtom)
{
if (JS::PropertySpecNameIsSymbol(name)) {
JS::SymbolCode which = PropertySpecNameToSymbolCode(name);
id.set(SYMBOL_TO_JSID(cx->wellKnownSymbols().get(which)));
} else {
JSAtom *atom = Atomize(cx, name, strlen(name), ib);
if (!atom)
return false;
id.set(AtomToId(atom));
}
return true;
}
JS_PUBLIC_API(bool)
JS::PropertySpecNameToPermanentId(JSContext *cx, const char *name, jsid *idp)
{
// We are calling fromMarkedLocation(idp) even though idp points to a
// location that will never be marked. This is OK because the whole point
// of this API is to populate *idp with a jsid that does not need to be
// marked.
return PropertySpecNameToId(cx, name, MutableHandleId::fromMarkedLocation(idp),
js::InternAtom);
}
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
JS_DefineProperties(JSContext *cx, HandleObject obj, const JSPropertySpec *ps) JS_DefineProperties(JSContext *cx, HandleObject obj, const JSPropertySpec *ps)
{ {
bool ok; RootedId id(cx);
for (ok = true; ps->name; ps++) {
for (; ps->name; ps++) {
if (!PropertySpecNameToId(cx, ps->name, &id))
return false;
if (ps->flags & JSPROP_NATIVE_ACCESSORS) { if (ps->flags & JSPROP_NATIVE_ACCESSORS) {
// If you declare native accessors, then you should have a native // If you declare native accessors, then you should have a native
// getter. // getter.
MOZ_ASSERT(ps->getter.propertyOp.op); MOZ_ASSERT(ps->getter.propertyOp.op);
// If you do not have a self-hosted getter, you should not have a // If you do not have a self-hosted getter, you should not have a
// self-hosted setter. This is the closest approximation to that // self-hosted setter. This is the closest approximation to that
// assertion we can have with our setup. // assertion we can have with our setup.
MOZ_ASSERT_IF(ps->setter.propertyOp.info, ps->setter.propertyOp.op); MOZ_ASSERT_IF(ps->setter.propertyOp.info, ps->setter.propertyOp.op);
ok = DefineProperty(cx, obj, ps->name, JS::UndefinedHandleValue, if (!DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
ps->getter.propertyOp, ps->setter.propertyOp, ps->flags, 0); ps->getter.propertyOp, ps->setter.propertyOp, ps->flags, 0))
{
return false;
}
} else { } else {
// If you have self-hosted getter/setter, you can't have a // If you have self-hosted getter/setter, you can't have a
// native one. // native one.
MOZ_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op); MOZ_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op);
MOZ_ASSERT(ps->flags & JSPROP_GETTER); MOZ_ASSERT(ps->flags & JSPROP_GETTER);
ok = DefineSelfHostedProperty(cx, obj, ps->name, if (!DefineSelfHostedProperty(cx, obj, id,
ps->getter.selfHosted.funname, ps->getter.selfHosted.funname,
ps->setter.selfHosted.funname, ps->setter.selfHosted.funname,
ps->flags, 0); ps->flags, 0))
{
return false;
}
} }
if (!ok)
break;
} }
return ok; return true;
} }
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
@ -3620,137 +3652,6 @@ JS_Enumerate(JSContext *cx, HandleObject obj)
return ida; return ida;
} }
/*
* XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
* prop_iterator_class somehow...
* + preserve the obj->enumerate API while optimizing the native object case
* + native case here uses a JSShape *, but that iterates in reverse!
* + so we make non-native match, by reverse-iterating after JS_Enumerating
*/
static const uint32_t JSSLOT_ITER_INDEX = 0;
static void
prop_iter_finalize(FreeOp *fop, JSObject *obj)
{
void *pdata = obj->as<NativeObject>().getPrivate();
if (!pdata)
return;
if (obj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32() >= 0) {
/* Non-native case: destroy the ida enumerated when obj was created. */
JSIdArray *ida = (JSIdArray *) pdata;
fop->free_(ida);
}
}
static void
prop_iter_trace(JSTracer *trc, JSObject *obj)
{
void *pdata = obj->as<NativeObject>().getPrivate();
if (!pdata)
return;
if (obj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32() < 0) {
/*
* Native case: just mark the next property to visit. We don't need a
* barrier here because the pointer is updated via setPrivate, which
* always takes a barrier.
*/
Shape *tmp = static_cast<Shape *>(pdata);
MarkShapeUnbarriered(trc, &tmp, "prop iter shape");
obj->as<NativeObject>().setPrivateUnbarriered(tmp);
} else {
/* Non-native case: mark each id in the JSIdArray private. */
JSIdArray *ida = (JSIdArray *) pdata;
MarkIdRange(trc, ida->length, ida->vector, "prop iter");
}
}
static const Class prop_iter_class = {
"PropertyIterator",
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(1),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
prop_iter_finalize,
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
prop_iter_trace
};
JS_PUBLIC_API(JSObject *)
JS_NewPropertyIterator(JSContext *cx, HandleObject obj)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
RootedNativeObject iterobj(cx, NewNativeObjectWithClassProto(cx, &prop_iter_class,
nullptr, obj));
if (!iterobj)
return nullptr;
int index;
if (obj->isNative()) {
/* Native case: start with the last property in obj. */
iterobj->setPrivateGCThing(obj->lastProperty());
index = -1;
} else {
/* Non-native case: enumerate a JSIdArray and keep it via private. */
JSIdArray *ida = JS_Enumerate(cx, obj);
if (!ida)
return nullptr;
iterobj->setPrivate((void *)ida);
index = ida->length;
}
/* iterobj cannot escape to other threads here. */
iterobj->setSlot(JSSLOT_ITER_INDEX, Int32Value(index));
return iterobj;
}
JS_PUBLIC_API(bool)
JS_NextProperty(JSContext *cx, HandleObject iterobj, MutableHandleId idp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, iterobj);
int32_t i = iterobj->as<NativeObject>().getSlot(JSSLOT_ITER_INDEX).toInt32();
if (i < 0) {
/* Native case: private data is a property tree node pointer. */
MOZ_ASSERT(iterobj->getParent()->isNative());
Shape *shape = static_cast<Shape *>(iterobj->as<NativeObject>().getPrivate());
while (shape->previous() && !shape->enumerable())
shape = shape->previous();
if (!shape->previous()) {
MOZ_ASSERT(shape->isEmptyShape());
idp.set(JSID_VOID);
} else {
iterobj->as<NativeObject>().setPrivateGCThing(const_cast<Shape *>(shape->previous().get()));
idp.set(shape->propid());
}
} else {
/* Non-native case: use the ida enumerated when iterobj was created. */
JSIdArray *ida = (JSIdArray *) iterobj->as<NativeObject>().getPrivate();
MOZ_ASSERT(i <= ida->length);
STATIC_ASSUME(i <= ida->length);
if (i == 0) {
idp.set(JSID_VOID);
} else {
idp.set(ida->vector[--i]);
iterobj->as<NativeObject>().setSlot(JSSLOT_ITER_INDEX, Int32Value(i));
}
}
return true;
}
JS_PUBLIC_API(jsval) JS_PUBLIC_API(jsval)
JS_GetReservedSlot(JSObject *obj, uint32_t index) JS_GetReservedSlot(JSObject *obj, uint32_t index)
{ {
@ -3899,12 +3800,14 @@ JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flag
JS_PUBLIC_API(JSFunction *) JS_PUBLIC_API(JSFunction *)
JS::GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, HandleId id, unsigned nargs) JS::GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, HandleId id, unsigned nargs)
{ {
MOZ_ASSERT(JSID_IS_STRING(id));
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx); AssertHeapIsIdle(cx);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
RootedAtom name(cx, JSID_TO_ATOM(id)); RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return nullptr;
RootedAtom shName(cx, Atomize(cx, selfHostedName, strlen(selfHostedName))); RootedAtom shName(cx, Atomize(cx, selfHostedName, strlen(selfHostedName)));
if (!shName) if (!shName)
return nullptr; return nullptr;
@ -4068,21 +3971,11 @@ JS_DefineFunctions(JSContext *cx, HandleObject obj, const JSFunctionSpec *fs)
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj); assertSameCompartment(cx, obj);
RootedId id(cx);
for (; fs->name; fs++) { for (; fs->name; fs++) {
RootedAtom atom(cx); if (!PropertySpecNameToId(cx, fs->name, &id))
// If the name starts with "@@", it must be a well-known symbol.
if (fs->name[0] != '@' || fs->name[1] != '@')
atom = Atomize(cx, fs->name, strlen(fs->name));
else if (strcmp(fs->name, "@@iterator") == 0)
// FIXME: This atom should be a symbol: bug 918828.
atom = cx->names().std_iterator;
else
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_SYMBOL, fs->name);
if (!atom)
return false; return false;
Rooted<jsid> id(cx, AtomToId(atom));
/* /*
* Define a generic arity N+1 static method for the arity N prototype * Define a generic arity N+1 static method for the arity N prototype
* method if flags contains JSFUN_GENERIC_NATIVE. * method if flags contains JSFUN_GENERIC_NATIVE.
@ -4124,8 +4017,11 @@ JS_DefineFunctions(JSContext *cx, HandleObject obj, const JSFunctionSpec *fs)
RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName))); RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
if (!shName) if (!shName)
return false; return false;
RootedAtom name(cx, IdToFunctionName(cx, id));
if (!name)
return false;
RootedValue funVal(cx); RootedValue funVal(cx);
if (!cx->global()->getSelfHostedFunction(cx, shName, atom, fs->nargs, &funVal)) if (!cx->global()->getSelfHostedFunction(cx, shName, name, fs->nargs, &funVal))
return false; return false;
if (!JSObject::defineGeneric(cx, obj, id, funVal, nullptr, nullptr, flags)) if (!JSObject::defineGeneric(cx, obj, id, funVal, nullptr, nullptr, flags))
return false; return false;
@ -5628,6 +5524,33 @@ JS::GetWellKnownSymbol(JSContext *cx, JS::SymbolCode which)
return cx->runtime()->wellKnownSymbols->get(uint32_t(which)); return cx->runtime()->wellKnownSymbols->get(uint32_t(which));
} }
static bool
PropertySpecNameIsDigits(const char *s) {
if (JS::PropertySpecNameIsSymbol(s))
return false;
if (!*s)
return false;
for (; *s; s++) {
if (*s < '0' || *s > '9')
return false;
}
return true;
}
JS_PUBLIC_API(bool)
JS::PropertySpecNameEqualsId(const char *name, HandleId id)
{
if (JS::PropertySpecNameIsSymbol(name)) {
if (!JSID_IS_SYMBOL(id))
return false;
Symbol *sym = JSID_TO_SYMBOL(id);
return sym->isWellKnownSymbol() && sym->code() == PropertySpecNameToSymbolCode(name);
}
MOZ_ASSERT(!PropertySpecNameIsDigits(name));
return JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_ATOM(id), name);
}
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
JS_Stringify(JSContext *cx, MutableHandleValue vp, HandleObject replacer, JS_Stringify(JSContext *cx, MutableHandleValue vp, HandleObject replacer,
HandleValue space, JSONWriteCallback callback, void *data) HandleValue space, JSONWriteCallback callback, void *data)

Просмотреть файл

@ -2475,15 +2475,27 @@ struct JSFunctionSpec {
* JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
* JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. Finally * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. Finally
* JS_FNSPEC has slots for all the fields. * JS_FNSPEC has slots for all the fields.
*
* The _SYM variants allow defining a function with a symbol key rather than a
* string key. For example, use JS_SYM_FN(iterator, ...) to define an
* @@iterator method.
*/ */
#define JS_FS(name,call,nargs,flags) \ #define JS_FS(name,call,nargs,flags) \
JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr) JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
#define JS_FN(name,call,nargs,flags) \ #define JS_FN(name,call,nargs,flags) \
JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
#define JS_SYM_FN(name,call,nargs,flags) \
JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
#define JS_FNINFO(name,call,info,nargs,flags) \ #define JS_FNINFO(name,call,info,nargs,flags) \
JS_FNSPEC(name, call, info, nargs, flags, nullptr) JS_FNSPEC(name, call, info, nargs, flags, nullptr)
#define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \ #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \
JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName) JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
#define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \
JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName)
#define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \
JS_FNSPEC(reinterpret_cast<const char *>( \
uint32_t(::JS::SymbolCode::symbol) + 1), \
call, info, nargs, flags, selfHostedName)
#define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \ #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \
{name, {call, info}, nargs, flags, selfHostedName} {name, {call, info}, nargs, flags, selfHostedName}
@ -3305,22 +3317,6 @@ JS_ReleaseMappedArrayBufferContents(void *contents, size_t length);
extern JS_PUBLIC_API(JSIdArray *) extern JS_PUBLIC_API(JSIdArray *)
JS_Enumerate(JSContext *cx, JS::HandleObject obj); JS_Enumerate(JSContext *cx, JS::HandleObject obj);
/*
* Create an object to iterate over enumerable properties of obj, in arbitrary
* property definition order. NB: This differs from longstanding for..in loop
* order, which uses order of property definition in obj.
*/
extern JS_PUBLIC_API(JSObject *)
JS_NewPropertyIterator(JSContext *cx, JS::Handle<JSObject*> obj);
/*
* Return true on success with *idp containing the id of the next enumerable
* property to visit using iterobj, or JSID_IS_VOID if there is no such property
* left to visit. Return false on error.
*/
extern JS_PUBLIC_API(bool)
JS_NextProperty(JSContext *cx, JS::HandleObject iterobj, JS::MutableHandleId idp);
extern JS_PUBLIC_API(jsval) extern JS_PUBLIC_API(jsval)
JS_GetReservedSlot(JSObject *obj, uint32_t index); JS_GetReservedSlot(JSObject *obj, uint32_t index);
@ -4510,6 +4506,31 @@ GetSymbolCode(Handle<Symbol*> symbol);
JS_PUBLIC_API(Symbol *) JS_PUBLIC_API(Symbol *)
GetWellKnownSymbol(JSContext *cx, SymbolCode which); GetWellKnownSymbol(JSContext *cx, SymbolCode which);
/*
* Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
* is actually a symbol code and not a string. See JS_SYM_FN.
*/
inline bool
PropertySpecNameIsSymbol(const char *name)
{
uintptr_t u = reinterpret_cast<uintptr_t>(name);
return u != 0 && u - 1 < WellKnownSymbolLimit;
}
JS_PUBLIC_API(bool)
PropertySpecNameEqualsId(const char *name, HandleId id);
/*
* Create a jsid that does not need to be marked for GC.
*
* 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
* resulting jsid, on success, is either an interned string or a well-known
* symbol; either way it is immune to GC so there is no need to visit *idp
* during GC marking.
*/
JS_PUBLIC_API(bool)
PropertySpecNameToPermanentId(JSContext *cx, const char *name, jsid *idp);
} /* namespace JS */ } /* namespace JS */
/************************************************************************/ /************************************************************************/

Просмотреть файл

@ -58,7 +58,6 @@ const char js_break_str[] = "break";
const char js_case_str[] = "case"; const char js_case_str[] = "case";
const char js_catch_str[] = "catch"; const char js_catch_str[] = "catch";
const char js_class_str[] = "class"; const char js_class_str[] = "class";
const char js_close_str[] = "close";
const char js_const_str[] = "const"; const char js_const_str[] = "const";
const char js_continue_str[] = "continue"; const char js_continue_str[] = "continue";
const char js_debugger_str[] = "debugger"; const char js_debugger_str[] = "debugger";

Просмотреть файл

@ -1109,11 +1109,10 @@ JSContext::JSContext(JSRuntime *rt)
data(nullptr), data(nullptr),
data2(nullptr), data2(nullptr),
outstandingRequests(0), outstandingRequests(0),
jitIsBroken(false), jitIsBroken(false)
#ifdef MOZ_TRACE_JSCALLS #ifdef MOZ_TRACE_JSCALLS
functionCallback(nullptr), , functionCallback(nullptr)
#endif #endif
innermostGenerator_(nullptr)
{ {
MOZ_ASSERT(static_cast<ContextFriendFields*>(this) == MOZ_ASSERT(static_cast<ContextFriendFields*>(this) ==
ContextFriendFields::get(this)); ContextFriendFields::get(this));
@ -1146,23 +1145,6 @@ JSContext::isThrowingOutOfMemory()
return throwing && unwrappedException_ == StringValue(names().outOfMemory); return throwing && unwrappedException_ == StringValue(names().outOfMemory);
} }
void
JSContext::enterGenerator(JSGenerator *gen)
{
MOZ_ASSERT(!gen->prevGenerator);
gen->prevGenerator = innermostGenerator_;
innermostGenerator_ = gen;
}
void
JSContext::leaveGenerator(JSGenerator *gen)
{
MOZ_ASSERT(innermostGenerator_ == gen);
innermostGenerator_ = innermostGenerator_->prevGenerator;
gen->prevGenerator = nullptr;
}
bool bool
JSContext::saveFrameChain() JSContext::saveFrameChain()
{ {

Просмотреть файл

@ -284,6 +284,7 @@ struct ThreadSafeContext : ContextFriendFields,
JSAtomState &names() { return *runtime_->commonNames; } JSAtomState &names() { return *runtime_->commonNames; }
StaticStrings &staticStrings() { return *runtime_->staticStrings; } StaticStrings &staticStrings() { return *runtime_->staticStrings; }
AtomSet &permanentAtoms() { return *runtime_->permanentAtoms; } AtomSet &permanentAtoms() { return *runtime_->permanentAtoms; }
WellKnownSymbols &wellKnownSymbols() { return *runtime_->wellKnownSymbols; }
const JS::AsmJSCacheOps &asmJSCacheOps() { return runtime_->asmJSCacheOps; } const JS::AsmJSCacheOps &asmJSCacheOps() { return runtime_->asmJSCacheOps; }
PropertyName *emptyString() { return runtime_->emptyString; } PropertyName *emptyString() { return runtime_->emptyString; }
FreeOp *defaultFreeOp() { return runtime_->defaultFreeOp(); } FreeOp *defaultFreeOp() { return runtime_->defaultFreeOp(); }
@ -551,14 +552,7 @@ struct JSContext : public js::ExclusiveContext,
runtime_->gc.gcIfNeeded(this); runtime_->gc.gcIfNeeded(this);
} }
private:
/* Innermost-executing generator or null if no generator are executing. */
JSGenerator *innermostGenerator_;
public: public:
JSGenerator *innermostGenerator() const { return innermostGenerator_; }
void enterGenerator(JSGenerator *gen);
void leaveGenerator(JSGenerator *gen);
bool isExceptionPending() { bool isExceptionPending() {
return throwing; return throwing;
} }

Просмотреть файл

@ -971,7 +971,7 @@ CopyFlatStringChars(char16_t *dest, JSFlatString *s, size_t len)
} }
JS_FRIEND_API(bool) JS_FRIEND_API(bool)
GetPropertyKeys(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props); GetPropertyKeys(JSContext *cx, JS::HandleObject obj, unsigned flags, JS::AutoIdVector *props);
JS_FRIEND_API(bool) JS_FRIEND_API(bool)
AppendUnique(JSContext *cx, JS::AutoIdVector &base, JS::AutoIdVector &others); AppendUnique(JSContext *cx, JS::AutoIdVector &base, JS::AutoIdVector &others);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше