author | Wes Kocher <wkocher@mozilla.com> |
Tue, 30 Sep 2014 17:13:45 -0700 | |
changeset 208112 | 3e171f1759c969d126c51600c9a320034aa7cb9b |
parent 208111 | 0204f2429e77707883f544ac32dff52023b185c1 (current diff) |
parent 208042 | 6c824fbb73e87044e63f52917f4159ffa4500be8 (diff) |
child 208113 | 24c6fdc973eb840129f882eb73ccf18319d8b190 |
push id | 27576 |
push user | cbook@mozilla.com |
push date | Wed, 01 Oct 2014 13:00:38 +0000 |
treeherder | autoland@1a550125928f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/jit-test/tests/sharedbuf/bug1068458-toolong.js | file | annotate | diff | comparison | revisions |
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -822,18 +822,21 @@ pref("network.activity.blipIntervalMilli // In some environments, such as the emulator or hardware with other network // connectivity, this is not desireable, however, in which case this pref // can be flipped to false. pref("network.gonk.manage-offline-status", true); // On Firefox Mulet, we can't enable shared JSM scope // as it breaks most Firefox JSMs (see bug 961777) #ifndef MOZ_MULET +// Break any JSMs or JS components that rely on shared scope +#ifndef DEBUG pref("jsloader.reuseGlobal", true); #endif +#endif // Enable font inflation for browser tab content. pref("font.size.inflation.minTwips", 120); // And disable it for lingering master-process UI. pref("font.size.inflation.disabledInMasterProcess", true); // Enable freeing dirty pages when minimizing memory; this reduces memory // consumption when applications are sent to the background.
--- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -481,16 +481,17 @@ let settingsToObserve = { prefName: 'nglayout.debug.paint_flashing', defaultValue: false }, 'devtools.eventlooplag.threshold': 100, 'devtools.remote.wifi.visible': { resetToPref: true }, 'dom.mozApps.use_reviewer_certs': false, + 'dom.mozApps.signed_apps_installable_from': 'https://marketplace.firefox.com', 'layers.draw-borders': false, 'layers.draw-tile-borders': false, 'layers.dump': false, 'layers.enable-tiles': true, 'layers.simple-tiles': false, 'layers.effect.invert': false, 'layers.effect.grayscale': false, 'layers.effect.contrast': "0.0",
--- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -10,25 +10,25 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/> <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/> @@ -128,16 +128,16 @@ <project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/> <!-- dolphin specific things --> <project name="device/sprd" path="device/sprd" revision="0351ccd65808a2486e0fefb99674ca7a64c2c6dc"/> <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/> <project name="platform/frameworks/av" path="frameworks/av" revision="4387fe988e5a1001f29ce05fcfda03ed2d32137b"/> <project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/> <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/> <project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/> - <project name="kernel/common" path="kernel" revision="28aab3bd1139b6beea545f50dee8903c0634de84"/> + <project name="kernel/common" path="kernel" revision="f365109310138f85bb91884b7dee60f6f0da042d"/> <project name="platform/system/core" path="system/core" revision="53d584d4a4b4316e4de9ee5f210d662f89b44e7e"/> <project name="u-boot" path="u-boot" revision="982c1fd67b89d5573317c1796cf5b0143de44e8a"/> <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="6974f8e771d4d8e910357a6739ab124768891e8f"/> <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="1d4697b16ed039fd1de0a23bda150523e743e2ad"/> <project name="vendor/sprd/partner" path="vendor/sprd/partner" revision="8649c7145972251af11b0639997edfecabfc7c2e"/> <project name="vendor/sprd/proprietories" path="vendor/sprd/proprietories" revision="d2466593022f7078aaaf69026adf3367c2adb7bb"/> </manifest>
--- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -14,23 +14,23 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/> <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/> <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/> <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/> <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/> <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -12,20 +12,20 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/> @@ -129,12 +129,12 @@ <project name="android-development" path="development" remote="b2g" revision="dab55669da8f48b6e57df95d5af9f16b4a87b0b1"/> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/> <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="197cd9492b9fadaa915c5daf36ff557f8f4a8d1c"/> <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/> <project name="libnfcemu" path="external/libnfcemu" remote="b2g" revision="125ccf9bd5986c7728ea44508b3e1d1185ac028b"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d259117b4976decbe2f76eeed85218bf0109190f"/> <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/> - <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="2a5dc67db7c9e6651c5fff855a6f69c1f2061ca7"/> + <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="cf9376f0f59ca72333dd24a54efe887d527da612"/> <project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/> <project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/> </manifest>
--- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -10,25 +10,25 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/> <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -14,23 +14,23 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/> <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/> <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/> <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/> <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/> <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -10,25 +10,25 @@ <!--original fetch url was git://codeaurora.org/--> <remote fetch="https://git.mozilla.org/external/caf" name="caf"/> <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/> <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/> <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/> <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/> @@ -146,13 +146,13 @@ <project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="2a1ded216a91bf62a72b1640cf01ab4998f37028"/> <project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="e5a971282719907f73fb1da964ca40aad67a3be0"/> <project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="9883ea57b0668d8f60dba025d4522dfa69a1fbfa"/> <project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="a558dc844bf5144fc38603fd8f4df8d9557052a5"/> <project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="57ee1320ed7b4a1a1274d8f3f6c177cd6b9becb2"/> <project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/> <project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/> <project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/> - <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="2a5dc67db7c9e6651c5fff855a6f69c1f2061ca7"/> + <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="cf9376f0f59ca72333dd24a54efe887d527da612"/> <project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/> <project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/> <project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="7704e16da545f4207812e593743d6743e1afb9c5"/> </manifest>
--- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -12,20 +12,20 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/> @@ -140,13 +140,13 @@ <project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="5e110615212302c5d798a3c223dcee458817651c"/> <project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="fa9ffd47948eb24466de227e48fe9c4a7c5e7711"/> <project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="cd76b19aafd4229ccf83853d02faef8c51ca8b34"/> <project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="8a0d0b0d9889ef99c4c6317c810db4c09295f15a"/> <project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="2208fa3537ace873b8f9ec2355055761c79dfd5f"/> <project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/> <project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/> <project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/> - <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="2a5dc67db7c9e6651c5fff855a6f69c1f2061ca7"/> + <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="cf9376f0f59ca72333dd24a54efe887d527da612"/> <project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/> <project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/> <project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/> </manifest>
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { "git_revision": "", "remote": "", "branch": "" }, - "revision": "fb5a4aa15e266e9aa0e44281241ad081b528c75b", + "revision": "7f097f40e32ecba580890ce1d3df2a493641bdec", "repo_path": "/integration/gaia-central" }
--- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -12,22 +12,22 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/> <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/> <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/> <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/> <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -10,17 +10,17 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -12,20 +12,20 @@ <!--original fetch url was https://git.mozilla.org/releases--> <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/> <!-- B2G specific things. --> <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> - <project name="gaia" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <!-- Stock Android things --> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/> <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/> <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/> <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/> @@ -124,17 +124,17 @@ <project name="platform/system/netd" path="system/netd" revision="56112dd7b811301b718d0643a82fd5cac9522073"/> <project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/> <project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/> <default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/> <!-- Nexus 4 specific things --> <project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/> <project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/> - <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="2a5dc67db7c9e6651c5fff855a6f69c1f2061ca7"/> + <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="cf9376f0f59ca72333dd24a54efe887d527da612"/> <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/> <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/> <project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/> <project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="b0a528d839cfd9d170d092fe3743b5252b4243a6"/> <project name="platform/hardware/qcom/bt" path="hardware/qcom/bt" revision="380945eaa249a2dbdde0daa4c8adb8ca325edba6"/> <project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="6f3b0272cefaffeaed2a7d2bb8f633059f163ddc"/> <project name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="16da8262c997a5a0d797885788a64a0771b26910"/> <project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="689b476ba3eb46c34b81343295fe144a0e81a18e"/>
--- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -12,22 +12,22 @@ <!--original fetch url was git://github.com/apitrace/--> <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/> <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e"> <copyfile dest="Makefile" src="core/root.mk"/> </project> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> - <project name="gaia.git" path="gaia" remote="mozillaorg" revision="77ef35f5429bc3dfe9ca192b9aacc3c0bf8857de"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e280591881d44b80f456bc27e12d9114c218868"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0f7792c39ad26aedecf457117c21b16cc1aee879"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4f9042d3a705307849a6f63961eaaaa2e1d85d77"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <!-- Stock Android things --> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/> <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/> <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/> <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/> <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -379,17 +379,18 @@ nsContextMenu.prototype = { else this.showItem("spell-no-suggestions", false); // dictionary list this.showItem("spell-dictionaries", canSpell && InlineSpellCheckerUI.enabled); if (canSpell) { var dictMenu = document.getElementById("spell-dictionaries-menu"); var dictSep = document.getElementById("spell-language-separator"); - InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep); + let count = InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep); + this.showItem(dictSep, count > 0); this.showItem("spell-add-dictionaries-main", false); } else if (this.onEditableArea) { // when there is no spellchecker but we might be able to spellcheck // add the add to dictionaries item. This will ensure that people // with no dictionaries will be able to download them this.showItem("spell-add-dictionaries-main", true); }
--- a/build/automationutils.py +++ b/build/automationutils.py @@ -281,24 +281,19 @@ def processSingleLeakFile(leakLogFileNam return if totalBytesLeaked == 0: log.info("TEST-PASS | leakcheck | %s no leaks detected!" % processString) return # totalBytesLeaked was seen and is non-zero. if totalBytesLeaked > leakThreshold: - if processType == "tab": - # For now, ignore tab process leaks. See bug 1051230. - log.info("WARNING | leakcheck | ignoring leaks in tab process") - prefix = "WARNING" - else: - logAsWarning = True - # Fail the run if we're over the threshold (which defaults to 0) - prefix = "TEST-UNEXPECTED-FAIL" + logAsWarning = True + # Fail the run if we're over the threshold (which defaults to 0) + prefix = "TEST-UNEXPECTED-FAIL" else: prefix = "WARNING" # Create a comma delimited string of the first N leaked objects found, # to aid with bug summary matching in TBPL. Note: The order of the objects # had no significance (they're sorted alphabetically). maxSummaryObjects = 5 leakedObjectSummary = ', '.join(leakedObjectNames[:maxSummaryObjects]) if len(leakedObjectNames) > maxSummaryObjects: @@ -306,55 +301,73 @@ def processSingleLeakFile(leakLogFileNam if logAsWarning: log.warning("%s | leakcheck | %s %d bytes leaked (%s)" % (prefix, processString, totalBytesLeaked, leakedObjectSummary)) else: log.info("%s | leakcheck | %s %d bytes leaked (%s)" % (prefix, processString, totalBytesLeaked, leakedObjectSummary)) -def processLeakLog(leakLogFile, leakThreshold = 0): +def processLeakLog(leakLogFile, leakThresholds): """Process the leak log, including separate leak logs created by child processes. Use this function if you want an additional PASS/FAIL summary. It must be used with the |XPCOM_MEM_BLOAT_LOG| environment variable. The base of leakLogFile for a non-default process needs to end with _proctype_pid12345.log "proctype" is a string denoting the type of the process, which should be the result of calling XRE_ChildProcessTypeToString(). 12345 is a series of digits that is the pid for the process. The .log is optional. All other file names are treated as being for default processes. + + leakThresholds should be a dict mapping process types to leak thresholds, + in bytes. If a process type is not present in the dict the threshold + will be 0. """ if not os.path.exists(leakLogFile): log.info("WARNING | leakcheck | refcount logging is off, so leaks can't be detected!") return - if leakThreshold != 0: - log.info("TEST-INFO | leakcheck | threshold set at %d bytes" % leakThreshold) + # This list is based on kGeckoProcessTypeString. ipdlunittest processes likely + # are not going to produce leak logs we will ever see. + knownProcessTypes = ["default", "plugin", "tab", "geckomediaplugin"] + + for processType in knownProcessTypes: + log.info("TEST-INFO | leakcheck | %s process: leak threshold set at %d bytes" + % (processType, leakThresholds.get(processType, 0))) + + for processType in leakThresholds: + if not processType in knownProcessTypes: + log.info("TEST-UNEXPECTED-FAIL | leakcheck | Unknown process type %s in leakThresholds" + % processType) (leakLogFileDir, leakFileBase) = os.path.split(leakLogFile) if leakFileBase[-4:] == ".log": leakFileBase = leakFileBase[:-4] fileNameRegExp = re.compile(r"_([a-z]*)_pid\d*.log$") else: fileNameRegExp = re.compile(r"_([a-z]*)_pid\d*$") for fileName in os.listdir(leakLogFileDir): if fileName.find(leakFileBase) != -1: thisFile = os.path.join(leakLogFileDir, fileName) m = fileNameRegExp.search(fileName) if m: processType = m.group(1) else: processType = "default" + if not processType in knownProcessTypes: + log.info("TEST-UNEXPECTED-FAIL | leakcheck | Leak log with unknown process type %s" + % processType) + leakThreshold = leakThresholds.get(processType, 0) processSingleLeakFile(thisFile, processType, leakThreshold) def replaceBackSlashes(input): return input.replace('\\', '/') class KeyValueParseError(Exception): """error when parsing strings of serialized key-values""" def __init__(self, msg, errors=()):
--- a/caps/nsIPrincipal.idl +++ b/caps/nsIPrincipal.idl @@ -108,23 +108,19 @@ interface nsIPrincipal : nsISerializable } %} /** * Checks whether this principal is allowed to load the network resource * located at the given URI under the same-origin policy. This means that * codebase principals are only allowed to load resources from the same * domain, the system principal is allowed to load anything, and null - * principals are not allowed to load anything. This is changed slightly - * by the optional flag allowIfInheritsPrincipal (which defaults to false) - * which allows the load of a data: URI (which inherits the principal of - * its loader) or a URI with the same principal as its loader (eg. a - * Blob URI). - * In these cases, with allowIfInheritsPrincipal set to true, the URI can - * be loaded by a null principal. + * principals can only load URIs where they are the principal. This is + * changed by the optional flag allowIfInheritsPrincipal (which defaults to + * false) which allows URIs that inherit their loader's principal. * * If the load is allowed this function does nothing. If the load is not * allowed the function throws NS_ERROR_DOM_BAD_URI. * * NOTE: Other policies might override this, such as the Access-Control * specification. * NOTE: The 'domain' attribute has no effect on the behaviour of this * function.
--- a/caps/nsNullPrincipal.cpp +++ b/caps/nsNullPrincipal.cpp @@ -234,27 +234,26 @@ nsNullPrincipal::SubsumesConsideringDoma NS_IMETHODIMP nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal) { if (aAllowIfInheritsPrincipal) { if (nsPrincipal::IsPrincipalInherited(aURI)) { return NS_OK; } + } - // Also allow the load if the principal of the URI being checked is exactly - // us ie this. - nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI); - if (uriPrinc) { - nsCOMPtr<nsIPrincipal> principal; - uriPrinc->GetPrincipal(getter_AddRefs(principal)); + // Also allow the load if we are the principal of the URI being checked. + nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI); + if (uriPrinc) { + nsCOMPtr<nsIPrincipal> principal; + uriPrinc->GetPrincipal(getter_AddRefs(principal)); - if (principal && principal == this) { - return NS_OK; - } + if (principal == this) { + return NS_OK; } } if (aReport) { nsScriptSecurityManager::ReportError( nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI, aURI); }
--- a/content/html/content/test/file_iframe_sandbox_b_if3.html +++ b/content/html/content/test/file_iframe_sandbox_b_if3.html @@ -6,33 +6,60 @@ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> </head> <script> function ok(result, message) { window.parent.postMessage({ok: result, desc: message}, "*"); } function testXHR() { - var xhr = new XMLHttpRequest(); - - xhr.open("GET", "file_iframe_sandbox_b_if1.html"); + // Standard URL should be blocked as we have a unique origin. + var xhr = new XMLHttpRequest(); + xhr.open("GET", "file_iframe_sandbox_b_if1.html"); + xhr.onreadystatechange = function (oEvent) { + var result = false; + if (xhr.readyState == 4) { + if (xhr.status == 0) { + result = true; + } + ok(result, "XHR should be blocked in an iframe sandboxed WITHOUT 'allow-same-origin'"); + } + } + xhr.send(null); - xhr.onreadystatechange = function (oEvent) { - var result = false; - if (xhr.readyState == 4) { - if (xhr.status == 0) { - result = true; + // Blob URL should work as it will have our unique origin. + var blobXhr = new XMLHttpRequest(); + var blobUrl = URL.createObjectURL(new Blob(["wibble"], {type: "text/plain"})); + blobXhr.open("GET", blobUrl); + blobXhr.onreadystatechange = function () { + if (this.readyState == 4) { + ok(this.status == 200 && this.response == "wibble", "XHR for a blob URL created in this document should NOT be blocked in an iframe sandboxed WITHOUT 'allow-same-origin'"); } - ok(result, "XHR should be blocked in an iframe sandboxed WITHOUT 'allow-same-origin'"); + } + try { + blobXhr.send(); + } catch(e) { + ok(false, "failed to send XHR for blob URL: error: " + e); + } + + // Data URL should work as it inherits the loader's origin. + var dataXhr = new XMLHttpRequest(); + dataXhr.open("GET", "data:text/html,wibble"); + dataXhr.onreadystatechange = function () { + if (this.readyState == 4) { + ok(this.status == 200 && this.response == "wibble", "XHR for a data URL should NOT be blocked in an iframe sandboxed WITHOUT 'allow-same-origin'"); + } + } + try { + dataXhr.send(); + } catch(e) { + ok(false, "failed to send XHR for data URL: error: " + e); } } - xhr.send(null); -} - function doStuff() { try { window.parent.ok(false, "documents sandboxed without 'allow-same-origin' should NOT be able to access their parent"); } catch (error) { ok(true, "documents sandboxed without 'allow-same-origin' should NOT be able to access their parent"); } // should NOT be able to access document.cookie @@ -51,15 +78,15 @@ // should NOT be able to access sessionStorage try { var foo = window.sessionStorage; } catch(error) { ok(true, "a document sandboxed without allow-same-origin should NOT be able to access sessionStorage"); } - testXHR(); + testXHR(); } </script> <body onLoad="doStuff()"> I am sandboxed but with "allow-scripts" </body> </html>
--- a/content/html/content/test/test_audio_wakelock.html +++ b/content/html/content/test/test_audio_wakelock.html @@ -34,17 +34,17 @@ function testAudioPlayPause() { audio.addEventListener('playing', function() { startDate = new Date(); // The next step is to unlock the resource. lockState = false; audio.pause(); }); - navigator.mozPower.addWakeLockListener(function testAudioPlayListener(topic, state) { + function testAudioPlayListener(topic, state) { is(topic, "cpu", "Audio element locked the target == cpu"); var locked = state == "locked-foreground" || state == "locked-background"; is(locked, lockState, "Audio element locked the cpu - no paused"); count++; // count == 1 is when the cpu wakelock is created @@ -53,18 +53,19 @@ function testAudioPlayPause() { if (count == 2) { var diffDate = (new Date() - startDate); ok(diffDate > 200, "There was at least 200 milliseconds between the stop and the wakelock release"); content.removeChild(audio); navigator.mozPower.removeWakeLockListener(testAudioPlayListener); runTests(); } - }); + }; + navigator.mozPower.addWakeLockListener(testAudioPlayListener); audio.play(); } function testAudioPlay() { var lockState = true; var count = 0; var content = document.getElementById('content'); @@ -73,17 +74,17 @@ function testAudioPlay() { audio.src = "wakelock.ogg"; content.appendChild(audio); var startDate; audio.addEventListener('progress', function() { startDate = new Date(); }); - navigator.mozPower.addWakeLockListener(function testAudioPlayListener(topic, state) { + function testAudioPlayListener(topic, state) { is(topic, "cpu", "Audio element locked the target == cpu"); var locked = state == "locked-foreground" || state == "locked-background"; is(locked, lockState, "Audio element locked the cpu - no paused"); count++; // count == 1 is when the cpu wakelock is created: the wakelock must be @@ -96,33 +97,37 @@ function testAudioPlay() { } else if (count == 2) { var diffDate = (new Date() - startDate); ok(diffDate > 200, "There was at least 200 milliseconds between the stop and the wakelock release"); content.removeChild(audio); navigator.mozPower.removeWakeLockListener(testAudioPlayListener); runTests(); } - }); + }; + navigator.mozPower.addWakeLockListener(testAudioPlayListener); audio.play(); } var tests = [ testAudioPlayPause, testAudioPlay ]; function runTests() { if (!tests.length) { SimpleTest.finish(); return; } var test = tests.pop(); test(); }; -SpecialPowers.addPermission("power", true, document); -SpecialPowers.pushPrefEnv({"set": [["media.wakelock_timeout", 500]]}, runTests); +SpecialPowers.pushPermissions( + [{'type': 'power', 'allow': true, 'context': document}], + function() { + SpecialPowers.pushPrefEnv({"set": [["media.wakelock_timeout", 500]]}, runTests); + }); SimpleTest.waitForExplicitFinish(); </script> </pre> </body> </html>
--- a/content/html/content/test/test_iframe_sandbox_same_origin.html +++ b/content/html/content/test/test_iframe_sandbox_same_origin.html @@ -23,18 +23,18 @@ function ok_wrapper(result, desc) { ok(result, desc); completedTests++; if (result) { passedTests++; } - if (completedTests == 12) { - is(passedTests, 12, "There are 12 same-origin tests that should pass"); + if (completedTests == 14) { + is(passedTests, completedTests, "There are " + completedTests + " same-origin tests that should pass"); SimpleTest.finish(); } } function receiveMessage(event) { ok_wrapper(event.data.ok, event.data.desc);
--- a/content/media/AudioBufferUtils.h +++ b/content/media/AudioBufferUtils.h @@ -116,16 +116,21 @@ public: * the number of frames written. */ uint32_t Empty(AudioCallbackBufferWrapper<T, CHANNELS>& aBuffer) { uint32_t framesToWrite = std::min(aBuffer.Available(), SamplesToFrames(CHANNELS, mPosition)); aBuffer.WriteFrames(mBuffer, framesToWrite); mPosition -= FramesToSamples(CHANNELS, framesToWrite); + // If we didn't empty the spill buffer for some reason, shift the remaining data down + if (mPosition > 0) { + PodMove(mBuffer, mBuffer + FramesToSamples(CHANNELS, framesToWrite), + mPosition); + } return framesToWrite; } /* Fill the spill buffer from aInput, containing aFrames frames, return the * number of frames written to the spill buffer */ uint32_t Fill(T* aInput, uint32_t aFrames) { uint32_t framesToWrite = std::min(aFrames, BLOCK_SIZE - SamplesToFrames(CHANNELS,
--- a/content/media/AudioSink.cpp +++ b/content/media/AudioSink.cpp @@ -50,28 +50,20 @@ AudioSink::AudioSink(MediaDecoderStateMa nsresult AudioSink::Init() { nsresult rv = NS_NewNamedThread("Media Audio", getter_AddRefs(mThread), nullptr, MEDIA_THREAD_STACK_SIZE); if (NS_FAILED(rv)) { - mStateMachine->OnAudioSinkError(); return rv; } - nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &AudioSink::AudioLoop); - rv = mThread->Dispatch(event, NS_DISPATCH_NORMAL); - if (NS_FAILED(rv)) { - mStateMachine->OnAudioSinkError(); - return rv; - } - - return NS_OK; + return mThread->Dispatch(event, NS_DISPATCH_NORMAL); } int64_t AudioSink::GetPosition() { if (!mAudioStream) { return 0; } @@ -141,18 +133,16 @@ AudioSink::StopPlayback() void AudioSink::AudioLoop() { AssertOnAudioThread(); SINK_LOG("AudioLoop started"); if (NS_FAILED(InitializeAudioStream())) { NS_WARNING("Initializing AudioStream failed."); - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - mStateMachine->OnAudioSinkError(); return; } while (1) { { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); WaitForAudioToPlay(); if (!IsPlaybackContinuing()) { @@ -202,23 +192,20 @@ AudioSink::AudioLoop() nsresult AudioSink::InitializeAudioStream() { // AudioStream initialization can block for extended periods in unusual // circumstances, so we take care to drop the decoder monitor while // initializing. RefPtr<AudioStream> audioStream(new AudioStream()); - nsresult rv = audioStream->Init(mInfo.mChannels, mInfo.mRate, - mChannel, AudioStream::HighLatency); - if (NS_FAILED(rv)) { - audioStream->Shutdown(); - return rv; - } - + audioStream->Init(mInfo.mChannels, mInfo.mRate, + mChannel, AudioStream::HighLatency); + // TODO: Check Init's return value and bail on error. Unfortunately this + // causes some tests to fail due to playback failing. ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); mAudioStream = audioStream; UpdateStreamSettings(); return NS_OK; } void
--- a/content/media/GraphDriver.cpp +++ b/content/media/GraphDriver.cpp @@ -800,62 +800,70 @@ AudioCallbackDriver::DataCallback(AudioD uint32_t durationMS = aFrames * 1000 / mSampleRate; // For now, simply average the duration with the previous // duration so there is some damping against sudden changes. if (!mIterationDurationMS) { mIterationDurationMS = durationMS; } else { - mIterationDurationMS += durationMS; - mIterationDurationMS /= 2; + mIterationDurationMS = (mIterationDurationMS*3) + durationMS; + mIterationDurationMS /= 4; } mBuffer.SetBuffer(aBuffer, aFrames); - + // fill part or all with leftover data from last iteration (since we + // align to Audio blocks) mScratchBuffer.Empty(mBuffer); - - mStateComputedTime = mNextStateComputedTime; + // if we totally filled the buffer (and mScratchBuffer isn't empty), + // we don't need to run an iteration and if we do so we may overflow. + if (mBuffer.Available()) { - // State computed time is decided by the audio callback's buffer length. We - // compute the iteration start and end from there, trying to keep the amount - // of buffering in the graph constant. - mNextStateComputedTime = - mGraphImpl->RoundUpToNextAudioBlock(mStateComputedTime + mBuffer.Available()); + mStateComputedTime = mNextStateComputedTime; + + // State computed time is decided by the audio callback's buffer length. We + // compute the iteration start and end from there, trying to keep the amount + // of buffering in the graph constant. + mNextStateComputedTime = + mGraphImpl->RoundUpToNextAudioBlock(mStateComputedTime + mBuffer.Available()); - mIterationStart = mIterationEnd; - // inGraph is the number of audio frames there is between the state time and - // the current time, i.e. the maximum theoretical length of the interval we - // could use as [mIterationStart; mIterationEnd]. - GraphTime inGraph = mStateComputedTime - mIterationStart; - // We want the interval [mIterationStart; mIterationEnd] to be before the - // interval [mStateComputedTime; mNextStateComputedTime]. We also want - // the distance between these intervals to be roughly equivalent each time, to - // ensure there is no clock drift between current time and state time. Since - // we can't act on the state time because we have to fill the audio buffer, we - // reclock the current time against the state time, here. - mIterationEnd = mIterationStart + 0.8 * inGraph; + mIterationStart = mIterationEnd; + // inGraph is the number of audio frames there is between the state time and + // the current time, i.e. the maximum theoretical length of the interval we + // could use as [mIterationStart; mIterationEnd]. + GraphTime inGraph = mStateComputedTime - mIterationStart; + // We want the interval [mIterationStart; mIterationEnd] to be before the + // interval [mStateComputedTime; mNextStateComputedTime]. We also want + // the distance between these intervals to be roughly equivalent each time, to + // ensure there is no clock drift between current time and state time. Since + // we can't act on the state time because we have to fill the audio buffer, we + // reclock the current time against the state time, here. + mIterationEnd = mIterationStart + 0.8 * inGraph; - STREAM_LOG(PR_LOG_DEBUG, ("interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) (duration ticks: %ld)\n", - (long)mIterationStart, (long)mIterationEnd, - (long)mStateComputedTime, (long)mNextStateComputedTime, - (long)aFrames, (uint32_t)durationMS, - (long)(mNextStateComputedTime - mStateComputedTime))); + STREAM_LOG(PR_LOG_DEBUG, ("interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) (duration ticks: %ld)\n", + (long)mIterationStart, (long)mIterationEnd, + (long)mStateComputedTime, (long)mNextStateComputedTime, + (long)aFrames, (uint32_t)durationMS, + (long)(mNextStateComputedTime - mStateComputedTime))); - mCurrentTimeStamp = TimeStamp::Now(); + mCurrentTimeStamp = TimeStamp::Now(); - if (mStateComputedTime < mIterationEnd) { - STREAM_LOG(PR_LOG_WARNING, ("Media graph global underrun detected")); - mIterationEnd = mStateComputedTime; - } + if (mStateComputedTime < mIterationEnd) { + STREAM_LOG(PR_LOG_WARNING, ("Media graph global underrun detected")); + mIterationEnd = mStateComputedTime; + } - stillProcessing = mGraphImpl->OneIteration(mIterationStart, - mIterationEnd, - mStateComputedTime, - mNextStateComputedTime); + stillProcessing = mGraphImpl->OneIteration(mIterationStart, + mIterationEnd, + mStateComputedTime, + mNextStateComputedTime); + } else { + NS_WARNING("DataCallback buffer filled entirely from scratch buffer, skipping iteration."); + stillProcessing = true; + } mBuffer.BufferFilled(); if (mNextDriver && stillProcessing) { { // If the audio stream has not been started by the previous driver or // the graph itself, keep it alive. MonitorAutoLock mon(mGraphImpl->GetMonitor()); @@ -891,17 +899,17 @@ AudioCallbackDriver::MixerCallback(Audio AudioSampleFormat aFormat, uint32_t aChannels, uint32_t aFrames, uint32_t aSampleRate) { uint32_t toWrite = mBuffer.Available(); if (!mBuffer.Available()) { - NS_WARNING("MediaStreamGraph SpillBuffer full, expect frame drop."); + NS_WARNING("DataCallback buffer full, expect frame drops."); } MOZ_ASSERT(mBuffer.Available() <= aFrames); mBuffer.WriteFrames(aMixedBuffer, mBuffer.Available()); MOZ_ASSERT(mBuffer.Available() == 0, "Missing frames to fill audio callback's buffer."); DebugOnly<uint32_t> written = mScratchBuffer.Fill(aMixedBuffer + toWrite * aChannels, aFrames - toWrite);
--- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -1149,19 +1149,19 @@ void MediaDecoderStateMachine::StartPlay DECODER_LOG("Offloading playback"); return; } mDecoder->NotifyPlaybackStarted(); SetPlayStartTime(TimeStamp::Now()); NS_ASSERTION(IsPlaying(), "Should report playing by end of StartPlayback()"); - nsresult rv = StartAudioThread(); - NS_ENSURE_SUCCESS_VOID(rv); - + if (NS_FAILED(StartAudioThread())) { + DECODER_WARN("Failed to create audio thread"); + } mDecoder->GetReentrantMonitor().NotifyAll(); mDecoder->UpdateStreamBlockingForStateMachinePlaying(); DispatchDecodeTasksIfNeeded(); } void MediaDecoderStateMachine::UpdatePlaybackPositionInternal(int64_t aTime) { SAMPLE_LOG("UpdatePlaybackPositionInternal(%lld) (mStartTime=%lld)", aTime, mStartTime); @@ -1786,22 +1786,25 @@ MediaDecoderStateMachine::StartAudioThre if (mAudioCaptured) { NS_ASSERTION(mStopAudioThread, "mStopAudioThread must always be true if audio is captured"); return NS_OK; } mStopAudioThread = false; if (HasAudio() && !mAudioSink) { mAudioCompleted = false; - mAudioSink = new AudioSink(this, mAudioStartTime, - mInfo.mAudio, mDecoder->GetAudioChannel()); - // OnAudioSinkError() will be called before Init() returns if an error - // occurs during initialization. + mAudioSink = new AudioSink(this, + mAudioStartTime, mInfo.mAudio, mDecoder->GetAudioChannel()); nsresult rv = mAudioSink->Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + DECODER_WARN("Changed state to SHUTDOWN because audio sink initialization failed"); + SetState(DECODER_STATE_SHUTDOWN); + mScheduler->ScheduleAndShutdown(); + return rv; + } mAudioSink->SetVolume(mVolume); mAudioSink->SetPlaybackRate(mPlaybackRate); mAudioSink->SetPreservesPitch(mPreservesPitch); } return NS_OK; } @@ -3116,34 +3119,15 @@ void MediaDecoderStateMachine::OnAudioSi return; } mAudioCompleted = true; UpdateReadyState(); // Kick the decode thread; it may be sleeping waiting for this to finish. mDecoder->GetReentrantMonitor().NotifyAll(); } -void MediaDecoderStateMachine::OnAudioSinkError() -{ - AssertCurrentThreadInMonitor(); - // AudioSink not used with captured streams, so ignore errors in this case. - if (mAudioCaptured) { - return; - } - - mAudioCompleted = true; - - // Notify media decoder/element about this error. - RefPtr<nsIRunnable> task( - NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnDecodeError)); - nsresult rv = mDecodeTaskQueue->Dispatch(task); - if (NS_FAILED(rv)) { - DECODER_WARN("Failed to dispatch OnDecodeError"); - } -} - } // namespace mozilla // avoid redefined macro in unified build #undef DECODER_LOG #undef VERBOSE_LOG #undef DECODER_WARN #undef DECODER_WARN_HELPER
--- a/content/media/MediaDecoderStateMachine.h +++ b/content/media/MediaDecoderStateMachine.h @@ -631,19 +631,16 @@ protected: // Update mDecoder's playback offset. void OnPlaybackOffsetUpdate(int64_t aPlaybackOffset); // Called by the AudioSink to signal that all outstanding work is complete // and the sink is shutting down. void OnAudioSinkComplete(); - // Called by the AudioSink to signal errors. - void OnAudioSinkError(); - // The decoder object that created this state machine. The state machine // holds a strong reference to the decoder to ensure that the decoder stays // alive once media element has started the decoder shutdown process, and has // dropped its reference to the decoder. This enables the state machine to // keep using the decoder's monitor until the state machine has finished // shutting down, without fear of the monitor being destroyed. After // shutting down, the state machine will then release this reference, // causing the decoder to be destroyed. This is accessed on the decode,
--- a/content/media/MediaStreamGraphImpl.h +++ b/content/media/MediaStreamGraphImpl.h @@ -148,18 +148,26 @@ public: * Called before the thread runs. */ void Init(); // The following methods run on the graph thread (or possibly the main thread if // mLifecycleState > LIFECYCLE_RUNNING) void AssertOnGraphThreadOrNotRunning() { // either we're on the right thread (and calling CurrentDriver() is safe), // or we're going to assert anyways, so don't cross-check CurrentDriver - MOZ_ASSERT(mDriver->OnThread() || - (mLifecycleState > LIFECYCLE_RUNNING && NS_IsMainThread())); +#ifdef DEBUG + // if all the safety checks fail, assert we own the monitor + if (!mDriver->OnThread()) { + if (!(mDetectedNotRunning && + mLifecycleState > LIFECYCLE_RUNNING && + NS_IsMainThread())) { + mMonitor.AssertCurrentThreadOwns(); + } + } +#endif } /* * This does the actual iteration: Message processing, MediaStream ordering, * blocking computation and processing. */ void DoIteration(); bool OneIteration(GraphTime aFrom, GraphTime aTo, @@ -419,40 +427,30 @@ public: */ void PausedIndefinitly(); void ResumedFromPaused(); /** * Not safe to call off the MediaStreamGraph thread unless monitor is held! */ GraphDriver* CurrentDriver() { -#ifdef DEBUG - // #ifdef since we're not wrapping it all in MOZ_ASSERT() - if (!mDriver->OnThread()) { - mMonitor.AssertCurrentThreadOwns(); - } -#endif + AssertOnGraphThreadOrNotRunning(); return mDriver; } /** * Effectively set the new driver, while we are switching. * It is only safe to call this at the very end of an iteration, when there * has been a SwitchAtNextIteration call during the iteration. The driver * should return and pass the control to the new driver shortly after. * We can also switch from Revive() (on MainThread), in which case the * monitor is held */ void SetCurrentDriver(GraphDriver* aDriver) { -#ifdef DEBUG - // #ifdef since we're not wrapping it all in MOZ_ASSERT() - if (!mDriver->OnThread()) { - mMonitor.AssertCurrentThreadOwns(); - } -#endif + AssertOnGraphThreadOrNotRunning(); mDriver = aDriver; } Monitor& GetMonitor() { return mMonitor; } void EnsureNextIteration() {
--- a/content/svg/content/src/SVGContentUtils.cpp +++ b/content/svg/content/src/SVGContentUtils.cpp @@ -117,20 +117,31 @@ GetStrokeDashData(SVGContentUtils::AutoS if (dashLength < 0.0) { return eContinuousStroke; // invalid } dashPattern[i] = dashLength; (i % 2 ? totalLengthOfGaps : totalLengthOfDashes) += dashLength; } } - // Now that aStrokeOptions.mDashPattern is fully initialized we can safely - // set mDashLength: + // Now that aStrokeOptions.mDashPattern is fully initialized (we didn't + // return early above) we can safely set mDashLength: aStrokeOptions->mDashLength = dashArrayLength; + if ((dashArrayLength % 2) == 1) { + // If we have a dash pattern with an odd number of lengths the pattern + // repeats a second time, per the SVG spec., and as implemented by Moz2D. + // When deciding whether to return eNoStroke or eContinuousStroke below we + // need to take into account that in the repeat pattern the dashes become + // gaps, and the gaps become dashes. + Float origTotalLengthOfDashes = totalLengthOfDashes; + totalLengthOfDashes += totalLengthOfGaps; + totalLengthOfGaps += origTotalLengthOfDashes; + } + if (totalLengthOfDashes <= 0 || totalLengthOfGaps <= 0) { if (totalLengthOfGaps > 0 && totalLengthOfDashes <= 0) { return eNoStroke; } return eContinuousStroke; } if (aContextPaint && aStyleSVG->mStrokeDashoffsetFromObject) { @@ -167,19 +178,19 @@ SVGContentUtils::GetStrokeOptions(AutoSt DashState dashState = GetStrokeDashData(aStrokeOptions, aElement, styleSVG, aContextPaint); if (dashState == eNoStroke) { // Hopefully this will shortcircuit any stroke operations: aStrokeOptions->mLineWidth = 0; return; } - if (dashState == eContinuousStroke) { - // Prevent our caller from wasting time looking at the dash array: - aStrokeOptions->mDashLength = 0; + if (dashState == eContinuousStroke && aStrokeOptions->mDashPattern) { + // Prevent our caller from wasting time looking at a pattern without gaps: + aStrokeOptions->DiscardDashPattern(); } aStrokeOptions->mLineWidth = GetStrokeWidth(aElement, styleContext, aContextPaint); aStrokeOptions->mMiterLimit = Float(styleSVG->mStrokeMiterlimit); switch (styleSVG->mStrokeLinejoin) {
--- a/content/svg/content/src/SVGContentUtils.h +++ b/content/svg/content/src/SVGContentUtils.h @@ -111,16 +111,23 @@ public: mDashPattern = mSmallArray; return mSmallArray; } static const mozilla::fallible_t fallible = mozilla::fallible_t(); Float* nonConstArray = new (fallible) Float[aDashCount]; mDashPattern = nonConstArray; return nonConstArray; } + void DiscardDashPattern() { + if (mDashPattern && mDashPattern != mSmallArray) { + delete [] mDashPattern; + } + mDashLength = 0; + mDashPattern = nullptr; + } private: // Most dasharrays will fit in this and save us allocating Float mSmallArray[16]; }; static void GetStrokeOptions(AutoStrokeOptions* aStrokeOptions, nsSVGElement* aElement, nsStyleContext* aStyleContext,
--- a/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp +++ b/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp @@ -22,16 +22,17 @@ #include "nsIMobileConnectionService.h" #include "nsIMobileNetworkInfo.h" #include "nsIObserverService.h" #include "nsISettingsService.h" #include "nsITelephonyService.h" #include "nsRadioInterfaceLayer.h" #include "nsServiceManagerUtils.h" #include "nsThreadUtils.h" +#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/SettingChangeNotificationBinding.h" #define MOZSETTINGS_CHANGED_ID "mozsettings-changed" #define AUDIO_VOLUME_BT_SCO_ID "audio.volume.bt_sco" using namespace mozilla; using namespace mozilla::ipc; USING_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth2/bluez/BluetoothHfpManager.cpp +++ b/dom/bluetooth2/bluez/BluetoothHfpManager.cpp @@ -18,16 +18,17 @@ #include "jsapi.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/Services.h" #include "mozilla/StaticPtr.h" #include "nsContentUtils.h" #include "nsIObserverService.h" #include "nsISettingsService.h" #include "nsServiceManagerUtils.h" +#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/SettingChangeNotificationBinding.h" #ifdef MOZ_B2G_RIL #include "nsIDOMIccInfo.h" #include "nsIIccProvider.h" #include "nsIMobileConnectionInfo.h" #include "nsIMobileConnectionService.h" #include "nsIMobileNetworkInfo.h"
--- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -6809,32 +6809,44 @@ TransactionBase::VerifyRequestParams(con if (NS_WARN_IF(!VerifyRequestParams(params.optionalKeyRange()))) { ASSERT_UNLESS_FUZZING(); return false; } break; } case RequestParams::TObjectStoreDeleteParams: { + if (NS_WARN_IF(mMode != IDBTransaction::READ_WRITE && + mMode != IDBTransaction::VERSION_CHANGE)) { + ASSERT_UNLESS_FUZZING(); + return false; + } + const ObjectStoreDeleteParams& params = aParams.get_ObjectStoreDeleteParams(); const nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata = GetMetadataForObjectStoreId(params.objectStoreId()); if (NS_WARN_IF(!objectStoreMetadata)) { ASSERT_UNLESS_FUZZING(); return false; } if (NS_WARN_IF(!VerifyRequestParams(params.keyRange()))) { ASSERT_UNLESS_FUZZING(); return false; } break; } case RequestParams::TObjectStoreClearParams: { + if (NS_WARN_IF(mMode != IDBTransaction::READ_WRITE && + mMode != IDBTransaction::VERSION_CHANGE)) { + ASSERT_UNLESS_FUZZING(); + return false; + } + const ObjectStoreClearParams& params = aParams.get_ObjectStoreClearParams(); const nsRefPtr<FullObjectStoreMetadata> objectStoreMetadata = GetMetadataForObjectStoreId(params.objectStoreId()); if (NS_WARN_IF(!objectStoreMetadata)) { ASSERT_UNLESS_FUZZING(); return false; }
--- a/dom/nfc/NfcContentHelper.js +++ b/dom/nfc/NfcContentHelper.js @@ -45,41 +45,29 @@ if (DEBUG) { } const NFCCONTENTHELPER_CID = Components.ID("{4d72c120-da5f-11e1-9b23-0800200c9a66}"); const NFC_IPC_MSG_NAMES = [ "NFC:ReadNDEFResponse", "NFC:WriteNDEFResponse", - "NFC:GetDetailsNDEFResponse", "NFC:MakeReadOnlyNDEFResponse", "NFC:ConnectResponse", "NFC:CloseResponse", "NFC:CheckP2PRegistrationResponse", "NFC:DOMEvent", "NFC:NotifySendFileStatusResponse", "NFC:ConfigResponse" ]; XPCOMUtils.defineLazyServiceGetter(this, "cpmm", "@mozilla.org/childprocessmessagemanager;1", "nsISyncMessageSender"); -function GetDetailsNDEFResponse(details) { - this.canBeMadeReadOnly = details.canBeMadeReadOnly; - this.isReadOnly = details.isReadOnly; - this.maxSupportedLength = details.maxSupportedLength; -} -GetDetailsNDEFResponse.prototype = { - __exposedProps__ : {canBeMadeReadOnly: 'r', - isReadOnly: 'r', - maxSupportedLength: 'r'} -}; - function NfcContentHelper() { this.initDOMRequestHelper(/* aWindow */ null, NFC_IPC_MSG_NAMES); Services.obs.addObserver(this, "xpcom-shutdown", false); this._requestMap = []; } NfcContentHelper.prototype = { @@ -122,32 +110,16 @@ NfcContentHelper.prototype = { // Report session to Nfc.js only. let val = cpmm.sendSyncMessage("NFC:CheckSessionToken", { sessionToken: sessionToken }); return (val[0] === NFC.NFC_SUCCESS); }, // NFCTag interface - getDetailsNDEF: function getDetailsNDEF(window, sessionToken) { - if (window == null) { - throw Components.Exception("Can't get window object", - Cr.NS_ERROR_UNEXPECTED); - } - let request = Services.DOMRequest.createRequest(window); - let requestId = btoa(this.getRequestId(request)); - this._requestMap[requestId] = window; - - cpmm.sendAsyncMessage("NFC:GetDetailsNDEF", { - requestId: requestId, - sessionToken: sessionToken - }); - return request; - }, - readNDEF: function readNDEF(window, sessionToken) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = btoa(this.getRequestId(request)); this._requestMap[requestId] = window; @@ -390,19 +362,16 @@ NfcContentHelper.prototype = { receiveMessage: function receiveMessage(message) { DEBUG && debug("Message received: " + JSON.stringify(message)); let result = message.json; switch (message.name) { case "NFC:ReadNDEFResponse": this.handleReadNDEFResponse(result); break; - case "NFC:GetDetailsNDEFResponse": - this.handleGetDetailsNDEFResponse(result); - break; case "NFC:CheckP2PRegistrationResponse": this.handleCheckP2PRegistrationResponse(result); break; case "NFC:ConnectResponse": // Fall through. case "NFC:CloseResponse": case "NFC:WriteNDEFResponse": case "NFC:MakeReadOnlyNDEFResponse": case "NFC:NotifySendFileStatusResponse": @@ -447,26 +416,16 @@ NfcContentHelper.prototype = { ndefMsg.push(new requester.MozNDEFRecord({tnf: record.tnf, type: record.type, id: record.id, payload: record.payload})); } this.fireRequestSuccess(requestId, ndefMsg); }, - handleGetDetailsNDEFResponse: function handleGetDetailsNDEFResponse(result) { - if (result.errorMsg) { - this.fireRequestError(atob(result.requestId), result.errorMsg); - return; - } - - let requestId = atob(result.requestId); - this.fireRequestSuccess(requestId, new GetDetailsNDEFResponse(result)); - }, - handleCheckP2PRegistrationResponse: function handleCheckP2PRegistrationResponse(result) { // Privilaged status API. Always fire success to avoid using exposed props. // The receiver must check the boolean mapped status code to handle. let requestId = atob(result.requestId); this.fireRequestSuccess(requestId, !result.errorMsg); }, };
--- a/dom/nfc/gonk/Nfc.js +++ b/dom/nfc/gonk/Nfc.js @@ -52,17 +52,16 @@ const NFC_IPC_ADD_EVENT_TARGET_MSG_NAMES ]; const NFC_IPC_MSG_NAMES = [ "NFC:CheckSessionToken" ]; const NFC_IPC_READ_PERM_MSG_NAMES = [ "NFC:ReadNDEF", - "NFC:GetDetailsNDEF", "NFC:Connect", "NFC:Close", ]; const NFC_IPC_WRITE_PERM_MSG_NAMES = [ "NFC:WriteNDEF", "NFC:MakeReadOnlyNDEF", "NFC:SendFile", @@ -258,17 +257,17 @@ XPCOMUtils.defineLazyGetter(this, "gMess */ receiveMessage: function receiveMessage(message) { DEBUG && debug("Received message from content process: " + JSON.stringify(message)); if (message.name == "child-process-shutdown") { this.removePeerTarget(message.target); this.nfc.removeTarget(message.target); - this.removeEventTarget(msg.target); + this.removeEventTarget(message.target); return null; } if (NFC_IPC_MSG_NAMES.indexOf(message.name) != -1 || NFC_IPC_ADD_EVENT_TARGET_MSG_NAMES.indexOf(message.name) != -1 ) { // Do nothing. } else if (NFC_IPC_READ_PERM_MSG_NAMES.indexOf(message.name) != -1) { if (!message.target.assertPermission("nfc-read")) { @@ -533,17 +532,16 @@ Nfc.prototype = { if (message.status === NFC.NFC_SUCCESS) { this.powerLevel = message.powerLevel; } this.sendNfcResponse(message); break; case "ConnectResponse": // Fall through. case "CloseResponse": - case "GetDetailsNDEFResponse": case "ReadNDEFResponse": case "MakeReadOnlyNDEFResponse": case "WriteNDEFResponse": this.sendNfcResponse(message); break; default: throw new Error("Don't know about this message type: " + message.type); } @@ -603,19 +601,16 @@ Nfc.prototype = { case "NFC:StopPoll": this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_LOW, requestId: message.data.requestId}); break; case "NFC:PowerOff": this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_DISABLED, requestId: message.data.requestId}); break; - case "NFC:GetDetailsNDEF": - this.sendToNfcService("getDetailsNDEF", message.data); - break; case "NFC:ReadNDEF": this.sendToNfcService("readNDEF", message.data); break; case "NFC:WriteNDEF": this.sendToNfcService("writeNDEF", message.data); break; case "NFC:MakeReadOnlyNDEF": this.sendToNfcService("makeReadOnlyNDEF", message.data);
--- a/dom/nfc/gonk/NfcGonkMessage.h +++ b/dom/nfc/gonk/NfcGonkMessage.h @@ -3,32 +3,30 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef NfcGonkMessage_h #define NfcGonkMessage_h namespace mozilla { #define NFCD_MAJOR_VERSION 1 -#define NFCD_MINOR_VERSION 9 +#define NFCD_MINOR_VERSION 10 enum NfcRequest { ConfigReq = 0, ConnectReq, CloseReq, - GetDetailsNDEFReq, ReadNDEFReq, WriteNDEFReq, MakeReadOnlyNDEFReq, }; enum NfcResponse { GeneralRsp = 1000, ConfigRsp, - GetDetailsNDEFRsp, ReadNDEFRsp, }; enum NfcNotification { Initialized = 2000, TechDiscovered, TechLost, HCIEventTransaction,
--- a/dom/nfc/gonk/NfcMessageHandler.cpp +++ b/dom/nfc/gonk/NfcMessageHandler.cpp @@ -12,25 +12,23 @@ #include <android/log.h> #define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "NfcMessageHandler", args) using namespace android; using namespace mozilla; using namespace mozilla::dom; static const char* kConfigRequest = "config"; -static const char* kGetDetailsNDEF = "getDetailsNDEF"; static const char* kReadNDEFRequest = "readNDEF"; static const char* kWriteNDEFRequest = "writeNDEF"; static const char* kMakeReadOnlyNDEFRequest = "makeReadOnlyNDEF"; static const char* kConnectRequest = "connect"; static const char* kCloseRequest = "close"; static const char* kConfigResponse = "ConfigResponse"; -static const char* kGetDetailsNDEFResponse = "GetDetailsNDEFResponse"; static const char* kReadNDEFResponse = "ReadNDEFResponse"; static const char* kWriteNDEFResponse = "WriteNDEFResponse"; static const char* kMakeReadOnlyNDEFResponse = "MakeReadOnlyNDEFResponse"; static const char* kConnectResponse = "ConnectResponse"; static const char* kCloseResponse = "CloseResponse"; static const char* kInitializedNotification = "InitializedNotification"; static const char* kTechDiscoveredNotification = "TechDiscoveredNotification"; @@ -41,18 +39,16 @@ static const char* kHCIEventTransactionN bool NfcMessageHandler::Marshall(Parcel& aParcel, const CommandOptions& aOptions) { bool result; const char* type = NS_ConvertUTF16toUTF8(aOptions.mType).get(); if (!strcmp(type, kConfigRequest)) { result = ConfigRequest(aParcel, aOptions); - } else if (!strcmp(type, kGetDetailsNDEF)) { - result = GetDetailsNDEFRequest(aParcel, aOptions); } else if (!strcmp(type, kReadNDEFRequest)) { result = ReadNDEFRequest(aParcel, aOptions); } else if (!strcmp(type, kWriteNDEFRequest)) { result = WriteNDEFRequest(aParcel, aOptions); mPendingReqQueue.AppendElement(NfcRequest::WriteNDEFReq); } else if (!strcmp(type, kMakeReadOnlyNDEFRequest)) { result = MakeReadOnlyNDEFRequest(aParcel, aOptions); mPendingReqQueue.AppendElement(NfcRequest::MakeReadOnlyNDEFReq); @@ -78,19 +74,16 @@ NfcMessageHandler::Unmarshall(const Parc switch (type) { case NfcResponse::GeneralRsp: result = GeneralResponse(aParcel, aOptions); break; case NfcResponse::ConfigRsp: result = ConfigResponse(aParcel, aOptions); break; - case NfcResponse::GetDetailsNDEFRsp: - result = GetDetailsNDEFResponse(aParcel, aOptions); - break; case NfcResponse::ReadNDEFRsp: result = ReadNDEFResponse(aParcel, aOptions); break; case NfcNotification::Initialized: result = InitializeNotification(aParcel, aOptions); break; case NfcNotification::TechDiscovered: result = TechDiscoveredNotification(aParcel, aOptions); @@ -167,45 +160,16 @@ NfcMessageHandler::ConfigResponse(const NS_ENSURE_TRUE(!mPowerLevelQueue.IsEmpty(), false); aOptions.mPowerLevel = mPowerLevelQueue[0]; mPowerLevelQueue.RemoveElementAt(0); return true; } bool -NfcMessageHandler::GetDetailsNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions) -{ - aParcel.writeInt32(NfcRequest::GetDetailsNDEFReq); - aParcel.writeInt32(aOptions.mSessionId); - mRequestIdQueue.AppendElement(aOptions.mRequestId); - return true; -} - -bool -NfcMessageHandler::GetDetailsNDEFResponse(const Parcel& aParcel, EventOptions& aOptions) -{ - aOptions.mType = NS_ConvertUTF8toUTF16(kGetDetailsNDEFResponse); - aOptions.mStatus = aParcel.readInt32(); - aOptions.mSessionId = aParcel.readInt32(); - - if (aOptions.mStatus == NfcErrorCode::Success) { - int readOnly = aParcel.readInt32(); - aOptions.mIsReadOnly = readOnly & 0xff; - aOptions.mCanBeMadeReadOnly = (readOnly >> 8) & 0xff; - aOptions.mMaxSupportedLength = aParcel.readInt32(); - } - - NS_ENSURE_TRUE(!mRequestIdQueue.IsEmpty(), false); - aOptions.mRequestId = mRequestIdQueue[0]; - mRequestIdQueue.RemoveElementAt(0); - return true; -} - -bool NfcMessageHandler::ReadNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions) { aParcel.writeInt32(NfcRequest::ReadNDEFReq); aParcel.writeInt32(aOptions.mSessionId); mRequestIdQueue.AppendElement(aOptions.mRequestId); return true; }
--- a/dom/nfc/gonk/NfcMessageHandler.h +++ b/dom/nfc/gonk/NfcMessageHandler.h @@ -22,18 +22,16 @@ class NfcMessageHandler public: bool Marshall(android::Parcel& aParcel, const CommandOptions& aOptions); bool Unmarshall(const android::Parcel& aParcel, EventOptions& aOptions); private: bool GeneralResponse(const android::Parcel& aParcel, EventOptions& aOptions); bool ConfigRequest(android::Parcel& aParcel, const CommandOptions& options); bool ConfigResponse(const android::Parcel& aParcel, EventOptions& aOptions); - bool GetDetailsNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); - bool GetDetailsNDEFResponse(const android::Parcel& aParcel, EventOptions& aOptions); bool ReadNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); bool ReadNDEFResponse(const android::Parcel& aParcel, EventOptions& aOptions); bool WriteNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); bool MakeReadOnlyNDEFRequest(android::Parcel& aParcel, const CommandOptions& options); bool ConnectRequest(android::Parcel& aParcel, const CommandOptions& options); bool CloseRequest(android::Parcel& aParcel, const CommandOptions& options); bool InitializeNotification(const android::Parcel& aParcel, EventOptions& aOptions);
--- a/dom/nfc/nsINfcContentHelper.idl +++ b/dom/nfc/nsINfcContentHelper.idl @@ -22,25 +22,24 @@ interface nsINfcDOMEventTarget : nsISupp * Callback function used to notify peerlost. * * @param sessionToken * SessionToken received from Chrome process */ void notifyPeerLost(in DOMString sessionToken); }; -[scriptable, uuid(7eaf4c31-e1d1-422e-aa55-181f4eb156b0)] +[scriptable, uuid(d3f1bdc1-048f-44a8-abe2-bc386edce40b)] interface nsINfcContentHelper : nsISupports { const long NFC_EVENT_PEER_READY = 0x01; const long NFC_EVENT_PEER_LOST = 0x02; boolean checkSessionToken(in DOMString sessionToken); - nsIDOMDOMRequest getDetailsNDEF(in nsIDOMWindow window, in DOMString sessionToken); nsIDOMDOMRequest readNDEF(in nsIDOMWindow window, in DOMString sessionToken); nsIDOMDOMRequest writeNDEF(in nsIDOMWindow window, in nsIVariant records, in DOMString sessionToken); nsIDOMDOMRequest makeReadOnlyNDEF(in nsIDOMWindow window, in DOMString sessionToken); nsIDOMDOMRequest connect(in nsIDOMWindow window, in unsigned long techType, in DOMString sessionToken); nsIDOMDOMRequest close(in nsIDOMWindow window, in DOMString sessionToken); /**
--- a/dom/resourcestats/ResourceStatsDB.jsm +++ b/dom/resourcestats/ResourceStatsDB.jsm @@ -9,16 +9,17 @@ this.EXPORTED_SYMBOLS = ['ResourceStatsD const DEBUG = false; function debug(s) { dump("-*- ResourceStatsDB: " + s + "\n"); } const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/IndexedDBHelper.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.importGlobalProperties(["indexedDB"]); XPCOMUtils.defineLazyServiceGetter(this, "appsService", "@mozilla.org/AppsService;1", "nsIAppsService"); const DB_NAME = "resource_stats"; const DB_VERSION = 1; const POWER_STATS_STORE = "power_stats_store";
--- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -2425,20 +2425,20 @@ WorkerPrivateParent<Derived>::NotifyPriv template <class Derived> bool WorkerPrivateParent<Derived>::Suspend(JSContext* aCx, nsPIDOMWindow* aWindow) { AssertIsOnParentThread(); MOZ_ASSERT(aCx); // Shared workers are only suspended if all of their owning documents are - // suspended. - if (IsSharedWorker() || IsServiceWorker()) { + // suspended. It can happen that mSharedWorkers is empty but this thread has + // not been unregistered yet. + if ((IsSharedWorker() || IsServiceWorker()) && mSharedWorkers.Count()) { AssertIsOnMainThread(); - MOZ_ASSERT(mSharedWorkers.Count()); struct Closure { nsPIDOMWindow* mWindow; bool mAllSuspended; explicit Closure(nsPIDOMWindow* aWindow) : mWindow(aWindow), mAllSuspended(true) @@ -2510,19 +2510,20 @@ template <class Derived> bool WorkerPrivateParent<Derived>::Resume(JSContext* aCx, nsPIDOMWindow* aWindow) { AssertIsOnParentThread(); MOZ_ASSERT(aCx); MOZ_ASSERT_IF(IsDedicatedWorker(), mParentSuspended); // Shared workers are resumed if any of their owning documents are resumed. - if (IsSharedWorker() || IsServiceWorker()) { + // It can happen that mSharedWorkers is empty but this thread has not been + // unregistered yet. + if ((IsSharedWorker() || IsServiceWorker()) && mSharedWorkers.Count()) { AssertIsOnMainThread(); - MOZ_ASSERT(mSharedWorkers.Count()); struct Closure { nsPIDOMWindow* mWindow; bool mAnyRunning; explicit Closure(nsPIDOMWindow* aWindow) : mWindow(aWindow), mAnyRunning(false)
--- a/gfx/2d/HelpersD2D.h +++ b/gfx/2d/HelpersD2D.h @@ -462,17 +462,20 @@ CreateStrokeStyleForOptions(const Stroke break; case JoinStyle::BEVEL: joinStyle = D2D1_LINE_JOIN_BEVEL; break; } HRESULT hr; - if (aStrokeOptions.mDashPattern) { + // We need to check mDashLength in addition to mDashPattern here since if + // mDashPattern is set but mDashLength is zero then the stroke will fail to + // paint. + if (aStrokeOptions.mDashLength > 0 && aStrokeOptions.mDashPattern) { typedef std::vector<Float> FloatVector; // D2D "helpfully" multiplies the dash pattern by the line width. // That's not what cairo does, or is what <canvas>'s dash wants. // So fix the multiplication in advance. Float lineWidth = aStrokeOptions.mLineWidth; FloatVector dash(aStrokeOptions.mDashPattern, aStrokeOptions.mDashPattern + aStrokeOptions.mDashLength); for (FloatVector::iterator it = dash.begin(); it != dash.end(); ++it) {
--- a/gfx/cairo/cairo/src/cairo-image-surface.c +++ b/gfx/cairo/cairo/src/cairo-image-surface.c @@ -1080,16 +1080,22 @@ static pixman_image_t * cache[i].image = pixman_image_ref (image); cache[i].color = pattern->color; UNLOCK: CAIRO_MUTEX_UNLOCK (_cairo_image_solid_cache_mutex); return image; } +static double +clamp (double val, double min, double max) +{ + return val < min ? min : (val > max ? max : val); +} + static pixman_image_t * _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern, const cairo_rectangle_int_t *extents, int *ix, int *iy) { pixman_image_t *pixman_image; pixman_gradient_stop_t pixman_stops_static[2]; pixman_gradient_stop_t *pixman_stops = pixman_stops_static; @@ -1141,16 +1147,17 @@ static pixman_image_t * else sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim); p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf); p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf); p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf); p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf); + /* cairo_matrix_scale does a pre-scale, we want a post-scale */ cairo_matrix_init_scale (&scale, sf, sf); cairo_matrix_multiply (&matrix, &matrix, &scale); } else { p1.x = _cairo_fixed_to_16_16 (linear->p1.x); p1.y = _cairo_fixed_to_16_16 (linear->p1.y); p2.x = _cairo_fixed_to_16_16 (linear->p2.x); @@ -1205,19 +1212,19 @@ static pixman_image_t * inv = matrix; status = cairo_matrix_invert (&inv); assert (status == CAIRO_STATUS_SUCCESS); x = _cairo_lround (inv.x0 / 2); y = _cairo_lround (inv.y0 / 2); max_x = PIXMAN_MAX_INT - 1 - fabs (extents->x + extents->width); - x = x > max_x ? max_x : (x < -max_x ? -max_x : x); + x = clamp(x, -max_x, max_x); max_y = PIXMAN_MAX_INT - 1 - fabs (extents->y + extents->height); - y = y > max_y ? max_y : (y < -max_y ? -max_y : y); + y = clamp(y, -max_y, max_y); tx = -x; ty = -y; cairo_matrix_init_translate (&inv, x, y); cairo_matrix_multiply (&m, &inv, &matrix); _cairo_matrix_to_pixman_matrix (&m, &pixman_transform, extents->x + extents->width/2., extents->y + extents->height/2.);
--- a/gfx/cairo/cairo/src/cairo-pattern.c +++ b/gfx/cairo/cairo/src/cairo-pattern.c @@ -1394,16 +1394,17 @@ static cairo_int_status_t else sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim); p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf); p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf); p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf); p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf); + /* cairo_matrix_scale does a pre-scale, we want a post-scale */ cairo_matrix_init_scale (&scale, sf, sf); cairo_matrix_multiply (&matrix, &matrix, &scale); } else { p1.x = _cairo_fixed_to_16_16 (linear->p1.x); p1.y = _cairo_fixed_to_16_16 (linear->p1.y); p2.x = _cairo_fixed_to_16_16 (linear->p2.x);
--- a/gfx/layers/RotatedBuffer.cpp +++ b/gfx/layers/RotatedBuffer.cpp @@ -224,17 +224,17 @@ RotatedContentBuffer::DrawTo(PaintedLaye (ToData(aLayer)->GetClipToVisibleRegion() && !aLayer->GetVisibleRegion().Contains(BufferRect())) || IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) { // We don't want to draw invalid stuff, so we need to clip. Might as // well clip to the smallest area possible --- the visible region. // Bug 599189 if there is a non-integer-translation transform in aTarget, // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong // and may cause gray lines. - gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion()); + gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion()); clipped = true; } DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aOp, aMask, aMaskTransform); if (clipped) { aTarget->PopClip(); } }
--- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -217,18 +217,21 @@ class TiledLayerComposer { public: /** * Update the current retained layer with the updated layer data. * It is expected that the tiles described by aTiledDescriptor are all in the * ReadLock state, so that the locks can be adopted when recreating a * ClientTiledLayerBuffer locally. This lock will be retained until the buffer * has completed uploading. + * + * Returns false if a deserialization error happened, in which case we will + * have to kill the child process. */ - virtual void UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, + virtual bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, const SurfaceDescriptorTiles& aTiledDescriptor) = 0; /** * If some part of the buffer is being rendered at a lower precision, this * returns that region. If it is not, an empty region will be returned. */ virtual const nsIntRegion& GetValidLowPrecisionRegion() const = 0;
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -1573,18 +1573,19 @@ nsEventStatus AsyncPanZoomController::On mY.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.y, aEvent.mTime); ScreenPoint panDisplacement = aEvent.mPanDisplacement; ToGlobalScreenCoordinates(&panDisplacement, aEvent.mPanStartPoint); HandlePanningUpdate(panDisplacement); // TODO: Handle pan events sent without pan begin / pan end events properly. if (mPanGestureState) { + ScreenPoint panDistance(fabs(panDisplacement.x), fabs(panDisplacement.y)); OverscrollHandoffState handoffState( - *mPanGestureState->GetOverscrollHandoffChain(), panDisplacement); + *mPanGestureState->GetOverscrollHandoffChain(), panDistance); CallDispatchScroll(aEvent.mPanStartPoint, aEvent.mPanStartPoint + aEvent.mPanDisplacement, handoffState); } return nsEventStatus_eConsumeNoDefault; } nsEventStatus AsyncPanZoomController::OnPanEnd(const PanGestureInput& aEvent) { @@ -2644,16 +2645,17 @@ bool AsyncPanZoomController::IsCurrently ReentrantMonitorAutoEnter lock(mMonitor); if (!gfxPrefs::APZAllowCheckerboarding()) { return false; } CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset; CSSRect painted = mLastContentPaintMetrics.mDisplayPort + mLastContentPaintMetrics.GetScrollOffset(); + painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1))); // fuzz for rounding error CSSRect visible = CSSRect(currentScrollOffset, mFrameMetrics.CalculateCompositedSizeInCssPixels()); return !painted.Contains(visible); } void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) { AssertOnCompositorThread(); ReentrantMonitorAutoEnter lock(mMonitor);
--- a/gfx/layers/apz/src/OverscrollHandoffState.h +++ b/gfx/layers/apz/src/OverscrollHandoffState.h @@ -126,16 +126,17 @@ struct OverscrollHandoffState { // The index of the APZC in the chain that we are currently giving scroll to. // This is non-const to indicate that this changes over the course of handoff. uint32_t mChainIndex; // The total distance since touch-start of the pan that triggered the // handoff. This is const to indicate that it does not change over the // course of handoff. + // The x/y components of this are non-negative. const ScreenPoint mPanDistance; }; // Don't pollute other files with this macro for now. #undef NS_INLINE_DECL_THREADSAFE_MUTABLE_REFCOUNTING } }
--- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -25,43 +25,45 @@ namespace mozilla { using namespace gfx; namespace layers { class Layer; TiledLayerBufferComposite::TiledLayerBufferComposite() : mFrameResolution(1.0) , mHasDoubleBufferedTiles(false) - , mUninitialized(true) + , mIsValid(false) {} /* static */ void TiledLayerBufferComposite::RecycleCallback(TextureHost* textureHost, void* aClosure) { textureHost->CompositorRecycle(); } TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator, const SurfaceDescriptorTiles& aDescriptor, const nsIntRegion& aOldPaintedRegion) { - mUninitialized = false; + mIsValid = true; mHasDoubleBufferedTiles = false; mValidRegion = aDescriptor.validRegion(); mPaintedRegion = aDescriptor.paintedRegion(); mRetainedWidth = aDescriptor.retainedWidth(); mRetainedHeight = aDescriptor.retainedHeight(); mResolution = aDescriptor.resolution(); mFrameResolution = CSSToParentLayerScale(aDescriptor.frameResolution()); // Combine any valid content that wasn't already uploaded nsIntRegion oldPaintedRegion(aOldPaintedRegion); oldPaintedRegion.And(oldPaintedRegion, mValidRegion); mPaintedRegion.Or(mPaintedRegion, oldPaintedRegion); + bool isSameProcess = aAllocator->IsSameProcess(); + const InfallibleTArray<TileDescriptor>& tiles = aDescriptor.tiles(); for(size_t i = 0; i < tiles.Length(); i++) { RefPtr<TextureHost> texture; RefPtr<TextureHost> textureOnWhite; const TileDescriptor& tileDesc = tiles[i]; switch (tileDesc.type()) { case TileDescriptor::TTexturedTileDescriptor : { texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent()); @@ -69,16 +71,27 @@ TiledLayerBufferComposite::TiledLayerBuf if (onWhite.type() == MaybeTexture::TPTextureParent) { textureOnWhite = TextureHost::AsTextureHost(onWhite.get_PTextureParent()); } const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock(); nsRefPtr<gfxSharedReadLock> sharedLock; if (ipcLock.type() == TileLock::TShmemSection) { sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection()); } else { + if (!isSameProcess) { + // Trying to use a memory based lock instead of a shmem based one in + // the cross-process case is a bad security violation. + NS_ERROR("A client process may be trying to peek at the host's address space!"); + // This tells the TiledContentHost that deserialization failed so that + // it can propagate the error. + mIsValid = false; + + mRetainedTiles.Clear(); + return; + } sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t()); if (sharedLock) { // The corresponding AddRef is in TiledClient::GetTileDescriptor sharedLock->Release(); } } mRetainedTiles.AppendElement(TileHost(sharedLock, texture, textureOnWhite)); @@ -282,17 +295,17 @@ TiledContentHost::Detach(Layer* aLayer, mTiledBuffer = TiledLayerBufferComposite(); mLowPrecisionTiledBuffer = TiledLayerBufferComposite(); mOldTiledBuffer = TiledLayerBufferComposite(); mOldLowPrecisionTiledBuffer = TiledLayerBufferComposite(); } CompositableHost::Detach(aLayer,aFlags); } -void +bool TiledContentHost::UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, const SurfaceDescriptorTiles& aTiledDescriptor) { if (aTiledDescriptor.resolution() < 1) { if (mPendingLowPrecisionUpload) { mLowPrecisionTiledBuffer.ReadUnlock(); } else { mPendingLowPrecisionUpload = true; @@ -305,29 +318,46 @@ TiledContentHost::UseTiledLayerBuffer(IS if (mLowPrecisionTiledBuffer.HasDoubleBufferedTiles()) { mOldLowPrecisionTiledBuffer = mLowPrecisionTiledBuffer; mOldLowPrecisionTiledBuffer.ReleaseTextureHosts(); } } mLowPrecisionTiledBuffer = TiledLayerBufferComposite(aAllocator, aTiledDescriptor, mLowPrecisionTiledBuffer.GetPaintedRegion()); + if (!mLowPrecisionTiledBuffer.IsValid()) { + // Something bad happened. Stop here, return false (kills the child process), + // and do as little work as possible on the received data as it appears + // to be corrupted. + mPendingLowPrecisionUpload = false; + mPendingUpload = false; + return false; + } } else { if (mPendingUpload) { mTiledBuffer.ReadUnlock(); } else { mPendingUpload = true; if (mTiledBuffer.HasDoubleBufferedTiles()) { mOldTiledBuffer = mTiledBuffer; mOldTiledBuffer.ReleaseTextureHosts(); } } mTiledBuffer = TiledLayerBufferComposite(aAllocator, aTiledDescriptor, mTiledBuffer.GetPaintedRegion()); + if (!mTiledBuffer.IsValid()) { + // Something bad happened. Stop here, return false (kills the child process), + // and do as little work as possible on the received data as it appears + // to be corrupted. + mPendingLowPrecisionUpload = false; + mPendingUpload = false; + return false; + } } + return true; } void TiledContentHost::Composite(EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect,
--- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -132,17 +132,17 @@ public: * don't have an internal buffer, this is unlikely to actually do anything. */ void Upload(); void SetCompositor(Compositor* aCompositor); bool HasDoubleBufferedTiles() { return mHasDoubleBufferedTiles; } - bool IsValid() const { return !mUninitialized; } + bool IsValid() const { return mIsValid; } #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 virtual void SetReleaseFence(const android::sp<android::Fence>& aReleaseFence); #endif // Recycle callback for TextureHost. // Used when TiledContentClient is present in client side. static void RecycleCallback(TextureHost* textureHost, void* aClosure); @@ -157,17 +157,17 @@ protected: void SwapTiles(TileHost& aTileA, TileHost& aTileB) { std::swap(aTileA, aTileB); } void UnlockTile(TileHost aTile) {} void PostValidate(const nsIntRegion& aPaintRegion) {} private: CSSToParentLayerScale mFrameResolution; bool mHasDoubleBufferedTiles; - bool mUninitialized; + bool mIsValid; }; /** * ContentHost for tiled PaintedLayers. Since tiled layers are special snow * flakes, we have a unique update process. All the textures that back the * tiles are added in the usual way, but Updated is called on the host side * in response to a message that describes the transaction for every tile. * Composition happens in the normal way. @@ -210,18 +210,18 @@ public: return false; } const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionTiledBuffer.GetValidRegion(); } - void UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, - const SurfaceDescriptorTiles& aTiledDescriptor); + virtual bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, + const SurfaceDescriptorTiles& aTiledDescriptor) MOZ_OVERRIDE; void Composite(EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion* aVisibleRegion = nullptr);
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp +++ b/gfx/layers/ipc/CompositableTransactionParent.cpp @@ -143,17 +143,20 @@ CompositableParentManager::ReceiveCompos MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); CompositableHost* compositable = AsCompositable(op); TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); NS_ASSERTION(tileComposer, "compositable is not a tile composer"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); - tileComposer->UseTiledLayerBuffer(this, tileDesc); + bool success = tileComposer->UseTiledLayerBuffer(this, tileDesc); + if (!success) { + return false; + } break; } case CompositableOperation::TOpRemoveTexture: { const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get());
--- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -680,26 +680,26 @@ CompositorParent::CompositeToTarget(Draw if (mCompositionManager->ReadyForCompose()) { mForceCompositionTask->Cancel(); mForceCompositionTask = nullptr; } else { return; } } + mCompositionManager->ComputeRotation(); + TimeStamp time = mIsTesting ? mTestTime : mLastCompose; bool requestNextFrame = mCompositionManager->TransformShadowTree(time); if (requestNextFrame) { ScheduleComposition(); } RenderTraceLayers(mLayerManager->GetRoot(), "0000"); - mCompositionManager->ComputeRotation(); - #ifdef MOZ_DUMP_PAINTING static bool gDumpCompositorTree = false; if (gDumpCompositorTree) { printf_stderr("Painting --- compositing layer tree:\n"); mLayerManager->Dump(); } #endif mLayerManager->SetDebugOverlayWantsNextFrame(false);
--- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -660,95 +660,64 @@ static void ClipToRegionInternal(gfxContext* aContext, const nsIntRegion& aRegion, bool aSnap) { PathFromRegionInternal(aContext, aRegion, aSnap); aContext->Clip(); } static TemporaryRef<Path> -PathFromRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion, - bool aSnap) +PathFromRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion) { - Matrix mat = aTarget->GetTransform(); - const gfxFloat epsilon = 0.000001; -#define WITHIN_E(a,b) (fabs((a)-(b)) < epsilon) - // We're essentially duplicating the logic in UserToDevicePixelSnapped here. - bool shouldNotSnap = !aSnap || (WITHIN_E(mat._11,1.0) && - WITHIN_E(mat._22,1.0) && - WITHIN_E(mat._12,0.0) && - WITHIN_E(mat._21,0.0)); -#undef WITHIN_E - RefPtr<PathBuilder> pb = aTarget->CreatePathBuilder(); nsIntRegionRectIterator iter(aRegion); const nsIntRect* r; - if (shouldNotSnap) { - while ((r = iter.Next()) != nullptr) { - pb->MoveTo(Point(r->x, r->y)); - pb->LineTo(Point(r->XMost(), r->y)); - pb->LineTo(Point(r->XMost(), r->YMost())); - pb->LineTo(Point(r->x, r->YMost())); - pb->Close(); - } - } else { - while ((r = iter.Next()) != nullptr) { - Rect rect(r->x, r->y, r->width, r->height); - - rect.Round(); - pb->MoveTo(rect.TopLeft()); - pb->LineTo(rect.TopRight()); - pb->LineTo(rect.BottomRight()); - pb->LineTo(rect.BottomLeft()); - pb->Close(); - } + while ((r = iter.Next()) != nullptr) { + pb->MoveTo(Point(r->x, r->y)); + pb->LineTo(Point(r->XMost(), r->y)); + pb->LineTo(Point(r->XMost(), r->YMost())); + pb->LineTo(Point(r->x, r->YMost())); + pb->Close(); } RefPtr<Path> path = pb->Finish(); return path; } static void -ClipToRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion, - bool aSnap) +ClipToRegionInternal(DrawTarget* aTarget, const nsIntRegion& aRegion) { if (!aRegion.IsComplex()) { nsIntRect rect = aRegion.GetBounds(); aTarget->PushClipRect(Rect(rect.x, rect.y, rect.width, rect.height)); return; } - RefPtr<Path> path = PathFromRegionInternal(aTarget, aRegion, aSnap); + RefPtr<Path> path = PathFromRegionInternal(aTarget, aRegion); aTarget->PushClip(path); } /*static*/ void gfxUtils::ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion) { ClipToRegionInternal(aContext, aRegion, false); } /*static*/ void gfxUtils::ClipToRegion(DrawTarget* aTarget, const nsIntRegion& aRegion) { - ClipToRegionInternal(aTarget, aRegion, false); + ClipToRegionInternal(aTarget, aRegion); } /*static*/ void gfxUtils::ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion) { ClipToRegionInternal(aContext, aRegion, true); } -/*static*/ void -gfxUtils::ClipToRegionSnapped(DrawTarget* aTarget, const nsIntRegion& aRegion) -{ - ClipToRegionInternal(aTarget, aRegion, true); -} - /*static*/ gfxFloat gfxUtils::ClampToScaleFactor(gfxFloat aVal) { // Arbitary scale factor limitation. We can increase this // for better scaling performance at the cost of worse // quality. static const gfxFloat kScaleResolution = 2;
--- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -95,21 +95,16 @@ public: static void ClipToRegion(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion); /** * Clip aContext to the region aRegion, snapping the rectangles. */ static void ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion); /** - * Clip aTarget to the region aRegion, snapping the rectangles. - */ - static void ClipToRegionSnapped(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion); - - /** * Create a path consisting of rectangles in |aRegion|. */ static void PathFromRegion(gfxContext* aContext, const nsIntRegion& aRegion); /** * Create a path consisting of rectangles in |aRegion|, snapping the rectangles. */ static void PathFromRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
--- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -1532,28 +1532,32 @@ gfxWindowsPlatform::InitD3D11Devices() D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels.Elements(), featureLevels.Length(), D3D11_SDK_VERSION, byRef(mD3D11Device), nullptr, nullptr); if (FAILED(hr)) { return; } + mD3D11Device->SetExceptionMode(0); + #ifdef USE_D2D1_1 if (Factory::SupportsD2D1()) { hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels.Elements(), featureLevels.Length(), D3D11_SDK_VERSION, byRef(mD3D11ContentDevice), nullptr, nullptr); if (FAILED(hr)) { mD3D11Device = nullptr; return; } + mD3D11ContentDevice->SetExceptionMode(0); + Factory::SetDirect3D11Device(mD3D11ContentDevice); } #endif // We leak these everywhere and we need them our entire runtime anyway, let's // leak it here as well. d3d11Module.disown(); }
--- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -1029,25 +1029,29 @@ obj_isExtensible(JSContext *cx, unsigned RootedObject obj(cx, &args.get(0).toObject()); if (!JSObject::isExtensible(cx, obj, &extensible)) return false; } args.rval().setBoolean(extensible); return true; } +// ES6 draft rev27 (2014/08/24) 19.1.2.15 Object.preventExtensions(O) static bool obj_preventExtensions(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - RootedObject obj(cx); - if (!GetFirstArgumentAsObject(cx, args, "Object.preventExtensions", &obj)) - return false; + args.rval().set(args.get(0)); - args.rval().setObject(*obj); + // step 1 + if (!args.get(0).isObject()) + return true; + + // steps 2-5 + RootedObject obj(cx, &args.get(0).toObject()); return JSObject::preventExtensions(cx, obj); } static bool obj_freeze(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp);
--- a/js/src/jit-test/tests/asm.js/bug885976.js +++ b/js/src/jit-test/tests/asm.js/bug885976.js @@ -3,10 +3,10 @@ function test(stdlib, foreign) { "use asm" var ff = foreign.ff function f(y) { y = +y; ff(0); } return f; }; -f = test(this, {ff: Object.preventExtensions}); +f = test(this, {ff: Object.defineProperty}); f();
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/simd-fbirds.js @@ -0,0 +1,210 @@ +/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level : 2 ; js-curly-indent-offset: 0 -*- */ +/* vim: set ts=4 et sw=4 tw=80: */ + +// Author: Peter Jensen + +load(libdir + "asm.js"); +if (!isSimdAvailable() || typeof SIMD === 'undefined') { + print("won't run tests as simd extensions aren't activated yet"); + quit(0); +} + +const NUM_BIRDS = 30; +const NUM_UPDATES = 20; +const ACCEL_DATA_STEPS = 30; + +var buffer = new ArrayBuffer(0x200000); +var bufferF32 = new Float32Array(buffer); + +var actualBirds = 0; + +function init() { + actualBirds = 0; + // Make it a power of two, for quick modulo wrapping. + var accelDataValues = [10.0, 9.5, 9.0, 8.0, 7.0, 6.0, 5.5, 5.0, 5.0, 5.0, 5.5, 6.0, 7.0, 8.0, 9.0, 10.0]; + accelDataValues = accelDataValues.map(function(v) { return 50*v; }); + var accelDataValuesLength = accelDataValues.length; + assertEq(accelDataValuesLength, 16); // Hard coded in the asm.js module + for (i = 0; i < accelDataValuesLength; i++) + bufferF32[i + NUM_BIRDS * 2] = accelDataValues[i]; +} + +function addBird(pos, vel) { + bufferF32[actualBirds] = pos; + bufferF32[actualBirds + NUM_BIRDS] = vel; + actualBirds++; + return actualBirds - 1; +} + +function getActualBirds() { + return actualBirds; +} + +var code = ` + "use asm"; + var toF = global.Math.fround; + var f32 = new global.Float32Array(buffer); + const maxBirds = 100000; + const maxBirdsx4 = 400000; + const maxBirdsx4Plus4 = 400004; + const maxBirdsx4Plus8 = 400008; + const maxBirdsx4Plus12 = 400012; + const maxBirdsx8 = 800000; + const accelMask = 0x3c; + const mk2 = 0x000ffffc; + + const getMaxPos = 1000.0; + const getAccelDataSteps = imp.accelDataSteps | 0; + var getActualBirds = imp.getActualBirds; + + var i4 = global.SIMD.int32x4; + var f4 = global.SIMD.float32x4; + var i4add = i4.add; + var i4and = i4.and; + var f4select = f4.select; + var f4add = f4.add; + var f4sub = f4.sub; + var f4mul = f4.mul; + var f4greaterThan = f4.greaterThan; + var f4splat = f4.splat; + + const zerox4 = f4(0.0,0.0,0.0,0.0); + + function declareHeapSize() { + f32[0x0007ffff] = toF(0.0); + } + + function update(timeDelta) { + timeDelta = toF(timeDelta); + // var steps = Math.ceil(timeDelta/accelData.interval); + var steps = 0; + var subTimeDelta = toF(0.0); + var actualBirds = 0; + var maxPos = toF(0.0); + var maxPosx4 = f4(0.0,0.0,0.0,0.0); + var subTimeDeltax4 = f4(0.0,0.0,0.0,0.0); + var subTimeDeltaSquaredx4 = f4(0.0,0.0,0.0,0.0); + var point5x4 = f4(0.5, 0.5, 0.5, 0.5); + var i = 0; + var len = 0; + var accelIndex = 0; + var newPosx4 = f4(0.0,0.0,0.0,0.0); + var newVelx4 = f4(0.0,0.0,0.0,0.0); + var accel = toF(0.0); + var accelx4 = f4(0.0,0.0,0.0,0.0); + var a = 0; + var posDeltax4 = f4(0.0,0.0,0.0,0.0); + var cmpx4 = i4(0,0,0,0); + var newVelTruex4 = f4(0.0,0.0,0.0,0.0); + + steps = getAccelDataSteps | 0; + subTimeDelta = toF(toF(timeDelta / toF(steps | 0)) / toF(1000.0)); + actualBirds = getActualBirds() | 0; + maxPos = toF(+getMaxPos); + maxPosx4 = f4splat(maxPos); + subTimeDeltax4 = f4splat(subTimeDelta); + subTimeDeltaSquaredx4 = f4mul(subTimeDeltax4, subTimeDeltax4); + + len = ((actualBirds + 3) >> 2) << 4; + + for (i = 0; (i | 0) < (len | 0); i = (i + 16) | 0) { + accelIndex = 0; + // Work around unimplemented Float32x4Array + newPosx4 = f4(toF(f32[(i & mk2) >> 2]), + toF(f32[(i & mk2) + 4 >> 2]), + toF(f32[(i & mk2) + 8 >> 2]), + toF(f32[(i & mk2) + 12 >> 2])); + newVelx4 = f4(toF(f32[(i & mk2) + maxBirdsx4 >> 2]), + toF(f32[(i & mk2) + maxBirdsx4Plus4 >> 2]), + toF(f32[(i & mk2) + maxBirdsx4Plus8 >> 2]), + toF(f32[(i & mk2) + maxBirdsx4Plus12 >> 2])); + for (a = 0; (a | 0) < (steps | 0); a = (a + 1) | 0) { + accel = toF(f32[(accelIndex & accelMask) + maxBirdsx8 >> 2]); + accelx4 = f4splat(accel); + accelIndex = (accelIndex + 4) | 0; + posDeltax4 = f4mul(point5x4, f4mul(accelx4, subTimeDeltaSquaredx4)); + posDeltax4 = f4add(posDeltax4, f4mul(newVelx4, subTimeDeltax4)); + newPosx4 = f4add(newPosx4, posDeltax4); + newVelx4 = f4add(newVelx4, f4mul(accelx4, subTimeDeltax4)); + cmpx4 = f4greaterThan(newPosx4, maxPosx4); + + if (cmpx4.signMask) { + // Work around unimplemented 'neg' operation, using 0 - x. + newVelTruex4 = f4sub(zerox4, newVelx4); + newVelx4 = f4select(cmpx4, newVelTruex4, newVelx4); + } + } + // Work around unimplemented Float32x4Array + f32[(i & mk2) >> 2] = newPosx4.x; + f32[(i & mk2) + 4 >> 2] = newPosx4.y; + f32[(i & mk2) + 8 >> 2] = newPosx4.z; + f32[(i & mk2) + 12 >> 2] = newPosx4.w; + f32[(i & mk2) + maxBirdsx4 >> 2] = newVelx4.x; + f32[(i & mk2) + maxBirdsx4Plus4 >> 2] = newVelx4.y; + f32[(i & mk2) + maxBirdsx4Plus8 >> 2] = newVelx4.z; + f32[(i & mk2) + maxBirdsx4Plus12 >> 2] = newVelx4.w; + } + } + + return update; +` + +var ffi = { + getActualBirds, + accelDataSteps: ACCEL_DATA_STEPS +}; + +var fbirds = asmLink(asmCompile('global', 'imp', 'buffer', code), this, ffi, buffer); + +init(); +for (var i = 0; i < NUM_BIRDS; i++) { + addBird(i / 10, Math.exp(2, NUM_BIRDS - i)); +} + +var b = dateNow(); +for (var j = 0; j < NUM_UPDATES; j++) { + fbirds(16); +} +print(dateNow() - b); + +assertEq(bufferF32[0], 0); +assertEq(bufferF32[1], 0.10000000149011612); +assertEq(bufferF32[2], 0.20000000298023224); +assertEq(bufferF32[3], 0.30000001192092896); +assertEq(bufferF32[4], 0.4000000059604645); +assertEq(bufferF32[5], 0.5); +assertEq(bufferF32[6], 0.6000000238418579); +assertEq(bufferF32[7], 0.699999988079071); +assertEq(bufferF32[8], 0.800000011920929); +assertEq(bufferF32[9], 0.8999999761581421); +assertEq(bufferF32[10], 1); +assertEq(bufferF32[11], 1.100000023841858); +assertEq(bufferF32[12], 1.2000000476837158); +assertEq(bufferF32[13], 1.2999999523162842); +assertEq(bufferF32[14], 1.399999976158142); +assertEq(bufferF32[15], 1.5); +assertEq(bufferF32[16], 1.600000023841858); +assertEq(bufferF32[17], 1.7000000476837158); +assertEq(bufferF32[18], 1.7999999523162842); +assertEq(bufferF32[19], 1.899999976158142); +assertEq(bufferF32[20], 2); +assertEq(bufferF32[21], 2.0999999046325684); +assertEq(bufferF32[22], 2.200000047683716); +assertEq(bufferF32[23], 2.299999952316284); +assertEq(bufferF32[24], 2.4000000953674316); +assertEq(bufferF32[25], 2.5); +assertEq(bufferF32[26], 2.5999999046325684); +assertEq(bufferF32[27], 2.700000047683716); +assertEq(bufferF32[28], 2.799999952316284); +assertEq(bufferF32[29], 2.9000000953674316); + + +// Code used to generate the assertEq list above. +function generateAssertList() { + var buf = ''; + for (var k = 0; k < NUM_BIRDS; k++) { + buf += 'assertEq(bufferF32['+ k + '], ' + bufferF32[k] + ');\n'; + } + print(buf); +} +//generateAssertList();
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/simd-mandelbrot.js @@ -0,0 +1,1814 @@ +/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 ; js-indent-level : 2 ; js-curly-indent-offset: 0 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +// Mandelbrot using SIMD +// Author: Peter Jensen, Intel Corporation + +load(libdir + "asm.js"); +if (!isSimdAvailable() || typeof SIMD === 'undefined') { + print("won't run tests as simd extensions aren't activated yet"); + quit(0); +} + +// global variables +const MAX_ITERATIONS = 10; +const DRAW_ITERATIONS = 10; + +const CANVAS_WIDTH = 20; +const CANVAS_HEIGHT = 20; + +const LIMIT_SHOW = 20 * 20 * 4; + +// Asm.js module buffer. +var buffer = new ArrayBuffer(16 * 1024 * 1024); +var view = new Uint8Array(buffer); + +var moduleCode = ` + "use asm" + var b8 = new global.Uint8Array(buffer); + var toF = global.Math.fround; + var i4 = global.SIMD.int32x4; + var f4 = global.SIMD.float32x4; + var i4add = i4.add; + var i4and = i4.and; + var f4add = f4.add; + var f4sub = f4.sub; + var f4mul = f4.mul; + var f4lessThanOrEqual = f4.lessThanOrEqual; + var f4splat = f4.splat; + var imul = global.Math.imul; + const one4 = i4(1,1,1,1), two4 = f4(2,2,2,2), four4 = f4(4,4,4,4); + + const mk0 = 0x007fffff; + + function declareHeapLength() { + b8[0x00ffffff] = 0; + } + + function mapColorAndSetPixel (x, y, width, value, max_iterations) { + x = x | 0; + y = y | 0; + width = width | 0; + value = value | 0; + max_iterations = max_iterations | 0; + + var rgb = 0, r = 0, g = 0, b = 0, index = 0; + + index = (((imul((width >>> 0), (y >>> 0)) + x) | 0) * 4) | 0; + if ((value | 0) == (max_iterations | 0)) { + r = 0; + g = 0; + b = 0; + } else { + rgb = ~~toF(toF(toF(toF(value >>> 0) * toF(0xffff)) / toF(max_iterations >>> 0)) * toF(0xff)); + r = rgb & 0xff; + g = (rgb >>> 8) & 0xff; + b = (rgb >>> 16) & 0xff; + } + b8[(index & mk0) >> 0] = r; + b8[(index & mk0) + 1 >> 0] = g; + b8[(index & mk0) + 2 >> 0] = b; + b8[(index & mk0) + 3 >> 0] = 255; + } + + function mandelPixelX4 (xf, yf, yd, max_iterations) { + xf = toF(xf); + yf = toF(yf); + yd = toF(yd); + max_iterations = max_iterations | 0; + var c_re4 = f4(0,0,0,0), c_im4 = f4(0,0,0,0); + var z_re4 = f4(0,0,0,0), z_im4 = f4(0,0,0,0); + var count4 = i4(0,0,0,0); + var z_re24 = f4(0,0,0,0), z_im24 = f4(0,0,0,0); + var new_re4 = f4(0,0,0,0), new_im4 = f4(0,0,0,0); + var i = 0; + var mi4 = i4(0,0,0,0); + + c_re4 = f4splat(xf); + c_im4 = f4(yf, toF(yd + yf), toF(yd + toF(yd + yf)), toF(yd + toF(yd + toF(yd + yf)))); + + z_re4 = c_re4; + z_im4 = c_im4; + + for (i = 0; (i | 0) < (max_iterations | 0); i = (i + 1) | 0) { + z_re24 = f4mul(z_re4, z_re4); + z_im24 = f4mul(z_im4, z_im4); + mi4 = f4lessThanOrEqual(f4add(z_re24, z_im24), four4); + // If all 4 values are greater than 4.0, there's no reason to continue. + if ((mi4.signMask | 0) == 0x00) + break; + + new_re4 = f4sub(z_re24, z_im24); + new_im4 = f4mul(f4mul(two4, z_re4), z_im4); + z_re4 = f4add(c_re4, new_re4); + z_im4 = f4add(c_im4, new_im4); + count4 = i4add(count4, i4and(mi4, one4)); + } + return i4(count4); + } + + function mandelColumnX4 (x, width, height, xf, yf, yd, max_iterations) { + x = x | 0; + width = width | 0; + height = height | 0; + xf = toF(xf); + yf = toF(yf); + yd = toF(yd); + max_iterations = max_iterations | 0; + + var y = 0; + var ydx4 = toF(0); + var m4 = i4(0,0,0,0); + + ydx4 = toF(yd * toF(4)); + for (y = 0; (y | 0) < (height | 0); y = (y + 4) | 0) { + m4 = i4(mandelPixelX4(toF(xf), toF(yf), toF(yd), max_iterations)); + mapColorAndSetPixel(x | 0, y | 0, width, m4.x, max_iterations); + mapColorAndSetPixel(x | 0, (y + 1) | 0, width, m4.y, max_iterations); + mapColorAndSetPixel(x | 0, (y + 2) | 0, width, m4.z, max_iterations); + mapColorAndSetPixel(x | 0, (y + 3) | 0, width, m4.w, max_iterations); + yf = toF(yf + ydx4); + } + } + + function mandel (width, height, xc, yc, scale, max_iterations) { + width = width | 0; + height = height | 0; + xc = toF(xc); + yc = toF(yc); + scale = toF(scale); + max_iterations = max_iterations | 0; + + var x0 = toF(0), y0 = toF(0); + var xd = toF(0), yd = toF(0); + var xf = toF(0); + var x = 0; + + x0 = toF(xc - toF(scale * toF(1.5))); + y0 = toF(yc - scale); + xd = toF(toF(scale * toF(3)) / toF(width >>> 0)); + yd = toF(toF(scale * toF(2)) / toF(height >>> 0)); + xf = x0; + + for (x = 0; (x | 0) < (width | 0); x = (x + 1) | 0) { + mandelColumnX4(x, width, height, xf, y0, yd, max_iterations); + xf = toF(xf + xd); + } + } + + return mandel; +`; + +var FFI = {}; +var mandelbro = asmLink(asmCompile('global', 'ffi', 'buffer', moduleCode), this, FFI, buffer); + +function animateMandelbrot () { + var scale_start = 1.0; + var scale_end = 0.0005; + var xc_start = -0.5; + var yc_start = 0.0; + var xc_end = 0.0; + var yc_end = 0.75; + var steps = 200.0; + var scale_step = (scale_end - scale_start)/steps; + var xc_step = (xc_end - xc_start)/steps; + var yc_step = (yc_end - yc_start)/steps; + var scale = scale_start; + var xc = xc_start; + var yc = yc_start; + var i = 0; + var now = dateNow(); + + function draw1 () { + mandelbro(CANVAS_WIDTH, CANVAS_HEIGHT, xc, yc, scale, MAX_ITERATIONS); + if (scale < scale_end || scale > scale_start) { + scale_step = -scale_step; + xc_step = -xc_step; + yc_step = -yc_step; + } + scale += scale_step; + xc += xc_step; + yc += yc_step; + i++; + } + + var b = dateNow(); + for (var j = DRAW_ITERATIONS; j --> 0;) + draw1(); + print(dateNow() - b); +} + +animateMandelbrot(); + +assertEq(view[0], 0, "0th value should be 0"); +assertEq(view[1], 0, "1th value should be 0"); +assertEq(view[2], 0, "2th value should be 0"); +assertEq(view[3], 255, "3th value should be 255"); +assertEq(view[4], 230, "4th value should be 230"); +assertEq(view[5], 127, "5th value should be 127"); +assertEq(view[6], 25, "6th value should be 25"); +assertEq(view[7], 255, "7th value should be 255"); +assertEq(view[8], 230, "8th value should be 230"); +assertEq(view[9], 127, "9th value should be 127"); +assertEq(view[10], 25, "10th value should be 25"); +assertEq(view[11], 255, "11th value should be 255"); +assertEq(view[12], 205, "12th value should be 205"); +assertEq(view[13], 255, "13th value should be 255"); +assertEq(view[14], 50, "14th value should be 50"); +assertEq(view[15], 255, "15th value should be 255"); +assertEq(view[16], 205, "16th value should be 205"); +assertEq(view[17], 255, "17th value should be 255"); +assertEq(view[18], 50, "18th value should be 50"); +assertEq(view[19], 255, "19th value should be 255"); +assertEq(view[20], 205, "20th value should be 205"); +assertEq(view[21], 255, "21th value should be 255"); +assertEq(view[22], 50, "22th value should be 50"); +assertEq(view[23], 255, "23th value should be 255"); +assertEq(view[24], 205, "24th value should be 205"); +assertEq(view[25], 255, "25th value should be 255"); +assertEq(view[26], 50, "26th value should be 50"); +assertEq(view[27], 255, "27th value should be 255"); +assertEq(view[28], 205, "28th value should be 205"); +assertEq(view[29], 255, "29th value should be 255"); +assertEq(view[30], 50, "30th value should be 50"); +assertEq(view[31], 255, "31th value should be 255"); +assertEq(view[32], 179, "32th value should be 179"); +assertEq(view[33], 127, "33th value should be 127"); +assertEq(view[34], 76, "34th value should be 76"); +assertEq(view[35], 255, "35th value should be 255"); +assertEq(view[36], 179, "36th value should be 179"); +assertEq(view[37], 127, "37th value should be 127"); +assertEq(view[38], 76, "38th value should be 76"); +assertEq(view[39], 255, "39th value should be 255"); +assertEq(view[40], 179, "40th value should be 179"); +assertEq(view[41], 127, "41th value should be 127"); +assertEq(view[42], 76, "42th value should be 76"); +assertEq(view[43], 255, "43th value should be 255"); +assertEq(view[44], 154, "44th value should be 154"); +assertEq(view[45], 255, "45th value should be 255"); +assertEq(view[46], 101, "46th value should be 101"); +assertEq(view[47], 255, "47th value should be 255"); +assertEq(view[48], 78, "48th value should be 78"); +assertEq(view[49], 127, "49th value should be 127"); +assertEq(view[50], 178, "50th value should be 178"); +assertEq(view[51], 255, "51th value should be 255"); +assertEq(view[52], 52, "52th value should be 52"); +assertEq(view[53], 255, "53th value should be 255"); +assertEq(view[54], 203, "54th value should be 203"); +assertEq(view[55], 255, "55th value should be 255"); +assertEq(view[56], 154, "56th value should be 154"); +assertEq(view[57], 255, "57th value should be 255"); +assertEq(view[58], 101, "58th value should be 101"); +assertEq(view[59], 255, "59th value should be 255"); +assertEq(view[60], 179, "60th value should be 179"); +assertEq(view[61], 127, "61th value should be 127"); +assertEq(view[62], 76, "62th value should be 76"); +assertEq(view[63], 255, "63th value should be 255"); +assertEq(view[64], 205, "64th value should be 205"); +assertEq(view[65], 255, "65th value should be 255"); +assertEq(view[66], 50, "66th value should be 50"); +assertEq(view[67], 255, "67th value should be 255"); +assertEq(view[68], 205, "68th value should be 205"); +assertEq(view[69], 255, "69th value should be 255"); +assertEq(view[70], 50, "70th value should be 50"); +assertEq(view[71], 255, "71th value should be 255"); +assertEq(view[72], 230, "72th value should be 230"); +assertEq(view[73], 127, "73th value should be 127"); +assertEq(view[74], 25, "74th value should be 25"); +assertEq(view[75], 255, "75th value should be 255"); +assertEq(view[76], 230, "76th value should be 230"); +assertEq(view[77], 127, "77th value should be 127"); +assertEq(view[78], 25, "78th value should be 25"); +assertEq(view[79], 255, "79th value should be 255"); +assertEq(view[80], 0, "80th value should be 0"); +assertEq(view[81], 0, "81th value should be 0"); +assertEq(view[82], 0, "82th value should be 0"); +assertEq(view[83], 255, "83th value should be 255"); +assertEq(view[84], 230, "84th value should be 230"); +assertEq(view[85], 127, "85th value should be 127"); +assertEq(view[86], 25, "86th value should be 25"); +assertEq(view[87], 255, "87th value should be 255"); +assertEq(view[88], 205, "88th value should be 205"); +assertEq(view[89], 255, "89th value should be 255"); +assertEq(view[90], 50, "90th value should be 50"); +assertEq(view[91], 255, "91th value should be 255"); +assertEq(view[92], 205, "92th value should be 205"); +assertEq(view[93], 255, "93th value should be 255"); +assertEq(view[94], 50, "94th value should be 50"); +assertEq(view[95], 255, "95th value should be 255"); +assertEq(view[96], 205, "96th value should be 205"); +assertEq(view[97], 255, "97th value should be 255"); +assertEq(view[98], 50, "98th value should be 50"); +assertEq(view[99], 255, "99th value should be 255"); +assertEq(view[100], 205, "100th value should be 205"); +assertEq(view[101], 255, "101th value should be 255"); +assertEq(view[102], 50, "102th value should be 50"); +assertEq(view[103], 255, "103th value should be 255"); +assertEq(view[104], 205, "104th value should be 205"); +assertEq(view[105], 255, "105th value should be 255"); +assertEq(view[106], 50, "106th value should be 50"); +assertEq(view[107], 255, "107th value should be 255"); +assertEq(view[108], 205, "108th value should be 205"); +assertEq(view[109], 255, "109th value should be 255"); +assertEq(view[110], 50, "110th value should be 50"); +assertEq(view[111], 255, "111th value should be 255"); +assertEq(view[112], 179, "112th value should be 179"); +assertEq(view[113], 127, "113th value should be 127"); +assertEq(view[114], 76, "114th value should be 76"); +assertEq(view[115], 255, "115th value should be 255"); +assertEq(view[116], 179, "116th value should be 179"); +assertEq(view[117], 127, "117th value should be 127"); +assertEq(view[118], 76, "118th value should be 76"); +assertEq(view[119], 255, "119th value should be 255"); +assertEq(view[120], 154, "120th value should be 154"); +assertEq(view[121], 255, "121th value should be 255"); +assertEq(view[122], 101, "122th value should be 101"); +assertEq(view[123], 255, "123th value should be 255"); +assertEq(view[124], 103, "124th value should be 103"); +assertEq(view[125], 255, "125th value should be 255"); +assertEq(view[126], 152, "126th value should be 152"); +assertEq(view[127], 255, "127th value should be 255"); +assertEq(view[128], 0, "128th value should be 0"); +assertEq(view[129], 0, "129th value should be 0"); +assertEq(view[130], 0, "130th value should be 0"); +assertEq(view[131], 255, "131th value should be 255"); +assertEq(view[132], 0, "132th value should be 0"); +assertEq(view[133], 0, "133th value should be 0"); +assertEq(view[134], 0, "134th value should be 0"); +assertEq(view[135], 255, "135th value should be 255"); +assertEq(view[136], 128, "136th value should be 128"); +assertEq(view[137], 127, "137th value should be 127"); +assertEq(view[138], 127, "138th value should be 127"); +assertEq(view[139], 255, "139th value should be 255"); +assertEq(view[140], 154, "140th value should be 154"); +assertEq(view[141], 255, "141th value should be 255"); +assertEq(view[142], 101, "142th value should be 101"); +assertEq(view[143], 255, "143th value should be 255"); +assertEq(view[144], 179, "144th value should be 179"); +assertEq(view[145], 127, "145th value should be 127"); +assertEq(view[146], 76, "146th value should be 76"); +assertEq(view[147], 255, "147th value should be 255"); +assertEq(view[148], 205, "148th value should be 205"); +assertEq(view[149], 255, "149th value should be 255"); +assertEq(view[150], 50, "150th value should be 50"); +assertEq(view[151], 255, "151th value should be 255"); +assertEq(view[152], 205, "152th value should be 205"); +assertEq(view[153], 255, "153th value should be 255"); +assertEq(view[154], 50, "154th value should be 50"); +assertEq(view[155], 255, "155th value should be 255"); +assertEq(view[156], 230, "156th value should be 230"); +assertEq(view[157], 127, "157th value should be 127"); +assertEq(view[158], 25, "158th value should be 25"); +assertEq(view[159], 255, "159th value should be 255"); +assertEq(view[160], 0, "160th value should be 0"); +assertEq(view[161], 0, "161th value should be 0"); +assertEq(view[162], 0, "162th value should be 0"); +assertEq(view[163], 255, "163th value should be 255"); +assertEq(view[164], 230, "164th value should be 230"); +assertEq(view[165], 127, "165th value should be 127"); +assertEq(view[166], 25, "166th value should be 25"); +assertEq(view[167], 255, "167th value should be 255"); +assertEq(view[168], 205, "168th value should be 205"); +assertEq(view[169], 255, "169th value should be 255"); +assertEq(view[170], 50, "170th value should be 50"); +assertEq(view[171], 255, "171th value should be 255"); +assertEq(view[172], 205, "172th value should be 205"); +assertEq(view[173], 255, "173th value should be 255"); +assertEq(view[174], 50, "174th value should be 50"); +assertEq(view[175], 255, "175th value should be 255"); +assertEq(view[176], 205, "176th value should be 205"); +assertEq(view[177], 255, "177th value should be 255"); +assertEq(view[178], 50, "178th value should be 50"); +assertEq(view[179], 255, "179th value should be 255"); +assertEq(view[180], 205, "180th value should be 205"); +assertEq(view[181], 255, "181th value should be 255"); +assertEq(view[182], 50, "182th value should be 50"); +assertEq(view[183], 255, "183th value should be 255"); +assertEq(view[184], 205, "184th value should be 205"); +assertEq(view[185], 255, "185th value should be 255"); +assertEq(view[186], 50, "186th value should be 50"); +assertEq(view[187], 255, "187th value should be 255"); +assertEq(view[188], 179, "188th value should be 179"); +assertEq(view[189], 127, "189th value should be 127"); +assertEq(view[190], 76, "190th value should be 76"); +assertEq(view[191], 255, "191th value should be 255"); +assertEq(view[192], 179, "192th value should be 179"); +assertEq(view[193], 127, "193th value should be 127"); +assertEq(view[194], 76, "194th value should be 76"); +assertEq(view[195], 255, "195th value should be 255"); +assertEq(view[196], 154, "196th value should be 154"); +assertEq(view[197], 255, "197th value should be 255"); +assertEq(view[198], 101, "198th value should be 101"); +assertEq(view[199], 255, "199th value should be 255"); +assertEq(view[200], 103, "200th value should be 103"); +assertEq(view[201], 255, "201th value should be 255"); +assertEq(view[202], 152, "202th value should be 152"); +assertEq(view[203], 255, "203th value should be 255"); +assertEq(view[204], 78, "204th value should be 78"); +assertEq(view[205], 127, "205th value should be 127"); +assertEq(view[206], 178, "206th value should be 178"); +assertEq(view[207], 255, "207th value should be 255"); +assertEq(view[208], 0, "208th value should be 0"); +assertEq(view[209], 0, "209th value should be 0"); +assertEq(view[210], 0, "210th value should be 0"); +assertEq(view[211], 255, "211th value should be 255"); +assertEq(view[212], 0, "212th value should be 0"); +assertEq(view[213], 0, "213th value should be 0"); +assertEq(view[214], 0, "214th value should be 0"); +assertEq(view[215], 255, "215th value should be 255"); +assertEq(view[216], 78, "216th value should be 78"); +assertEq(view[217], 127, "217th value should be 127"); +assertEq(view[218], 178, "218th value should be 178"); +assertEq(view[219], 255, "219th value should be 255"); +assertEq(view[220], 128, "220th value should be 128"); +assertEq(view[221], 127, "221th value should be 127"); +assertEq(view[222], 127, "222th value should be 127"); +assertEq(view[223], 255, "223th value should be 255"); +assertEq(view[224], 154, "224th value should be 154"); +assertEq(view[225], 255, "225th value should be 255"); +assertEq(view[226], 101, "226th value should be 101"); +assertEq(view[227], 255, "227th value should be 255"); +assertEq(view[228], 205, "228th value should be 205"); +assertEq(view[229], 255, "229th value should be 255"); +assertEq(view[230], 50, "230th value should be 50"); +assertEq(view[231], 255, "231th value should be 255"); +assertEq(view[232], 205, "232th value should be 205"); +assertEq(view[233], 255, "233th value should be 255"); +assertEq(view[234], 50, "234th value should be 50"); +assertEq(view[235], 255, "235th value should be 255"); +assertEq(view[236], 230, "236th value should be 230"); +assertEq(view[237], 127, "237th value should be 127"); +assertEq(view[238], 25, "238th value should be 25"); +assertEq(view[239], 255, "239th value should be 255"); +assertEq(view[240], 0, "240th value should be 0"); +assertEq(view[241], 0, "241th value should be 0"); +assertEq(view[242], 0, "242th value should be 0"); +assertEq(view[243], 255, "243th value should be 255"); +assertEq(view[244], 205, "244th value should be 205"); +assertEq(view[245], 255, "245th value should be 255"); +assertEq(view[246], 50, "246th value should be 50"); +assertEq(view[247], 255, "247th value should be 255"); +assertEq(view[248], 205, "248th value should be 205"); +assertEq(view[249], 255, "249th value should be 255"); +assertEq(view[250], 50, "250th value should be 50"); +assertEq(view[251], 255, "251th value should be 255"); +assertEq(view[252], 205, "252th value should be 205"); +assertEq(view[253], 255, "253th value should be 255"); +assertEq(view[254], 50, "254th value should be 50"); +assertEq(view[255], 255, "255th value should be 255"); +assertEq(view[256], 205, "256th value should be 205"); +assertEq(view[257], 255, "257th value should be 255"); +assertEq(view[258], 50, "258th value should be 50"); +assertEq(view[259], 255, "259th value should be 255"); +assertEq(view[260], 205, "260th value should be 205"); +assertEq(view[261], 255, "261th value should be 255"); +assertEq(view[262], 50, "262th value should be 50"); +assertEq(view[263], 255, "263th value should be 255"); +assertEq(view[264], 179, "264th value should be 179"); +assertEq(view[265], 127, "265th value should be 127"); +assertEq(view[266], 76, "266th value should be 76"); +assertEq(view[267], 255, "267th value should be 255"); +assertEq(view[268], 179, "268th value should be 179"); +assertEq(view[269], 127, "269th value should be 127"); +assertEq(view[270], 76, "270th value should be 76"); +assertEq(view[271], 255, "271th value should be 255"); +assertEq(view[272], 154, "272th value should be 154"); +assertEq(view[273], 255, "273th value should be 255"); +assertEq(view[274], 101, "274th value should be 101"); +assertEq(view[275], 255, "275th value should be 255"); +assertEq(view[276], 52, "276th value should be 52"); +assertEq(view[277], 255, "277th value should be 255"); +assertEq(view[278], 203, "278th value should be 203"); +assertEq(view[279], 255, "279th value should be 255"); +assertEq(view[280], 0, "280th value should be 0"); +assertEq(view[281], 0, "281th value should be 0"); +assertEq(view[282], 0, "282th value should be 0"); +assertEq(view[283], 255, "283th value should be 255"); +assertEq(view[284], 0, "284th value should be 0"); +assertEq(view[285], 0, "285th value should be 0"); +assertEq(view[286], 0, "286th value should be 0"); +assertEq(view[287], 255, "287th value should be 255"); +assertEq(view[288], 0, "288th value should be 0"); +assertEq(view[289], 0, "289th value should be 0"); +assertEq(view[290], 0, "290th value should be 0"); +assertEq(view[291], 255, "291th value should be 255"); +assertEq(view[292], 0, "292th value should be 0"); +assertEq(view[293], 0, "293th value should be 0"); +assertEq(view[294], 0, "294th value should be 0"); +assertEq(view[295], 255, "295th value should be 255"); +assertEq(view[296], 0, "296th value should be 0"); +assertEq(view[297], 0, "297th value should be 0"); +assertEq(view[298], 0, "298th value should be 0"); +assertEq(view[299], 255, "299th value should be 255"); +assertEq(view[300], 52, "300th value should be 52"); +assertEq(view[301], 255, "301th value should be 255"); +assertEq(view[302], 203, "302th value should be 203"); +assertEq(view[303], 255, "303th value should be 255"); +assertEq(view[304], 52, "304th value should be 52"); +assertEq(view[305], 255, "305th value should be 255"); +assertEq(view[306], 203, "306th value should be 203"); +assertEq(view[307], 255, "307th value should be 255"); +assertEq(view[308], 179, "308th value should be 179"); +assertEq(view[309], 127, "309th value should be 127"); +assertEq(view[310], 76, "310th value should be 76"); +assertEq(view[311], 255, "311th value should be 255"); +assertEq(view[312], 205, "312th value should be 205"); +assertEq(view[313], 255, "313th value should be 255"); +assertEq(view[314], 50, "314th value should be 50"); +assertEq(view[315], 255, "315th value should be 255"); +assertEq(view[316], 205, "316th value should be 205"); +assertEq(view[317], 255, "317th value should be 255"); +assertEq(view[318], 50, "318th value should be 50"); +assertEq(view[319], 255, "319th value should be 255"); +assertEq(view[320], 230, "320th value should be 230"); +assertEq(view[321], 127, "321th value should be 127"); +assertEq(view[322], 25, "322th value should be 25"); +assertEq(view[323], 255, "323th value should be 255"); +assertEq(view[324], 205, "324th value should be 205"); +assertEq(view[325], 255, "325th value should be 255"); +assertEq(view[326], 50, "326th value should be 50"); +assertEq(view[327], 255, "327th value should be 255"); +assertEq(view[328], 205, "328th value should be 205"); +assertEq(view[329], 255, "329th value should be 255"); +assertEq(view[330], 50, "330th value should be 50"); +assertEq(view[331], 255, "331th value should be 255"); +assertEq(view[332], 205, "332th value should be 205"); +assertEq(view[333], 255, "333th value should be 255"); +assertEq(view[334], 50, "334th value should be 50"); +assertEq(view[335], 255, "335th value should be 255"); +assertEq(view[336], 205, "336th value should be 205"); +assertEq(view[337], 255, "337th value should be 255"); +assertEq(view[338], 50, "338th value should be 50"); +assertEq(view[339], 255, "339th value should be 255"); +assertEq(view[340], 179, "340th value should be 179"); +assertEq(view[341], 127, "341th value should be 127"); +assertEq(view[342], 76, "342th value should be 76"); +assertEq(view[343], 255, "343th value should be 255"); +assertEq(view[344], 154, "344th value should be 154"); +assertEq(view[345], 255, "345th value should be 255"); +assertEq(view[346], 101, "346th value should be 101"); +assertEq(view[347], 255, "347th value should be 255"); +assertEq(view[348], 154, "348th value should be 154"); +assertEq(view[349], 255, "349th value should be 255"); +assertEq(view[350], 101, "350th value should be 101"); +assertEq(view[351], 255, "351th value should be 255"); +assertEq(view[352], 128, "352th value should be 128"); +assertEq(view[353], 127, "353th value should be 127"); +assertEq(view[354], 127, "354th value should be 127"); +assertEq(view[355], 255, "355th value should be 255"); +assertEq(view[356], 52, "356th value should be 52"); +assertEq(view[357], 255, "357th value should be 255"); +assertEq(view[358], 203, "358th value should be 203"); +assertEq(view[359], 255, "359th value should be 255"); +assertEq(view[360], 0, "360th value should be 0"); +assertEq(view[361], 0, "361th value should be 0"); +assertEq(view[362], 0, "362th value should be 0"); +assertEq(view[363], 255, "363th value should be 255"); +assertEq(view[364], 0, "364th value should be 0"); +assertEq(view[365], 0, "365th value should be 0"); +assertEq(view[366], 0, "366th value should be 0"); +assertEq(view[367], 255, "367th value should be 255"); +assertEq(view[368], 0, "368th value should be 0"); +assertEq(view[369], 0, "369th value should be 0"); +assertEq(view[370], 0, "370th value should be 0"); +assertEq(view[371], 255, "371th value should be 255"); +assertEq(view[372], 0, "372th value should be 0"); +assertEq(view[373], 0, "373th value should be 0"); +assertEq(view[374], 0, "374th value should be 0"); +assertEq(view[375], 255, "375th value should be 255"); +assertEq(view[376], 0, "376th value should be 0"); +assertEq(view[377], 0, "377th value should be 0"); +assertEq(view[378], 0, "378th value should be 0"); +assertEq(view[379], 255, "379th value should be 255"); +assertEq(view[380], 0, "380th value should be 0"); +assertEq(view[381], 0, "381th value should be 0"); +assertEq(view[382], 0, "382th value should be 0"); +assertEq(view[383], 255, "383th value should be 255"); +assertEq(view[384], 52, "384th value should be 52"); +assertEq(view[385], 255, "385th value should be 255"); +assertEq(view[386], 203, "386th value should be 203"); +assertEq(view[387], 255, "387th value should be 255"); +assertEq(view[388], 179, "388th value should be 179"); +assertEq(view[389], 127, "389th value should be 127"); +assertEq(view[390], 76, "390th value should be 76"); +assertEq(view[391], 255, "391th value should be 255"); +assertEq(view[392], 205, "392th value should be 205"); +assertEq(view[393], 255, "393th value should be 255"); +assertEq(view[394], 50, "394th value should be 50"); +assertEq(view[395], 255, "395th value should be 255"); +assertEq(view[396], 205, "396th value should be 205"); +assertEq(view[397], 255, "397th value should be 255"); +assertEq(view[398], 50, "398th value should be 50"); +assertEq(view[399], 255, "399th value should be 255"); +assertEq(view[400], 205, "400th value should be 205"); +assertEq(view[401], 255, "401th value should be 255"); +assertEq(view[402], 50, "402th value should be 50"); +assertEq(view[403], 255, "403th value should be 255"); +assertEq(view[404], 205, "404th value should be 205"); +assertEq(view[405], 255, "405th value should be 255"); +assertEq(view[406], 50, "406th value should be 50"); +assertEq(view[407], 255, "407th value should be 255"); +assertEq(view[408], 205, "408th value should be 205"); +assertEq(view[409], 255, "409th value should be 255"); +assertEq(view[410], 50, "410th value should be 50"); +assertEq(view[411], 255, "411th value should be 255"); +assertEq(view[412], 205, "412th value should be 205"); +assertEq(view[413], 255, "413th value should be 255"); +assertEq(view[414], 50, "414th value should be 50"); +assertEq(view[415], 255, "415th value should be 255"); +assertEq(view[416], 154, "416th value should be 154"); +assertEq(view[417], 255, "417th value should be 255"); +assertEq(view[418], 101, "418th value should be 101"); +assertEq(view[419], 255, "419th value should be 255"); +assertEq(view[420], 128, "420th value should be 128"); +assertEq(view[421], 127, "421th value should be 127"); +assertEq(view[422], 127, "422th value should be 127"); +assertEq(view[423], 255, "423th value should be 255"); +assertEq(view[424], 154, "424th value should be 154"); +assertEq(view[425], 255, "425th value should be 255"); +assertEq(view[426], 101, "426th value should be 101"); +assertEq(view[427], 255, "427th value should be 255"); +assertEq(view[428], 128, "428th value should be 128"); +assertEq(view[429], 127, "429th value should be 127"); +assertEq(view[430], 127, "430th value should be 127"); +assertEq(view[431], 255, "431th value should be 255"); +assertEq(view[432], 103, "432th value should be 103"); +assertEq(view[433], 255, "433th value should be 255"); +assertEq(view[434], 152, "434th value should be 152"); +assertEq(view[435], 255, "435th value should be 255"); +assertEq(view[436], 0, "436th value should be 0"); +assertEq(view[437], 0, "437th value should be 0"); +assertEq(view[438], 0, "438th value should be 0"); +assertEq(view[439], 255, "439th value should be 255"); +assertEq(view[440], 0, "440th value should be 0"); +assertEq(view[441], 0, "441th value should be 0"); +assertEq(view[442], 0, "442th value should be 0"); +assertEq(view[443], 255, "443th value should be 255"); +assertEq(view[444], 0, "444th value should be 0"); +assertEq(view[445], 0, "445th value should be 0"); +assertEq(view[446], 0, "446th value should be 0"); +assertEq(view[447], 255, "447th value should be 255"); +assertEq(view[448], 0, "448th value should be 0"); +assertEq(view[449], 0, "449th value should be 0"); +assertEq(view[450], 0, "450th value should be 0"); +assertEq(view[451], 255, "451th value should be 255"); +assertEq(view[452], 0, "452th value should be 0"); +assertEq(view[453], 0, "453th value should be 0"); +assertEq(view[454], 0, "454th value should be 0"); +assertEq(view[455], 255, "455th value should be 255"); +assertEq(view[456], 0, "456th value should be 0"); +assertEq(view[457], 0, "457th value should be 0"); +assertEq(view[458], 0, "458th value should be 0"); +assertEq(view[459], 255, "459th value should be 255"); +assertEq(view[460], 0, "460th value should be 0"); +assertEq(view[461], 0, "461th value should be 0"); +assertEq(view[462], 0, "462th value should be 0"); +assertEq(view[463], 255, "463th value should be 255"); +assertEq(view[464], 78, "464th value should be 78"); +assertEq(view[465], 127, "465th value should be 127"); +assertEq(view[466], 178, "466th value should be 178"); +assertEq(view[467], 255, "467th value should be 255"); +assertEq(view[468], 154, "468th value should be 154"); +assertEq(view[469], 255, "469th value should be 255"); +assertEq(view[470], 101, "470th value should be 101"); +assertEq(view[471], 255, "471th value should be 255"); +assertEq(view[472], 205, "472th value should be 205"); +assertEq(view[473], 255, "473th value should be 255"); +assertEq(view[474], 50, "474th value should be 50"); +assertEq(view[475], 255, "475th value should be 255"); +assertEq(view[476], 205, "476th value should be 205"); +assertEq(view[477], 255, "477th value should be 255"); +assertEq(view[478], 50, "478th value should be 50"); +assertEq(view[479], 255, "479th value should be 255"); +assertEq(view[480], 205, "480th value should be 205"); +assertEq(view[481], 255, "481th value should be 255"); +assertEq(view[482], 50, "482th value should be 50"); +assertEq(view[483], 255, "483th value should be 255"); +assertEq(view[484], 205, "484th value should be 205"); +assertEq(view[485], 255, "485th value should be 255"); +assertEq(view[486], 50, "486th value should be 50"); +assertEq(view[487], 255, "487th value should be 255"); +assertEq(view[488], 179, "488th value should be 179"); +assertEq(view[489], 127, "489th value should be 127"); +assertEq(view[490], 76, "490th value should be 76"); +assertEq(view[491], 255, "491th value should be 255"); +assertEq(view[492], 179, "492th value should be 179"); +assertEq(view[493], 127, "493th value should be 127"); +assertEq(view[494], 76, "494th value should be 76"); +assertEq(view[495], 255, "495th value should be 255"); +assertEq(view[496], 128, "496th value should be 128"); +assertEq(view[497], 127, "497th value should be 127"); +assertEq(view[498], 127, "498th value should be 127"); +assertEq(view[499], 255, "499th value should be 255"); +assertEq(view[500], 52, "500th value should be 52"); +assertEq(view[501], 255, "501th value should be 255"); +assertEq(view[502], 203, "502th value should be 203"); +assertEq(view[503], 255, "503th value should be 255"); +assertEq(view[504], 0, "504th value should be 0"); +assertEq(view[505], 0, "505th value should be 0"); +assertEq(view[506], 0, "506th value should be 0"); +assertEq(view[507], 255, "507th value should be 255"); +assertEq(view[508], 78, "508th value should be 78"); +assertEq(view[509], 127, "509th value should be 127"); +assertEq(view[510], 178, "510th value should be 178"); +assertEq(view[511], 255, "511th value should be 255"); +assertEq(view[512], 52, "512th value should be 52"); +assertEq(view[513], 255, "513th value should be 255"); +assertEq(view[514], 203, "514th value should be 203"); +assertEq(view[515], 255, "515th value should be 255"); +assertEq(view[516], 0, "516th value should be 0"); +assertEq(view[517], 0, "517th value should be 0"); +assertEq(view[518], 0, "518th value should be 0"); +assertEq(view[519], 255, "519th value should be 255"); +assertEq(view[520], 0, "520th value should be 0"); +assertEq(view[521], 0, "521th value should be 0"); +assertEq(view[522], 0, "522th value should be 0"); +assertEq(view[523], 255, "523th value should be 255"); +assertEq(view[524], 0, "524th value should be 0"); +assertEq(view[525], 0, "525th value should be 0"); +assertEq(view[526], 0, "526th value should be 0"); +assertEq(view[527], 255, "527th value should be 255"); +assertEq(view[528], 0, "528th value should be 0"); +assertEq(view[529], 0, "529th value should be 0"); +assertEq(view[530], 0, "530th value should be 0"); +assertEq(view[531], 255, "531th value should be 255"); +assertEq(view[532], 0, "532th value should be 0"); +assertEq(view[533], 0, "533th value should be 0"); +assertEq(view[534], 0, "534th value should be 0"); +assertEq(view[535], 255, "535th value should be 255"); +assertEq(view[536], 0, "536th value should be 0"); +assertEq(view[537], 0, "537th value should be 0"); +assertEq(view[538], 0, "538th value should be 0"); +assertEq(view[539], 255, "539th value should be 255"); +assertEq(view[540], 0, "540th value should be 0"); +assertEq(view[541], 0, "541th value should be 0"); +assertEq(view[542], 0, "542th value should be 0"); +assertEq(view[543], 255, "543th value should be 255"); +assertEq(view[544], 0, "544th value should be 0"); +assertEq(view[545], 0, "545th value should be 0"); +assertEq(view[546], 0, "546th value should be 0"); +assertEq(view[547], 255, "547th value should be 255"); +assertEq(view[548], 154, "548th value should be 154"); +assertEq(view[549], 255, "549th value should be 255"); +assertEq(view[550], 101, "550th value should be 101"); +assertEq(view[551], 255, "551th value should be 255"); +assertEq(view[552], 205, "552th value should be 205"); +assertEq(view[553], 255, "553th value should be 255"); +assertEq(view[554], 50, "554th value should be 50"); +assertEq(view[555], 255, "555th value should be 255"); +assertEq(view[556], 205, "556th value should be 205"); +assertEq(view[557], 255, "557th value should be 255"); +assertEq(view[558], 50, "558th value should be 50"); +assertEq(view[559], 255, "559th value should be 255"); +assertEq(view[560], 205, "560th value should be 205"); +assertEq(view[561], 255, "561th value should be 255"); +assertEq(view[562], 50, "562th value should be 50"); +assertEq(view[563], 255, "563th value should be 255"); +assertEq(view[564], 179, "564th value should be 179"); +assertEq(view[565], 127, "565th value should be 127"); +assertEq(view[566], 76, "566th value should be 76"); +assertEq(view[567], 255, "567th value should be 255"); +assertEq(view[568], 179, "568th value should be 179"); +assertEq(view[569], 127, "569th value should be 127"); +assertEq(view[570], 76, "570th value should be 76"); +assertEq(view[571], 255, "571th value should be 255"); +assertEq(view[572], 154, "572th value should be 154"); +assertEq(view[573], 255, "573th value should be 255"); +assertEq(view[574], 101, "574th value should be 101"); +assertEq(view[575], 255, "575th value should be 255"); +assertEq(view[576], 103, "576th value should be 103"); +assertEq(view[577], 255, "577th value should be 255"); +assertEq(view[578], 152, "578th value should be 152"); +assertEq(view[579], 255, "579th value should be 255"); +assertEq(view[580], 0, "580th value should be 0"); +assertEq(view[581], 0, "581th value should be 0"); +assertEq(view[582], 0, "582th value should be 0"); +assertEq(view[583], 255, "583th value should be 255"); +assertEq(view[584], 0, "584th value should be 0"); +assertEq(view[585], 0, "585th value should be 0"); +assertEq(view[586], 0, "586th value should be 0"); +assertEq(view[587], 255, "587th value should be 255"); +assertEq(view[588], 0, "588th value should be 0"); +assertEq(view[589], 0, "589th value should be 0"); +assertEq(view[590], 0, "590th value should be 0"); +assertEq(view[591], 255, "591th value should be 255"); +assertEq(view[592], 0, "592th value should be 0"); +assertEq(view[593], 0, "593th value should be 0"); +assertEq(view[594], 0, "594th value should be 0"); +assertEq(view[595], 255, "595th value should be 255"); +assertEq(view[596], 0, "596th value should be 0"); +assertEq(view[597], 0, "597th value should be 0"); +assertEq(view[598], 0, "598th value should be 0"); +assertEq(view[599], 255, "599th value should be 255"); +assertEq(view[600], 0, "600th value should be 0"); +assertEq(view[601], 0, "601th value should be 0"); +assertEq(view[602], 0, "602th value should be 0"); +assertEq(view[603], 255, "603th value should be 255"); +assertEq(view[604], 0, "604th value should be 0"); +assertEq(view[605], 0, "605th value should be 0"); +assertEq(view[606], 0, "606th value should be 0"); +assertEq(view[607], 255, "607th value should be 255"); +assertEq(view[608], 0, "608th value should be 0"); +assertEq(view[609], 0, "609th value should be 0"); +assertEq(view[610], 0, "610th value should be 0"); +assertEq(view[611], 255, "611th value should be 255"); +assertEq(view[612], 0, "612th value should be 0"); +assertEq(view[613], 0, "613th value should be 0"); +assertEq(view[614], 0, "614th value should be 0"); +assertEq(view[615], 255, "615th value should be 255"); +assertEq(view[616], 0, "616th value should be 0"); +assertEq(view[617], 0, "617th value should be 0"); +assertEq(view[618], 0, "618th value should be 0"); +assertEq(view[619], 255, "619th value should be 255"); +assertEq(view[620], 0, "620th value should be 0"); +assertEq(view[621], 0, "621th value should be 0"); +assertEq(view[622], 0, "622th value should be 0"); +assertEq(view[623], 255, "623th value should be 255"); +assertEq(view[624], 0, "624th value should be 0"); +assertEq(view[625], 0, "625th value should be 0"); +assertEq(view[626], 0, "626th value should be 0"); +assertEq(view[627], 255, "627th value should be 255"); +assertEq(view[628], 154, "628th value should be 154"); +assertEq(view[629], 255, "629th value should be 255"); +assertEq(view[630], 101, "630th value should be 101"); +assertEq(view[631], 255, "631th value should be 255"); +assertEq(view[632], 205, "632th value should be 205"); +assertEq(view[633], 255, "633th value should be 255"); +assertEq(view[634], 50, "634th value should be 50"); +assertEq(view[635], 255, "635th value should be 255"); +assertEq(view[636], 205, "636th value should be 205"); +assertEq(view[637], 255, "637th value should be 255"); +assertEq(view[638], 50, "638th value should be 50"); +assertEq(view[639], 255, "639th value should be 255"); +assertEq(view[640], 179, "640th value should be 179"); +assertEq(view[641], 127, "641th value should be 127"); +assertEq(view[642], 76, "642th value should be 76"); +assertEq(view[643], 255, "643th value should be 255"); +assertEq(view[644], 179, "644th value should be 179"); +assertEq(view[645], 127, "645th value should be 127"); +assertEq(view[646], 76, "646th value should be 76"); +assertEq(view[647], 255, "647th value should be 255"); +assertEq(view[648], 154, "648th value should be 154"); +assertEq(view[649], 255, "649th value should be 255"); +assertEq(view[650], 101, "650th value should be 101"); +assertEq(view[651], 255, "651th value should be 255"); +assertEq(view[652], 128, "652th value should be 128"); +assertEq(view[653], 127, "653th value should be 127"); +assertEq(view[654], 127, "654th value should be 127"); +assertEq(view[655], 255, "655th value should be 255"); +assertEq(view[656], 52, "656th value should be 52"); +assertEq(view[657], 255, "657th value should be 255"); +assertEq(view[658], 203, "658th value should be 203"); +assertEq(view[659], 255, "659th value should be 255"); +assertEq(view[660], 0, "660th value should be 0"); +assertEq(view[661], 0, "661th value should be 0"); +assertEq(view[662], 0, "662th value should be 0"); +assertEq(view[663], 255, "663th value should be 255"); +assertEq(view[664], 0, "664th value should be 0"); +assertEq(view[665], 0, "665th value should be 0"); +assertEq(view[666], 0, "666th value should be 0"); +assertEq(view[667], 255, "667th value should be 255"); +assertEq(view[668], 0, "668th value should be 0"); +assertEq(view[669], 0, "669th value should be 0"); +assertEq(view[670], 0, "670th value should be 0"); +assertEq(view[671], 255, "671th value should be 255"); +assertEq(view[672], 0, "672th value should be 0"); +assertEq(view[673], 0, "673th value should be 0"); +assertEq(view[674], 0, "674th value should be 0"); +assertEq(view[675], 255, "675th value should be 255"); +assertEq(view[676], 0, "676th value should be 0"); +assertEq(view[677], 0, "677th value should be 0"); +assertEq(view[678], 0, "678th value should be 0"); +assertEq(view[679], 255, "679th value should be 255"); +assertEq(view[680], 0, "680th value should be 0"); +assertEq(view[681], 0, "681th value should be 0"); +assertEq(view[682], 0, "682th value should be 0"); +assertEq(view[683], 255, "683th value should be 255"); +assertEq(view[684], 0, "684th value should be 0"); +assertEq(view[685], 0, "685th value should be 0"); +assertEq(view[686], 0, "686th value should be 0"); +assertEq(view[687], 255, "687th value should be 255"); +assertEq(view[688], 0, "688th value should be 0"); +assertEq(view[689], 0, "689th value should be 0"); +assertEq(view[690], 0, "690th value should be 0"); +assertEq(view[691], 255, "691th value should be 255"); +assertEq(view[692], 0, "692th value should be 0"); +assertEq(view[693], 0, "693th value should be 0"); +assertEq(view[694], 0, "694th value should be 0"); +assertEq(view[695], 255, "695th value should be 255"); +assertEq(view[696], 0, "696th value should be 0"); +assertEq(view[697], 0, "697th value should be 0"); +assertEq(view[698], 0, "698th value should be 0"); +assertEq(view[699], 255, "699th value should be 255"); +assertEq(view[700], 0, "700th value should be 0"); +assertEq(view[701], 0, "701th value should be 0"); +assertEq(view[702], 0, "702th value should be 0"); +assertEq(view[703], 255, "703th value should be 255"); +assertEq(view[704], 0, "704th value should be 0"); +assertEq(view[705], 0, "705th value should be 0"); +assertEq(view[706], 0, "706th value should be 0"); +assertEq(view[707], 255, "707th value should be 255"); +assertEq(view[708], 154, "708th value should be 154"); +assertEq(view[709], 255, "709th value should be 255"); +assertEq(view[710], 101, "710th value should be 101"); +assertEq(view[711], 255, "711th value should be 255"); +assertEq(view[712], 179, "712th value should be 179"); +assertEq(view[713], 127, "713th value should be 127"); +assertEq(view[714], 76, "714th value should be 76"); +assertEq(view[715], 255, "715th value should be 255"); +assertEq(view[716], 205, "716th value should be 205"); +assertEq(view[717], 255, "717th value should be 255"); +assertEq(view[718], 50, "718th value should be 50"); +assertEq(view[719], 255, "719th value should be 255"); +assertEq(view[720], 154, "720th value should be 154"); +assertEq(view[721], 255, "721th value should be 255"); +assertEq(view[722], 101, "722th value should be 101"); +assertEq(view[723], 255, "723th value should be 255"); +assertEq(view[724], 52, "724th value should be 52"); +assertEq(view[725], 255, "725th value should be 255"); +assertEq(view[726], 203, "726th value should be 203"); +assertEq(view[727], 255, "727th value should be 255"); +assertEq(view[728], 128, "728th value should be 128"); +assertEq(view[729], 127, "729th value should be 127"); +assertEq(view[730], 127, "730th value should be 127"); +assertEq(view[731], 255, "731th value should be 255"); +assertEq(view[732], 78, "732th value should be 78"); +assertEq(view[733], 127, "733th value should be 127"); +assertEq(view[734], 178, "734th value should be 178"); +assertEq(view[735], 255, "735th value should be 255"); +assertEq(view[736], 0, "736th value should be 0"); +assertEq(view[737], 0, "737th value should be 0"); +assertEq(view[738], 0, "738th value should be 0"); +assertEq(view[739], 255, "739th value should be 255"); +assertEq(view[740], 0, "740th value should be 0"); +assertEq(view[741], 0, "741th value should be 0"); +assertEq(view[742], 0, "742th value should be 0"); +assertEq(view[743], 255, "743th value should be 255"); +assertEq(view[744], 0, "744th value should be 0"); +assertEq(view[745], 0, "745th value should be 0"); +assertEq(view[746], 0, "746th value should be 0"); +assertEq(view[747], 255, "747th value should be 255"); +assertEq(view[748], 0, "748th value should be 0"); +assertEq(view[749], 0, "749th value should be 0"); +assertEq(view[750], 0, "750th value should be 0"); +assertEq(view[751], 255, "751th value should be 255"); +assertEq(view[752], 0, "752th value should be 0"); +assertEq(view[753], 0, "753th value should be 0"); +assertEq(view[754], 0, "754th value should be 0"); +assertEq(view[755], 255, "755th value should be 255"); +assertEq(view[756], 0, "756th value should be 0"); +assertEq(view[757], 0, "757th value should be 0"); +assertEq(view[758], 0, "758th value should be 0"); +assertEq(view[759], 255, "759th value should be 255"); +assertEq(view[760], 0, "760th value should be 0"); +assertEq(view[761], 0, "761th value should be 0"); +assertEq(view[762], 0, "762th value should be 0"); +assertEq(view[763], 255, "763th value should be 255"); +assertEq(view[764], 0, "764th value should be 0"); +assertEq(view[765], 0, "765th value should be 0"); +assertEq(view[766], 0, "766th value should be 0"); +assertEq(view[767], 255, "767th value should be 255"); +assertEq(view[768], 0, "768th value should be 0"); +assertEq(view[769], 0, "769th value should be 0"); +assertEq(view[770], 0, "770th value should be 0"); +assertEq(view[771], 255, "771th value should be 255"); +assertEq(view[772], 0, "772th value should be 0"); +assertEq(view[773], 0, "773th value should be 0"); +assertEq(view[774], 0, "774th value should be 0"); +assertEq(view[775], 255, "775th value should be 255"); +assertEq(view[776], 0, "776th value should be 0"); +assertEq(view[777], 0, "777th value should be 0"); +assertEq(view[778], 0, "778th value should be 0"); +assertEq(view[779], 255, "779th value should be 255"); +assertEq(view[780], 0, "780th value should be 0"); +assertEq(view[781], 0, "781th value should be 0"); +assertEq(view[782], 0, "782th value should be 0"); +assertEq(view[783], 255, "783th value should be 255"); +assertEq(view[784], 78, "784th value should be 78"); +assertEq(view[785], 127, "785th value should be 127"); +assertEq(view[786], 178, "786th value should be 178"); +assertEq(view[787], 255, "787th value should be 255"); +assertEq(view[788], 154, "788th value should be 154"); +assertEq(view[789], 255, "789th value should be 255"); +assertEq(view[790], 101, "790th value should be 101"); +assertEq(view[791], 255, "791th value should be 255"); +assertEq(view[792], 179, "792th value should be 179"); +assertEq(view[793], 127, "793th value should be 127"); +assertEq(view[794], 76, "794th value should be 76"); +assertEq(view[795], 255, "795th value should be 255"); +assertEq(view[796], 205, "796th value should be 205"); +assertEq(view[797], 255, "797th value should be 255"); +assertEq(view[798], 50, "798th value should be 50"); +assertEq(view[799], 255, "799th value should be 255"); +assertEq(view[800], 128, "800th value should be 128"); +assertEq(view[801], 127, "801th value should be 127"); +assertEq(view[802], 127, "802th value should be 127"); +assertEq(view[803], 255, "803th value should be 255"); +assertEq(view[804], 0, "804th value should be 0"); +assertEq(view[805], 0, "805th value should be 0"); +assertEq(view[806], 0, "806th value should be 0"); +assertEq(view[807], 255, "807th value should be 255"); +assertEq(view[808], 26, "808th value should be 26"); +assertEq(view[809], 127, "809th value should be 127"); +assertEq(view[810], 229, "810th value should be 229"); +assertEq(view[811], 255, "811th value should be 255"); +assertEq(view[812], 0, "812th value should be 0"); +assertEq(view[813], 0, "813th value should be 0"); +assertEq(view[814], 0, "814th value should be 0"); +assertEq(view[815], 255, "815th value should be 255"); +assertEq(view[816], 0, "816th value should be 0"); +assertEq(view[817], 0, "817th value should be 0"); +assertEq(view[818], 0, "818th value should be 0"); +assertEq(view[819], 255, "819th value should be 255"); +assertEq(view[820], 0, "820th value should be 0"); +assertEq(view[821], 0, "821th value should be 0"); +assertEq(view[822], 0, "822th value should be 0"); +assertEq(view[823], 255, "823th value should be 255"); +assertEq(view[824], 0, "824th value should be 0"); +assertEq(view[825], 0, "825th value should be 0"); +assertEq(view[826], 0, "826th value should be 0"); +assertEq(view[827], 255, "827th value should be 255"); +assertEq(view[828], 0, "828th value should be 0"); +assertEq(view[829], 0, "829th value should be 0"); +assertEq(view[830], 0, "830th value should be 0"); +assertEq(view[831], 255, "831th value should be 255"); +assertEq(view[832], 0, "832th value should be 0"); +assertEq(view[833], 0, "833th value should be 0"); +assertEq(view[834], 0, "834th value should be 0"); +assertEq(view[835], 255, "835th value should be 255"); +assertEq(view[836], 0, "836th value should be 0"); +assertEq(view[837], 0, "837th value should be 0"); +assertEq(view[838], 0, "838th value should be 0"); +assertEq(view[839], 255, "839th value should be 255"); +assertEq(view[840], 0, "840th value should be 0"); +assertEq(view[841], 0, "841th value should be 0"); +assertEq(view[842], 0, "842th value should be 0"); +assertEq(view[843], 255, "843th value should be 255"); +assertEq(view[844], 0, "844th value should be 0"); +assertEq(view[845], 0, "845th value should be 0"); +assertEq(view[846], 0, "846th value should be 0"); +assertEq(view[847], 255, "847th value should be 255"); +assertEq(view[848], 0, "848th value should be 0"); +assertEq(view[849], 0, "849th value should be 0"); +assertEq(view[850], 0, "850th value should be 0"); +assertEq(view[851], 255, "851th value should be 255"); +assertEq(view[852], 0, "852th value should be 0"); +assertEq(view[853], 0, "853th value should be 0"); +assertEq(view[854], 0, "854th value should be 0"); +assertEq(view[855], 255, "855th value should be 255"); +assertEq(view[856], 0, "856th value should be 0"); +assertEq(view[857], 0, "857th value should be 0"); +assertEq(view[858], 0, "858th value should be 0"); +assertEq(view[859], 255, "859th value should be 255"); +assertEq(view[860], 0, "860th value should be 0"); +assertEq(view[861], 0, "861th value should be 0"); +assertEq(view[862], 0, "862th value should be 0"); +assertEq(view[863], 255, "863th value should be 255"); +assertEq(view[864], 103, "864th value should be 103"); +assertEq(view[865], 255, "865th value should be 255"); +assertEq(view[866], 152, "866th value should be 152"); +assertEq(view[867], 255, "867th value should be 255"); +assertEq(view[868], 154, "868th value should be 154"); +assertEq(view[869], 255, "869th value should be 255"); +assertEq(view[870], 101, "870th value should be 101"); +assertEq(view[871], 255, "871th value should be 255"); +assertEq(view[872], 179, "872th value should be 179"); +assertEq(view[873], 127, "873th value should be 127"); +assertEq(view[874], 76, "874th value should be 76"); +assertEq(view[875], 255, "875th value should be 255"); +assertEq(view[876], 205, "876th value should be 205"); +assertEq(view[877], 255, "877th value should be 255"); +assertEq(view[878], 50, "878th value should be 50"); +assertEq(view[879], 255, "879th value should be 255"); +assertEq(view[880], 179, "880th value should be 179"); +assertEq(view[881], 127, "881th value should be 127"); +assertEq(view[882], 76, "882th value should be 76"); +assertEq(view[883], 255, "883th value should be 255"); +assertEq(view[884], 179, "884th value should be 179"); +assertEq(view[885], 127, "885th value should be 127"); +assertEq(view[886], 76, "886th value should be 76"); +assertEq(view[887], 255, "887th value should be 255"); +assertEq(view[888], 128, "888th value should be 128"); +assertEq(view[889], 127, "889th value should be 127"); +assertEq(view[890], 127, "890th value should be 127"); +assertEq(view[891], 255, "891th value should be 255"); +assertEq(view[892], 103, "892th value should be 103"); +assertEq(view[893], 255, "893th value should be 255"); +assertEq(view[894], 152, "894th value should be 152"); +assertEq(view[895], 255, "895th value should be 255"); +assertEq(view[896], 26, "896th value should be 26"); +assertEq(view[897], 127, "897th value should be 127"); +assertEq(view[898], 229, "898th value should be 229"); +assertEq(view[899], 255, "899th value should be 255"); +assertEq(view[900], 0, "900th value should be 0"); +assertEq(view[901], 0, "901th value should be 0"); +assertEq(view[902], 0, "902th value should be 0"); +assertEq(view[903], 255, "903th value should be 255"); +assertEq(view[904], 0, "904th value should be 0"); +assertEq(view[905], 0, "905th value should be 0"); +assertEq(view[906], 0, "906th value should be 0"); +assertEq(view[907], 255, "907th value should be 255"); +assertEq(view[908], 0, "908th value should be 0"); +assertEq(view[909], 0, "909th value should be 0"); +assertEq(view[910], 0, "910th value should be 0"); +assertEq(view[911], 255, "911th value should be 255"); +assertEq(view[912], 0, "912th value should be 0"); +assertEq(view[913], 0, "913th value should be 0"); +assertEq(view[914], 0, "914th value should be 0"); +assertEq(view[915], 255, "915th value should be 255"); +assertEq(view[916], 0, "916th value should be 0"); +assertEq(view[917], 0, "917th value should be 0"); +assertEq(view[918], 0, "918th value should be 0"); +assertEq(view[919], 255, "919th value should be 255"); +assertEq(view[920], 0, "920th value should be 0"); +assertEq(view[921], 0, "921th value should be 0"); +assertEq(view[922], 0, "922th value should be 0"); +assertEq(view[923], 255, "923th value should be 255"); +assertEq(view[924], 0, "924th value should be 0"); +assertEq(view[925], 0, "925th value should be 0"); +assertEq(view[926], 0, "926th value should be 0"); +assertEq(view[927], 255, "927th value should be 255"); +assertEq(view[928], 0, "928th value should be 0"); +assertEq(view[929], 0, "929th value should be 0"); +assertEq(view[930], 0, "930th value should be 0"); +assertEq(view[931], 255, "931th value should be 255"); +assertEq(view[932], 0, "932th value should be 0"); +assertEq(view[933], 0, "933th value should be 0"); +assertEq(view[934], 0, "934th value should be 0"); +assertEq(view[935], 255, "935th value should be 255"); +assertEq(view[936], 0, "936th value should be 0"); +assertEq(view[937], 0, "937th value should be 0"); +assertEq(view[938], 0, "938th value should be 0"); +assertEq(view[939], 255, "939th value should be 255"); +assertEq(view[940], 0, "940th value should be 0"); +assertEq(view[941], 0, "941th value should be 0"); +assertEq(view[942], 0, "942th value should be 0"); +assertEq(view[943], 255, "943th value should be 255"); +assertEq(view[944], 0, "944th value should be 0"); +assertEq(view[945], 0, "945th value should be 0"); +assertEq(view[946], 0, "946th value should be 0"); +assertEq(view[947], 255, "947th value should be 255"); +assertEq(view[948], 154, "948th value should be 154"); +assertEq(view[949], 255, "949th value should be 255"); +assertEq(view[950], 101, "950th value should be 101"); +assertEq(view[951], 255, "951th value should be 255"); +assertEq(view[952], 179, "952th value should be 179"); +assertEq(view[953], 127, "953th value should be 127"); +assertEq(view[954], 76, "954th value should be 76"); +assertEq(view[955], 255, "955th value should be 255"); +assertEq(view[956], 205, "956th value should be 205"); +assertEq(view[957], 255, "957th value should be 255"); +assertEq(view[958], 50, "958th value should be 50"); +assertEq(view[959], 255, "959th value should be 255"); +assertEq(view[960], 179, "960th value should be 179"); +assertEq(view[961], 127, "961th value should be 127"); +assertEq(view[962], 76, "962th value should be 76"); +assertEq(view[963], 255, "963th value should be 255"); +assertEq(view[964], 179, "964th value should be 179"); +assertEq(view[965], 127, "965th value should be 127"); +assertEq(view[966], 76, "966th value should be 76"); +assertEq(view[967], 255, "967th value should be 255"); +assertEq(view[968], 179, "968th value should be 179"); +assertEq(view[969], 127, "969th value should be 127"); +assertEq(view[970], 76, "970th value should be 76"); +assertEq(view[971], 255, "971th value should be 255"); +assertEq(view[972], 154, "972th value should be 154"); +assertEq(view[973], 255, "973th value should be 255"); +assertEq(view[974], 101, "974th value should be 101"); +assertEq(view[975], 255, "975th value should be 255"); +assertEq(view[976], 103, "976th value should be 103"); +assertEq(view[977], 255, "977th value should be 255"); +assertEq(view[978], 152, "978th value should be 152"); +assertEq(view[979], 255, "979th value should be 255"); +assertEq(view[980], 0, "980th value should be 0"); +assertEq(view[981], 0, "981th value should be 0"); +assertEq(view[982], 0, "982th value should be 0"); +assertEq(view[983], 255, "983th value should be 255"); +assertEq(view[984], 0, "984th value should be 0"); +assertEq(view[985], 0, "985th value should be 0"); +assertEq(view[986], 0, "986th value should be 0"); +assertEq(view[987], 255, "987th value should be 255"); +assertEq(view[988], 0, "988th value should be 0"); +assertEq(view[989], 0, "989th value should be 0"); +assertEq(view[990], 0, "990th value should be 0"); +assertEq(view[991], 255, "991th value should be 255"); +assertEq(view[992], 0, "992th value should be 0"); +assertEq(view[993], 0, "993th value should be 0"); +assertEq(view[994], 0, "994th value should be 0"); +assertEq(view[995], 255, "995th value should be 255"); +assertEq(view[996], 0, "996th value should be 0"); +assertEq(view[997], 0, "997th value should be 0"); +assertEq(view[998], 0, "998th value should be 0"); +assertEq(view[999], 255, "999th value should be 255"); +assertEq(view[1000], 0, "1000th value should be 0"); +assertEq(view[1001], 0, "1001th value should be 0"); +assertEq(view[1002], 0, "1002th value should be 0"); +assertEq(view[1003], 255, "1003th value should be 255"); +assertEq(view[1004], 0, "1004th value should be 0"); +assertEq(view[1005], 0, "1005th value should be 0"); +assertEq(view[1006], 0, "1006th value should be 0"); +assertEq(view[1007], 255, "1007th value should be 255"); +assertEq(view[1008], 0, "1008th value should be 0"); +assertEq(view[1009], 0, "1009th value should be 0"); +assertEq(view[1010], 0, "1010th value should be 0"); +assertEq(view[1011], 255, "1011th value should be 255"); +assertEq(view[1012], 0, "1012th value should be 0"); +assertEq(view[1013], 0, "1013th value should be 0"); +assertEq(view[1014], 0, "1014th value should be 0"); +assertEq(view[1015], 255, "1015th value should be 255"); +assertEq(view[1016], 0, "1016th value should be 0"); +assertEq(view[1017], 0, "1017th value should be 0"); +assertEq(view[1018], 0, "1018th value should be 0"); +assertEq(view[1019], 255, "1019th value should be 255"); +assertEq(view[1020], 0, "1020th value should be 0"); +assertEq(view[1021], 0, "1021th value should be 0"); +assertEq(view[1022], 0, "1022th value should be 0"); +assertEq(view[1023], 255, "1023th value should be 255"); +assertEq(view[1024], 0, "1024th value should be 0"); +assertEq(view[1025], 0, "1025th value should be 0"); +assertEq(view[1026], 0, "1026th value should be 0"); +assertEq(view[1027], 255, "1027th value should be 255"); +assertEq(view[1028], 154, "1028th value should be 154"); +assertEq(view[1029], 255, "1029th value should be 255"); +assertEq(view[1030], 101, "1030th value should be 101"); +assertEq(view[1031], 255, "1031th value should be 255"); +assertEq(view[1032], 205, "1032th value should be 205"); +assertEq(view[1033], 255, "1033th value should be 255"); +assertEq(view[1034], 50, "1034th value should be 50"); +assertEq(view[1035], 255, "1035th value should be 255"); +assertEq(view[1036], 205, "1036th value should be 205"); +assertEq(view[1037], 255, "1037th value should be 255"); +assertEq(view[1038], 50, "1038th value should be 50"); +assertEq(view[1039], 255, "1039th value should be 255"); +assertEq(view[1040], 205, "1040th value should be 205"); +assertEq(view[1041], 255, "1041th value should be 255"); +assertEq(view[1042], 50, "1042th value should be 50"); +assertEq(view[1043], 255, "1043th value should be 255"); +assertEq(view[1044], 179, "1044th value should be 179"); +assertEq(view[1045], 127, "1045th value should be 127"); +assertEq(view[1046], 76, "1046th value should be 76"); +assertEq(view[1047], 255, "1047th value should be 255"); +assertEq(view[1048], 179, "1048th value should be 179"); +assertEq(view[1049], 127, "1049th value should be 127"); +assertEq(view[1050], 76, "1050th value should be 76"); +assertEq(view[1051], 255, "1051th value should be 255"); +assertEq(view[1052], 154, "1052th value should be 154"); +assertEq(view[1053], 255, "1053th value should be 255"); +assertEq(view[1054], 101, "1054th value should be 101"); +assertEq(view[1055], 255, "1055th value should be 255"); +assertEq(view[1056], 128, "1056th value should be 128"); +assertEq(view[1057], 127, "1057th value should be 127"); +assertEq(view[1058], 127, "1058th value should be 127"); +assertEq(view[1059], 255, "1059th value should be 255"); +assertEq(view[1060], 0, "1060th value should be 0"); +assertEq(view[1061], 0, "1061th value should be 0"); +assertEq(view[1062], 0, "1062th value should be 0"); +assertEq(view[1063], 255, "1063th value should be 255"); +assertEq(view[1064], 0, "1064th value should be 0"); +assertEq(view[1065], 0, "1065th value should be 0"); +assertEq(view[1066], 0, "1066th value should be 0"); +assertEq(view[1067], 255, "1067th value should be 255"); +assertEq(view[1068], 26, "1068th value should be 26"); +assertEq(view[1069], 127, "1069th value should be 127"); +assertEq(view[1070], 229, "1070th value should be 229"); +assertEq(view[1071], 255, "1071th value should be 255"); +assertEq(view[1072], 26, "1072th value should be 26"); +assertEq(view[1073], 127, "1073th value should be 127"); +assertEq(view[1074], 229, "1074th value should be 229"); +assertEq(view[1075], 255, "1075th value should be 255"); +assertEq(view[1076], 0, "1076th value should be 0"); +assertEq(view[1077], 0, "1077th value should be 0"); +assertEq(view[1078], 0, "1078th value should be 0"); +assertEq(view[1079], 255, "1079th value should be 255"); +assertEq(view[1080], 0, "1080th value should be 0"); +assertEq(view[1081], 0, "1081th value should be 0"); +assertEq(view[1082], 0, "1082th value should be 0"); +assertEq(view[1083], 255, "1083th value should be 255"); +assertEq(view[1084], 0, "1084th value should be 0"); +assertEq(view[1085], 0, "1085th value should be 0"); +assertEq(view[1086], 0, "1086th value should be 0"); +assertEq(view[1087], 255, "1087th value should be 255"); +assertEq(view[1088], 0, "1088th value should be 0"); +assertEq(view[1089], 0, "1089th value should be 0"); +assertEq(view[1090], 0, "1090th value should be 0"); +assertEq(view[1091], 255, "1091th value should be 255"); +assertEq(view[1092], 0, "1092th value should be 0"); +assertEq(view[1093], 0, "1093th value should be 0"); +assertEq(view[1094], 0, "1094th value should be 0"); +assertEq(view[1095], 255, "1095th value should be 255"); +assertEq(view[1096], 0, "1096th value should be 0"); +assertEq(view[1097], 0, "1097th value should be 0"); +assertEq(view[1098], 0, "1098th value should be 0"); +assertEq(view[1099], 255, "1099th value should be 255"); +assertEq(view[1100], 0, "1100th value should be 0"); +assertEq(view[1101], 0, "1101th value should be 0"); +assertEq(view[1102], 0, "1102th value should be 0"); +assertEq(view[1103], 255, "1103th value should be 255"); +assertEq(view[1104], 0, "1104th value should be 0"); +assertEq(view[1105], 0, "1105th value should be 0"); +assertEq(view[1106], 0, "1106th value should be 0"); +assertEq(view[1107], 255, "1107th value should be 255"); +assertEq(view[1108], 154, "1108th value should be 154"); +assertEq(view[1109], 255, "1109th value should be 255"); +assertEq(view[1110], 101, "1110th value should be 101"); +assertEq(view[1111], 255, "1111th value should be 255"); +assertEq(view[1112], 205, "1112th value should be 205"); +assertEq(view[1113], 255, "1113th value should be 255"); +assertEq(view[1114], 50, "1114th value should be 50"); +assertEq(view[1115], 255, "1115th value should be 255"); +assertEq(view[1116], 205, "1116th value should be 205"); +assertEq(view[1117], 255, "1117th value should be 255"); +assertEq(view[1118], 50, "1118th value should be 50"); +assertEq(view[1119], 255, "1119th value should be 255"); +assertEq(view[1120], 205, "1120th value should be 205"); +assertEq(view[1121], 255, "1121th value should be 255"); +assertEq(view[1122], 50, "1122th value should be 50"); +assertEq(view[1123], 255, "1123th value should be 255"); +assertEq(view[1124], 205, "1124th value should be 205"); +assertEq(view[1125], 255, "1125th value should be 255"); +assertEq(view[1126], 50, "1126th value should be 50"); +assertEq(view[1127], 255, "1127th value should be 255"); +assertEq(view[1128], 205, "1128th value should be 205"); +assertEq(view[1129], 255, "1129th value should be 255"); +assertEq(view[1130], 50, "1130th value should be 50"); +assertEq(view[1131], 255, "1131th value should be 255"); +assertEq(view[1132], 179, "1132th value should be 179"); +assertEq(view[1133], 127, "1133th value should be 127"); +assertEq(view[1134], 76, "1134th value should be 76"); +assertEq(view[1135], 255, "1135th value should be 255"); +assertEq(view[1136], 154, "1136th value should be 154"); +assertEq(view[1137], 255, "1137th value should be 255"); +assertEq(view[1138], 101, "1138th value should be 101"); +assertEq(view[1139], 255, "1139th value should be 255"); +assertEq(view[1140], 128, "1140th value should be 128"); +assertEq(view[1141], 127, "1141th value should be 127"); +assertEq(view[1142], 127, "1142th value should be 127"); +assertEq(view[1143], 255, "1143th value should be 255"); +assertEq(view[1144], 128, "1144th value should be 128"); +assertEq(view[1145], 127, "1145th value should be 127"); +assertEq(view[1146], 127, "1146th value should be 127"); +assertEq(view[1147], 255, "1147th value should be 255"); +assertEq(view[1148], 103, "1148th value should be 103"); +assertEq(view[1149], 255, "1149th value should be 255"); +assertEq(view[1150], 152, "1150th value should be 152"); +assertEq(view[1151], 255, "1151th value should be 255"); +assertEq(view[1152], 78, "1152th value should be 78"); +assertEq(view[1153], 127, "1153th value should be 127"); +assertEq(view[1154], 178, "1154th value should be 178"); +assertEq(view[1155], 255, "1155th value should be 255"); +assertEq(view[1156], 0, "1156th value should be 0"); +assertEq(view[1157], 0, "1157th value should be 0"); +assertEq(view[1158], 0, "1158th value should be 0"); +assertEq(view[1159], 255, "1159th value should be 255"); +assertEq(view[1160], 0, "1160th value should be 0"); +assertEq(view[1161], 0, "1161th value should be 0"); +assertEq(view[1162], 0, "1162th value should be 0"); +assertEq(view[1163], 255, "1163th value should be 255"); +assertEq(view[1164], 0, "1164th value should be 0"); +assertEq(view[1165], 0, "1165th value should be 0"); +assertEq(view[1166], 0, "1166th value should be 0"); +assertEq(view[1167], 255, "1167th value should be 255"); +assertEq(view[1168], 0, "1168th value should be 0"); +assertEq(view[1169], 0, "1169th value should be 0"); +assertEq(view[1170], 0, "1170th value should be 0"); +assertEq(view[1171], 255, "1171th value should be 255"); +assertEq(view[1172], 0, "1172th value should be 0"); +assertEq(view[1173], 0, "1173th value should be 0"); +assertEq(view[1174], 0, "1174th value should be 0"); +assertEq(view[1175], 255, "1175th value should be 255"); +assertEq(view[1176], 0, "1176th value should be 0"); +assertEq(view[1177], 0, "1177th value should be 0"); +assertEq(view[1178], 0, "1178th value should be 0"); +assertEq(view[1179], 255, "1179th value should be 255"); +assertEq(view[1180], 0, "1180th value should be 0"); +assertEq(view[1181], 0, "1181th value should be 0"); +assertEq(view[1182], 0, "1182th value should be 0"); +assertEq(view[1183], 255, "1183th value should be 255"); +assertEq(view[1184], 26, "1184th value should be 26"); +assertEq(view[1185], 127, "1185th value should be 127"); +assertEq(view[1186], 229, "1186th value should be 229"); +assertEq(view[1187], 255, "1187th value should be 255"); +assertEq(view[1188], 154, "1188th value should be 154"); +assertEq(view[1189], 255, "1189th value should be 255"); +assertEq(view[1190], 101, "1190th value should be 101"); +assertEq(view[1191], 255, "1191th value should be 255"); +assertEq(view[1192], 205, "1192th value should be 205"); +assertEq(view[1193], 255, "1193th value should be 255"); +assertEq(view[1194], 50, "1194th value should be 50"); +assertEq(view[1195], 255, "1195th value should be 255"); +assertEq(view[1196], 205, "1196th value should be 205"); +assertEq(view[1197], 255, "1197th value should be 255"); +assertEq(view[1198], 50, "1198th value should be 50"); +assertEq(view[1199], 255, "1199th value should be 255"); +assertEq(view[1200], 230, "1200th value should be 230"); +assertEq(view[1201], 127, "1201th value should be 127"); +assertEq(view[1202], 25, "1202th value should be 25"); +assertEq(view[1203], 255, "1203th value should be 255"); +assertEq(view[1204], 205, "1204th value should be 205"); +assertEq(view[1205], 255, "1205th value should be 255"); +assertEq(view[1206], 50, "1206th value should be 50"); +assertEq(view[1207], 255, "1207th value should be 255"); +assertEq(view[1208], 205, "1208th value should be 205"); +assertEq(view[1209], 255, "1209th value should be 255"); +assertEq(view[1210], 50, "1210th value should be 50"); +assertEq(view[1211], 255, "1211th value should be 255"); +assertEq(view[1212], 205, "1212th value should be 205"); +assertEq(view[1213], 255, "1213th value should be 255"); +assertEq(view[1214], 50, "1214th value should be 50"); +assertEq(view[1215], 255, "1215th value should be 255"); +assertEq(view[1216], 205, "1216th value should be 205"); +assertEq(view[1217], 255, "1217th value should be 255"); +assertEq(view[1218], 50, "1218th value should be 50"); +assertEq(view[1219], 255, "1219th value should be 255"); +assertEq(view[1220], 154, "1220th value should be 154"); +assertEq(view[1221], 255, "1221th value should be 255"); +assertEq(view[1222], 101, "1222th value should be 101"); +assertEq(view[1223], 255, "1223th value should be 255"); +assertEq(view[1224], 154, "1224th value should be 154"); +assertEq(view[1225], 255, "1225th value should be 255"); +assertEq(view[1226], 101, "1226th value should be 101"); +assertEq(view[1227], 255, "1227th value should be 255"); +assertEq(view[1228], 154, "1228th value should be 154"); +assertEq(view[1229], 255, "1229th value should be 255"); +assertEq(view[1230], 101, "1230th value should be 101"); +assertEq(view[1231], 255, "1231th value should be 255"); +assertEq(view[1232], 128, "1232th value should be 128"); +assertEq(view[1233], 127, "1233th value should be 127"); +assertEq(view[1234], 127, "1234th value should be 127"); +assertEq(view[1235], 255, "1235th value should be 255"); +assertEq(view[1236], 26, "1236th value should be 26"); +assertEq(view[1237], 127, "1237th value should be 127"); +assertEq(view[1238], 229, "1238th value should be 229"); +assertEq(view[1239], 255, "1239th value should be 255"); +assertEq(view[1240], 0, "1240th value should be 0"); +assertEq(view[1241], 0, "1241th value should be 0"); +assertEq(view[1242], 0, "1242th value should be 0"); +assertEq(view[1243], 255, "1243th value should be 255"); +assertEq(view[1244], 0, "1244th value should be 0"); +assertEq(view[1245], 0, "1245th value should be 0"); +assertEq(view[1246], 0, "1246th value should be 0"); +assertEq(view[1247], 255, "1247th value should be 255"); +assertEq(view[1248], 0, "1248th value should be 0"); +assertEq(view[1249], 0, "1249th value should be 0"); +assertEq(view[1250], 0, "1250th value should be 0"); +assertEq(view[1251], 255, "1251th value should be 255"); +assertEq(view[1252], 0, "1252th value should be 0"); +assertEq(view[1253], 0, "1253th value should be 0"); +assertEq(view[1254], 0, "1254th value should be 0"); +assertEq(view[1255], 255, "1255th value should be 255"); +assertEq(view[1256], 0, "1256th value should be 0"); +assertEq(view[1257], 0, "1257th value should be 0"); +assertEq(view[1258], 0, "1258th value should be 0"); +assertEq(view[1259], 255, "1259th value should be 255"); +assertEq(view[1260], 0, "1260th value should be 0"); +assertEq(view[1261], 0, "1261th value should be 0"); +assertEq(view[1262], 0, "1262th value should be 0"); +assertEq(view[1263], 255, "1263th value should be 255"); +assertEq(view[1264], 78, "1264th value should be 78"); +assertEq(view[1265], 127, "1265th value should be 127"); +assertEq(view[1266], 178, "1266th value should be 178"); +assertEq(view[1267], 255, "1267th value should be 255"); +assertEq(view[1268], 179, "1268th value should be 179"); +assertEq(view[1269], 127, "1269th value should be 127"); +assertEq(view[1270], 76, "1270th value should be 76"); +assertEq(view[1271], 255, "1271th value should be 255"); +assertEq(view[1272], 205, "1272th value should be 205"); +assertEq(view[1273], 255, "1273th value should be 255"); +assertEq(view[1274], 50, "1274th value should be 50"); +assertEq(view[1275], 255, "1275th value should be 255"); +assertEq(view[1276], 205, "1276th value should be 205"); +assertEq(view[1277], 255, "1277th value should be 255"); +assertEq(view[1278], 50, "1278th value should be 50"); +assertEq(view[1279], 255, "1279th value should be 255"); +assertEq(view[1280], 0, "1280th value should be 0"); +assertEq(view[1281], 0, "1281th value should be 0"); +assertEq(view[1282], 0, "1282th value should be 0"); +assertEq(view[1283], 255, "1283th value should be 255"); +assertEq(view[1284], 205, "1284th value should be 205"); +assertEq(view[1285], 255, "1285th value should be 255"); +assertEq(view[1286], 50, "1286th value should be 50"); +assertEq(view[1287], 255, "1287th value should be 255"); +assertEq(view[1288], 205, "1288th value should be 205"); +assertEq(view[1289], 255, "1289th value should be 255"); +assertEq(view[1290], 50, "1290th value should be 50"); +assertEq(view[1291], 255, "1291th value should be 255"); +assertEq(view[1292], 205, "1292th value should be 205"); +assertEq(view[1293], 255, "1293th value should be 255"); +assertEq(view[1294], 50, "1294th value should be 50"); +assertEq(view[1295], 255, "1295th value should be 255"); +assertEq(view[1296], 205, "1296th value should be 205"); +assertEq(view[1297], 255, "1297th value should be 255"); +assertEq(view[1298], 50, "1298th value should be 50"); +assertEq(view[1299], 255, "1299th value should be 255"); +assertEq(view[1300], 205, "1300th value should be 205"); +assertEq(view[1301], 255, "1301th value should be 255"); +assertEq(view[1302], 50, "1302th value should be 50"); +assertEq(view[1303], 255, "1303th value should be 255"); +assertEq(view[1304], 179, "1304th value should be 179"); +assertEq(view[1305], 127, "1305th value should be 127"); +assertEq(view[1306], 76, "1306th value should be 76"); +assertEq(view[1307], 255, "1307th value should be 255"); +assertEq(view[1308], 154, "1308th value should be 154"); +assertEq(view[1309], 255, "1309th value should be 255"); +assertEq(view[1310], 101, "1310th value should be 101"); +assertEq(view[1311], 255, "1311th value should be 255"); +assertEq(view[1312], 154, "1312th value should be 154"); +assertEq(view[1313], 255, "1313th value should be 255"); +assertEq(view[1314], 101, "1314th value should be 101"); +assertEq(view[1315], 255, "1315th value should be 255"); +assertEq(view[1316], 0, "1316th value should be 0"); +assertEq(view[1317], 0, "1317th value should be 0"); +assertEq(view[1318], 0, "1318th value should be 0"); +assertEq(view[1319], 255, "1319th value should be 255"); +assertEq(view[1320], 0, "1320th value should be 0"); +assertEq(view[1321], 0, "1321th value should be 0"); +assertEq(view[1322], 0, "1322th value should be 0"); +assertEq(view[1323], 255, "1323th value should be 255"); +assertEq(view[1324], 0, "1324th value should be 0"); +assertEq(view[1325], 0, "1325th value should be 0"); +assertEq(view[1326], 0, "1326th value should be 0"); +assertEq(view[1327], 255, "1327th value should be 255"); +assertEq(view[1328], 0, "1328th value should be 0"); +assertEq(view[1329], 0, "1329th value should be 0"); +assertEq(view[1330], 0, "1330th value should be 0"); +assertEq(view[1331], 255, "1331th value should be 255"); +assertEq(view[1332], 0, "1332th value should be 0"); +assertEq(view[1333], 0, "1333th value should be 0"); +assertEq(view[1334], 0, "1334th value should be 0"); +assertEq(view[1335], 255, "1335th value should be 255"); +assertEq(view[1336], 0, "1336th value should be 0"); +assertEq(view[1337], 0, "1337th value should be 0"); +assertEq(view[1338], 0, "1338th value should be 0"); +assertEq(view[1339], 255, "1339th value should be 255"); +assertEq(view[1340], 0, "1340th value should be 0"); +assertEq(view[1341], 0, "1341th value should be 0"); +assertEq(view[1342], 0, "1342th value should be 0"); +assertEq(view[1343], 255, "1343th value should be 255"); +assertEq(view[1344], 0, "1344th value should be 0"); +assertEq(view[1345], 0, "1345th value should be 0"); +assertEq(view[1346], 0, "1346th value should be 0"); +assertEq(view[1347], 255, "1347th value should be 255"); +assertEq(view[1348], 179, "1348th value should be 179"); +assertEq(view[1349], 127, "1349th value should be 127"); +assertEq(view[1350], 76, "1350th value should be 76"); +assertEq(view[1351], 255, "1351th value should be 255"); +assertEq(view[1352], 205, "1352th value should be 205"); +assertEq(view[1353], 255, "1353th value should be 255"); +assertEq(view[1354], 50, "1354th value should be 50"); +assertEq(view[1355], 255, "1355th value should be 255"); +assertEq(view[1356], 205, "1356th value should be 205"); +assertEq(view[1357], 255, "1357th value should be 255"); +assertEq(view[1358], 50, "1358th value should be 50"); +assertEq(view[1359], 255, "1359th value should be 255"); +assertEq(view[1360], 0, "1360th value should be 0"); +assertEq(view[1361], 0, "1361th value should be 0"); +assertEq(view[1362], 0, "1362th value should be 0"); +assertEq(view[1363], 255, "1363th value should be 255"); +assertEq(view[1364], 205, "1364th value should be 205"); +assertEq(view[1365], 255, "1365th value should be 255"); +assertEq(view[1366], 50, "1366th value should be 50"); +assertEq(view[1367], 255, "1367th value should be 255"); +assertEq(view[1368], 205, "1368th value should be 205"); +assertEq(view[1369], 255, "1369th value should be 255"); +assertEq(view[1370], 50, "1370th value should be 50"); +assertEq(view[1371], 255, "1371th value should be 255"); +assertEq(view[1372], 205, "1372th value should be 205"); +assertEq(view[1373], 255, "1373th value should be 255"); +assertEq(view[1374], 50, "1374th value should be 50"); +assertEq(view[1375], 255, "1375th value should be 255"); +assertEq(view[1376], 205, "1376th value should be 205"); +assertEq(view[1377], 255, "1377th value should be 255"); +assertEq(view[1378], 50, "1378th value should be 50"); +assertEq(view[1379], 255, "1379th value should be 255"); +assertEq(view[1380], 205, "1380th value should be 205"); +assertEq(view[1381], 255, "1381th value should be 255"); +assertEq(view[1382], 50, "1382th value should be 50"); +assertEq(view[1383], 255, "1383th value should be 255"); +assertEq(view[1384], 205, "1384th value should be 205"); +assertEq(view[1385], 255, "1385th value should be 255"); +assertEq(view[1386], 50, "1386th value should be 50"); +assertEq(view[1387], 255, "1387th value should be 255"); +assertEq(view[1388], 179, "1388th value should be 179"); +assertEq(view[1389], 127, "1389th value should be 127"); +assertEq(view[1390], 76, "1390th value should be 76"); +assertEq(view[1391], 255, "1391th value should be 255"); +assertEq(view[1392], 179, "1392th value should be 179"); +assertEq(view[1393], 127, "1393th value should be 127"); +assertEq(view[1394], 76, "1394th value should be 76"); +assertEq(view[1395], 255, "1395th value should be 255"); +assertEq(view[1396], 103, "1396th value should be 103"); +assertEq(view[1397], 255, "1397th value should be 255"); +assertEq(view[1398], 152, "1398th value should be 152"); +assertEq(view[1399], 255, "1399th value should be 255"); +assertEq(view[1400], 78, "1400th value should be 78"); +assertEq(view[1401], 127, "1401th value should be 127"); +assertEq(view[1402], 178, "1402th value should be 178"); +assertEq(view[1403], 255, "1403th value should be 255"); +assertEq(view[1404], 52, "1404th value should be 52"); +assertEq(view[1405], 255, "1405th value should be 255"); +assertEq(view[1406], 203, "1406th value should be 203"); +assertEq(view[1407], 255, "1407th value should be 255"); +assertEq(view[1408], 0, "1408th value should be 0"); +assertEq(view[1409], 0, "1409th value should be 0"); +assertEq(view[1410], 0, "1410th value should be 0"); +assertEq(view[1411], 255, "1411th value should be 255"); +assertEq(view[1412], 0, "1412th value should be 0"); +assertEq(view[1413], 0, "1413th value should be 0"); +assertEq(view[1414], 0, "1414th value should be 0"); +assertEq(view[1415], 255, "1415th value should be 255"); +assertEq(view[1416], 52, "1416th value should be 52"); +assertEq(view[1417], 255, "1417th value should be 255"); +assertEq(view[1418], 203, "1418th value should be 203"); +assertEq(view[1419], 255, "1419th value should be 255"); +assertEq(view[1420], 128, "1420th value should be 128"); +assertEq(view[1421], 127, "1421th value should be 127"); +assertEq(view[1422], 127, "1422th value should be 127"); +assertEq(view[1423], 255, "1423th value should be 255"); +assertEq(view[1424], 128, "1424th value should be 128"); +assertEq(view[1425], 127, "1425th value should be 127"); +assertEq(view[1426], 127, "1426th value should be 127"); +assertEq(view[1427], 255, "1427th value should be 255"); +assertEq(view[1428], 205, "1428th value should be 205"); +assertEq(view[1429], 255, "1429th value should be 255"); +assertEq(view[1430], 50, "1430th value should be 50"); +assertEq(view[1431], 255, "1431th value should be 255"); +assertEq(view[1432], 205, "1432th value should be 205"); +assertEq(view[1433], 255, "1433th value should be 255"); +assertEq(view[1434], 50, "1434th value should be 50"); +assertEq(view[1435], 255, "1435th value should be 255"); +assertEq(view[1436], 230, "1436th value should be 230"); +assertEq(view[1437], 127, "1437th value should be 127"); +assertEq(view[1438], 25, "1438th value should be 25"); +assertEq(view[1439], 255, "1439th value should be 255"); +assertEq(view[1440], 0, "1440th value should be 0"); +assertEq(view[1441], 0, "1441th value should be 0"); +assertEq(view[1442], 0, "1442th value should be 0"); +assertEq(view[1443], 255, "1443th value should be 255"); +assertEq(view[1444], 230, "1444th value should be 230"); +assertEq(view[1445], 127, "1445th value should be 127"); +assertEq(view[1446], 25, "1446th value should be 25"); +assertEq(view[1447], 255, "1447th value should be 255"); +assertEq(view[1448], 205, "1448th value should be 205"); +assertEq(view[1449], 255, "1449th value should be 255"); +assertEq(view[1450], 50, "1450th value should be 50"); +assertEq(view[1451], 255, "1451th value should be 255"); +assertEq(view[1452], 205, "1452th value should be 205"); +assertEq(view[1453], 255, "1453th value should be 255"); +assertEq(view[1454], 50, "1454th value should be 50"); +assertEq(view[1455], 255, "1455th value should be 255"); +assertEq(view[1456], 205, "1456th value should be 205"); +assertEq(view[1457], 255, "1457th value should be 255"); +assertEq(view[1458], 50, "1458th value should be 50"); +assertEq(view[1459], 255, "1459th value should be 255"); +assertEq(view[1460], 205, "1460th value should be 205"); +assertEq(view[1461], 255, "1461th value should be 255"); +assertEq(view[1462], 50, "1462th value should be 50"); +assertEq(view[1463], 255, "1463th value should be 255"); +assertEq(view[1464], 205, "1464th value should be 205"); +assertEq(view[1465], 255, "1465th value should be 255"); +assertEq(view[1466], 50, "1466th value should be 50"); +assertEq(view[1467], 255, "1467th value should be 255"); +assertEq(view[1468], 179, "1468th value should be 179"); +assertEq(view[1469], 127, "1469th value should be 127"); +assertEq(view[1470], 76, "1470th value should be 76"); +assertEq(view[1471], 255, "1471th value should be 255"); +assertEq(view[1472], 179, "1472th value should be 179"); +assertEq(view[1473], 127, "1473th value should be 127"); +assertEq(view[1474], 76, "1474th value should be 76"); +assertEq(view[1475], 255, "1475th value should be 255"); +assertEq(view[1476], 179, "1476th value should be 179"); +assertEq(view[1477], 127, "1477th value should be 127"); +assertEq(view[1478], 76, "1478th value should be 76"); +assertEq(view[1479], 255, "1479th value should be 255"); +assertEq(view[1480], 128, "1480th value should be 128"); +assertEq(view[1481], 127, "1481th value should be 127"); +assertEq(view[1482], 127, "1482th value should be 127"); +assertEq(view[1483], 255, "1483th value should be 255"); +assertEq(view[1484], 103, "1484th value should be 103"); +assertEq(view[1485], 255, "1485th value should be 255"); +assertEq(view[1486], 152, "1486th value should be 152"); +assertEq(view[1487], 255, "1487th value should be 255"); +assertEq(view[1488], 0, "1488th value should be 0"); +assertEq(view[1489], 0, "1489th value should be 0"); +assertEq(view[1490], 0, "1490th value should be 0"); +assertEq(view[1491], 255, "1491th value should be 255"); +assertEq(view[1492], 0, "1492th value should be 0"); +assertEq(view[1493], 0, "1493th value should be 0"); +assertEq(view[1494], 0, "1494th value should be 0"); +assertEq(view[1495], 255, "1495th value should be 255"); +assertEq(view[1496], 128, "1496th value should be 128"); +assertEq(view[1497], 127, "1497th value should be 127"); +assertEq(view[1498], 127, "1498th value should be 127"); +assertEq(view[1499], 255, "1499th value should be 255"); +assertEq(view[1500], 154, "1500th value should be 154"); +assertEq(view[1501], 255, "1501th value should be 255"); +assertEq(view[1502], 101, "1502th value should be 101"); +assertEq(view[1503], 255, "1503th value should be 255"); +assertEq(view[1504], 179, "1504th value should be 179"); +assertEq(view[1505], 127, "1505th value should be 127"); +assertEq(view[1506], 76, "1506th value should be 76"); +assertEq(view[1507], 255, "1507th value should be 255"); +assertEq(view[1508], 205, "1508th value should be 205"); +assertEq(view[1509], 255, "1509th value should be 255"); +assertEq(view[1510], 50, "1510th value should be 50"); +assertEq(view[1511], 255, "1511th value should be 255"); +assertEq(view[1512], 205, "1512th value should be 205"); +assertEq(view[1513], 255, "1513th value should be 255"); +assertEq(view[1514], 50, "1514th value should be 50"); +assertEq(view[1515], 255, "1515th value should be 255"); +assertEq(view[1516], 230, "1516th value should be 230"); +assertEq(view[1517], 127, "1517th value should be 127"); +assertEq(view[1518], 25, "1518th value should be 25"); +assertEq(view[1519], 255, "1519th value should be 255"); +assertEq(view[1520], 0, "1520th value should be 0"); +assertEq(view[1521], 0, "1521th value should be 0"); +assertEq(view[1522], 0, "1522th value should be 0"); +assertEq(view[1523], 255, "1523th value should be 255"); +assertEq(view[1524], 230, "1524th value should be 230"); +assertEq(view[1525], 127, "1525th value should be 127"); +assertEq(view[1526], 25, "1526th value should be 25"); +assertEq(view[1527], 255, "1527th value should be 255"); +assertEq(view[1528], 230, "1528th value should be 230"); +assertEq(view[1529], 127, "1529th value should be 127"); +assertEq(view[1530], 25, "1530th value should be 25"); +assertEq(view[1531], 255, "1531th value should be 255"); +assertEq(view[1532], 205, "1532th value should be 205"); +assertEq(view[1533], 255, "1533th value should be 255"); +assertEq(view[1534], 50, "1534th value should be 50"); +assertEq(view[1535], 255, "1535th value should be 255"); +assertEq(view[1536], 205, "1536th value should be 205"); +assertEq(view[1537], 255, "1537th value should be 255"); +assertEq(view[1538], 50, "1538th value should be 50"); +assertEq(view[1539], 255, "1539th value should be 255"); +assertEq(view[1540], 205, "1540th value should be 205"); +assertEq(view[1541], 255, "1541th value should be 255"); +assertEq(view[1542], 50, "1542th value should be 50"); +assertEq(view[1543], 255, "1543th value should be 255"); +assertEq(view[1544], 205, "1544th value should be 205"); +assertEq(view[1545], 255, "1545th value should be 255"); +assertEq(view[1546], 50, "1546th value should be 50"); +assertEq(view[1547], 255, "1547th value should be 255"); +assertEq(view[1548], 205, "1548th value should be 205"); +assertEq(view[1549], 255, "1549th value should be 255"); +assertEq(view[1550], 50, "1550th value should be 50"); +assertEq(view[1551], 255, "1551th value should be 255"); +assertEq(view[1552], 179, "1552th value should be 179"); +assertEq(view[1553], 127, "1553th value should be 127"); +assertEq(view[1554], 76, "1554th value should be 76"); +assertEq(view[1555], 255, "1555th value should be 255"); +assertEq(view[1556], 179, "1556th value should be 179"); +assertEq(view[1557], 127, "1557th value should be 127"); +assertEq(view[1558], 76, "1558th value should be 76"); +assertEq(view[1559], 255, "1559th value should be 255"); +assertEq(view[1560], 179, "1560th value should be 179"); +assertEq(view[1561], 127, "1561th value should be 127"); +assertEq(view[1562], 76, "1562th value should be 76"); +assertEq(view[1563], 255, "1563th value should be 255"); +assertEq(view[1564], 154, "1564th value should be 154"); +assertEq(view[1565], 255, "1565th value should be 255"); +assertEq(view[1566], 101, "1566th value should be 101"); +assertEq(view[1567], 255, "1567th value should be 255"); +assertEq(view[1568], 26, "1568th value should be 26"); +assertEq(view[1569], 127, "1569th value should be 127"); +assertEq(view[1570], 229, "1570th value should be 229"); +assertEq(view[1571], 255, "1571th value should be 255"); +assertEq(view[1572], 0, "1572th value should be 0"); +assertEq(view[1573], 0, "1573th value should be 0"); +assertEq(view[1574], 0, "1574th value should be 0"); +assertEq(view[1575], 255, "1575th value should be 255"); +assertEq(view[1576], 154, "1576th value should be 154"); +assertEq(view[1577], 255, "1577th value should be 255"); +assertEq(view[1578], 101, "1578th value should be 101"); +assertEq(view[1579], 255, "1579th value should be 255"); +assertEq(view[1580], 179, "1580th value should be 179"); +assertEq(view[1581], 127, "1581th value should be 127"); +assertEq(view[1582], 76, "1582th value should be 76"); +assertEq(view[1583], 255, "1583th value should be 255"); +assertEq(view[1584], 205, "1584th value should be 205"); +assertEq(view[1585], 255, "1585th value should be 255"); +assertEq(view[1586], 50, "1586th value should be 50"); +assertEq(view[1587], 255, "1587th value should be 255"); +assertEq(view[1588], 205, "1588th value should be 205"); +assertEq(view[1589], 255, "1589th value should be 255"); +assertEq(view[1590], 50, "1590th value should be 50"); +assertEq(view[1591], 255, "1591th value should be 255"); +assertEq(view[1592], 230, "1592th value should be 230"); +assertEq(view[1593], 127, "1593th value should be 127"); +assertEq(view[1594], 25, "1594th value should be 25"); +assertEq(view[1595], 255, "1595th value should be 255"); +assertEq(view[1596], 230, "1596th value should be 230"); +assertEq(view[1597], 127, "1597th value should be 127"); +assertEq(view[1598], 25, "1598th value should be 25"); +assertEq(view[1599], 255, "1599th value should be 255"); + +// Code used to generate the assertEq list above. +function generateAssertList() { + function template(i, x) { + return 'assertEq(view[' + i + '], ' + x + ', "' + i + 'th value should be ' + x + '");\n'; + } + var buf = '' + for (var i = 0; i < LIMIT_SHOW; i++) + buf += template(i, view[i]); + print(buf); +} +//generateAssertList();
--- a/js/src/jit-test/tests/asm.js/testStackWalking.js +++ b/js/src/jit-test/tests/asm.js/testStackWalking.js @@ -60,17 +60,17 @@ try { } catch (e) { caught = true; matchStack(e.stack, ['asmRec', 'asmRec', 'asmRec', 'asmRec']); } assertEq(caught, true); var caught = false; try { - callFFI(null, {ffi:Object.preventExtensions})(); + callFFI(null, {ffi:Object.defineProperty})(); } catch (e) { caught = true; } assertEq(caught, true); asmLink(callFFI, null, {ffi:eval})(); asmLink(callFFI, null, {ffi:Function})(); asmLink(callFFI, null, {ffi:Error})();
rename from js/src/jit-test/tests/sharedbuf/bug1068458-toolong.js rename to js/src/jit-test/tests/sharedbuf/toolong.js --- a/js/src/jit-test/tests/sharedbuf/bug1068458-toolong.js +++ b/js/src/jit-test/tests/sharedbuf/toolong.js @@ -1,14 +1,22 @@ -// This used to assert, now it will throw because the limit -// (in bytes) on a SharedArrayBuffer is INT32_MAX. +// Various cases that used to assert, but will now throw (as they should). if (!this.SharedUint16Array) quit(); var thrown = false; try { - new SharedUint16Array(2147483647); + new SharedUint16Array(2147483647); // Bug 1068458 } catch (e) { thrown = true; } assertEq(thrown, true); + +var thrown = false; +try { + new SharedUint16Array(0xdeadbeef); // Bug 1072176 +} +catch (e) { + thrown = true; +} +assertEq(thrown, true);
--- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -1123,17 +1123,17 @@ BacktrackingAllocator::reifyAllocations( if (LDefinition *def = FindReusingDefinition(ins, alloc)) { LiveInterval *outputInterval = vregs[def->virtualRegister()].intervalFor(outputOf(ins)); LAllocation *res = outputInterval->getAllocation(); LAllocation *sourceAlloc = interval->getAllocation(); if (*res != *alloc) { LMoveGroup *group = getInputMoveGroup(inputOf(ins)); - if (!group->addAfter(sourceAlloc, res, def->type())) + if (!group->addAfter(sourceAlloc, res, reg->type())) return false; *alloc = *res; } } } addLiveRegistersForInterval(reg, interval); }
--- a/js/src/jit/LIR.cpp +++ b/js/src/jit/LIR.cpp @@ -343,16 +343,18 @@ LAllocation::aliases(const LAllocation & static const char * const TypeChars[] = { "g", // GENERAL "i", // INT32 "o", // OBJECT "s", // SLOTS "f", // FLOAT32 "d", // DOUBLE + "i32x4", // INT32X4 + "f32x4", // FLOAT32X4 #ifdef JS_NUNBOX32 "t", // TYPE "p" // PAYLOAD #elif JS_PUNBOX64 "x" // BOX #endif }; @@ -536,19 +538,35 @@ LInstruction::initSafepoint(TempAllocato safepoint_ = new(alloc) LSafepoint(alloc); JS_ASSERT(safepoint_); } bool LMoveGroup::add(LAllocation *from, LAllocation *to, LDefinition::Type type) { #ifdef DEBUG - JS_ASSERT(*from != *to); + MOZ_ASSERT(*from != *to); for (size_t i = 0; i < moves_.length(); i++) - JS_ASSERT(*to != *moves_[i].to()); + MOZ_ASSERT(*to != *moves_[i].to()); + + // Check that SIMD moves are aligned according to ABI requirements. + if (LDefinition(type).isSimdType()) { + if (from->isMemory()) { + if (from->isArgument()) + MOZ_ASSERT(from->toArgument()->index() % SimdStackAlignment == 0); + else + MOZ_ASSERT(from->toStackSlot()->slot() % SimdStackAlignment == 0); + } + if (to->isMemory()) { + if (to->isArgument()) + MOZ_ASSERT(to->toArgument()->index() % SimdStackAlignment == 0); + else + MOZ_ASSERT(to->toStackSlot()->slot() % SimdStackAlignment == 0); + } + } #endif return moves_.append(LMove(from, to, type)); } bool LMoveGroup::addAfter(LAllocation *from, LAllocation *to, LDefinition::Type type) { // Transform the operands to this move so that performing the result @@ -577,13 +595,17 @@ LMoveGroup::addAfter(LAllocation *from, void LMoveGroup::printOperands(FILE *fp) { for (size_t i = 0; i < numMoves(); i++) { const LMove &move = getMove(i); // Use two printfs, as LAllocation::toString is not reentrant. fprintf(fp, " [%s", move.from()->toString()); - fprintf(fp, " -> %s]", move.to()->toString()); + fprintf(fp, " -> %s", move.to()->toString()); +#ifdef DEBUG + fprintf(fp, ", %s", TypeChars[move.type()]); +#endif + fprintf(fp, "]"); if (i != numMoves() - 1) fprintf(fp, ","); } }
--- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -411,16 +411,17 @@ class LDefinition // A random register of an appropriate class will be assigned. REGISTER, // One definition per instruction must re-use the first input // allocation, which (for now) must be a register. MUST_REUSE_INPUT }; + // This should be kept in sync with LIR.cpp's TypeChars. enum Type { GENERAL, // Generic, integer or pointer-width data (GPR). INT32, // int32 data (GPR). OBJECT, // Pointer that may be collected as garbage (GPR). SLOTS, // Slots/elements pointer that may be moved by minor GCs (GPR). FLOAT32, // 32-bit floating-point value (FPU). DOUBLE, // 64-bit floating-point value (FPU). INT32X4, // SIMD data containing four 32-bit integers (FPU).
--- a/js/src/jit/RegisterAllocator.cpp +++ b/js/src/jit/RegisterAllocator.cpp @@ -402,17 +402,17 @@ AllocationIntegrityState::dump() fprintf(stderr, "["); if (input != CodePosition::MIN) fprintf(stderr, "%u,%u ", input.bits(), output.bits()); fprintf(stderr, "%s]", ins->opName()); if (ins->isMoveGroup()) { LMoveGroup *group = ins->toMoveGroup(); for (int i = group->numMoves() - 1; i >= 0; i--) { - // Use two printfs, as LAllocation::toString is not reentant. + // Use two printfs, as LAllocation::toString is not reentrant. fprintf(stderr, " [%s", group->getMove(i).from()->toString()); fprintf(stderr, " -> %s]", group->getMove(i).to()->toString()); } fprintf(stderr, "\n"); continue; } for (size_t i = 0; i < ins->numDefs(); i++)
--- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -737,19 +737,16 @@ random_generateSeed() */ rand_s(&seed.u32[0]); #elif defined(XP_UNIX) /* * In the unlikely event we can't read /dev/urandom, there's not much we can * do, so just mix in the fd error code and the current time. */ int fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - perror("FITZGEN: error opening /dev/urandom: "); - } MOZ_ASSERT(fd >= 0, "Can't open /dev/urandom"); if (fd >= 0) { (void)read(fd, seed.u8, mozilla::ArrayLength(seed.u8)); close(fd); } seed.u32[0] ^= fd; #else # error "Platform needs to implement random_generateSeed()"
--- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1520,18 +1520,20 @@ JSObject * js::NewObjectWithGivenProto(ExclusiveContext *cxArg, const js::Class *clasp, js::TaggedProto protoArg, JSObject *parentArg, gc::AllocKind allocKind, NewObjectKind newKind) { if (CanBeFinalizedInBackground(allocKind, clasp)) allocKind = GetBackgroundAllocKind(allocKind); NewObjectCache::EntryIndex entry = -1; + uint64_t gcNumber = 0; if (JSContext *cx = cxArg->maybeJSContext()) { - NewObjectCache &cache = cx->runtime()->newObjectCache; + JSRuntime *rt = cx->runtime(); + NewObjectCache &cache = rt->newObjectCache; if (protoArg.isObject() && newKind == GenericObject && !cx->compartment()->hasObjectMetadataCallback() && (!parentArg || parentArg == protoArg.toObject()->getParent()) && !protoArg.toObject()->is<GlobalObject>()) { if (cache.lookupProto(clasp, protoArg.toObject(), allocKind, &entry)) { JSObject *obj = cache.newObjectFromHit<NoGC>(cx, entry, GetInitialHeap(newKind, clasp)); @@ -1542,16 +1544,17 @@ js::NewObjectWithGivenProto(ExclusiveCon RootedObject parent(cxArg, parentArg); obj = cache.newObjectFromHit<CanGC>(cx, entry, GetInitialHeap(newKind, clasp)); JS_ASSERT(!obj); parentArg = parent; protoArg = proto; } } } + gcNumber = rt->gc.gcNumber(); } Rooted<TaggedProto> proto(cxArg, protoArg); RootedObject parent(cxArg, parentArg); types::TypeObject *type = cxArg->getNewType(clasp, proto, nullptr); if (!type) return nullptr; @@ -1562,17 +1565,19 @@ js::NewObjectWithGivenProto(ExclusiveCon */ if (!parent && proto.isObject()) parent = proto.toObject()->getParent(); RootedObject obj(cxArg, NewObject(cxArg, type, parent, allocKind, newKind)); if (!obj) return nullptr; - if (entry != -1 && !obj->hasDynamicSlots()) { + if (entry != -1 && !obj->hasDynamicSlots() && + cxArg->asJSContext()->runtime()->gc.gcNumber() == gcNumber) + { cxArg->asJSContext()->runtime()->newObjectCache.fillProto(entry, clasp, proto, allocKind, obj); } return obj; } static JSProtoKey
new file mode 100644 --- /dev/null +++ b/js/src/tests/ecma_6/Object/preventExtensions.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var BUGNUMBER = 1073446; +var summary = "Object.preventExtensions() should return its argument with no conversion when the argument is a primitive value"; + +print(BUGNUMBER + ": " + summary); +assertEq(Object.preventExtensions(), undefined); +assertEq(Object.preventExtensions(undefined), undefined); +assertEq(Object.preventExtensions(null), null); +assertEq(Object.preventExtensions(1), 1); +assertEq(Object.preventExtensions("foo"), "foo"); +assertEq(Object.preventExtensions(true), true); +if (typeof Symbol === "function") { + assertEq(Object.preventExtensions(Symbol.for("foo")), Symbol.for("foo")); +} + +if (typeof reportCompare === "function") + reportCompare(true, true);
--- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -310,28 +310,33 @@ class NewObjectCache JS_ASSERT(obj->type() == type); return fill(entry, type->clasp(), type, kind, obj); } /* Invalidate any entries which might produce an object with shape/proto. */ void invalidateEntriesForShape(JSContext *cx, HandleShape shape, HandleObject proto); private: - bool lookup(const Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) { + EntryIndex makeIndex(const Class *clasp, gc::Cell *key, gc::AllocKind kind) { uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind; - *pentry = hash % mozilla::ArrayLength(entries); + return hash % mozilla::ArrayLength(entries); + } + bool lookup(const Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) { + *pentry = makeIndex(clasp, key, kind); Entry *entry = &entries[*pentry]; /* N.B. Lookups with the same clasp/key but different kinds map to different entries. */ return entry->clasp == clasp && entry->key == key; } - void fill(EntryIndex entry_, const Class *clasp, gc::Cell *key, gc::AllocKind kind, JSObject *obj) { + void fill(EntryIndex entry_, const Class *clasp, gc::Cell *key, gc::AllocKind kind, + JSObject *obj) { JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries)); + JS_ASSERT(entry_ == makeIndex(clasp, key, kind)); Entry *entry = &entries[entry_]; JS_ASSERT(!obj->hasDynamicSlots() && !obj->hasDynamicElements()); entry->clasp = clasp; entry->key = key; entry->kind = kind;
--- a/js/src/vm/SharedTypedArrayObject.cpp +++ b/js/src/vm/SharedTypedArrayObject.cpp @@ -140,16 +140,18 @@ class SharedTypedArrayObjectTemplate : p obj->setType(type); return &obj->as<SharedTypedArrayObject>(); } static SharedTypedArrayObject * makeTypedInstance(JSContext *cx, uint32_t len, AllocKind allocKind) { + JS_ASSERT(len <= MAX_LENGTH / sizeof(NativeType)); + // Multiplication is safe due to preconditions for makeInstance(). if (len * sizeof(NativeType) >= SharedTypedArrayObject::SINGLETON_TYPE_BYTE_LENGTH) { return &NewBuiltinClassInstance(cx, instanceClass(), allocKind, SingletonObject)->as<SharedTypedArrayObject>(); } jsbytecode *pc; RootedScript script(cx, cx->currentScript(&pc)); @@ -168,18 +170,18 @@ class SharedTypedArrayObjectTemplate : p return &obj->as<SharedTypedArrayObject>(); } static JSObject * makeInstance(JSContext *cx, Handle<SharedArrayBufferObject *> buffer, uint32_t byteOffset, uint32_t len, HandleObject proto) { JS_ASSERT(buffer); + JS_ASSERT(byteOffset <= MAX_BYTEOFFSET); JS_ASSERT(len <= MAX_LENGTH / sizeof(NativeType)); - JS_ASSERT(byteOffset <= MAX_BYTEOFFSET); gc::AllocKind allocKind = GetGCObjectKind(instanceClass()); Rooted<SharedTypedArrayObject*> obj(cx); if (proto) obj = makeProtoInstance(cx, proto, allocKind); else obj = makeTypedInstance(cx, len, allocKind); @@ -299,28 +301,16 @@ class SharedTypedArrayObjectTemplate : p return nullptr; } } } return fromBuffer(cx, dataObj, byteOffset, length); } - static bool - createArrayBuffer(JSContext *cx, uint32_t nelements, MutableHandle<SharedArrayBufferObject *> buffer) - { - if (nelements > MAX_LENGTH / sizeof(NativeType)) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, - JSMSG_NEED_DIET, "shared typed array"); - return false; - } - buffer.set(SharedArrayBufferObject::New(cx, nelements * sizeof(NativeType))); - return !!buffer; - } - template<Value ValueGetter(SharedTypedArrayObject *tarr)> static bool GetterImpl(JSContext *cx, CallArgs args) { JS_ASSERT(is(args.thisv())); args.rval().set(ValueGetter(&args.thisv().toObject().as<SharedTypedArrayObject>())); return true; } @@ -407,81 +397,79 @@ class SharedTypedArrayObjectTemplate : p setIndex(SharedTypedArrayObject &tarray, uint32_t index, NativeType val) { MOZ_ASSERT(index < tarray.length()); static_cast<NativeType*>(tarray.viewData())[index] = val; } static Value getIndexValue(JSObject *tarray, uint32_t index); + static bool fun_subarray(JSContext *cx, unsigned argc, Value *vp); + static bool fun_copyWithin(JSContext *cx, unsigned argc, Value *vp); + static bool fun_set(JSContext *cx, unsigned argc, Value *vp); + + public: static JSObject * fromBufferWithProto(JSContext *cx, HandleObject bufobj, uint32_t byteOffset, uint32_t length, HandleObject proto) { if (!ObjectClassIs(bufobj, ESClass_SharedArrayBuffer, cx)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_TYPED_ARRAY_BAD_OBJECT); return nullptr; // must be SharedArrayBuffer } - JS_ASSERT(IsSharedArrayBuffer(bufobj) || bufobj->is<ProxyObject>()); - if (bufobj->is<ProxyObject>()) { // Complicated, see TypedArrayObject.cpp for code. For now, punt. JS_ReportError(cx, "Permission denied to access object"); return nullptr; } Rooted<SharedArrayBufferObject *> buffer(cx, &AsSharedArrayBuffer(bufobj)); if (byteOffset > buffer->byteLength() || byteOffset % sizeof(NativeType) != 0) { // Invalid byteOffset. JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_TYPED_ARRAY_BAD_ARGS); return nullptr; } - JS_ASSERT(byteOffset <= buffer->byteLength()); uint32_t bytesAvailable = buffer->byteLength() - byteOffset; if (length == LENGTH_NOT_PROVIDED) { if (bytesAvailable % sizeof(NativeType) != 0) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_TYPED_ARRAY_BAD_ARGS); return nullptr; } length = bytesAvailable / sizeof(NativeType); } if (length > MAX_LENGTH / sizeof(NativeType) || length * sizeof(NativeType) > bytesAvailable) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SHARED_TYPED_ARRAY_BAD_ARGS); + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH); return nullptr; } return makeInstance(cx, buffer, byteOffset, length, proto); } - static bool fun_subarray(JSContext *cx, unsigned argc, Value *vp); - static bool fun_copyWithin(JSContext *cx, unsigned argc, Value *vp); - static bool fun_set(JSContext *cx, unsigned argc, Value *vp); - - public: static JSObject * fromBuffer(JSContext *cx, HandleObject bufobj, uint32_t byteOffset, uint32_t length) { - JS_ASSERT(byteOffset <= MAX_BYTEOFFSET); - JS_ASSERT(length <= MAX_LENGTH || length == LENGTH_NOT_PROVIDED); RootedObject proto(cx, nullptr); return fromBufferWithProto(cx, bufobj, byteOffset, length, proto); } static JSObject * fromLength(JSContext *cx, uint32_t nelements) { - JS_ASSERT(nelements <= MAX_LENGTH); - Rooted<SharedArrayBufferObject *> buffer(cx); - // Invariant established by createArrayBuffer(): nelements * sizeof(NativeType) <= MAX_LENGTH. - if (!createArrayBuffer(cx, nelements, &buffer)) + if (nelements > MAX_LENGTH / sizeof(NativeType)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH); + return nullptr; + } + Rooted<SharedArrayBufferObject *> buffer( + cx, SharedArrayBufferObject::New(cx, nelements * sizeof(NativeType))); + if (!buffer) return nullptr; return makeInstance(cx, buffer, 0, nelements); } }; class SharedInt8ArrayObject : public SharedTypedArrayObjectTemplate<int8_t> { public: enum { ACTUAL_TYPE = Scalar::Int8 };
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -384,17 +384,18 @@ mozJSComponentLoader::ReallyInit() { nsresult rv; mReuseLoaderGlobal = Preferences::GetBool("jsloader.reuseGlobal"); // XXXkhuey B2G child processes have some sort of preferences race that // results in getting the wrong value. // But we don't want that on Firefox Mulet as it break most Firefox JSMs... -#if defined(MOZ_B2G) && !defined(MOZ_MULET) + // Also disable on debug builds to break js components that rely on this. +#if defined(MOZ_B2G) && !defined(MOZ_MULET) && !defined(DEBUG) mReuseLoaderGlobal = true; #endif nsCOMPtr<nsIScriptSecurityManager> secman = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); if (!secman) return NS_ERROR_FAILURE;
--- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -321,17 +321,17 @@ fuzzy-if(OSX==10.7,6,2) fuzzy-if(OSX==10 == text-layout-05.svg text-layout-05-ref.svg fuzzy-if(cocoaWidget&&layersGPUAccelerated,1,3) == text-layout-06.svg text-layout-06-ref.svg == text-layout-07.svg text-layout-07-ref.svg == text-layout-08.svg text-layout-08-ref.svg == text-scale-01.svg text-scale-01-ref.svg HTTP(..) == text-scale-02.svg text-scale-02-ref.svg HTTP(..) == text-scale-03.svg text-scale-03-ref.svg == text-stroke-scaling-01.svg text-stroke-scaling-01-ref.svg -fails-if(OSX==10.8) == stroke-dasharray-01.svg stroke-dasharray-01-ref.svg # bug 896487 +== stroke-dasharray-01.svg stroke-dasharray-01-ref.svg == stroke-dasharray-02.svg pass.svg == stroke-dasharray-and-pathLength-01.svg pass.svg == stroke-dasharray-and-text-01.svg stroke-dasharray-and-text-01-ref.svg == stroke-dashoffset-01.svg pass.svg == stroke-linecap-square-w-zero-length-segs-01.svg pass.svg == stroke-linecap-square-w-zero-length-segs-02.svg pass.svg == textPath-01.svg textPath-01-ref.svg == textPath-02.svg pass.svg
--- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -2704,17 +2704,17 @@ public: * @param aShouldPaintSVGGlyphs Whether SVG glyphs should be painted. */ SVGTextDrawPathCallbacks(nsRenderingContext* aContext, nsTextFrame* aFrame, const gfxMatrix& aCanvasTM, bool aShouldPaintSVGGlyphs) : DrawPathCallbacks(aShouldPaintSVGGlyphs), gfx(aContext->ThebesContext()), - mRenderMode(SVGAutoRenderState::GetRenderMode(aContext)), + mRenderMode(SVGAutoRenderState::GetRenderMode(aContext->GetDrawTarget())), mFrame(aFrame), mCanvasTM(aCanvasTM) { } void NotifyBeforeText(nscolor aColor) MOZ_OVERRIDE; void NotifyGlyphPathEmitted() MOZ_OVERRIDE; void NotifyBeforeSVGGlyphPainted() MOZ_OVERRIDE; @@ -5112,17 +5112,18 @@ SVGTextFrame::DoGlyphPositioning() } bool SVGTextFrame::ShouldRenderAsPath(nsRenderingContext* aContext, nsTextFrame* aFrame, bool& aShouldPaintSVGGlyphs) { // Rendering to a clip path. - if (SVGAutoRenderState::GetRenderMode(aContext) != SVGAutoRenderState::NORMAL) { + if (SVGAutoRenderState::GetRenderMode(aContext->GetDrawTarget()) != + SVGAutoRenderState::NORMAL) { aShouldPaintSVGGlyphs = false; return true; } aShouldPaintSVGGlyphs = true; const nsStyleSVG* style = aFrame->StyleSVG();
--- a/layout/svg/nsSVGClipPathFrame.cpp +++ b/layout/svg/nsSVGClipPathFrame.cpp @@ -89,17 +89,18 @@ nsSVGClipPathFrame::ApplyClipOrPaintClip gfx->Clip(); gfx->NewPath(); return NS_OK; } // Seems like this is a non-trivial clipPath, so we need to use a clip mask. // Notify our children that they're painting into a clip mask: - SVGAutoRenderState mode(aContext, SVGAutoRenderState::CLIP_MASK); + SVGAutoRenderState mode(aContext->GetDrawTarget(), + SVGAutoRenderState::CLIP_MASK); // Check if this clipPath is itself clipped by another clipPath: nsSVGClipPathFrame *clipPathFrame = nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nullptr); bool referencedClipIsTrivial; if (clipPathFrame) { referencedClipIsTrivial = clipPathFrame->IsTrivial(); gfx->Save();
--- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -261,17 +261,17 @@ nsSVGForeignObjectFrame::PaintSVG(nsRend float cssPxPerDevPx = PresContext()-> AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel()); gfxMatrix canvasTMForChildren = aTransform; canvasTMForChildren.Scale(cssPxPerDevPx, cssPxPerDevPx); gfx->Multiply(canvasTMForChildren); uint32_t flags = nsLayoutUtils::PAINT_IN_TRANSFORM; - if (SVGAutoRenderState::IsPaintingToWindow(aContext)) { + if (SVGAutoRenderState::IsPaintingToWindow(aContext->GetDrawTarget())) { flags |= nsLayoutUtils::PAINT_TO_WINDOW; } nsresult rv = nsLayoutUtils::PaintFrame(aContext, kid, nsRegion(kidDirtyRect), NS_RGBA(0,0,0,0), flags); gfx->Restore(); return rv;
--- a/layout/svg/nsSVGGradientFrame.cpp +++ b/layout/svg/nsSVGGradientFrame.cpp @@ -258,23 +258,22 @@ nsSVGGradientFrame::GetPaintServerPatter // above since this call can be expensive when "gradientUnits" is set to // "objectBoundingBox" (since that requiring a GetBBox() call). gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds); if (patternMatrix.IsSingular()) { return nullptr; } - // revert the vector effect transform so that the gradient appears unchanged + // revert any vector effect transform so that the gradient appears unchanged if (aFillOrStroke == &nsStyleSVG::mStroke) { - gfxMatrix nonScalingStrokeTM = nsSVGUtils::GetStrokeTransform(aSource); - if (!nonScalingStrokeTM.Invert()) { - return nullptr; + gfxMatrix userToOuterSVG; + if (nsSVGUtils::GetNonScalingStrokeTransform(aSource, &userToOuterSVG)) { + patternMatrix *= userToOuterSVG; } - patternMatrix *= nonScalingStrokeTM; } if (!patternMatrix.Invert()) { return nullptr; } nsRefPtr<gfxPattern> gradient = CreateGradient(); if (!gradient || gradient->CairoStatus())
--- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -585,17 +585,18 @@ nsDisplayOuterSVG::Paint(nsDisplayListBu nsRenderingContext* aContext) { #if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) PRTime start = PR_Now(); #endif // Create an SVGAutoRenderState so we can call SetPaintingToWindow on // it, but do so without changing the render mode: - SVGAutoRenderState state(aContext, SVGAutoRenderState::GetRenderMode(aContext)); + SVGAutoRenderState state(aContext->GetDrawTarget(), + SVGAutoRenderState::GetRenderMode(aContext->GetDrawTarget())); if (aBuilder->IsPaintingToWindow()) { state.SetPaintingToWindow(true); } nsRect viewportRect = mFrame->GetContentRectRelativeToSelf() + ToReferenceFrame();
--- a/layout/svg/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/nsSVGPathGeometryFrame.cpp @@ -7,16 +7,17 @@ #include "nsSVGPathGeometryFrame.h" // Keep others in (case-insensitive) order: #include "gfx2DGlue.h" #include "gfxContext.h" #include "gfxPlatform.h" #include "gfxSVGGlyphs.h" #include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Helpers.h" #include "mozilla/RefPtr.h" #include "nsDisplayList.h" #include "nsGkAtoms.h" #include "nsLayoutUtils.h" #include "nsRenderingContext.h" #include "nsSVGEffects.h" #include "nsSVGIntegrationUtils.h" #include "nsSVGMarkerFrame.h" @@ -102,21 +103,19 @@ nsDisplaySVGPathGeometry::Paint(nsDispla // ToReferenceFrame includes our mRect offset, but painting takes // account of that too. To avoid double counting, we subtract that // here. nsPoint offset = ToReferenceFrame() - mFrame->GetPosition(); gfxPoint devPixelOffset = nsLayoutUtils::PointToGfxPoint(offset, appUnitsPerDevPixel); - aCtx->ThebesContext()->Save(); gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(mFrame) * gfxMatrix::Translation(devPixelOffset); static_cast<nsSVGPathGeometryFrame*>(mFrame)->PaintSVG(aCtx, tm); - aCtx->ThebesContext()->Restore(); } //---------------------------------------------------------------------- // nsIFrame methods void nsSVGPathGeometryFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, @@ -214,30 +213,39 @@ nsSVGPathGeometryFrame::BuildDisplayList nsresult nsSVGPathGeometryFrame::PaintSVG(nsRenderingContext *aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect) { if (!StyleVisibility()->IsVisible()) return NS_OK; + gfxContext* gfx = aContext->ThebesContext(); + + // Matrix to the geometry's user space: + gfxMatrix newMatrix = + gfx->CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers(); + if (newMatrix.IsSingular()) { + return NS_OK; + } + uint32_t paintOrder = StyleSVG()->mPaintOrder; if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) { - Render(aContext, eRenderFill | eRenderStroke, aTransform); + Render(gfx, eRenderFill | eRenderStroke, newMatrix); PaintMarkers(aContext, aTransform); } else { while (paintOrder) { uint32_t component = paintOrder & ((1 << NS_STYLE_PAINT_ORDER_BITWIDTH) - 1); switch (component) { case NS_STYLE_PAINT_ORDER_FILL: - Render(aContext, eRenderFill, aTransform); + Render(gfx, eRenderFill, newMatrix); break; case NS_STYLE_PAINT_ORDER_STROKE: - Render(aContext, eRenderStroke, aTransform); + Render(gfx, eRenderStroke, newMatrix); break; case NS_STYLE_PAINT_ORDER_MARKERS: PaintMarkers(aContext, aTransform); break; } paintOrder >>= NS_STYLE_PAINT_ORDER_BITWIDTH; } } @@ -289,28 +297,25 @@ nsSVGPathGeometryFrame::GetFrameForPoint if (hitTestFlags & SVG_HIT_TEST_FILL) { isHit = path->ContainsPoint(ToPoint(aPoint), Matrix()); } if (!isHit && (hitTestFlags & SVG_HIT_TEST_STROKE)) { Point point = ToPoint(aPoint); SVGContentUtils::AutoStrokeOptions stroke; SVGContentUtils::GetStrokeOptions(&stroke, content, StyleContext(), nullptr); - Matrix nonScalingStrokeMatrix = ToMatrix(nsSVGUtils::GetStrokeTransform(this)); - if (!nonScalingStrokeMatrix.IsIdentity()) { + gfxMatrix userToOuterSVG; + if (nsSVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) { // We need to transform the path back into the appropriate ancestor // coordinate system in order for non-scaled stroke to be correct. // Naturally we also need to transform the point into the same // coordinate system in order to hit-test against the path. - if (!nonScalingStrokeMatrix.Invert()) { - return nullptr; - } - point = nonScalingStrokeMatrix * point; + point = ToMatrix(userToOuterSVG) * point; RefPtr<PathBuilder> builder = - path->TransformedCopyToBuilder(nonScalingStrokeMatrix, fillRule); + path->TransformedCopyToBuilder(ToMatrix(userToOuterSVG), fillRule); path = builder->Finish(); } isHit = path->StrokeContainsPoint(stroke, point, Matrix()); } if (isHit && nsSVGUtils::HitTestClip(this, aPoint)) return this; @@ -603,101 +608,103 @@ nsSVGPathGeometryFrame::MarkerProperties { if (!mMarkerEnd) return nullptr; return static_cast<nsSVGMarkerFrame *> (mMarkerEnd->GetReferencedFrame(nsGkAtoms::svgMarkerFrame, nullptr)); } void -nsSVGPathGeometryFrame::Render(nsRenderingContext *aContext, +nsSVGPathGeometryFrame::Render(gfxContext* aContext, uint32_t aRenderComponents, - const gfxMatrix& aTransform) + const gfxMatrix& aNewTransform) { - gfxContext *gfx = aContext->ThebesContext(); + MOZ_ASSERT(!aNewTransform.IsSingular()); + + DrawTarget* drawTarget = aContext->GetDrawTarget(); - gfxMatrix newMatrix = - gfx->CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers(); - if (newMatrix.IsSingular()) { - return; - } + uint16_t renderMode = SVGAutoRenderState::GetRenderMode(drawTarget); + MOZ_ASSERT(renderMode == SVGAutoRenderState::NORMAL || + renderMode == SVGAutoRenderState::CLIP_MASK, + "Unknown render mode"); - uint16_t renderMode = SVGAutoRenderState::GetRenderMode(aContext); FillRule fillRule = - nsSVGUtils::ToFillRule(renderMode == SVGAutoRenderState::CLIP_MASK ? - StyleSVG()->mClipRule : StyleSVG()->mFillRule); + nsSVGUtils::ToFillRule(renderMode == SVGAutoRenderState::NORMAL ? + StyleSVG()->mFillRule : StyleSVG()->mClipRule); - RefPtr<PathBuilder> builder = - aContext->GetDrawTarget()->CreatePathBuilder(fillRule); + RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(fillRule); if (!builder) { return; } RefPtr<Path> path = static_cast<nsSVGPathGeometryElement*>(mContent)->BuildPath(builder); if (!path) { return; } - switch (StyleSVG()->mShapeRendering) { - case NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED: - case NS_STYLE_SHAPE_RENDERING_CRISPEDGES: - gfx->SetAntialiasMode(AntialiasMode::NONE); - break; - default: - gfx->SetAntialiasMode(AntialiasMode::SUBPIXEL); - break; - } + AntialiasMode aaMode = + (StyleSVG()->mShapeRendering == NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED || + StyleSVG()->mShapeRendering == NS_STYLE_SHAPE_RENDERING_CRISPEDGES) ? + AntialiasMode::NONE : AntialiasMode::SUBPIXEL; + + // We wait as late as possible before setting the transform so that we don't + // set it unnecessarily if we return early (it's an expensive operation for + // some backends). + gfxContextMatrixAutoSaveRestore autoRestoreTransform(aContext); + aContext->SetMatrix(aNewTransform); if (renderMode == SVGAutoRenderState::CLIP_MASK) { - FillRule oldFillRule = gfx->CurrentFillRule(); - gfxContextMatrixAutoSaveRestore autoSaveRestore(gfx); - - gfx->SetMatrix(newMatrix); - gfx->SetFillRule(fillRule); - gfx->SetColor(gfxRGBA(1.0f, 1.0f, 1.0f, 1.0f)); - gfx->SetPath(path); - gfx->Fill(); - - gfx->SetFillRule(oldFillRule); - gfx->NewPath(); + drawTarget->Fill(path, ColorPattern(Color(1.0f, 1.0f, 1.0f, 1.0f)), + DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode)); return; } - NS_ABORT_IF_FALSE(renderMode == SVGAutoRenderState::NORMAL, - "Unknown render mode"); - - gfxContextAutoSaveRestore autoSaveRestore(gfx); - gfx->SetMatrix(newMatrix); + gfxTextContextPaint *contextPaint = + (gfxTextContextPaint*)drawTarget-> + GetUserData(&gfxTextContextPaint::sUserDataKey); - gfxTextContextPaint *contextPaint = - (gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey); - - if ((aRenderComponents & eRenderFill)) { + if (aRenderComponents & eRenderFill) { GeneralPattern fillPattern; - nsSVGUtils::MakeFillPatternFor(this, gfx, &fillPattern, contextPaint); + nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern, contextPaint); if (fillPattern.GetPattern()) { - gfx->SetPath(path); - gfx->SetFillRule(fillRule); - gfx->Fill(fillPattern); + drawTarget->Fill(path, fillPattern, + DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode)); } } if ((aRenderComponents & eRenderStroke) && nsSVGUtils::HasStroke(this, contextPaint)) { + // Account for vector-effect:non-scaling-stroke: + gfxMatrix userToOuterSVG; + if (nsSVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) { + // We need to transform the path back into the appropriate ancestor + // coordinate system, and paint it it that coordinate system, in order + // for non-scaled stroke to paint correctly. + gfxMatrix outerSVGToUser = userToOuterSVG; + outerSVGToUser.Invert(); + aContext->Multiply(outerSVGToUser); + builder = path->TransformedCopyToBuilder(ToMatrix(userToOuterSVG), fillRule); + path = builder->Finish(); + } GeneralPattern strokePattern; - nsSVGUtils::MakeStrokePatternFor(this, gfx, &strokePattern, contextPaint); + nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern, contextPaint); if (strokePattern.GetPattern()) { - gfx->SetPath(path); - nsSVGUtils::SetupCairoStrokeGeometry(this, gfx, contextPaint); - gfx->Stroke(strokePattern); + SVGContentUtils::AutoStrokeOptions strokeOptions; + SVGContentUtils::GetStrokeOptions(&strokeOptions, + static_cast<nsSVGElement*>(mContent), + StyleContext(), contextPaint); + // GetStrokeOptions may set the line width to zero as an optimization + if (strokeOptions.mLineWidth <= 0) { + return; + } + drawTarget->Stroke(path, strokePattern, strokeOptions, + DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode)); } } - - gfx->NewPath(); } void nsSVGPathGeometryFrame::GeneratePath(gfxContext* aContext, const Matrix &aTransform) { if (aTransform.IsSingular()) { aContext->SetMatrix(gfxMatrix());
--- a/layout/svg/nsSVGPathGeometryFrame.h +++ b/layout/svg/nsSVGPathGeometryFrame.h @@ -10,16 +10,22 @@ #include "gfxMatrix.h" #include "gfxRect.h" #include "nsFrame.h" #include "nsISVGChildFrame.h" #include "nsLiteralString.h" #include "nsQueryFrame.h" #include "nsSVGUtils.h" +namespace mozilla { +namespace gfx { +class DrawTarget; +} +} + class gfxContext; class nsDisplaySVGPathGeometry; class nsIAtom; class nsIFrame; class nsIPresShell; class nsRenderingContext; class nsStyleContext; class nsSVGMarkerFrame; @@ -29,16 +35,18 @@ struct nsPoint; struct nsRect; struct nsIntRect; typedef nsFrame nsSVGPathGeometryFrameBase; class nsSVGPathGeometryFrame : public nsSVGPathGeometryFrameBase, public nsISVGChildFrame { + typedef mozilla::gfx::DrawTarget DrawTarget; + friend nsIFrame* NS_NewSVGPathGeometryFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); friend class nsDisplaySVGPathGeometry; protected: explicit nsSVGPathGeometryFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrameBase(aContext) @@ -108,17 +116,17 @@ protected: * This function returns a set of bit flags indicating which parts of the * element (fill, stroke, bounds) should intercept pointer events. It takes * into account the type of element and the value of the 'pointer-events' * property on the element. */ virtual uint16_t GetHitTestFlags(); private: enum { eRenderFill = 1, eRenderStroke = 2 }; - void Render(nsRenderingContext *aContext, uint32_t aRenderComponents, + void Render(gfxContext* aContext, uint32_t aRenderComponents, const gfxMatrix& aTransform); /** * @param aMatrix The transform that must be multiplied onto aContext to * establish this frame's SVG user space. */ void PaintMarkers(nsRenderingContext *aContext, const gfxMatrix& aMatrix);
--- a/layout/svg/nsSVGPatternFrame.cpp +++ b/layout/svg/nsSVGPatternFrame.cpp @@ -246,21 +246,21 @@ nsSVGPatternFrame::PaintPattern(const Dr * patternTransform) * Create the surface * Calculate the content transformation matrix * Get our children (we may need to get them from another Pattern) * Call SVGPaint on all of our children * Return */ - // Get the first child of the pattern data we will render - nsIFrame* firstKid = GetPatternFirstChild(); - if (!firstKid) { + nsSVGPatternFrame* patternWithChildren = GetPatternWithChildren(); + if (!patternWithChildren) { return nullptr; // Either no kids or a bad reference } + nsIFrame* firstKid = patternWithChildren->mFrames.FirstChild(); const nsSVGViewBox& viewBox = GetViewBox(); uint16_t patternContentUnits = GetEnumValue(SVGPatternElement::PATTERNCONTENTUNITS); uint16_t patternUnits = GetEnumValue(SVGPatternElement::PATTERNUNITS); @@ -298,44 +298,43 @@ nsSVGPatternFrame::PaintPattern(const Dr // Construct the CTM that we will provide to our children when we // render them into the tile. gfxMatrix ctm = ConstructCTM(viewBox, patternContentUnits, patternUnits, callerBBox, aContextMatrix, aSource); if (ctm.IsSingular()) { return nullptr; } - // Get the pattern we are going to render - nsSVGPatternFrame *patternFrame = - static_cast<nsSVGPatternFrame*>(firstKid->GetParent()); - if (patternFrame->mCTM) { - *patternFrame->mCTM = ctm; + if (patternWithChildren->mCTM) { + *patternWithChildren->mCTM = ctm; } else { - patternFrame->mCTM = new gfxMatrix(ctm); + patternWithChildren->mCTM = new gfxMatrix(ctm); } // Get the bounding box of the pattern. This will be used to determine // the size of the surface, and will also be used to define the bounding // box for the pattern tile. gfxRect bbox = GetPatternRect(patternUnits, callerBBox, aContextMatrix, aSource); if (bbox.Width() <= 0.0 || bbox.Height() <= 0.0) { return nullptr; } // Get the pattern transform Matrix patternTransform = ToMatrix(GetPatternTransform()); // revert the vector effect transform so that the pattern appears unchanged if (aFillOrStroke == &nsStyleSVG::mStroke) { - Matrix strokeTransform = ToMatrix(nsSVGUtils::GetStrokeTransform(aSource)); - if (!strokeTransform.Invert()) { - NS_WARNING("Should we get here if the stroke transform is singular?"); - return nullptr; + gfxMatrix userToOuterSVG; + if (nsSVGUtils::GetNonScalingStrokeTransform(aSource, &userToOuterSVG)) { + patternTransform *= ToMatrix(userToOuterSVG); + if (patternTransform.IsSingular()) { + NS_WARNING("Singular matrix painting non-scaling-stroke"); + return nullptr; + } } - patternTransform *= strokeTransform; } // Get the transformation matrix that we will hand to the renderer's pattern // routine. *patternMatrix = GetPatternMatrix(patternUnits, patternTransform, bbox, callerBBox, aContextMatrix); if (patternMatrix->IsSingular()) { return nullptr; @@ -361,17 +360,17 @@ nsSVGPatternFrame::PaintPattern(const Dr if (resultOverflows || patternWidth != surfaceSize.width || patternHeight != surfaceSize.height) { // scale drawing to pattern surface size gfxMatrix tempTM = gfxMatrix(surfaceSize.width / patternWidth, 0.0f, 0.0f, surfaceSize.height / patternHeight, 0.0f, 0.0f); - patternFrame->mCTM->PreMultiply(tempTM); + patternWithChildren->mCTM->PreMultiply(tempTM); // and rescale pattern to compensate patternMatrix->PreScale(patternWidth / surfaceSize.width, patternHeight / surfaceSize.height); } RefPtr<DrawTarget> dt = aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8); @@ -394,72 +393,71 @@ nsSVGPatternFrame::PaintPattern(const Dr } // OK, now render -- note that we use "firstKid", which // we got at the beginning because it takes care of the // referenced pattern situation for us if (aSource->IsFrameOfType(nsIFrame::eSVGGeometry)) { // Set the geometrical parent of the pattern we are rendering - patternFrame->mSource = static_cast<nsSVGPathGeometryFrame*>(aSource); + patternWithChildren->mSource = static_cast<nsSVGPathGeometryFrame*>(aSource); } // Delay checking NS_FRAME_DRAWING_AS_PAINTSERVER bit until here so we can // give back a clear surface if there's a loop - if (!(patternFrame->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) { - patternFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER); + if (!(patternWithChildren->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) { + patternWithChildren->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER); for (nsIFrame* kid = firstKid; kid; kid = kid->GetNextSibling()) { // The CTM of each frame referencing us can be different nsISVGChildFrame* SVGFrame = do_QueryFrame(kid); if (SVGFrame) { SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED); } - gfxMatrix tm = *(patternFrame->mCTM); + gfxMatrix tm = *(patternWithChildren->mCTM); if (kid->GetContent()->IsSVG()) { tm = static_cast<nsSVGElement*>(kid->GetContent())-> PrependLocalTransformsTo(tm, nsSVGElement::eUserSpaceToParent); } nsSVGUtils::PaintFrameWithEffects(kid, context, tm); } - patternFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER); + patternWithChildren->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER); } - patternFrame->mSource = nullptr; + patternWithChildren->mSource = nullptr; if (aGraphicOpacity != 1.0f) { gfx->PopGroupToSource(); gfx->Paint(aGraphicOpacity); gfx->Restore(); } // caller now owns the surface return dt->Snapshot(); } /* Will probably need something like this... */ // How do we handle the insertion of a new frame? // We really don't want to rerender this every time, // do we? -nsIFrame* -nsSVGPatternFrame::GetPatternFirstChild() +nsSVGPatternFrame* +nsSVGPatternFrame::GetPatternWithChildren() { // Do we have any children ourselves? - nsIFrame* kid = mFrames.FirstChild(); - if (kid) - return kid; + if (!mFrames.IsEmpty()) + return this; // No, see if we chain to someone who does AutoPatternReferencer patternRef(this); nsSVGPatternFrame* next = GetReferencedPatternIfNotInUse(); if (!next) return nullptr; - return next->GetPatternFirstChild(); + return next->GetPatternWithChildren(); } uint16_t nsSVGPatternFrame::GetEnumValue(uint32_t aIndex, nsIContent *aDefault) { nsSVGEnum& thisEnum = static_cast<SVGPatternElement *>(mContent)->mEnumAttributes[aIndex];
--- a/layout/svg/nsSVGPatternFrame.h +++ b/layout/svg/nsSVGPatternFrame.h @@ -115,17 +115,27 @@ protected: mozilla::TemporaryRef<SourceSurface> PaintPattern(const DrawTarget* aDrawTarget, Matrix *patternMatrix, const Matrix &aContextMatrix, nsIFrame *aSource, nsStyleSVGPaint nsStyleSVG::*aFillOrStroke, float aGraphicOpacity, const gfxRect *aOverrideBounds); - nsIFrame* GetPatternFirstChild(); + + /** + * A <pattern> element may reference another <pattern> element using + * xlink:href and, if it doesn't have any child content of its own, then it + * will "inherit" the children of the referenced pattern (which may itself be + * inheriting its children if it references another <pattern>). This + * function returns this nsSVGPatternFrame or the first pattern along the + * reference chain (if there is one) to have children. + */ + nsSVGPatternFrame* GetPatternWithChildren(); + gfxRect GetPatternRect(uint16_t aPatternUnits, const gfxRect &bbox, const Matrix &callerCTM, nsIFrame *aTarget); gfxMatrix ConstructCTM(const nsSVGViewBox& aViewBox, uint16_t aPatternContentUnits, uint16_t aPatternUnits, const gfxRect &callerBBox,
--- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -78,61 +78,61 @@ NS_SVGNewGetBBoxEnabled() { return sSVGNewGetBBoxEnabled; } // we only take the address of this: static mozilla::gfx::UserDataKey sSVGAutoRenderStateKey; -SVGAutoRenderState::SVGAutoRenderState(nsRenderingContext *aContext, +SVGAutoRenderState::SVGAutoRenderState(DrawTarget* aDrawTarget, RenderMode aMode MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) - : mContext(aContext) + : mDrawTarget(aDrawTarget) , mOriginalRenderState(nullptr) , mMode(aMode) , mPaintingToWindow(false) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; mOriginalRenderState = - aContext->GetDrawTarget()->RemoveUserData(&sSVGAutoRenderStateKey); + aDrawTarget->RemoveUserData(&sSVGAutoRenderStateKey); // We always remove ourselves from aContext before it dies, so // passing nullptr as the destroy function is okay. - aContext->GetDrawTarget()->AddUserData(&sSVGAutoRenderStateKey, this, nullptr); + aDrawTarget->AddUserData(&sSVGAutoRenderStateKey, this, nullptr); } SVGAutoRenderState::~SVGAutoRenderState() { - mContext->GetDrawTarget()->RemoveUserData(&sSVGAutoRenderStateKey); + mDrawTarget->RemoveUserData(&sSVGAutoRenderStateKey); if (mOriginalRenderState) { - mContext->GetDrawTarget()->AddUserData(&sSVGAutoRenderStateKey, - mOriginalRenderState, nullptr); + mDrawTarget->AddUserData(&sSVGAutoRenderStateKey, + mOriginalRenderState, nullptr); } } void SVGAutoRenderState::SetPaintingToWindow(bool aPaintingToWindow) { mPaintingToWindow = aPaintingToWindow; } /* static */ SVGAutoRenderState::RenderMode -SVGAutoRenderState::GetRenderMode(nsRenderingContext *aContext) +SVGAutoRenderState::GetRenderMode(DrawTarget* aDrawTarget) { - void *state = aContext->GetDrawTarget()->GetUserData(&sSVGAutoRenderStateKey); + void *state = aDrawTarget->GetUserData(&sSVGAutoRenderStateKey); if (state) { return static_cast<SVGAutoRenderState*>(state)->mMode; } return NORMAL; } /* static */ bool -SVGAutoRenderState::IsPaintingToWindow(nsRenderingContext *aContext) +SVGAutoRenderState::IsPaintingToWindow(DrawTarget* aDrawTarget) { - void *state = aContext->GetDrawTarget()->GetUserData(&sSVGAutoRenderStateKey); + void *state = aDrawTarget->GetUserData(&sSVGAutoRenderStateKey); if (state) { return static_cast<SVGAutoRenderState*>(state)->mPaintingToWindow; } return false; } void nsSVGUtils::Init() @@ -769,35 +769,16 @@ nsSVGUtils::GetCoveredRegion(const nsFra nsRect childRect = child->GetCoveredRegion(); rect.UnionRect(rect, childRect); } } return rect; } -nsPoint -nsSVGUtils::TransformOuterSVGPointToChildFrame(nsPoint aPoint, - const gfxMatrix& aFrameToCanvasTM, - nsPresContext* aPresContext) -{ - NS_ABORT_IF_FALSE(!aFrameToCanvasTM.IsSingular(), - "Callers must not pass a singular matrix"); - gfxMatrix canvasDevToFrameUserSpace = aFrameToCanvasTM; - canvasDevToFrameUserSpace.Invert(); - gfxPoint cssPxPt = - gfxPoint(aPoint.x, aPoint.y) / aPresContext->AppUnitsPerCSSPixel(); - gfxPoint userPt = canvasDevToFrameUserSpace.Transform(cssPxPt); - gfxPoint appPt = (userPt * aPresContext->AppUnitsPerCSSPixel()).Round(); - userPt.x = clamped(appPt.x, gfxFloat(nscoord_MIN), gfxFloat(nscoord_MAX)); - userPt.y = clamped(appPt.y, gfxFloat(nscoord_MIN), gfxFloat(nscoord_MAX)); - // now guaranteed to be safe: - return nsPoint(nscoord(userPt.x), nscoord(userPt.y)); -} - nsRect nsSVGUtils::TransformFrameRectToOuterSVG(const nsRect& aRect, const gfxMatrix& aMatrix, nsPresContext* aPresContext) { gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height); r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel()); return nsLayoutUtils::RoundGfxRectToAppRect( @@ -1114,54 +1095,55 @@ nsSVGUtils::GetFirstNonAAncestorFrame(ns ancestorFrame = ancestorFrame->GetParent()) { if (ancestorFrame->GetType() != nsGkAtoms::svgAFrame) { return ancestorFrame; } } return nullptr; } -gfxMatrix -nsSVGUtils::GetStrokeTransform(nsIFrame *aFrame) +bool +nsSVGUtils::GetNonScalingStrokeTransform(nsIFrame *aFrame, + gfxMatrix* aUserToOuterSVG) { if (aFrame->GetContent()->IsNodeOfType(nsINode::eTEXT)) { aFrame = aFrame->GetParent(); } - if (aFrame->StyleSVGReset()->mVectorEffect == - NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE) { - - nsIContent *content = aFrame->GetContent(); - NS_ABORT_IF_FALSE(content->IsSVG(), "bad cast"); + if (aFrame->StyleSVGReset()->mVectorEffect != + NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE) { + return false; + } - // a non-scaling stroke is in the screen co-ordinate - // space rather so we need to invert the transform - // to the screen co-ordinate space to get there. - // See http://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke - gfx::Matrix transform = SVGContentUtils::GetCTM( - static_cast<nsSVGElement*>(content), true); - if (!transform.IsSingular()) { - transform.Invert(); - return ThebesMatrix(transform); - } - } - return gfxMatrix(); + nsIContent *content = aFrame->GetContent(); + NS_ABORT_IF_FALSE(content->IsSVG(), "bad cast"); + + *aUserToOuterSVG = ThebesMatrix(SVGContentUtils::GetCTM( + static_cast<nsSVGElement*>(content), true)); + + return !aUserToOuterSVG->IsIdentity(); } // The logic here comes from _cairo_stroke_style_max_distance_from_path static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents, nsIFrame* aFrame, double aStyleExpansionFactor, const gfxMatrix& aMatrix) { double style_expansion = aStyleExpansionFactor * nsSVGUtils::GetStrokeWidth(aFrame); - gfxMatrix matrix = aMatrix * nsSVGUtils::GetStrokeTransform(aFrame); + gfxMatrix matrix = aMatrix; + + gfxMatrix outerSVGToUser; + if (nsSVGUtils::GetNonScalingStrokeTransform(aFrame, &outerSVGToUser)) { + outerSVGToUser.Invert(); + matrix *= outerSVGToUser; + } double dx = style_expansion * (fabs(matrix._11) + fabs(matrix._21)); double dy = style_expansion * (fabs(matrix._22) + fabs(matrix._12)); gfxRect strokeExtents = aPathExtents; strokeExtents.Inflate(dx, dy); return strokeExtents; } @@ -1491,19 +1473,20 @@ nsSVGUtils::SetupCairoStrokeGeometry(nsI gfxTextContextPaint *aContextPaint) { float width = GetStrokeWidth(aFrame, aContextPaint); if (width <= 0) return; aContext->SetLineWidth(width); // Apply any stroke-specific transform - gfxMatrix strokeTransform = GetStrokeTransform(aFrame); - if (!strokeTransform.IsIdentity()) { - aContext->Multiply(strokeTransform); + gfxMatrix outerSVGToUser; + if (GetNonScalingStrokeTransform(aFrame, &outerSVGToUser) && + outerSVGToUser.Invert()) { + aContext->Multiply(outerSVGToUser); } const nsStyleSVG* style = aFrame->StyleSVG(); switch (style->mStrokeLinecap) { case NS_STYLE_STROKE_LINECAP_BUTT: aContext->SetLineCap(gfxContext::LINE_CAP_BUTT); break;
--- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -56,16 +56,17 @@ struct nsPoint; namespace mozilla { class SVGAnimatedPreserveAspectRatio; class SVGPreserveAspectRatio; namespace dom { class Element; class UserSpaceMetrics; } // namespace dom namespace gfx { +class DrawTarget; class GeneralPattern; class SourceSurface; } } // namespace mozilla // maximum dimension of an offscreen surface - choose so that // the surface size doesn't overflow a 32-bit signed int using // 4 bytes per pixel; in line with gfxASurface::CheckSurfaceSize @@ -140,43 +141,45 @@ private: bool mIsEmpty; }; // GRRR WINDOWS HATE HATE HATE #undef CLIP_MASK class MOZ_STACK_CLASS SVGAutoRenderState { + typedef mozilla::gfx::DrawTarget DrawTarget; + public: enum RenderMode { /** * Used to inform SVG frames that they should paint as normal. */ NORMAL, /** * Used to inform SVG frames when they are painting as the child of a * complex clipPath that requires the use of a clip mask. In this case they * should only draw their basic geometry as a path and then fill it using * fully opaque white. They should not stroke, or paint anything else. */ CLIP_MASK }; - SVGAutoRenderState(nsRenderingContext *aContext, RenderMode aMode + SVGAutoRenderState(DrawTarget* aDrawTarget, RenderMode aMode MOZ_GUARD_OBJECT_NOTIFIER_PARAM); ~SVGAutoRenderState(); void SetPaintingToWindow(bool aPaintingToWindow); - static RenderMode GetRenderMode(nsRenderingContext *aContext); - static bool IsPaintingToWindow(nsRenderingContext *aContext); + static RenderMode GetRenderMode(DrawTarget* aDrawTarget); + static bool IsPaintingToWindow(DrawTarget* aDrawTarget); private: - nsRenderingContext *mContext; - void *mOriginalRenderState; + DrawTarget* mDrawTarget; + void* mOriginalRenderState; RenderMode mMode; bool mPaintingToWindow; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; #define NS_ISVGFILTERREFERENCE_IID \ { 0x9744ee20, 0x1bcf, 0x4c62, \ @@ -334,25 +337,16 @@ public: NotifyChildrenOfSVGChange(nsIFrame *aFrame, uint32_t aFlags); /* * Get frame's covered region by walking the children and doing union. */ static nsRect GetCoveredRegion(const nsFrameList &aFrames); - // Converts aPoint from an app unit point in outer-<svg> content rect space - // to an app unit point in a frame's SVG userspace. - // This is a temporary helper we should no longer need after bug 614732 is - // fixed. - static nsPoint - TransformOuterSVGPointToChildFrame(nsPoint aPoint, - const gfxMatrix& aFrameToCanvasTM, - nsPresContext* aPresContext); - static nsRect TransformFrameRectToOuterSVG(const nsRect& aRect, const gfxMatrix& aMatrix, nsPresContext* aPresContext); /* * Convert a surface size to an integer for use by thebes * possibly making it smaller in the process so the surface does not @@ -459,21 +453,28 @@ public: * Find the first frame, starting with aStartFrame and going up its * parent chain, that is not an svgAFrame. */ static nsIFrame* GetFirstNonAAncestorFrame(nsIFrame* aStartFrame); static bool OuterSVGIsCallingReflowSVG(nsIFrame *aFrame); static bool AnyOuterSVGIsCallingReflowSVG(nsIFrame *aFrame); - /* - * Get any additional transforms that apply only to stroking - * e.g. non-scaling-stroke + /** + * See https://svgwg.org/svg2-draft/painting.html#NonScalingStroke + * + * If the computed value of the 'vector-effect' property on aFrame is + * 'non-scaling-stroke', then this function will set aUserToOuterSVG to the + * transform from aFrame's SVG user space to the initial coordinate system + * established by the viewport of aFrame's outer-<svg>'s (the coordinate + * system in which the stroke is fixed). If aUserToOuterSVG is set to a + * non-identity matrix this function returns true, else it returns false. */ - static gfxMatrix GetStrokeTransform(nsIFrame *aFrame); + static bool GetNonScalingStrokeTransform(nsIFrame *aFrame, + gfxMatrix* aUserToOuterSVG); /** * Compute the maximum possible device space stroke extents of a path given * the path's device space path extents, its stroke style and its ctm. * * This is a workaround for the lack of suitable cairo API for getting the * tight device space stroke extents of a path. This basically gives us the * tightest extents that we can guarantee fully enclose the inked stroke
--- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -157,16 +157,19 @@ class RemoteOptions(ReftestOptions): f.close() # httpd-path is specified by standard makefile targets and may be specified # on the command line to select a particular version of httpd.js. If not # specified, try to select the one from hostutils.zip, as required in bug 882932. if not options.httpdPath: options.httpdPath = os.path.join(options.utilityPath, "components") + # Android does not run leak tests, but set some reasonable defaults to avoid errors. + options.leakThresholds = {} + # TODO: Copied from main, but I think these are no longer used in a post xulrunner world #options.xrePath = options.remoteTestRoot + self.automation._product + '/xulrunner' #options.utilityPath = options.testRoot + self.automation._product + '/bin' return options class ReftestServer: """ Web server used to serve Reftests, for closer fidelity to the real web. It is virtually identical to the server used in mochitest and will only
--- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -339,17 +339,17 @@ class RefTest(object): cmdlineArgs, utilityPath = options.utilityPath, xrePath=options.xrePath, debuggerInfo=debuggerInfo, symbolsPath=options.symbolsPath, # give the JS harness 30 seconds to deal # with its own timeouts timeout=options.timeout + 30.0) - processLeakLog(self.leakLogFile, options.leakThreshold) + processLeakLog(self.leakLogFile, options.leakThresholds) self.automation.log.info("\nREFTEST INFO | runreftest.py | Running tests: end.") finally: self.cleanup(profileDir) return status def copyExtraFilesToProfile(self, options, profile): "Copy extra files or dirs specified on the command line to the testing profile." profileDir = profile.profile @@ -389,22 +389,22 @@ class ReftestOptions(OptionParser): action = "append", dest = "extraProfileFiles", default = [], help = "copy specified files/dirs to testing profile") self.add_option("--timeout", action = "store", dest = "timeout", type = "int", default = 5 * 60, # 5 minutes per bug 479518 help = "reftest will timeout in specified number of seconds. [default %default s].") self.add_option("--leak-threshold", - action = "store", type = "int", dest = "leakThreshold", + action = "store", type = "int", dest = "defaultLeakThreshold", default = 0, - help = "fail if the number of bytes leaked through " - "refcounted objects (or bytes in classes with " - "MOZ_COUNT_CTOR and MOZ_COUNT_DTOR) is greater " - "than the given number") + help = "fail if the number of bytes leaked in default " + "processes through refcounted objects (or bytes " + "in classes with MOZ_COUNT_CTOR and MOZ_COUNT_DTOR) " + "is greater than the given number") self.add_option("--utility-path", action = "store", type = "string", dest = "utilityPath", default = self.automation.DIST_BIN, help = "absolute path to directory containing utility " "programs (xpcshell, ssltunnel, certutil)") defaults["utilityPath"] = self.automation.DIST_BIN self.add_option("--total-chunks", @@ -506,16 +506,18 @@ class ReftestOptions(OptionParser): self.error("cannot specify logfile with parallel tests") if options.totalChunks is not None and options.thisChunk is None: self.error("cannot specify thisChunk or totalChunks with parallel tests") if options.focusFilterMode != "all": self.error("cannot specify focusFilterMode with parallel tests") if options.debugger is not None: self.error("cannot specify a debugger with parallel tests") + options.leakThresholds = {"default": options.defaultLeakThreshold} + return options def main(): automation = Automation() parser = ReftestOptions(automation) reftest = RefTest(automation) options, args = parser.parse_args()
--- a/netwerk/base/public/nsICachingChannel.idl +++ b/netwerk/base/public/nsICachingChannel.idl @@ -12,17 +12,17 @@ interface nsIFile; * to affect its behavior with respect to how it uses the cache service. * * This interface provides: * 1) Support for "stream as file" semantics (for JAR and plugins). * 2) Support for "pinning" cached data in the cache (for printing and save-as). * 3) Support for uniquely identifying cached data in cases when the URL * is insufficient (e.g., HTTP form submission). */ -[scriptable, uuid(a77b664e-e707-4017-9c03-47bcedcb5b05)] +[scriptable, uuid(3d46b469-7405-416e-ba42-84899963b403)] interface nsICachingChannel : nsICacheInfoChannel { /** * Set/get the cache token... uniquely identifies the data in the cache. * Holding a reference to this token prevents the cached data from being * removed. * * A cache token retrieved from a particular instance of nsICachingChannel @@ -59,16 +59,24 @@ interface nsICachingChannel : nsICacheIn * the cache entry may be validated, overwritten, or simply read. * * The cache key may be NULL indicating that the URI of the channel is * sufficient to locate the same cache entry. Setting a NULL cache key * is likewise valid. */ attribute nsISupports cacheKey; + /** + * Instructs the channel to only store the metadata of the entry, and not + * the content. When reading an existing entry, this automatically sets + * LOAD_ONLY_IF_MODIFIED flag. + * Must be called before asyncOpen(). + */ + attribute boolean cacheOnlyMetadata; + /************************************************************************** * Caching channel specific load flags: */ /** * This load flag inhibits fetching from the net. An error of * NS_ERROR_DOCUMENT_NOT_CACHED will be sent to the listener's * onStopRequest if network IO is necessary to complete the request.
--- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -203,16 +203,17 @@ AutoRedirectVetoNotifier::ReportRedirect nsHttpChannel::nsHttpChannel() : HttpAsyncAborter<nsHttpChannel>(MOZ_THIS_IN_INITIALIZER_LIST()) , mLogicalOffset(0) , mPostID(0) , mRequestTime(0) , mOfflineCacheLastModifiedTime(0) , mCachedContentIsValid(false) , mCachedContentIsPartial(false) + , mCacheOnlyMetadata(false) , mTransactionReplaced(false) , mAuthRetryPending(false) , mProxyAuthPending(false) , mResuming(false) , mInitedCacheEntry(false) , mFallbackChannel(false) , mCustomConditionalRequest(false) , mFallingBack(false) @@ -2821,18 +2822,26 @@ nsHttpChannel::OnCacheEntryCheck(nsICach LOG(("Cached data size does not match the Content-Length header " "[content-length=%lld size=%lld]\n", contentLength, size)); rv = MaybeSetupByteRangeRequest(size, contentLength); mCachedContentIsPartial = NS_SUCCEEDED(rv) && mIsPartialRequest; if (mCachedContentIsPartial) { rv = OpenCacheInputStream(entry, false, !!appCache); *aResult = ENTRY_NEEDS_REVALIDATION; + return rv; + } else if (size == 0 && mCacheOnlyMetadata) { + // Don't break cache entry load when the entry's data size + // is 0 and mCacheOnlyMetadata flag is set. In that case we + // want to proceed since the LOAD_ONLY_IF_MODIFIED flag is + // also set. + MOZ_ASSERT(mLoadFlags & LOAD_ONLY_IF_MODIFIED); + } else { + return rv; } - return rv; } } bool usingSSL = false; rv = mURI->SchemeIs("https", &usingSSL); NS_ENSURE_SUCCESS(rv,rv); bool doValidation = false; @@ -3998,24 +4007,34 @@ nsHttpChannel::InstallCacheListener(int6 // We must close the input stream first because cache entries do not // correctly handle having an output stream and input streams open at // the same time. mCacheInputStream.CloseAndRelease(); nsCOMPtr<nsIOutputStream> out; rv = mCacheEntry->OpenOutputStream(offset, getter_AddRefs(out)); if (rv == NS_ERROR_NOT_AVAILABLE) { - LOG((" entry doomed, not writing it [channel=%p]", this)); - // Entry is already doomed. - // This may happen when expiration time is set to past and the entry - // has been removed by the background eviction logic. - return NS_OK; + LOG((" entry doomed, not writing it [channel=%p]", this)); + // Entry is already doomed. + // This may happen when expiration time is set to past and the entry + // has been removed by the background eviction logic. + return NS_OK; } if (NS_FAILED(rv)) return rv; + if (mCacheOnlyMetadata) { + LOG(("Not storing content, cacheOnlyMetadata set")); + // We must open and then close the output stream of the cache entry. + // This way we indicate the content has been written (despite with zero + // length) and the entry is now in the ready state with "having data". + + out->Close(); + return NS_OK; + } + // XXX disk cache does not support overlapped i/o yet #if 0 // Mark entry valid inorder to allow simultaneous reading... rv = mCacheEntry->MarkValid(); if (NS_FAILED(rv)) return rv; #endif nsCOMPtr<nsIStreamListenerTee> tee = @@ -5711,16 +5730,40 @@ nsHttpChannel::SetCacheKey(nsISupports * if (NS_FAILED(rv)) return rv; rv = container->GetData(&mPostID); if (NS_FAILED(rv)) return rv; } return NS_OK; } +NS_IMETHODIMP +nsHttpChannel::GetCacheOnlyMetadata(bool *aOnlyMetadata) +{ + NS_ENSURE_ARG(aOnlyMetadata); + *aOnlyMetadata = mCacheOnlyMetadata; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::SetCacheOnlyMetadata(bool aOnlyMetadata) +{ + LOG(("nsHttpChannel::SetCacheOnlyMetadata [this=%p only-metadata=%d]\n", + this, aOnlyMetadata)); + + ENSURE_CALLED_BEFORE_ASYNC_OPEN(); + + mCacheOnlyMetadata = aOnlyMetadata; + if (aOnlyMetadata) { + mLoadFlags |= LOAD_ONLY_IF_MODIFIED; + } + + return NS_OK; +} + //----------------------------------------------------------------------------- // nsHttpChannel::nsIResumableChannel //----------------------------------------------------------------------------- NS_IMETHODIMP nsHttpChannel::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
--- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -380,16 +380,17 @@ private: uint32_t mRedirectType; static const uint32_t WAIT_FOR_CACHE_ENTRY = 1; static const uint32_t WAIT_FOR_OFFLINE_CACHE_ENTRY = 2; // state flags uint32_t mCachedContentIsValid : 1; uint32_t mCachedContentIsPartial : 1; + uint32_t mCacheOnlyMetadata : 1; uint32_t mTransactionReplaced : 1; uint32_t mAuthRetryPending : 1; uint32_t mProxyAuthPending : 1; uint32_t mResuming : 1; uint32_t mInitedCacheEntry : 1; // True if we are loading a fallback cache entry from the // application cache. uint32_t mFallbackChannel : 1;
new file mode 100644 --- /dev/null +++ b/netwerk/test/unit/test_bug1064258.js @@ -0,0 +1,154 @@ +/** + * Check how nsICachingChannel.cacheOnlyMetadata works. + * - all channels involved in this test are set cacheOnlyMetadata = true + * - do a previously uncached request for a long living content + * - check we have downloaded the content from the server (channel provides it) + * - check the entry has metadata, but zero-length content + * - load the same URL again, now cached + * - check the channel is giving no content (no call to OnDataAvailable) but succeeds + * - repeat again, but for a different URL that is not cached (immediately expires) + * - only difference is that we get a newer version of the content from the server during the second request + */ + +Cu.import("resource://testing-common/httpd.js"); + +XPCOMUtils.defineLazyGetter(this, "URL", function() { + return "http://localhost:" + httpServer.identity.primaryPort; +}); + +var httpServer = null; + +function make_channel(url, callback, ctx) { + var ios = Cc["@mozilla.org/network/io-service;1"]. + getService(Ci.nsIIOService); + return ios.newChannel(url, "", null); +} + +const responseBody1 = "response body 1"; +const responseBody2a = "response body 2a"; +const responseBody2b = "response body 2b"; + +function contentHandler1(metadata, response) +{ + response.setHeader("Content-Type", "text/plain"); + response.setHeader("Cache-control", "max-age=999999"); + response.bodyOutputStream.write(responseBody1, responseBody1.length); +} + +var content2passCount = 0; + +function contentHandler2(metadata, response) +{ + response.setHeader("Content-Type", "text/plain"); + response.setHeader("Cache-control", "no-cache"); + switch (content2passCount++) { + case 0: + response.setHeader("ETag", "testetag"); + response.bodyOutputStream.write(responseBody2a, responseBody2a.length); + break; + case 1: + do_check_true(metadata.hasHeader("If-None-Match")); + do_check_eq(metadata.getHeader("If-None-Match"), "testetag"); + response.bodyOutputStream.write(responseBody2b, responseBody2b.length); + break; + default: + throw "Unexpected request in the test"; + } +} + + +function run_test() +{ + httpServer = new HttpServer(); + httpServer.registerPathHandler("/content1", contentHandler1); + httpServer.registerPathHandler("/content2", contentHandler2); + httpServer.start(-1); + + run_test_content1a(); + do_test_pending(); +} + +function run_test_content1a() +{ + var chan = make_channel(URL + "/content1"); + caching = chan.QueryInterface(Ci.nsICachingChannel); + caching.cacheOnlyMetadata = true; + chan.asyncOpen(new ChannelListener(contentListener1a, null), null); +} + +function contentListener1a(request, buffer) +{ + do_check_eq(buffer, responseBody1); + + asyncOpenCacheEntry(URL + "/content1", "disk", 0, null, cacheCheck1) +} + +function cacheCheck1(status, entry) +{ + do_check_eq(status, 0); + do_check_eq(entry.dataSize, 0); + try { + do_check_neq(entry.getMetaDataElement("response-head"), null); + } + catch (ex) { + do_throw("Missing response head"); + } + + var chan = make_channel(URL + "/content1"); + caching = chan.QueryInterface(Ci.nsICachingChannel); + caching.cacheOnlyMetadata = true; + chan.asyncOpen(new ChannelListener(contentListener1b, null, CL_IGNORE_CL), null); +} + +function contentListener1b(request, buffer) +{ + request.QueryInterface(Ci.nsIHttpChannel); + do_check_eq(request.requestMethod, "GET"); + do_check_eq(request.responseStatus, 200); + do_check_eq(request.getResponseHeader("Cache-control"), "max-age=999999"); + + do_check_eq(buffer, ""); + run_test_content2a(); +} + +// Now same set of steps but this time for an immediately expiring content. + +function run_test_content2a() +{ + var chan = make_channel(URL + "/content2"); + caching = chan.QueryInterface(Ci.nsICachingChannel); + caching.cacheOnlyMetadata = true; + chan.asyncOpen(new ChannelListener(contentListener2a, null), null); +} + +function contentListener2a(request, buffer) +{ + do_check_eq(buffer, responseBody2a); + + asyncOpenCacheEntry(URL + "/content2", "disk", 0, null, cacheCheck2) +} + +function cacheCheck2(status, entry) +{ + do_check_eq(status, 0); + do_check_eq(entry.dataSize, 0); + try { + do_check_neq(entry.getMetaDataElement("response-head"), null); + do_check_true(entry.getMetaDataElement("response-head").match('Etag: testetag')); + } + catch (ex) { + do_throw("Missing response head"); + } + + var chan = make_channel(URL + "/content2"); + caching = chan.QueryInterface(Ci.nsICachingChannel); + caching.cacheOnlyMetadata = true; + chan.asyncOpen(new ChannelListener(contentListener2b, null), null); +} + +function contentListener2b(request, buffer) +{ + do_check_eq(buffer, responseBody2b); + + httpServer.stop(do_test_finished); +}
--- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -153,16 +153,17 @@ skip-if = os == "android" [test_bug667818.js] [test_bug669001.js] [test_bug712914_secinfo_validation.js] [test_bug770243.js] [test_bug894586.js] # Allocating 4GB might actually succeed on 64 bit machines skip-if = bits != 32 [test_bug935499.js] +[test_bug1064258.js] [test_udpsocket.js] [test_doomentry.js] [test_cacheflags.js] [test_cache_jar.js] [test_channel_close.js] [test_compareURIs.js] [test_compressappend.js] [test_content_encoding_gzip.js]
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -10,16 +10,18 @@ #include "nsIFrame.h" #include "mozilla/Likely.h" class nsPresContext; nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder) : scriptingEnabled(false) , fragment(false) + , contextName(nullptr) + , contextNamespace(kNameSpaceID_None) , contextNode(nullptr) , formPointer(nullptr) , headPointer(nullptr) , mBuilder(aBuilder) , mViewSource(nullptr) , mOpSink(nullptr) , mHandles(nullptr) , mHandlesUsed(0) @@ -32,16 +34,18 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(n { MOZ_COUNT_CTOR(nsHtml5TreeBuilder); } nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink, nsHtml5TreeOpStage* aStage) : scriptingEnabled(false) , fragment(false) + , contextName(nullptr) + , contextNamespace(kNameSpaceID_None) , contextNode(nullptr) , formPointer(nullptr) , headPointer(nullptr) , mBuilder(nullptr) , mViewSource(nullptr) , mOpSink(aOpSink) , mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH]) , mHandlesUsed(0)
new file mode 100644 --- /dev/null +++ b/testing/config/tooltool-manifests/androidarm/releng.manifest @@ -0,0 +1,7 @@ +[{ +"size": 261782928, +"digest": "7140e026b7b747236545dc30e377a959b0bdf91bb4d70efd7f97f92fce12a9196042503124b8df8d30c2d97b7eb5f9df9556afdffa0b5d9625008aead305c32b", +"algorithm": "sha512", +"filename": "AVDs-armv7a-gingerbread-build-2014-01-23-ubuntu.tar.gz", +"unpack": "True" +}]
new file mode 100644 --- /dev/null +++ b/testing/config/tooltool-manifests/androidx86/releng.manifest @@ -0,0 +1,7 @@ +[{ +"size": 561274118, +"digest": "3b2d18eb0194d82c70c5ee17487ccbac309f9b2e9839fe7ca4a27a9a06f6338bb24394476da78559685d99151fccc85fdde03297aa73ee2f7fb3183e11925c4d", +"algorithm": "sha512", +"filename": "AVDs-x86-android-4.2_r1-build-2013-11-13-ubuntu.tar.gz", +"unpack": "True" +}]
--- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -218,22 +218,22 @@ class MochitestOptions(optparse.OptionPa "dest": "browserArgs", "metavar": "ARG", "help": "provides an argument to the test application", "default": [], }], [["--leak-threshold"], { "action": "store", "type": "int", - "dest": "leakThreshold", + "dest": "defaultLeakThreshold", "metavar": "THRESHOLD", - "help": "fail if the number of bytes leaked through " - "refcounted objects (or bytes in classes with " - "MOZ_COUNT_CTOR and MOZ_COUNT_DTOR) is greater " - "than the given number", + "help": "fail if the number of bytes leaked in default " + "processes through refcounted objects (or bytes " + "in classes with MOZ_COUNT_CTOR and MOZ_COUNT_DTOR) " + "is greater than the given number", "default": 0, }], [["--fatal-assertions"], { "action": "store_true", "dest": "fatalAssertions", "help": "abort testing whenever an assertion is hit " "(requires a debug build to be effective)", "default": False, @@ -605,16 +605,21 @@ class MochitestOptions(optparse.OptionPa if options.useTestMediaDevices: if not mozinfo.isLinux: self.error('--use-test-media-devices is only supported on Linux currently') for f in ['/usr/bin/gst-launch-0.10', '/usr/bin/pactl']: if not os.path.isfile(f): self.error('Missing binary %s required for --use-test-media-devices') + options.leakThresholds = { + "default": options.defaultLeakThreshold, + "tab": 10000, # See dependencies of bug 1051230. + } + return options class B2GOptions(MochitestOptions): b2g_options = [ [["--b2gpath"], { "action": "store", "type": "string", @@ -762,17 +767,17 @@ class B2GOptions(MochitestOptions): defaults["httpPort"] = DEFAULT_PORTS['http'] defaults["sslPort"] = DEFAULT_PORTS['https'] defaults["logFile"] = "mochitest.log" defaults["autorun"] = True defaults["closeWhenDone"] = True defaults["testPath"] = "" defaults["extensionsToExclude"] = ["specialpowers"] # See dependencies of bug 1038943. - defaults["leakThreshold"] = 5180 + defaults["defaultLeakThreshold"] = 5180 self.set_defaults(**defaults) def verifyRemoteOptions(self, options): if options.remoteWebServer == None: if os.name != "nt": options.remoteWebServer = moznetwork.get_ip() else: self.error("You must specify a --remote-webserver=<ip address>")
--- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -1837,17 +1837,17 @@ class Mochitest(MochitestUtilsMixin): self.log.error("Automation Error: Received unexpected exception while running application\n") status = 1 finally: if options.vmwareRecording: self.stopVMwareRecording(); self.stopServers() - processLeakLog(self.leak_report_file, options.leakThreshold) + processLeakLog(self.leak_report_file, options.leakThresholds) if self.nsprLogs: with zipfile.ZipFile("%s/nsprlog.zip" % browserEnv["MOZ_UPLOAD_DIR"], "w", zipfile.ZIP_DEFLATED) as logzip: for logfile in glob.glob("%s/nspr*.log*" % tempfile.gettempdir()): logzip.write(logfile) os.remove(logfile) self.log.info("runtests.py | Running tests: end.")
--- a/testing/mochitest/runtestsb2g.py +++ b/testing/mochitest/runtestsb2g.py @@ -197,17 +197,17 @@ class B2GMochitest(MochitestUtilsMixin): if status is None: # the runner has timed out status = 124 local_leak_file = tempfile.NamedTemporaryFile() self.app_ctx.dm.getFile(self.leak_report_file, local_leak_file.name) self.app_ctx.dm.removeFile(self.leak_report_file) - processLeakLog(local_leak_file.name, options.leakThreshold) + processLeakLog(local_leak_file.name, options.leakThresholds) except KeyboardInterrupt: self.log.info("runtests.py | Received keyboard interrupt.\n"); status = -1 except: traceback.print_exc() self.log.error("Automation Error: Received unexpected exception while running application\n") if hasattr(self, 'runner'): self.runner.check_for_crashes()
--- a/toolkit/modules/InlineSpellChecker.jsm +++ b/toolkit/modules/InlineSpellChecker.jsm @@ -154,16 +154,21 @@ InlineSpellChecker.prototype = { { this.mDictionaryMenu = menu; this.mDictionaryNames = []; this.mDictionaryItems = []; if (! this.mInlineSpellChecker || ! this.enabled) return 0; var spellchecker = this.mInlineSpellChecker.spellChecker; + + // Cannot access the dictionary list from another process so just return 0. + if (Components.utils.isCrossProcessWrapper(spellchecker)) + return 0; + var o1 = {}, o2 = {}; spellchecker.GetDictionaryList(o1, o2); var list = o1.value; var listcount = o2.value; var curlang = ""; try { curlang = spellchecker.GetCurrentDictionary(); } catch(e) {}
--- a/tools/profiler/GeckoTaskTracer.cpp +++ b/tools/profiler/GeckoTaskTracer.cpp @@ -195,44 +195,44 @@ GetCurTraceInfo(uint64_t* aOutSourceEven *aOutParentTaskId = info->mCurTaskId; *aOutSourceEventType = info->mCurTraceSourceType; } void LogDispatch(uint64_t aTaskId, uint64_t aParentTaskId, uint64_t aSourceEventId, SourceEventType aSourceEventType) { - NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId); + NS_ENSURE_TRUE_VOID(IsInitialized()); // Log format: // [0 taskId dispatchTime sourceEventId sourceEventType parentTaskId] } void LogBegin(uint64_t aTaskId, uint64_t aSourceEventId) { - NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId); + NS_ENSURE_TRUE_VOID(IsInitialized()); // Log format: // [1 taskId beginTime processId threadId] } void LogEnd(uint64_t aTaskId, uint64_t aSourceEventId) { - NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId); + NS_ENSURE_TRUE_VOID(IsInitialized()); // Log format: // [2 taskId endTime] } void LogVirtualTablePtr(uint64_t aTaskId, uint64_t aSourceEventId, int* aVptr) { - NS_ENSURE_TRUE_VOID(IsInitialized() && aSourceEventId); + NS_ENSURE_TRUE_VOID(IsInitialized()); // Log format: // [4 taskId address] } void FreeTraceInfo() {
--- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2828,16 +2828,21 @@ nsNativeThemeCocoa::DrawWidgetBackground DrawTabPanel(cgContext, macRect, aFrame); break; case NS_THEME_RESIZER: DrawResizer(cgContext, macRect, aFrame); break; } + if (hidpi) { + // Reset the base CTM. + CGContextSetBaseCTM(cgContext, CGAffineTransformIdentity); + } + nativeDrawing.EndNativeDrawing(); return NS_OK; NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } nsIntMargin
--- a/widget/gonk/GeckoTouchDispatcher.cpp +++ b/widget/gonk/GeckoTouchDispatcher.cpp @@ -344,18 +344,23 @@ IsExpired(const MultiTouchInput& aTouch) { // No pending events, the filter state can be updated. uint64_t timeNowMs = systemTime(SYSTEM_TIME_MONOTONIC) / 1000000; return (timeNowMs - aTouch.mTime) > kInputExpirationThresholdMs; } void GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch) { - if (aMultiTouch.mType == MultiTouchInput::MULTITOUCH_START && + if ((aMultiTouch.mType == MultiTouchInput::MULTITOUCH_END || + aMultiTouch.mType == MultiTouchInput::MULTITOUCH_CANCEL) && aMultiTouch.mTouches.Length() == 1) { + MutexAutoLock lock(mTouchQueueLock); + mTouchMoveEvents.clear(); + } else if (aMultiTouch.mType == MultiTouchInput::MULTITOUCH_START && + aMultiTouch.mTouches.Length() == 1) { mTouchEventsFiltered = IsExpired(aMultiTouch); } if (mTouchEventsFiltered) { return; } bool captured = false;
--- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -971,22 +971,22 @@ GfxInfo::GetGfxDriverInfo() nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_DISCOURAGED, DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL, (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_DISCOURAGED, DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions ); /** - * Disable D2D on Intel HD 3000 for graphics drivers <= 8.15.10.2321. - * See bug 1018278. + * Disable acceleration on Intel HD 3000 for graphics drivers <= 8.15.10.2321. + * See bug 1018278 and bug 1060736. */ APPEND_TO_DRIVER_BLOCKLIST( DRIVER_OS_ALL, (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelHD3000), - nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2321), "8.15.10.2342" ); /* Disable D2D on Win7 on Intel HD Graphics on driver <= 8.15.10.2302 * See bug 806786 */ APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_7, (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelMobileHDGraphics), nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,